← /writing/case-study·2026 · 02 · 21·4 min read

Building a Subscription Commerce Platform for On-Demand Car Washing

Most marketplaces eventually become operations platforms. This one started as one - and that was the right call.

companion: Daily route generation under real-world constraints: a hand-rolled scheduler

Most "marketplace" platforms eventually become operations platforms. This one started as one - and that was the right call.

The client offered car washing as a subscription. Customers signed up monthly; field workers cleaned cars on a route; the operations team coordinated the route. The product wasn't really a marketplace. It was a workforce-and-route engine with a thin booking app on top.

Context

Car washing is a deceptively complex local service. Each customer has a parking constraint (covered, uncovered, basement), a vehicle type (sedan, SUV, electric), and a time window when the wash is allowed. Each field worker has a daily route capacity, an equipment kit, and a skill level. Each supervisor manages a cluster of workers and resolves the day's exceptions.

The customer's expected experience was "I subscribed; my car gets washed; I see when it's done." Every layer underneath had to make that happen - at scale, at low cost, with skipped days handled gracefully when the customer was traveling.

The product challenge

A single subscription, three roles, and a scheduling problem.

The scheduling problem was the load-bearing piece. A daily wash plan for 500 customers across a city is not a calendar - it's a route-optimization problem with constraints (vehicle accessibility windows, skipped days, complaints requiring re-do, worker availability). Hand-built schedules collapsed at scale; generic scheduling tools didn't understand the constraints; building an internal scheduler was the right answer but the wrong place to start.

So we built the simple version first, watched where it broke, and replaced pieces as the data told us to.

My role

I led product and engineering execution: subscription model, three role-specific apps, scheduling engine, route handoffs, complaint workflow, payments, and the operating playbook the supervisors used at 6 a.m. each morning to start the day's routes.

Core features

  • Subscription engine: daily, weekly, on-demand bookings with skipped-day handling.
  • Customer app: subscribe, see today's plan, request changes, raise complaints, view wash history with photos.
  • Field worker app: daily route, current job, photo evidence, completion logging.
  • Supervisor app: cluster overview, exceptions queue, complaint dispatch, route adjustment.
  • Scheduling engine: daily route generation with parking-window constraints and skip rules.
  • Complaint flow: customer raises, supervisor triages, worker re-does, evidence captured at each step.

Technical highlights

The subscription model was less interesting than the scheduling. We treated "wash days" as the primitive - a customer on a daily plan generated 30 wash-day events per month, each with their own state (planned, completed, skipped, complained, re-done). The plan layer just generated and prorated. The state machine sat on the wash day, where the actual operations lived.

Photo evidence at each completion turned out to be load-bearing. It was the disambiguator for complaints (was the wash actually subpar, or was something on the car after?), the supervisor's QA tool, and the customer's emotional reassurance that the work happened. We made it non-skippable in the worker's flow even when it slowed them down.

The scheduling engine started as a deterministic rule-based assignment - workers had clusters, customers had clusters, the night-before run paired them up. As volume grew, we layered on capacity smoothing (no worker overloaded), parking-window constraints (basement accesses had narrow windows), and exception queueing (yesterday's complaints went first today). It never became a full optimizer; it became "good enough that supervisors trusted it."

Route handoffs between workers and supervisors used short structured messages, not free-form chat. A complaint became a structured ticket with a reason code; a route change became a structured assignment; a skip request became a structured exception. Free-form chat existed but did not drive operations.

What this taught me

The hidden complexity behind simple booking apps. Customers think they bought "a wash." Operationally, they bought a recurring slot, a route position, a worker assignment, and a complaint-handling SLA. Every part of that chain has to hold or the customer experience breaks. The simplicity is on the customer's side; the complexity sits underneath.

Three roles, three apps, one state. Building one combined app that tried to serve everyone would have produced a worse experience for each role. Each role saw exactly what they needed to act on, nothing more. That alone reduced training time for new field workers from days to hours.

Digitizing offline service businesses is not "automation." It is structured visibility. The supervisors didn't want fewer decisions to make - they wanted the right information in front of them when they made decisions. A real-time view of the day's progress, exceptions, and worker status was worth more than any AI assignment they were tempted to ask for.

Outcome

The platform converted a manual coordination process into a software-coordinated one without changing what the field workers actually did. Supervisors gained a real-time view of route progress and exceptions. Customers gained reliable service with proof. The scheduling engine, once trusted, allowed the operator to expand to more clusters without proportionally growing the supervisor team.


If you are digitizing a local service business: do not build the marketplace. Build the operations platform underneath. Then put a customer-facing app on top of it, not the other way around.