Jerome NazarioHow I build and ship real products
← Back

Bayou Detail Co.

Full Stack Developer · Shipped in < 4 hours · 3 min read

A mobile car-detailing crew in Houston had a booking problem that had nothing to do with detailing. Every job came in through a generic web form: a customer typed out what they wanted and when, someone on the crew read it, checked whether the address was even in range, worked out a time, and messaged back. Each booking cost a conversation. The ask was simple — make booking take a minute, not a thread.

Bayou Detail Co. is the answer: a single-page, mobile-first booking site built specifically around how this business actually works. Customers pick a service, pick a slot, and request the visit. No accounts, no payments, nothing to learn. And the whole thing — design, front end, database, security policies, deploy — shipped in under four hours.

Bayou Detail Co. landing page hero

The customer flow

The old form asked open-ended questions and produced open-ended answers. The new page asks four closed ones, in the order the business needs them answered:

Are we in your neighborhood?

A ZIP gate up front. The crew serves exactly 18 Houston-area ZIPs — West U, The Heights, Bellaire, Katy and the rest — so that's checked before anything else. In-area, a green banner opens the form. Out-of-area, a friendly waitlist captures email and ZIP instead of a dead end.

Which package?

Four flat prices, no upsells at the curb: Wash & Wax $129, Interior Deep Clean $189, Full Detail $249 (marked most popular), and a $99 Maintenance Plan Visit for returning customers.

When?

A slot picker over the next 7 days starting tomorrow, hourly from 8:00 AM to 3:00 PM, in Houston time. Dates are computed on the server per request, so the calendar is never stale.

Who are you?

Name and vehicle. That's the entire form. Submit, and a confirmation screen tells the customer the crew has the request.

ZIP coverage check with in-area confirmation
Service cards and the 7-day hourly slot picker

Built for a phone in a driveway

Most of these bookings happen on a phone, often while the customer is standing next to the car. The layout is designed at phone width first — sticky nav with a single Book now action, full-width tap targets for ZIP, services, and slots — and then widened for desktop, not the other way around.

Phone views: hero, ZIP gate, and slot pickerPhone views: hero, ZIP gate, and slot pickerPhone views: hero, ZIP gate, and slot picker

The database does the bouncing

There are two tables in Supabase: bookings (name, vehicle, ZIP, service, slot date, slot time, status) and waitlist_emails. Submissions go through Next.js server actions that re-validate ZIP, service, date, and slot before inserting — but the interesting part is that the server isn't the only line of defence.

Row Level Security is on, and the public anon key can insert only. Nobody can read customer data through the key shipped to the browser. The second commit went further and moved the validation rules into the insert policy itself: the ZIP must be on the allowlist, the service must be one of the four names, the time must match an HH:00 slot between 08 and 15, the date must fall within the booking window, name and vehicle have length limits, and waitlist emails must be well-formed. Even someone who extracts the anon key and calls the API directly can't insert junk.

Validation lives in three layers — the form, the server action, and the Postgres policy — and the database layer is the one that can't be bypassed. Migrations are committed in supabase/migrations/, with a flat schema.sql for the dashboard SQL editor.

Under four hours

The stack is deliberately current and deliberately small: Next.js 16.2 on the App Router, React 19, TypeScript, Tailwind v4, Supabase Postgres, deployed on Vercel. No auth provider, no payment SDK, no CMS — none of which the business needed on day one. Scope discipline is the reason a real, hardened booking system for a real crew went from blank repo to live URL in a single afternoon.

How it works section — booked in a minute

What comes next

Every booking lands with status = 'pending', which is the hook for the next step: an owner view to confirm or reschedule, SMS confirmations, and eventually the Maintenance Plan turning into a real recurring schedule. The schema already leaves room for all of it.

Tech stack
Visit live site