Flagship project · 2026

Spatchr

Field-service software for the office and the field, for businesses of any size: leads, estimates, scheduling, jobs, invoices, payments and an AI assistant, in one app that keeps working with no signal. I designed it, built it with AI coding agents, and deploy and run it myself.

app.spatchr.com/reports
Spatchr reports on the web: leads by source and revenue by source for the year
Jobs on a satellite map on a phone
My roleFounder, product designer, architect and operator. AI coding agents (mostly Claude Code) wrote the code under my direction.
PlatformsAndroid and web from one codebase (iOS next)
StackTypeScript, React Native / Expo, React Native Web, SQLite on device, Node, self-hosted PostgreSQL, Stripe Connect, Cloudflare R2, OpenRouter + Whisper
StatusLive at spatchr.com, entering beta with real field-service businesses

What Spatchr does

Spatch AI: ask your business anything

A voice and text assistant built into the app. Ask "who owes me the most?" and it answers from your real data. Ask it to book a job or record a payment and it shows you exactly what it will do, then waits for you to confirm.

  • 96% correct on 82 real-world requests, measured by an evaluation suite
  • About $0.56 per user per month, with every call metered
How it worksAn agent loop calls 6 tools generated from the app's data model. Changes go through preview, then confirm, then commit, using the same save path as the app's screens. Keys stay on my server, which relays to the model and to Whisper for voice. Full breakdown below.
Tool callingZodOpenRouterWhisperEvals
app.spatchr.com/jobs
A job Spatch AI created on the web, with the conversation beside it
One sentence in, a real job out: the customer, two line items, tax, and a visit booked for Tuesday at 9 AM
Spatch AI listing the clients who owe money
"Who owes me money?"
Spatch AI totaling materials spending, with a follow-up question
Follow-up questions

One app on the phone and the web

The same codebase runs the Android app and the full web app. On a desk it opens into a sidebar, wide tables and side-by-side previews. On a phone it becomes a bottom tab bar, cards and thumb-sized actions. I directed every screen of the UI, from layout and wording to how it should feel at a desk or on a job site.

How it worksReact Native with React Native Web and Expo Router, so one set of screens ships to both platforms. Underneath sits spatch-kit, my own UI kit of about 81 components (overlays, data tables, pickers, theming), shared with Shoptigo too. Layouts respond to screen size instead of being built twice, and tests keep the kit free of app-specific code.
React NativeReact Native WebExpo RouterNativeWindDesign system
app.spatchr.com/estimates
Every estimate in a wide sortable table on the web
Web: wide tables
Jobs as cards with call, text and directions on a phone
Phone: cards and quick actions

The whole business at a glance

The home screen answers an owner's first questions every morning: what's unscheduled, what's waiting on a customer's yes, who owes money, and what got paid. The pipeline shows every open job by stage with the dollars attached.

How it worksEvery number is computed locally in the app from its own database copy, so the dashboard loads instantly and works offline on the phone. Each metric has a stable ID, exactly one SQL query and a test that checks it, so a number can't silently change meaning.
SQLiteDrizzleReact Native
app.spatchr.com
Home dashboard on the web
Home on the web
Home on a phone
Home on a phone

Estimates and invoices customers actually see

Build an estimate on site, send it, and watch a live preview of the exact branded document the customer receives. The customer gets a link that opens the document on any phone, where they can accept it, decline it or request changes, and their answer shows up on the job right away. Approved estimates become jobs, and jobs become invoices that customers can pay online.

  • Server-assigned numbers and frozen snapshots, so a sent document never changes
  • Card payments with Stripe, and Tap to Pay on the phone
  • E-signed contracts with an evidence trail
How it worksWhen a document is finalized, the server assigns its number and freezes a snapshot of every line, price and tax. One renderer with zero dependencies draws that snapshot in the app, the preview and the public web viewer, so all three always match. Payments use Stripe Connect direct charges, so money goes straight to each business with a platform fee taken automatically.
Stripe ConnectStripe TerminalCloudflare PagesNode
app.spatchr.com/estimates/0044
Estimate with live document preview
The owner's view
The customer's estimate link on a phone, with Accept, Decline and Request Changes
The customer's link

