We Built Our Own Support Ticketing System
Production-grade, multi-tenant, offense-informed, and shipped in weeks — not months. This is why we did it, how we thought through it, and what it proves about the way ThinkOpen delivers technology.
April 2026
01 · The Decision
Why We Built Instead of Buying HelpSpot
HelpSpot is a respectable SaaS ticketing product used by many managed service providers. We evaluated it seriously. We chose to build our own anyway. Here is the thinking behind that call.
The criteria we scored against
Every technology decision at ThinkOpen runs through the same five-layer mental model: Technical · Security · Operations · Business · Human. HelpSpot won on operations — it ships today. It lost on the four that matter most over a five-year horizon.
| Criterion | HelpSpot (SaaS or Self-Hosted) | ThinkOpen Custom Build |
|---|---|---|
| Data ownership | Vendor-managed storage, export tied to their schema | Our Supabase instance, our schema, our backups, our encryption keys |
| Client compliance framing | "A third-party vendor holds your fiduciary client data" | "ThinkOpen holds it directly in an infrastructure we can audit line-by-line" |
| Customization velocity | Plugin API, support tickets, vendor roadmap wait times | New feature on Friday, shipped by Monday. No vendor dependency. |
| UX control | Generic vendor design, branding limited to logo swap | Apple-palette design language matching every other ThinkOpen deliverable |
| Five-year cost | Recurring seat-based licensing that grows with headcount | One-time build, near-zero marginal cost per engineer added |
| Security posture | Shared responsibility model — we inherit vendor CVEs | Offense-informed by design, CEH-mindset audited, remediated in-house |
| Proof to prospects | "We use HelpSpot" — zero differentiation | "We built ours in 120 hours. Imagine what we can build for you." |
The Strategic Insight
Every client engagement we win is partly because the prospect believes we can deliver technology at a level they cannot hire in-house. A ticketing system we use ourselves, built to a higher standard than the off-the-shelf alternative, at a fraction of the traditional build cost — that is not just internal tooling. It is a sales exhibit.
The honest risks we accepted going in
- Maintenance burden — we own it forever, we patch it forever. But we also own our stack end-to-end for clients we already support, so this was a capability we had to have regardless.
- Security responsibility — no vendor to blame. Which is exactly how ThinkOpen positions itself anyway: "offense-informed, we own our security outcomes." Building our own forced us to live that principle internally.
- Initial velocity risk — a traditional build might take months. Our AI-augmented workflow collapsed that to weeks. The economics section below shows the real numbers.
02 · Architecture
How It's Wired Together
One Next.js application, two subdomains, three identity flows, and a clean separation between client-facing and engineer-facing surfaces. Every box below is intentional — no accidental dependencies, no vendor lock-in traps.
App Router, server components, server actions. TypeScript throughout. Zero client-side state library — all state lives in the database and flows through server actions.
Postgres for structured data, Storage for files. Drizzle ORM for type-safe queries. Schema migrations run via node scripts against DATABASE_URL.
Microsoft Entra SSO with MFA and Conditional Access for staff. Resend magic link for clients, with DKIM on a dedicated subdomain. DMARC at p=none during observation.
03 · Progressive Delivery
From Zero to Production in Phases
We did not try to boil the ocean. Each phase shipped a working system — useful on its own — with the next phase building on the previous. This is how ThinkOpen delivers every client engagement: ship the minimum, prove it works, iterate with data.
Phase 0 — Foundation
Week 1Scaffolded the Next.js app, provisioned Supabase, wired NextAuth with magic link and Microsoft Entra SSO, designed the initial schema in Drizzle ORM. Deployed to Vercel on day two.
Phase 1 — Core Ticketing
Week 2Full ticket CRUD with status enums, priority levels, SLA config per priority, ticket numbering (YYYYMMDD-NNNNNN atomic counter), internal vs public comments with visibility control, audit log infrastructure.
Phase 2 — Organizations & Access
Week 2–3Parent/child organization hierarchy with domain-based child detection (email domain maps to subsidiary automatically), engineer-to-organization assignments, role-based access control (admin · engineer · viewer · client).
Phase 3 — Files & Rich Comments
Week 3File attachments with internal-by-default policy for engineers (compliance), Supabase Storage integration, file proxy API that never exposes signed URLs to the browser, overlay file viewer modal with blurred backdrop.
Phase 4 — Notifications & Workflow
Week 3–4Email notifications via Resend for status changes, assignments, resolutions, and mentions. Daily digest cron via Vercel Cron. Client satisfaction rating on resolved tickets. Ticket reassignment with full audit trail.
Phase 5 — Time & Money
Week 4–5Start/stop timers with pulsing live counter. Time entries linked to tickets and engineers with billable flag. Hour buckets (prepaid pools per engineer) with 50/75/90/100% threshold alerts. Idle timer auto-stop. Engineer hourly rate with inline Apple-style editor. Payroll with unpaid balance and self-healing for legacy zero-rate entries.
Phase 6 — Engineer Presence & Ops
Week 5Real-time engineer presence tracking (online / idle / busy / meeting / offline) via heartbeat API. Ticket takeover with audit and previous-assignee notification. Organization lifecycle (trash with 30-day recovery, auto-archive with 7-year retention). Disaster recovery backup/restore tool producing AES-256 encrypted bundles.
Phase 7 — Security Hardening: Portal Split
April 2026Triggered by a real incident: an engineer authenticated via magic link, bypassing our Microsoft Entra MFA and Conditional Access enforcement. We split the login surfaces in half — support.thinkopen.net became clients-only with magic link, staff.thinkopen.net became engineers-only with SSO. Server-side hard rejection layer added so the rule cannot be bypassed via direct HTTP calls. Shipped in one day.
Phase 8 — Unseen Gaps Audit
April 2026Because closing one attack path never means the system is done. Eight-gap offense-informed audit across privilege escalation, access control, rate limiting, session lifecycle, email authentication, endpoint authorization, and normalization edge cases. Seventeen findings surfaced — three Critical, two High, six Medium, six Low/Info. All Critical and High items remediated in a single atomic deploy.
Phase 9 — Email Authentication Foundation
April 2026Enabled Microsoft 365 DKIM signing via the new managed DKIM format. Published DMARC at p=none with aggregate reporting to dmarcian. Verified both outbound mail paths — M365-via-Barracuda and Resend-via-SES — pass SPF + DKIM + DMARC alignment. Now in the 14-day observation window before progressive enforcement.
04 · Capability Surface
Thirty-Plus Production Features
Every feature listed here is live in production, used daily, and has shipped code with a verification step. Nothing on this list is theoretical or roadmapped.
Ticketing Core
Full CRUD + SLA
Create, update, assign, resolve. SLA targets configurable per priority. Atomic YYYYMMDD-NNNNNN numbering.
Internal vs Public Comments
Engineers can post internal notes visible only to other engineers, or public replies visible to the client.
Domain-Based Auto-Assignment
Client email domain maps to a subsidiary organization automatically — no manual sorting.
Audit Trail
Every state change — status, priority, assignment, comment edit, takeover — logged with actor and timestamp.
Ticket Takeover
Engineers can take over tickets from colleagues with one click. Previous assignee gets notified.
Org Reassignment
Inline org dropdown on the contact card lets engineers correct mis-routed tickets.
Client Satisfaction Rating
Resolved tickets automatically prompt the client for a satisfaction rating.
Comment Edit with History
Internal comments editable with full audit trail — old value preserved.
Files & Rich Content
File Proxy API
Files stream through a server API route. Supabase signed URLs are never exposed to the browser.
Internal-by-Default
Engineer-uploaded files default to internal visibility. Compliance-safe without forcing a checkbox every time.
Overlay File Viewer
Images and PDFs open in a blurred-backdrop modal. No tab switching, no losing context.
Comment-Scoped Attachments
Files linked to specific comments, not just the ticket globally. Preserves conversational context.
Collapsible Long Content
Comments over five lines collapse to "Show more / less" — avoids the wall-of-text problem.
MIME Type Allow-List
Explicit allow-list of file types. 10 MB size limit. Uploaded filename sanitization.
Time & Money
Live Timers
Start/stop timer on any ticket. Pulsing red indicator. Live elapsed counter in the UI.
Idle Auto-Stop
Timers exceeding two hours auto-stop and email the engineer. Prevents forgotten-overnight timers.
Hour Buckets
Prepaid hour pools per engineer per organization. Progress bars with color escalation.
Threshold Alerts
Automatic email alerts at 50 / 75 / 90 / 100% bucket usage — admins get warned before overrun.
Engineer Hourly Rate
Per-engineer rate stored. Rate snapshotted onto time entries so retroactive changes do not rewrite history.
Payroll with Self-Healing
Unpaid balance computed with fallback to current rate for legacy zero-rate entries. Record-payment action backfills.
Time Reports
Rolling 30-day reports by engineer and by organization. Billable vs non-billable breakdown.
Inline Rate Editor
Apple-style inline editor with ✓/✕ buttons, Enter/Esc keys, and a "Saved" flash. No modal dialogs.
Identity & Access
Dual Portal
staff.thinkopen.net (SSO only) and support.thinkopen.net (magic link only) — enforced at UI, middleware, and server.
Configurable Staff Tenants
STAFF_TENANT_DOMAINS environment variable — add new owned domains without a code change.
Role-Based Access Control
admin · engineer · viewer · client. Checked at layout, action, and API layer.
Ticket Access Guard
requireTicketAccess() called on every ticket-scoped mutation. Cross-tenant actions impossible.
Engineer Management
Admin-only add/remove engineers. Elevation purges legacy sessions and forces SSO re-auth.
Parent/Child Org Model
Engineers assigned to a parent org automatically see all subsidiary tickets.
Operations & Reliability
Engineer Presence
Real-time online/idle/busy/meeting/offline tracking via heartbeat API. Visible in admin shell.
Daily Digest Cron
Vercel Cron runs daily at 7 AM Pacific. Sends per-engineer digest of open tickets grouped by age.
Org Lifecycle
Soft-delete to trash with 30-day recovery. Auto-archive after seven years via daily cron. Nothing lost, nothing clutters.
Backup/Restore Tool
One command produces an AES-256 encrypted ZIP of DB, storage, secrets, and code. One-command restore.
Rate Limiting
Per-user, per-email, per-IP limits on every mutation and public endpoint. HTTP 429 on violation.
Session Lifecycle
Seven-day max session age with 24-hour rolling refresh. Down from NextAuth default of 30 days.
05 · Offense-Informed Security
How We Think About Security
Security-by-design is a phrase everyone uses. The way we prove it is by running the same offense-informed playbook on our own product that we run on every client engagement — and publishing the findings.
The thinking behind every control
Before any feature ships, we ask the same five questions:
- What asset is at risk? Is it client data, session tokens, files, credentials?
- What is the threat vector? Who attacks this, how, and why?
- What is the current exposure? Is there a gap between the assumed control and the actual code?
- What is the recommended control? Not the obvious one — the one that makes the attack infeasible.
- What is the residual risk? What remains after the control, and is it acceptable?
This is the CEH threat modeling template applied to every architectural decision. When we wire a new server action, the question "how would an attacker abuse this?" is asked before the code is written.
Phase 1 — The Portal Split
A ThinkOpen engineer logged in via magic link one afternoon, bypassing the Microsoft Entra MFA and Conditional Access policies we had spent time configuring. It was not malicious — they were tired and clicked the wrong button on a login page that offered two equivalent-looking options. But the consequence was real: a staff session established without MFA, outside Conditional Access, invisible to our identity audit trail.
The standard response would have been a Slack reminder. We treated it as a design failure and rebuilt the login architecture in a day.
What we shipped
- •Two subdomains, two surfaces. support.thinkopen.net shows only the magic link form. staff.thinkopen.net shows only the Microsoft SSO button. Neither option exists on the other.
- •Host-aware rendering via server-side headers() detection — same route file, different UI depending on which subdomain served the request.
- •A hard server-side rejection layer. Even if an attacker bypasses the UI and posts directly to the auth API with a staff email, the signIn callback refuses the attempt. UI is defense-in-depth. The callback is the boundary.
- •Configurable tenant policy via environment variable, so adding future staff domains is a zero-code change.
Shipped and Verified
Five end-to-end tests covering every combination of email, portal, and bypass attempt. All passed before traffic was allowed through.
Phase 2 — The Unseen Gaps Audit
Closing the portal gap surfaced an uncomfortable question: what else might be wrong that we have not looked at? ThinkOpen's standard engagement methodology includes a passive-recon and gap-analysis pass on every client. We ran that same playbook on ourselves.
The eight audit gaps
| Gap | What we looked for | Result |
|---|---|---|
| A · Privilege Escalation | Every code path that assigns elevated roles. Can an attacker get there without MFA? | Critical · Found |
| B · Rate Limiting | Endpoints that send email, SMS, or create state. Are they protected from enumeration and abuse? | High · Found |
| C · Email Authentication | SPF, DKIM, DMARC. Can someone spoof our domain with no downstream block? | Critical · Found |
| D · Session Lifecycle | How long do sessions live? Can an exfiltrated cookie be used from a different device? | Medium · Found |
| E · Dual-Linked Accounts | Are any identities linked to multiple providers in ways that create lateral-move paths? | Clean |
| F · Hidden Routing | Any redirects or rewrites configured outside the repo that could be a blind spot? | Low · Found |
| G · Normalization Gaps | String comparisons used as security boundaries. Do they handle whitespace, unicode, case? | Medium · Found |
| H · Endpoint Authorization | Every API route and server action. Does the auth check match the data being accessed? | Critical · Found |
What came out of it
Seventeen findings total, categorized and ranked. Three required immediate action, two were high-priority, six were medium, six were low or informational. The audit itself is documented in a separate ThinkOpen-branded internal report.
Infrastructure disclosure, privilege escalation bypass, and absence of email spoofing defense. All remediated in the first deploy.
Cross-tenant IDOR on ticket-scoped actions and zero rate limiting on the sign-in endpoint. Both closed in the same sprint.
Session hardening, normalization, policy cleanup. Staged across subsequent sprints without urgency.
Sprint 1 Remediation — One Atomic Deploy
Every Critical and every High finding, plus three of the Mediums, shipped as a single verified deploy. The shape of the work:
Infrastructure exposure
A debug endpoint that had been helpful during initial development was still public and responding to unauthenticated requests. Deleted. Whatever diagnostic information remains necessary is captured in server logs instead.
Privilege escalation boundary
The admin action that elevates a user to engineer role now requires the target email to be in the staff tenant allow-list, purges any existing sessions on the user being elevated, deletes any legacy magic-link account rows, and writes a structured log entry. An admin can no longer accidentally elevate a client, and an attacker with a live client session cannot have it silently upgraded to engineer privilege.
Cross-tenant access control
Every server action and API endpoint that accepts a ticket identifier from user input now calls requireTicketAccess() before operating. A client in organization A cannot post comments on, upload files to, or take any action against a ticket in organization B, regardless of whether they know the ticket identifier.
Authentication abuse prevention
Magic-link sending is now rate-limited per email at five requests per 15 minutes. Public chat and form endpoints are rate-limited per IP at five and three per hour respectively. The limits return HTTP 429 on violation, proven in smoke test.
Session lifecycle tightening
Session max age reduced from NextAuth's 30-day default to 7 days with a 24-hour rolling refresh window. An exfiltrated session cookie has a three-week shorter validity window.
Normalization hardening
Staff tenant email matching now applies .trim() and Unicode NFKC normalization before the domain comparison. Closes a subtle class of bypass where a raw HTTP client sends whitespace or compatibility characters that browser forms would strip but the server would miss.
Deploy Smoke Tests
Four smoke tests verified in production immediately post-deploy: debug endpoint returns 404, both portal login surfaces render correctly, and rate-limit enforcement returned HTTP 429 on the fourth through sixth requests to a public form endpoint within a minute.
Sprint 2 — Email Authentication
The Critical-3 finding was the absence of a DMARC record on thinkopen.net. An attacker could clone one of our ticketing sign-in emails, spoof the sender, and harvest credentials from clients who had been trained to click our links. Fixing this required more than a DNS record — it required a staged rollout with observation data, which is why it is its own workstream.
What we shipped on day one
- •Microsoft 365 DKIM enabled for thinkopen.net using Microsoft's new managed DKIM format, hosted on Azure DNS via an ICANN-delegated brand TLD.
- •DMARC TXT record published at p=none with aggregate reporting going to dmarcian — observation mode, no mail flow impact.
- •mail-tester.com verification on both outbound paths: M365-via-Barracuda scored 10/10, Resend-via-SES scored 8/10 with the two lost points being transient shared-IP blocklist noise, not authentication failures. DMARC alignment passed on both paths.
The progressive enforcement plan
Day 1 to Day 14 is pure observation. Aggregate DMARC reports flow into dmarcian and we watch for any legitimate sender that is failing alignment, for spoofing attempts, and for the volume baseline. At Day 15 — assuming clean reports — the policy moves to p=quarantine. At Day 22, if still clean, it moves to p=reject. That is the end state: spoofed mail from our domain gets refused at the receiving server.
At no point during this rollout does any change touch Barracuda Email Security Gateway, Exchange Online connectors, accepted domains, or mail flow rules. The only things that move are DNS records and a DMARC policy string.
Data Safety Note
This case study intentionally omits specific file paths to vulnerable code as it existed before remediation, infrastructure identifiers (project IDs, API key prefixes, IP addresses), and specific ticket identifiers or client data beyond publicly-known engagement names. The audit report with full technical detail is an internal-only document. Everything here is safe to share externally.
06 · UX & Human Behavior
Design Choices Rooted in How People Actually Work
Good security UX is not about friction. It is about making the right path the easy path, and the wrong path structurally unavailable. Every design decision in this product traces back to either a specific user-behavior observation or an offense-informed threat model.
Path of least resistance wins every time
Humans, even trained ones, take the fast path under cognitive load. A single login page with two equivalent-looking options will produce the "wrong path" behavior a nontrivial fraction of the time. The solution is not to add a warning label — it is to remove the wrong option entirely from the surface where it does not belong. Hence the dual portal. Clients never see the SSO button. Engineers never see the magic link field. The decision is made by the URL, not the user.
Subtle cues get ignored under load
During the portal split design review, the first proposal was a small "Staff? Use Microsoft" label under the magic link form. We rejected it. A label the user has to read, recognize themselves in, and consciously act on is three failure points stacked. Either the distinction is loud enough to route behavior, or it is decoration. We picked loud.
Apple palette, no exceptions
Every surface — ticket list, admin dashboard, settings, login, email templates — uses the same color vocabulary, the same typography stack, the same spacing rhythm. One accent, one critical, one success, one warn, one info. Orange means "pay attention." Red means "do not do this." Blue means "primary action." Consistency across surfaces reduces the cognitive tax of learning the interface.
Inline editing, never modal dialogs
Browser prompt() dialogs are an anti-pattern. They break context, they cannot be styled, they cannot be keyboard-navigated consistently. Every inline edit in this product is a compact form that appears in place with ✓ and ✕ buttons, supports Enter to save and Escape to cancel, and flashes a brief "Saved" indicator on success.
Files open in place, not in new tabs
A "new tab" file view loses conversational context. Our file viewer is an overlay modal with a blurred backdrop — the ticket remains visible, the file is the focus, one click dismisses and you are exactly where you left off.
Collapsible long content
Long comments become wall-of-text noise that flattens the reading hierarchy. We automatically collapse comments over five lines to a "Show more" preview. The default view remains scannable.
Real-time presence because silence is confusing
When a client files a ticket and then wonders "did anyone see it," the cost is low-grade anxiety and sometimes a follow-up email that doubles our ticket volume. Our admin shell surfaces engineer presence — online, idle, busy, meeting, offline — so admins can route work to the right person, and so clients asking over the phone "is anyone there" get an accurate answer.
07 · The Economics
What This Would Have Cost — Three Ways
A fair comparison requires an honest scope and honest rates. Below is the scope of work in hours, estimated from the actual feature set, the actual security remediation work, and the actual email authentication rollout. Then the same scope costed three ways.
The scope in hours
Summing the major work streams at traditional-shop velocity (one senior engineer, no AI augmentation, full test coverage, PM overhead):
| Work Stream | Est. Hours |
|---|---|
| Authentication — dual portal, SSO, magic link, role-based layouts | 60 |
| Ticketing core — CRUD, SLA config, numbering, enums, state machine | 80 |
| Comments and attachments — visibility model, file proxy, overlay viewer | 50 |
| Organization hierarchy — parent/child, domain detection, trash lifecycle | 40 |
| Engineer management — presence, assignments, takeover, audit log | 40 |
| Time tracking — timers, entries, buckets, alerts, idle detection | 80 |
| Payroll — hourly rates, unpaid balance, self-healing queries | 30 |
| Email notifications — templates, triggers, daily digest cron | 30 |
| Admin UI — settings, reports, dashboard, engineers page | 60 |
| Client portal UI — ticket list, ticket detail, rating flow | 30 |
| File storage pipeline — upload, proxy API, preview modal, MIME allow-list | 40 |
| Audit log infrastructure and enum coverage | 20 |
| Backup and restore tooling — encrypted bundles, one-command restore | 20 |
| Bug fixing and testing across the build | 40 |
| Security audit — eight-gap offense-informed pass and report | 12 |
| Remediation — ten security fixes in one atomic deploy | 12 |
| DMARC and DKIM hardening, vendor evaluation, rollout plan | 8 |
| Total | 652 |
Traditional Dev Shop
- Senior engineer rate$200/hr
- Base hours652
- Base cost$130,400
- PM + QA overhead+25%
- Design consultingincluded
- Timeline3–4 months
- AI augmentationminimal
Senior Freelancer
- Freelancer rate$125/hr
- Base hours652
- Base cost$81,500
- Rework cycles+15%
- Design polishextra
- Timeline4–6 months
- AI augmentationvaries
ThinkOpen
- Blended rate$187.50/hr
- Effective hours~130
- Base cost$24,375
- Verification + test+15%
- Design systemreused
- Timelineweeks
- AI augmentation5× velocity
Why the ThinkOpen number is what it is
Our rate is not cheap. $175–200 per hour is a premium rate that reflects senior engineering and a security-first methodology. The savings do not come from cheaper labor — they come from roughly five-times velocity on well-scoped work, driven by AI augmentation applied by an engineer who already owns the client context and the stack.
What a traditional shop bills for eight hours of research, scaffolding, and boilerplate, we can produce in under two hours because the AI does the boilerplate while the engineer stays at the architectural level. That ratio holds across most of the build except the work that genuinely requires deep, slow thinking — security audit, threat modeling, and remediation design — where we spend the same human time a traditional shop would, because that work is where the value lives.
Compared to HelpSpot
HelpSpot cloud pricing at our engineer count is roughly $1,000 to $2,500 per year, recurring forever, in exchange for generic UX and no customization velocity. Over a five-year horizon, $5,000–$12,500 of license cost buys you a product you do not control. Our $28,000 buys a product we can extend at will and use as a sales exhibit.
Hidden Value Beyond the Line Items
Every feature we ship here becomes institutional knowledge, reusable code, and a reference implementation for client engagements. Time tracking with bucket alerts is not just our internal tool — it is a capability we now know how to build for any client in days, not months.
08 · Production Snapshot
What Is Live Right Now
As of April 2026. This system is handling real client tickets from real organizations today.
TrusteeCorps, Ground Up Renovations, Sysblocks — plus ThinkOpen internal.
Parent/child hierarchy in production under TrusteeCorps.
Every one in production use, documented, and tested.
Every finding from the Phase 2 audit has a remediation state.
Current security posture
| Control | State | Notes |
|---|---|---|
| Dual portal authentication | Live | Five E2E tests passed |
| Cross-tenant access control | Live | requireTicketAccess on every action |
| Privilege escalation boundary | Live | Session purge on role elevation |
| Rate limiting — auth paths | Live | Per-email and per-IP |
| Rate limiting — public endpoints | Live | HTTP 429 verified in smoke test |
| Session lifecycle | Live | 7 days max, 24h rolling |
| Email: SPF | Live | Outlook + Barracuda + Resend |
| Email: DKIM (M365) | Live | Managed DKIM via Microsoft |
| Email: DKIM (Resend) | Live | Subdomain-based, signed |
| Email: DMARC | Observing | p=none, 14-day window |
| Disaster recovery | Live | Encrypted backup + restore tool |
09 · What's Next
The Roadmap From Here
Every item on this list is planned, not speculative. Each one has a defined trigger and a defined outcome.
Two weeks out
- •DMARC to quarantine — after 14 days of clean observation data from dmarcian, move the DMARC policy from p=none to p=quarantine. One-line DNS change, reviewed against the aggregate reports.
- •Sprint 2 Medium findings — viewer role scope audit, IP-layer rate limiting for authenticated actions, magic-link email template refresh.
- •Rate limit store to Vercel KV — migrate from the in-memory serverless store so limits enforce consistently across instances.
Four weeks out
- •DMARC to reject — the end state. Spoofed thinkopen.net mail refused at the receiving server.
- •Add additional staff tenant domains to the allow-list via environment variable once the accounts are ready for MFA enrollment.
- •Mobile keyboard fix for the known iOS landscape input issue.
Productization track
- •Multi-tenant extraction — the product is architected as multi-tenant today but configured as single-tenant. Separating the tenant boundary is a known task for the SaaS productization path.
- •Self-serve onboarding — if we ever ship this as a SaaS for other MSPs, the onboarding flow needs to handle org creation, domain verification, and initial admin provisioning automatically.
- •Pricing model evaluation — per-engineer, per-ticket, or flat infrastructure fee. Market research needed.
Continuous posture
- •Quarterly offense-informed audit — same eight-gap playbook applied every three months against the current codebase.
- •Dependency update discipline — Next.js, Supabase client, NextAuth, Drizzle ORM. Watch the release notes. Patch within 72 hours of any advisory.
- •Client feedback loop — client satisfaction ratings surface in the weekly digest and feed directly into feature prioritization.
10 · The Pitch
This Is What We Can Build For You
If ThinkOpen's internal ticketing platform can ship at this velocity, with this security posture, at this economics — imagine what that capability looks like pointed at your infrastructure problem.
For IT leaders
Custom internal tooling, client portals, audit dashboards, compliance reports. Built at weeks-not-months velocity. Owned by you, not a vendor.
For security-conscious firms
Offense-informed design reviews, penetration test readiness, DMARC/DKIM rollouts, M365 hardening, incident response retainers, quarterly audits.
For regulated industries
Fiduciary-grade data handling, compliance-aware architecture, lender/insurer-ready documentation, end-to-end encryption, disaster recovery runbooks.
424.437.8173 · info@thinkopen.net