Skip to content

TidyOps

Scheduling, staff and invoicing for commercial cleaning companies, moved off a hosted low-code platform onto infrastructure we control.

Sector
Field services · Cleaning
Year
2026
Stack
TanStack Start · React · TypeScript · Express · PostgreSQL 17 · Docker · nginx · Cloudflare
Live
See it running (opens in a new tab)

The problem

TidyOps handles the daily running of a commercial cleaning business. Who is working where tomorrow, what was done on site, which invoices are still outstanding. The first version was built on a hosted low-code platform, which got the product working quickly. The trade-off was that the important parts ran on infrastructure we did not control, and there was a limit to what could be built on top of it.

Depending on a platform is one of those risks that is easy to ignore until it matters. Vendors change their pricing, get bought, or discontinue products, and none of that is negotiable at the time. TidyOps schedules tomorrow's shifts and issues this month's invoices, so we wanted that dependency gone. The job was to replace what sat underneath the software without changing what it did for the people using it.


What we built

We replaced the platform with three containers. A web front end, an API, and a PostgreSQL database, all on one virtual server behind its own TLS certificate. The front end is TanStack Start with React and TypeScript, the API is Express, and PostgreSQL 17 holds the data. Docker, nginx and Cloudflare sit around it. There is a separate development environment, and a release goes out with one script.

Authorisation is handled by PostgreSQL itself. More than forty row-level security policies check the current user on every request, which the API sets before it runs any query. A query that is missing its filter returns no rows. Most multi-tenant applications do this check in the application code instead, and rely on every developer remembering it on every screen they write.

In the product

  • Scheduling and dispatch, with a week view for the office and a day view for each cleaner.
  • A public booking page for each company, and recurring jobs that repeat on their own.
  • Client records and service types, so quotes and jobs draw on the same information.
  • Staff availability, invitations, and separate access for owners and cleaners.
  • A checklist on each job, and a record of what was done and by whom.
  • Invoicing, payroll and reporting, all built from the same job data.
  • Each company's data separated at the database level.

Outcome

TidyOps runs in production on a single virtual server with its own TLS certificate, alongside a separate development environment. A release takes one script. Nothing underneath it can be repriced or withdrawn by a third party.

We have no figures for revenue or hours saved, because we have not measured any.