The problem
A pet-waste-removal company in Utah runs a fleet of technicians visiting hundreds of yards on recurring schedules. The owner was juggling a calendar, a spreadsheet and text messages to plan routes, confirm visits and answer "did anyone actually come today?"
What I built
The platform behind the business: customer and subscription management, recurring job generation, daily route planning for each technician, a mobile-friendly tech view with photo proof of every visit, and customer notifications.
Decisions worth mentioning
- Recurring jobs are generated, not stored. Subscriptions define the rule (weekly, bi-weekly, day preference); concrete visits are materialised a rolling window ahead so a schedule change never leaves stale future jobs behind.
- Route order is a first-class field. Dispatchers reorder a tech's day by dragging; the order is persisted, so the tech's phone shows the same list the office sees.
- Photo proof with the job, not in chat. Each completed visit stores photos and a timestamp against the job, which killed the "did you come?" support load.
- Timezone discipline. Everything stored in UTC, everything displayed in the business's local time, because a 6 am job in Utah must not become a 5 pm job in Islamabad.
What I'd do differently
- Build the technician's phone view before the office dashboard. The office is where the owner sits, so it got built first, but the tech app is what makes or breaks the day, and its constraints (one hand, bright sun, patchy signal) should have shaped the data model earlier.
- Make route order a proper sequence type with gap handling instead of a plain integer; reorders on a long day caused more writes than they needed to.
Outcome
Live at poopypuppy.com and used daily by the business.