</engineering>
The systems I have built, grouped by what they do. Each one links to its case study.
Live. Answers questions from the company’s own knowledge base and runs tasks with human approval: nothing goes ahead until a person signs off.
A small internal tool for his own work: notes, files, email and calendar synced into Postgres, searched and queried across all of it, with every answer cited back to the note, file, message or event it came from.
An internal assistant that answers from the company’s own knowledge base and runs tasks only after a person approves. Article and caption drafts are written only from a fact bundle built out of the database, and rejected on blocked claims.
A coordination layer for AI coding agents: one append-only ledger per room, a closed union of 23 event types, 29 MCP tools. Discontinued for now.
A small model fine-tuned on labels from a large one: 0.840 macro-F1 against 0.337 for a keyword filter on 500 held-out headlines, measured against the teacher’s labels.
A command-line linter for MCP servers: specification checks and safety heuristics over what a server declares.
A Claude agent with 34 tools, every input checked with zod. Writes come back as a proposal and run only after a tap. Search fuses Postgres full-text and pgvector with reciprocal rank fusion and cites the source of every hit. Claude Code reaches the same tools through an MCP server.
A Postgres-backed listings platform. Website enquiries are validated, stored with an insert-only key and forwarded to the control plane with a bearer secret and deduped on the lead id there.
Healthcare startup, admin portal and CRM
Through Startup Link, led a student engineering team. Upgraded the admin portal and CRM into one system and built the version now in use, with automation for lead intake and locum doctor onboarding and a connector layer to the applications the company already runs.
The internal systems and tooling a logistics company still runs its operations on. Built solo in eight weeks: live data feeds in place of a once-a-day spreadsheet update, role-based access for three roles, and a weekly report sent on a schedule instead of built by hand every Monday. Under NDA.
Google Calendar two-way, every 15 minutes and on push notifications, with an echo guard and a single stale-etag retry. Gmail through a read-only scope. Notes through GitHub. Approved mail leaves with a one-time token bound to the draft’s content hash.
A cron behind its own secret publishes what is due and once a week drafts an article from a fact bundle built out of the database. A draft with a blocked claim is rejected, and a person approves each one before it goes out.
An AI news app that turned a topic into a report with an event timeline and a blind spots section. Released on the App Store in March 2026; its news sources are paused for a revamp.
Built in SwiftUI for iOS 17: one observable app state, a state machine per report card, and a queue that processed one report at a time to bound API cost.
SwiftUI app that identified a trading card from the camera and showed its prices, with live and mock services behind one protocol. Discontinued in 2026.
A native shell around the web app in a WKWebView, seven WidgetKit widgets, and an app-only gate on the server.
Leads insert-only for the public key, a per-address rate limit, a bot check and a honeypot on the form. The content cron runs behind its own secret.
A statusline that never exits non-zero: every segment runs against one shared deadline, and a test asserts the line is never empty. Zero runtime dependencies.
This site: a Windows 95 desktop where every window is a server-rendered URL, with SEO parity, link and copy gates before each deploy.
20 cron jobs on 26 schedules, each recording its run, its error and its idle streak. Row level security forced on every table with owner-only policies, 58 migrations, 61 API routes, 160 test files. Pay-per-token model calls only on explicit opt-in.
Two pipelines. Enquiries: the website form validates input with a schema, a honeypot, a rate limit of five per minute and a bot check, inserts the lead with a public key that can insert but not read, then forwards it to the control plane with a bearer secret, where duplicates are ignored by lead id and the lead becomes a task. Content: a cron every four hours publishes what is due and once a week drafts an article from a fact bundle built from the database; drafts with blocked phrases are rejected and a person approves each one.
Google Calendar (two-way, with push notifications), Gmail through a read-only scope, the Obsidian vault through GitHub, git commit trailers and Claude Code sessions feed a Next.js app on Vercel with 61 API routes and 20 cron jobs on 26 schedules, each run recorded. JJ Marine website enquiries arrive at an ingest route that checks a bearer secret, validates the body and ignores duplicates by lead id. The app stores everything in a Supabase Postgres schema with 58 migrations and owner-only row level security, with full-text and vector search. It is read by the web app, a native macOS app with seven widgets, an MCP server for Claude Code, and this site through a public totals-only status endpoint. The Ask agent has 34 tools; anything that writes or sends is proposed first, and a send needs a one-time approval token bound to the draft.
TypeScript · Next.js · React · Node · Postgres (Supabase, row level security, pgvector) · Vercel (functions, cron) · Claude API and Agent SDK · MCP · zod · Vitest · Playwright · Swift and SwiftUI · Python