The "Excel" Exorcism
There is a specific kind of chaos that comes from running a successful mobile car wash business using only a WordPress landing page, a phone number, and a shared Excel spreadsheet.
"Car Wash From Home" (CWFH) was growing fast, but their backend operations were stuck in 2010. Double bookings were common, customers had to call to find an open slot, and the admins were spending their evenings manually reconciling paper notes with digital spreadsheets.
They needed to stop playing "Tetris" with appointments and start automating.
Contents
- The Mission
- The Solution: More Than Just a Date Picker
- The Technical Deep Dive
- The Results
- Conclusion
The Mission
I was brought in to perform a complete digital overhaul. The goal was simple but ambitious: kill the spreadsheet, modernize the brand, and build a booking brain that could handle the nuances of a real-world workforce.
The Solution: More Than Just a Date Picker
A generic booking plugin wouldn't cut it. CWFH needed logic that understood that humans need lunch breaks, that Christmas exists, and that sometimes a van breaks down on a Tuesday.
I built a custom solution centered around granular availability control.
Admin Autonomy
Admins aren't locked into a rigid 9-to-5 structure. They can define standard opening hours, but easily override them for Ad Hoc events, set specific closing days, or block out time for equipment maintenance instantly.
Instant UX
By moving away from their sluggish WordPress theme to a bespoke Next.js frontend, we achieved near-instant page loads. The booking flow guides the user from service selection to confirmation in under 60 seconds.
The Technical Deep Dive
The UI was the fun part, but the database was the headache. Designing a schema that is performant enough to query availability in real-time, while being flexible enough to handle "Standard Tuesdays" vs "Christmas Eve Tuesday," required a complex relational structure.
I settled on a 5-table architecture (appointments, business-hours, recurring-time-slots, slot-exceptions, adhoc-time-slots) to decouple "Time" from "Availability."
A high-level view of the schema separating Business Rules from Actual Appointments.
The Schema Strategy
Structuring Complexity
We couldn't just have an appointments table. We needed to define the "Potential" for appointments first.
-
business-hours: Defines the recursive weekly template for standard opening hours.
-
recurring-time-slots: Represents normalized, recurring availability derived from the weekly template.
-
slot-exceptions: Handles specific-date overrides (Holidays, Sick leave, one-off closed days).
-
adhoc-time-slots: Fixed, ad-hoc intra-day blocks (Lunch, shift changes, temporary capacity adjustments).
-
appointments: The actual committed slots.
The Logic
Here is a simplified look at how we calculate slots. We don't store "free slots" in the DB; we calculate them on the fly to ensure atomic accuracy.
// Simplified logic for generating availability
async function getAvailableSlots(date: Date, serviceDuration: number) {
// 1. Fetch Master Rules (business-hours), recurring time slots and slot-exceptions (Holidays or one-offs)
const rules = await prisma.businessHours.findMany({ ... });
// 2. Fetch existing appointments for that specific day
const appointments = await prisma.appointment.findMany({
where: { date: date }
});
// 3. Generate all possible time chunks (e.g., 09:00, 09:30...)
const potentialSlots = generateTimeChunks(rules);
// 4. Filter out collisions
return potentialSlots.filter(slot => {
return !isOverlapping(slot, appointments) && !isDuringBreak(slot);
});
}The Results
We launched the new platform just before the spring rush. The impact was immediate. The phone stopped ringing off the hook, not because customers left, but because they were happily booking online at 11 PM.
66%
Speed Increase
10k+
Happy Users
80%
Admin Time Saved
The greatest win wasn't the code; it was the lifestyle change for the client. Zero manual booking handling means the team can focus on washing cars, not shuffling paper.
Conclusion
This project proved that for local businesses, a custom solution isn't vanity—it's necessary efficiency. Moving from WordPress to a Serverless Next.js architecture didn't just make the site look pretty; it fundamentally changed how the company operates.
And honestly? I don't miss migrating data from Excel one bit. 😴
Inspired by this project?
I can help you build something similar — let's chat about your idea and the next steps.
Subscribe to my newsletter
Get updates about new projects and occasional tips and tricks — just useful stuff.
Read another project
If you'd like to explore more, here's another project you might enjoy.
