Car washes running on paper and phone calls
Car wash businesses in Costa Rica were managing customer queues on whiteboards. Staff had no real-time visibility into which bays were occupied, and when a car was ready the owner had to manually call the customer — or the customer had to drive back and check. No status tracking, no scale, no customer experience.
The opportunity: a lightweight SaaS that replaces the whiteboard, notifies customers automatically via WhatsApp, and gives business owners a live view of every vehicle in their queue.
Multi-tenant from day one
Every business that signs up gets a fully isolated environment — their queue, clients, employees, and analytics — all enforced at the database level via Supabase Row Level Security policies. No custom middleware, no shared-data leaks.
Every tool a car wash needs, nothing it doesn't
Built around the actual workflow: register a vehicle, move it through stages, notify the customer at each step. Everything else — CRM, analytics, employee management — supports that core loop.
Kanban drag-and-drop board
Built with DnD Kit. Four stages: Received → Washing → Drying → Ready. Real-time status per bay, with time-in-stage tracking.
Automatic customer notifications
A message fires on every stage change. Customers get a live status page — no calls needed, no waiting.
Client & vehicle history
Repeat customers, past services, and vehicle profiles saved per business. Fast repeat-visit registration.
Business stats dashboard
Revenue, volume, and service-type breakdown. Built with Recharts and server-side Supabase aggregations.
Four decisions worth talking about
Some parts of the stack required real thought. These were the interesting ones.
Chose Paddle over Stripe for its Merchant of Record model — Paddle handles VAT and tax compliance across regions so the business doesn't have to. Subscription lifecycle events arrive as webhooks and are synced to Supabase.
Tenant isolation is enforced at the Postgres level via RLS policies. A policy on every table ensures a business can only ever query its own rows — no application-layer filtering required.
Claude powers ETA suggestions and queue-optimization hints. Structured output via the API — context is built from live queue state and historical service times.
Transactional emails are React components rendered server-side. Templates for onboarding, subscription events, and service receipts — each branded with the business name.
Shipped, live, and in use
LavApp went from zero to a deployed, subscription-based SaaS. The full stack — frontend, backend, payments, notifications, AI — designed, built, and maintained by one developer.