Overview
SAWN is a single Flutter app for a mobile car wash service: customers book a wash, polish, nano-ceramic or PPF appointment and track the technician on the way, while the same account type switches into a field-technician view for the assigned crew. A NestJS and PostgreSQL backend serves that app and a Next.js operations dashboard from one set of records.
Challenge
A booking only has value if someone acts on it. Customers needed a fast phone-number sign-in, a clear service and package catalog, and live status on their wash; staff needed to see every booking, confirm payment, assign a technician and keep an auditable invoice trail without re-entering anything the app already captured.
Solution
One Flutter codebase renders the customer flow (OTP sign-in, service catalog, booking, packages and live tracking) and, for a technician account, the day's assigned jobs instead. The Next.js dashboard reads and writes the same backend: staff confirm bookings, assign technicians from a live roster, and pull a VAT-ready sales report with exportable invoices.
Engineering
Phone-number sign-in runs on short-lived OTP codes. Bookings carry service, add-ons, car, location and a package-aware discount; a dev-only fake payment provider stands in for the licensed gateway until that integration lands, keeping bookings in a clear pending-payment state either way. Technician assignment, job status and sales reporting run off the same booking record the app writes.
Architecture
Riverpod and go_router manage the app's state and the role-based split between customer and technician views from one account type. NestJS exposes a single API over PostgreSQL (via Drizzle ORM) that both the Flutter app and the Next.js dashboard depend on, so a booking's status is never duplicated or out of sync between them.
Features
Phone OTP sign-in, service and package catalog, booking with live technician tracking, technician job view, staff booking board with technician assignment, technician roster, VAT sales report with exportable invoices, Arabic and English.
Results
The screenshots show the running local build: a confirmed, technician-assigned booking in the app and the same booking on the dashboard's board. No live booking volume, technician count or revenue is claimed.