Scheduling and dispatch

A dispatch board for assigning crews by the hour, and a calendar for the month. Service plans generate recurring visits automatically, and timesheets track who worked when.

How it worksA recurrence engine projects future visits from a rule instead of storing thousands of rows. A visit only becomes a real record when someone changes it, so a weekly service plan costs one row, not fifty-two.
Recurrence engineTypeScript
app.spatchr.com/scheduling
Scheduling calendar on the web
The month on desktop
The same schedule on a phone
The day on a phone

Jobs on the map, and an area measuring tool

Every job and property on a satellite map, clustered when zoomed out. The area tool lets you trace a driveway, roof or lawn with your finger and get its square footage and perimeter on the spot, then price the job from the measurement.

How it worksNative maps on the phone and Google Maps on the web. The polygon editor keeps an undo history, and areas are computed with Turf's geodesic math, so square footage is accurate at any zoom.
react-native-mapsGoogle MapsTurf.js
app.spatchr.com/map
Jobs on a satellite map
Tracing a driveway to measure 5,737 square feet

Works in the office and in the field

The full web app runs the office, and the phone app keeps working on a job site with no signal. Changes sync the moment a device is back online.

How it worksEvery read and write goes to SQLite on the phone first. Writes land in an outbox that's pushed to the server. Every server change is stamped with a version number, so a phone pulls only what's new. A realtime service nudges the phone the moment something changes, and Postgres row-level security decides what each person can receive. I designed this sync engine instead of buying one, and fuzz tests prove it holds up with many phones editing the same data offline.
SQLiteOutbox syncPostgreSQL RLSCentrifugoFuzz testing
Home on a phone
Today
Spatch AI on a phone
Spatch AI
Measuring a driveway on a phone
Area measuring
Map on a phone
Map

And everything else a service business needs

Leads and contactsEvery customer, property and conversation in one place
Lead intake APIWebsite forms and providers like CallRail and Angi feed leads in automatically
Pricing catalogServices priced per square foot, linear foot or item
Online paymentsStripe Connect pays each business directly; Tap to Pay on the phone
ContractsA clause library and e-signatures with an evidence trail
Teams and rolesOwners, office staff and technicians each see only what they should
ReportsRevenue, pipeline and team metrics for any period
NotificationsReminders, follow-ups and quiet hours, even offline
English and SpanishBuilt for bilingual teams

How Spatch AI is engineered

Built to be useful and safe enough to touch real business data. This is the part I'm proudest of.

Tools, not guesses

The assistant works through 6 tools generated from the app's own data definitions: 5 that only read (search, calculate, context, schedule, lookup) and 1 that acts. One schema both describes each tool to the model and validates what the model sends back.

Nothing changes without a yes

Every change goes preview → confirm → commit, and is checked against the user's role. The assistant writes through the same save path as the app's own screens, so it can't do anything a user couldn't.

Measured, not hoped

An evaluation suite grades it on 82 real-world requests (79 correct) and 15 curated scenarios. Every miss is written down. A test fails the build if the suite grades a tool the model isn't actually offered.

Cost and safety controls

Keys stay on the server, which relays to OpenRouter for the model and Whisper for speech-to-text. Production allows only vetted models. Every call is metered in micro-dollars, with a limit that stops abuse.

Hands-free

Built for people on ladders: speak a request, hear the answer, and the assistant keeps listening when it needs a follow-up.

Capped and contained

The agent loop runs at most 12 steps per request. Answers come from the business's own records, filtered by the same permissions as everything else.

How it's built

I don't read every line the AI writes. Nobody could at this size. Instead I make the decisions only a person can, and I build checks that prove the result is right.

Direct: the decisions that shaped it

Verify: proof instead of trust

35% of the codebase is automated tests: 211,000 lines across 770 test files, plus 140 rules that fail the build if the architecture is broken.

Ship: I run it