MSP operations platform · Live in production
Warp
The system my IT company runs on: tickets, billing, documentation, security work, phones and the client portal, in one place instead of six.
Role: Product design, flow design, and direction of the agents that wrote it.
Timeline: Ongoing — in daily production use
- Kinds of information tracked
- 137
- Things it can do
- 788
- Lines of code
- ~224k
- Automated test files
- 120
- Commits
- 3,325
Distinct record types in the data model, from counting the table definitions in the schema file. Counted on 21 September 2026.
Separate operations the system can perform, from counting the HTTP endpoints registered in the server code. Counted on 21 September 2026.
Across 557 TypeScript files, excluding generated migrations and build output. Counted on 21 September 2026.
Files of automated tests that run on every change. Counted on 21 September 2026.
Individual changes recorded in the project history, from git rev-list --count HEAD. Counted on 21 September 2026.
What was actually broken
A managed IT company runs on a stack of tools that don't know about each other. Ticketing in one, invoicing in another, documentation in a third that nobody updates, security compliance in a spreadsheet, and the phone system off to the side entirely.
The cost isn't the licences. It's the seams. Time gets worked and never billed because it lived in the wrong tab. Documentation goes stale the moment the person who wrote it fixes the thing a different way. A client asks "what did you actually do for us last month" and answering honestly takes an afternoon.
Warp is what happens when you stop integrating those tools and build the thing they were all approximating.
The flow I designed
The whole platform is organised around one question a technician asks constantly: what should I be working on right now?
Almost every design decision follows from taking that question seriously.
The day starts with what's rotting, not with what's newest. Tickets that have gone quiet get pinned to the top of the queue rather than sinking down it. A list sorted by recency is a list that hides its own failures.
Snoozing is a first-class action. "Not now" is the most common honest answer about a ticket, and every system that lacks a word for it gets that answer expressed as an ignored row instead. Snoozed work comes back on its own.
The phone never moves. It is built once and stays put, so a call survives you navigating anywhere else. This is the decision people feel most, every day.
Clients get a door, not a login. Their portal opens from a private link sent to them. No password to set, none to forget, and no support ticket about the password for the ticket system.
Documentation is a by-product of the work, not a second job. When a ticket resolves, the system drafts the documentation from what actually happened. Nobody has ever reliably written docs as a separate task, and building as if they would is a design failure dressed up as a process problem.
Interface notes
The sidebar is mounted once
Built once, never rebuilt. That is why a call in progress survives you navigating anywhere.
One badge is drawn heavier than the rest
“Customer Reply” is filled; every other status is a quiet outline. A waiting customer is the one that costs you the client.
Going quiet is a visible state
Nine days quiet earns a marker instead of sinking down the list. Sorting by newest hides your own failures.
The queue answers a question
The panel says what to do next and why. Ranking is the product; the list is just the evidence.
Every document knows where it came from
That is a link, not a label. If you cannot walk back to the job it came from, it is just generated text nobody can check.
Drafted, then updated, not overwritten
Marked as written or updated by AI, with a version. A later job revises the page rather than adding a second one.
A technician can always correct it
There is a box at the bottom of every document for a technician to correct it. When people cannot fix what the AI got wrong, they stop trusting all of it.
It refuses to be generic
Step zero is not security work. It is learning what this client actually runs, because advice that fits everyone fits nobody.
It asks rather than assumes
It says what it does not know and asks for one thing at a time, rather than handing over a 200-row spreadsheet.
Sequenced, not listed
Five stages, each with its own progress. Nobody starts on policy while the backups are still unchecked.
The hard part
Making the write-up happen exactly once.
The writing was never the hard part. "When a job is finished, write it up" is a deceptively difficult sentence.
A job can be marked finished twice. Two people can finish it in the same moment. The server can restart halfway through. Each of those turns a helpful feature into either duplicated nonsense or a write-up that never happened — and never happening is worse, because nothing looks broken.
The answer is unglamorous: before anything gets written, the system claims the job so nothing else can pick it up. Anything claimed but left unfinished gets swept up and retried later.
That is the shape of most of this work. The feature is easy. The guarantee is hard.
Stack
| Frontend | React 18 + Vite, Wouter, TanStack Query |
|---|---|
| UI | shadcn/ui on Radix, Tailwind, framer-motion, TipTap, dnd-kit |
| Backend | Express + TypeScript, bundled with esbuild |
| Database | PostgreSQL (Neon) + Drizzle ORM |
| Auth | Two systems: session + TOTP 2FA for staff, signed tokens for the client portal — Staff and clients have genuinely different threat models; sharing one auth system would have compromised both. |
| Payments | Stripe, with Bill.com invoice sync |
| Resend, SendGrid, MailerSend and Gmail API, behind one interface | |
| Telephony | Twilio voice, SMS and video — softphone, IVR, voicemail |
| AI | Claude primary with an OpenAI fallback, behind a single aiChat() call |
| Storage | Google Cloud Storage |
| Testing | Vitest, colocated with source |
| Hosting | Replit autoscale + Neon Postgres |
Outcome
Warp runs a real business every day. It replaced the ticketing system, the invoicing, the documentation wiki, the security-compliance spreadsheets, and the phone system.
It was built from the start to run more than one company, with every request checking that you are only ever shown your own data — so it can take on other IT firms, not just mine.