A curtain maker runs a job queue that shifts every day. Fabric arrives late. A customer asks to push their fitting back a week. A rush order jumps the line. Every one of those changes used to mean manually recalculating every ETA sitting below it in a spreadsheet, by hand, while also trying to remember which jobs were actually blocked and which had just gone quiet.

The spreadsheet wasn’t badly built. It was just the wrong tool for a queue that needed to cascade. One late fabric delivery should push every job after it, automatically, without anyone doing the maths. A spreadsheet can be coaxed into that with enough formulas, but it breaks the moment a job needs to be paused, reordered, or pulled out of the sequence entirely without dragging every other row with it.

What changed

The replacement is a proper scheduling app, built around the way the work actually flows rather than the way a grid forces it to look.

Jobs now cascade automatically. Move one job, and every job behind it recalculates its ETA based on working days, not calendar days, so weekends and holidays don’t quietly throw the numbers off. Jobs waiting on materials can be put on hold without breaking that chain; a blocked job simply steps aside and lets the queue flow around it until it’s ready to rejoin.

Reordering is a drag and drop, not a cut and paste and hope. And every customer now has their own portal, a single link that shows the live status of their job without a phone call or a text to chase it.

The stack

It’s a fairly small, ordinary set of tools underneath, which is rather the point. The front end is React on Vite. The database, authentication, and real time sync all run through Supabase, using Postgres tables with row level security and a scheduler that recalculates the cascade on the fly. Sign in is Google OAuth, so there’s no password to forget. The whole thing is deployed on Vercel, connected straight to a GitHub repo, so a push to the main branch redeploys the live site automatically.

The nicer detail is that it costs nothing to run. GitHub, Supabase, and Vercel all have free tiers generous enough for a single person’s job queue, and the app lives entirely under her own accounts on each. No hosting bill, no third party holding the data, and nothing to migrate if any of it ever needs to move.

The part that actually matters

The scheduling logic was the hard problem to solve, but the outcome is a much smaller thing: she gets to tick a job off and move on. Marking a job complete is now a genuine moment of satisfaction rather than a chore of finding the right row and deleting it correctly. It sounds trivial. It isn’t, when the alternative was fifteen minutes of spreadsheet gymnastics disguised as admin.

The bigger shift has been on the customer side. Nobody is texting to ask where their curtains are anymore. They check the portal. The ETA is right there, and it’s accurate, because it’s coming from the same cascade that’s actually running the business, not a number someone half remembered and typed into a message.

None of this needed to be complicated. It needed to reflect how the work actually happens, and stop pretending a grid of cells could do that job forever.

← back to blog index