Cleaning company operations app
An iOS app for a commercial cleaning company: cleaners see the jobs assigned to them, clock in on site, work the checklist, capture before-and-after photos and take a customer signature. Forked from the pub staff platform rather than started from scratch — and then rebuilt where the domain differs.
The access decision
A cleaning company holds alarm codes, gate codes and key details for every site it cleans. That is the most sensitive data in the business, and it sits in a database a phone app talks to directly.
- Cleaners can read a site’s access codes only if they are assigned to a job there, and only in the 24 hours before that job starts. Outside that window the row simply isn’t returned.
- The rule lives in row-level security, not in the app. A leaked key, a modified client or a direct API call still can’t read a code it isn’t entitled to — the database refuses, not the interface.
- Role checks run through helper functions rather than being repeated in every policy, so there is one definition of what an admin is and it can’t drift between tables.
Reused deliberately, isolated deliberately
The app was forked from the pub staff platform rather than started from scratch. Authentication, the clock-in flow, GPS handling, notifications and the component library carried across untouched; customers, sites, jobs, photos, signatures and hazards were rebuilt, because that domain has nothing to do with pub shifts.
What I built
- Fifteen domain tables with row-level security on every one, plus role helper functions and update triggers throughout; storage buckets all private with per-bucket size and type limits.
- Sign-up as an application rather than an open door: someone requests access, an admin approves or rejects with a reason, and approval issues their credentials. Nobody self-serves into a system holding other people’s alarm codes.
- The cleaner’s day: today’s jobs, site detail with entry instructions and hazards, GPS clock-in, mandatory before-and-after photos, checklist, consumables, customer signature, upload on completion.
- Auto-exposure of new tables switched off and automatic row-level security switched on at the project level — so a table added in a hurry is private by default rather than public by default.
App Review
Submitted, rejected three times, and resolved each time before approval. One of those was account deletion: Apple requires any app with sign-up to let a user delete their account from inside the app, not by emailing support.
Scope, held
The full specification runs to a customer portal, automated invoicing, inventory with low-stock alerts, AI photo comparison, offline mode and a KPI dashboard.