THE PROBLEM
The job takes an hour. The work around it does not stop.
From outside, a service call looks simple: someone books, a technician shows up, the work gets done. Around that hour sit a dozen small jobs, each a few minutes long: answer the enquiry, quote it, find a time that fits the day, confirm it, remind them the night before, tell them when the tech is on the way, take before and after photos, write the report, send the invoice, chase the payment, ask for a review, and remind them next year.
In my previous business those steps ran on several tools joined together, which worked until it didn't: the tools fought the way the business actually ran, and charged for features nobody used. So for Aeris I started from the work, not the software, and built one app around it.
WHAT I BUILT
One app, four ways in
One app and one database. Each person lands in the part their role needs, and nothing is typed twice.
FOR CUSTOMERS
- Online booking in three steps: a service and add-ons from the price book with a running total, a date and time, then their details, with the address found as they type.
- A quote request for homes and businesses, which arrives as a lead.
- Spam kept out with a bot check, a hidden trap field, and limits per phone number and connection.
FOR THE OFFICE
- A leads board, drag and drop, with spam and duplicates set aside and returning customers marked.
- Jobs, a calendar and a map of the day's jobs, filtered by technician.
- Customer records with every address, message and statement, and duplicate customers found and merged.
- Quotes, invoices and payments, including one payment split across several invoices, and refunds.
- One inbox and reports: customers, the team and each job in one place; reports by technician, money owed by age, and where customers came from.
FOR TECHNICIANS
- Today's jobs on the phone, plus anything left unfinished this week.
- On my way: the app suggests an arrival time from live traffic, the tech approves it, and the customer gets a text. The tech's location is never stored.
- Photos with a before and after mode that lines the two shots up, notes drawn on the photo, and uploads that wait for signal.
- Completion forms, an invoice and a pay link, all on the spot.
BY LINK, FOR THE CUSTOMER
- The invoice, with a Pay now button. Card payments are live.
- The quote, which they can accept online.
- The service report, with before and after photos side by side.
- Their statement, and a PDF of each of the four.
HOW IT FLOWS
How a job moves through it
Each step hands the next one what it needs, so nobody copies details from one screen to another. The amber step is the one a person decides.
- Booked onlineService, add-ons, a time and the address, checked against the schedule.
- ConfirmedA text and an email at once. Texts go only to a number that can take them.
- RemindedOne reminder the evening before, by text, or by email when there is no mobile.
- On the wayThe tech approves the arrival time; the customer gets it by text.
- Photos and reportBefore and after photos lined up, and a completion form.
- InvoicedSent from the job with a pay link. Card payments go straight through.
- PaidReminders until it is paid, a receipt when it is. The job closes only when it is paid and its report is done.
- Next timeReview requests and a yearly service reminder are built in.
Runs on its ownA person decides
THE SIZE OF IT
What is under the hood
- 74screens: 52 for the office, 6 for technicians, 16 for customers
- 163server routes behind those screens
- 1,588automated tests, from single functions to whole screens
- 14background jobs sending confirmations, reminders and reports
Built from March 29 to October 12, 2026, in 1,848 changes to the code. 776 of them were written with Claude Code. I set the requirements, the workflow and every decision, and checked each change against how the business actually runs; the AI wrote much of the code under that direction.
Built to protect customers and their data
- Each person sees only what their role allows: 27 permissions across owner, admin, dispatcher and technician, enforced in the database itself, not only on the screen.
- Deactivating someone ends their access on their next click.
- A repeated payment notice can never record a payment twice, and a reminder checks before it sends, so nobody gets the same message twice.
- An email counts as sent only when the provider confirms it.
WHAT I DID
What I did
Every step in the flow is one I had done by hand, so the requirements came from the work itself.
Each step from enquiry to next year's reminder: who does it, and what it needs from the step before.
The data model, the roles and permissions, the screens for each person, and when each message fires.
With Claude Code as my coding partner, in 1,848 changes over six and a half months.
1,588 automated tests across the server, the screens and how they look.
Card payments proven with a real payment and refund, and a morning email listing anything that failed quietly.
BUILT WITH
Built with
- Next.js
- React
- TypeScript
- Tailwind CSS
- Supabase (Postgres, Auth, Storage)
- Inngest
- Stripe
- RingCentral (texts)
- Resend (email)
- Google Maps Platform
- Cloudflare Turnstile
- Vercel
- Claude Code