All projects

live ยท Oct 2026 to present

Stratum Desk

An operations desk for my IT and repair business that handles tickets, repair jobs, booking, texting, email, payments and an AI copilot in one web app.

  • Next.js 16
  • React 19
  • TypeScript
  • Better Auth (MFA)
  • Drizzle ORM
  • Postgres (embedded PGlite locally, Neon in production)
  • Vercel Blob
  • Anthropic SDK (Claude)
  • Stripe
  • Twilio
  • Zod
  • Vitest
  • Playwright
  • Vercel cron

My role

I directed AI (Claude Code, with Hermes Agent for some tasks) to build this. I decided the scope, pricing, safety rules and the human-approval design, and I tested the results. The AI wrote the code. The plan notes model tiering: a stronger model for architecture and review, a faster one for implementation. Git history shows two author names, both on this one PC. No other people are recorded as working on it.

What it is

Stratum Desk is the back office for my IT and repair business, Stratum Tech Group. One Next.js app is both the public website and the private desk where tickets, repair jobs with a timer and hourly billing, residential booking, two-way texting, email intake, Stripe pay links, a client portal and monthly client reports live.

It includes a Claude-powered ticket copilot that searches client records and documentation and drafts fixes. The copilot can only propose. A person approves before anything is published or sent, and it runs with limits on model rounds, tool calls and daily requests. The design docs also set a production spending cap of 5 dollars a day and 100 dollars a month for AI.

It exists so one person can deliver service like a small IT team. The docs say it is never sold as software. I am not claiming customer counts or revenue here because none are documented.

How it was built

  1. Started from an earlier IT desk designEarly IT desk design, build and test work was done on 5 to 6 Oct 2026 in a separate folder, then archived. On 10 Oct 2026 the IT version was restored into a clean folder and the first git commit was made, titled 'Restore Stratum Desk (IT helpdesk) from pre-EMS archive'.
  2. Wrote a plan and docs before featuresThe project has 25 documents in docs: plan, current state, deploy, SEO, the A2P texting campaign, testing, operating model and an AI harness spec. The plan assigns the stronger model to architecture and review and the faster model to implementation lanes.
  3. Split the code into domain modulessrc/modules holds separate folders for identity, access, clients, tickets, documents, search, agent, mail, storage, billing, booking, jobs, messaging, growth, maps, planner and more (at least 26 folders found; the listing was truncated). Screens in src/app stay thin and call these services.
  4. Locked down identity and accessBetter Auth handles sign-in with authenticator MFA and recovery codes. Public sign-up is disabled, staff are invite-only, and an access module decides which client records each employee can see. A console command (owner:init) issues a one-hour private link for the first owner enrollment.
  5. Built the database in small SQL migrations47 reviewed SQL migration files (0000 to 0048, with 0032 and 0037 unused) in db/migrations. Locally the app runs on embedded Postgres with pgvector on a loopback port. Production uses Neon.
  6. Added search and the bounded AI copilotSearch combines keyword retrieval with pgvector semantic search and reciprocal-rank fusion. The copilot is a manual Claude tool loop in src/modules/ai/claude.ts with limits of 5 model rounds and 8 tool calls per request. It cannot publish, send email, change accounts or run commands. Documents are proposals with text diffs and immutable approved versions.
  7. Connected texting, email, billing and bookingTwilio for two-way texting, nodemailer plus a signed mail relay endpoint for email intake, Stripe pay links for invoices, and a booking flow that creates a call slot and a texted status link. Cron endpoints run dispatch every 2 minutes, a sentinel every 5, an overseer every 30, geocoding every 10 and cleanup hourly (designed for the Vercel Pro plan).
  8. Built the front end and the public pages57 page routes cover the public site, the client portal and the desk screens. The front end was rebuilt on 12 Oct 2026 in a polished style with a gold accent, with dark mode. Git tags site-v1-original and site-v2-emil-rounded allow rolling the design back.
  9. Tested with unit and browser testsVitest unit tests, DB-backed harness tests and Playwright end to end tests. A project note from 14 Oct 2026 records all unit tests and all 23 e2e files passing.
  10. Deployed with a checklist after a bad deployThe site went live on Vercel (Hobby plan) with Neon, Blob, Stripe and Twilio on 12 Oct 2026. A deploy from a failed worktree shipped an empty folder and caused about 3 minutes of 404 errors. The fix was an assert-then-deploy checklist.

Decisions and why

The AI copilot proposes and a human approves
A wrong auto-sent message or published fix would hurt a real client. The agent harness spec forbids auto-sending.
Separate domain modules instead of logic inside pages
Keeps permissions, billing and AI behind services that every screen reuses, which makes the AI-written code easier to review.
Cap AI spending per day and per month
Usage can run away. The docs set 5 dollars a day and 100 dollars a month in production, plus per-user request limits.
Invite-only staff accounts with MFA and per-client access grants
The app stores client device and ticket data, so each employee should only see assigned clients.
Embedded Postgres locally, Neon in production
The desk runs fully offline on a loopback port for testing, with the same SQL migrations used in both places.

Hardest problems

A deploy from a broken worktree published an empty site and caused about 3 minutes of 404 errors on 12 Oct 2026.
An assert-then-deploy checklist that confirms the build output exists before deploying, plus tagged design rollbacks.
Texting compliance: the A2P campaign registration took four submissions.
Aligning the public texting page content with the campaign description, adding a sender spam guard and Cloudflare Turnstile on forms.
Local and production differ on upload limits (10 MB locally, 4 MB on Vercel) and cron frequency (Hobby plan allows only daily).
Documented both in docs/DEPLOY.md and designed the cron set for the Pro plan.
Keeping an AI agent from doing damage.
A bounded tool loop where every tool rechecks permissions, a draft-only agent, approval cards, audit log and undo.

Numbers

SQL migrations47 files (0000 to 0048)2026-11-06
Page routes572026-11-06
Documents in docs252026-11-06
Git commit entries144 of 181 reflog lines2026-11-06
Copilot limits per request5 model rounds, 8 tool calls2026-11
AI spending cap in production5 dollars per day, 100 dollars per month2026-10
Passing end to end test files232026-10-14

Timeline

  • 5 to 6 Oct 2026Earlier IT desk design, build and test work, later archived.
  • 10 Oct 2026Restored into a clean folder, first git commit, then repair jobs, live AI copilot and booking backend added the same day.
  • 12 Oct 2026Live on the web (Vercel, Neon, Stripe, Twilio). Front end rebuilt. A bad deploy caused about 3 minutes of 404s.
  • 13 to 14 Oct 2026Inbox merge, monthly client report, ticket copilot packages 1 to 4 verified.
  • About 18 Oct 2026Last commit in the history: in-home visit option with a free address check.

What I took from it

  • Writing the plan and safety rules first (human approval, spending caps, access scoping) made AI-written code far easier to review.
  • Deploys need an assert step. One empty deploy cost minutes of downtime and led to a checklist.
  • Third-party compliance such as A2P texting can take several attempts, so start it early.

Links