Case study
Designing a form staff will still be fast on during the busiest ten minutes of their shift.
The interesting problem wasn't the data model. It was making sure the check-in screen never becomes the reason a line forms at the gate.
The problem
A register book is slow. A bad app is slower.
The system this replaced was a physical register — plate number, time, category, written by hand. It worked, in the sense that it produced a record. It didn't work in the sense that nobody could search it, total it, or trust that today's handwriting matched yesterday's.
The trap was building something that solved the record-keeping problem but made the actual check-in slower than the register book it replaced. A five-field form with dropdowns and validation is a worse tool at a busy gate than a pen, even if it produces cleaner data — staff will find a way around a tool that slows them down, and then the data gets worse than paper, not better.
The approach
Design the screen around the busiest ten minutes, not the average one.
Every screen maps to exactly one moment at the gate: InUserScreen for a vehicle arriving, OutUserScreen for one leaving, nothing generic in between. Vehicle category is a short, admin-configured list (VehicleCategoryListScreen) rather than free text, because a staff member choosing from three options is faster and more reliable than one typing a rate from memory.
Access followed the same "match the real shift, not an idealized one" logic: staff get individual logins rather than one shared device password, and a separate super-user tier (SuperUserSettingsScreen) is the only place pricing and categories can change — so the person handling the gate at 11pm can't accidentally (or deliberately) edit a rate, and there's an honest log of who did.
The architecture
What's actually running under it.
- Mobile app
React Native, with dedicated screens for check-in, check-out, vehicle categories, staff, and reports — one screen per real task, not a shared generic form.- Backend
- A
PHPAPI handling vehicles, categories, staff accounts, and check-in/out records. - Access control
- Per-staff login plus a super-user settings tier that gates pricing and category changes specifically.
- Reporting
- Date-range earnings reports (total earnings, vehicles checked out, per-vehicle amount charged) with server-side pagination, plus a manual "mark as out" override for a vehicle someone forgot to check out at the gate.
- Delivery
- Android and iOS from one React Native codebase.
The outcome
What's live, and what's honestly still being worked on.
Check-in/check-out, configurable vehicle categories, per-staff access, and date-range earnings reports are all built and in use — pick a range, get total earnings and a per-vehicle amount breakdown, with a manual override to close out a vehicle someone forgot to check out. That last part matters more than it sounds: a report is only trustworthy if there's a way to fix the record when the real world doesn't match it.
An earlier direction explored camera-based number-plate recognition so staff wouldn't have to type a plate at all. It's not accurate or reliable enough yet to put in front of a real client, so it's deliberately off this page until it is — the honest version of this app right now is a fast, well-scoped manual check-in flow, not an automated one.
Running a gate, a lot, or any operation where a paper log is the current system of record?
Get in touch