Detailing Booking Platform
A booking and operations platform that runs a detailing business end to end, website, scheduling, payments, and back office.

The business serves Vancouver and the Lower Mainland, detailing vehicles at customers' locations and in its own garages. The build spans three applications: a public marketing and booking site, a staff back-office panel, and an API that runs scheduling, payments, and automation, all sharing one PostgreSQL domain model.
The platform replaces separate tools for website, booking, scheduling, payment collection, refund tracking, and customer follow-up with a single source of truth. Customers book multi-vehicle visits online with verified contact details; staff review, approve, and collect payment through hosted Square checkout links; and scheduled jobs carry the routine communication load.
Everything a visitor sees on the public site, packages, pricing, hero images, before/after galleries, testimonials, FAQs, policies, is edited in the admin panel, with targeted cache invalidation putting changes live in seconds without a deployment.
A business that generic booking tools handle badly
A single appointment here is not one service, it is a visit that can cover several vehicles, each with its own package, add-ons, condition, and even its own fulfillment mode: the crew drives to the customer, or the car comes to a garage. Off-the-shelf scheduling software has no model for that.
Money moves in stages. Quotes are approved by staff before payment; customers may pay upfront or after the work, by card, e-transfer, or cash; and when part of a multi-car order is declined after payment, someone has to know exactly who owes whom what. Layer on Canadian sales tax that differs by province, mobile jobs that depend on site conditions, and staff who live in a calendar, and the operation needed purpose-built software.

Orders, not appointments, and payments gated on approval
The domain model separates the booking order, one visit, one time slot, one payment position, from its lines, one per vehicle, each with its own service, add-ons, price, and status. Staff can accept some vehicles and decline others; the order total recalculates while a frozen original-value snapshot preserves what was quoted. This one modeling choice is what makes partial declines, partial refunds, and honest reporting possible.
Customers do not pay at submit time. They book, staff review and accept, and the system then emails a hosted Square payment link for the exact accepted amount. If the amount later changes, the old link is destroyed and a fresh one issued, the customer can never pay a stale price.
The website itself is data, not code: the whole public site is content managed from the admin panel, so the business changes its packages, galleries, and policies without touching a deployment.

One system from booking wizard to payments ledger
Customers move through a guided six-step wizard, package, verify, address, vehicles, schedule, confirm, that handles multiple vehicles per visit, mobile-versus-garage selection per line, Google Places address autocomplete, a live estimated total with per-province GST/PST breakdown, and an availability calendar computed from service schedules, existing bookings, and the company's timezone. Identity is verified with a one-time code by SMS or email, no passwords, no account friction.
The admin home is a bookings workspace: a filterable list plus month and week calendars, with a dedicated queue for orders awaiting confirmation. Staff accept or decline per order, reschedule, assign crews, record cash or e-transfer payments, and manage refund positions. Payment confirmations arrive by webhook when configured, or through a polling reconciler that checks Square every five minutes when webhook credentials are not available; recording a manual payment automatically closes any open checkout link so a customer cannot pay twice.
Scheduled jobs handle the rest: retrying failed payment-link emails, reminding customers about unpaid orders, alerting staff when an order is unpaid close to its appointment, and sending appointment reminders to customers and crew, each with deduplication stamps. Follow-up campaigns let staff build audiences, such as customers inactive for a configurable number of days, and send templated email or SMS with per-send logging.
Multi-vehicle booking wizard
A guided six-step flow with per-vehicle packages and add-ons, mobile-or-garage selection, live pricing with per-province Canadian tax, and passwordless OTP verification by SMS or email.
Approval-gated payment links
Staff accept or decline each order before a hosted Square payment link is emailed for the exact approved amount, and stale links are destroyed and reissued whenever the total changes.
Refund-position accounting
A frozen original-quote snapshot alongside the live keep total means 'what we're keeping', 'what was quoted', and 'who owes whom now' stay consistent across admin, reports, and the customer's order view.
Automated reminders and alerts
Scheduled jobs retry failed emails, chase unpaid orders, warn staff about approaching unpaid appointments, and remind customers and crew, all with deduplication so nobody is nagged twice.
Full website CMS
Packages, pricing comparisons, hero images, before/after galleries, testimonials, FAQs, and policies are edited in the admin panel and go live in seconds via targeted cache invalidation.
Follow-up marketing
Staff define message templates, build audiences from customer activity, and send campaigns by email, SMS, or both, with per-send logging and a newsletter subscriber list.




- 01
Two-level order model with a frozen value snapshot
Orders and per-vehicle lines with independent statuses, backed by roughly twenty documented money scenarios, underpay, overpay, partial decline after payment, fee-kept refunds, so every surface agrees.
- 02
Webhooks optional by design
Payment confirmation works two ways: signed Square webhooks when credentials exist, otherwise a five-minute polling reconciler. The integration degrades gracefully instead of failing.
- 03
Timezone pinning with daily recompute
Bookings store wall-clock time and computed UTC instants tagged with the timezone-library version; a nightly job recomputes future bookings so DST rule changes never shift an appointment.
- 04
Graceful degradation for every external service
Without email credentials, messages log to console; without cloud storage, uploads go to local disk; without Square, links are disabled with clear operator warnings, the whole system runs locally on a demo seed.
- 05
Test coverage on the highest-risk logic
70-plus automated test files across the three apps, concentrated on payment provenance, refund flows, availability math, timezone recomputation, and booking-store normalization.
- One platform replaces separate tools for website, booking, scheduling, payment collection, refund tracking, and customer follow-up.
- Customers book multi-vehicle visits online with verified contact details and pay through hosted Square checkout at staff-approved amounts.
- Staff run the day from a single workspace, calendars, pending queue, order money positions, and a payments ledger with CSV export, with role-appropriate access for crews.
- The business edits its entire public website from the admin panel, with changes live in seconds.