Designed and built a three-tier authorization model (super-admin / org-admin /
per-item share) from scratch across two personal apps' databases, web frontends, and mobile clients, then promoted both straight to production the next day, where a real user click, not any automated check, caught a bug that had silently broken every "create" action since the model went live.
The challenge
Two personal apps (a vehicle/asset tracker and a project tracker) needed real multi-user access control before they could move onto shared production infrastructure. Neither app had it: one was single-owner-only, the other let every user see everything. Neither model works once more than one person's data can be nearby on the same system. The requirement: private data stays private until deliberately shared, a group admin sees only their own group, and a top-level access-control account can manage who belongs where without ever being able to see the data itself.
Approach
- One design, not two. A single three-tier model, made up of super admin (access control only, zero data visibility), org/group (member vs. admin, scoped to their own group), and per-item share (owner invites specific people, contributor or viewer), was designed and written down before any code was touched, so both apps could apply the exact same pattern instead of drifting into two bespoke systems.
- Real accounts, not mocks. Two live test accounts were created and used to verify every claim about what each access level could and couldn't see, rather than trusting the policy text.
- Scoped to what the first release actually needed. Mobile clients got only what was load-bearing for the promotion (tagging new items with the right group) while full share-management screens were deliberately deferred to mobile, since phones only needed to consume shares made elsewhere, not create them. That cut the risk surface of the first mobile release in half.
- A storage-security risk defused on paper. File-storage access rules were designed scoped to the specific item's path from the start, closing a would-be leak (files visible across groups) before it could ever ship.
What happened next
Both apps were promoted to production and live-verified the following day. Every automated check had passed: schema validation, permission probes, scripted smoke tests. But the very first real "create" action in production failed. The cause: the access rule that decides whether you can read back a row you just created was, itself, checking your permission by re-querying that same row in the same operation, and a row still being created isn't visible yet to a lookup run in that same instant. The rule always failed, silently breaking the "create, then confirm" pattern everywhere the new model applied, since the moment it first shipped, a day earlier. Nothing scripted had caught it. A person clicking a button did.
It was root-caused and fixed the same day, verified against a real reproduction of the failure plus a specific check that ordinary users still couldn't see anything they shouldn't. A second, unrelated pre-existing display bug was found and fixed the same way, as a byproduct of a human actually using the freshly promoted apps. The natural next question ("how do we catch this automatically next time?") became its own project: real browser-driven tests that exercise actual write paths, specifically because this class of bug evades permission-probe scripts by design.
Results
- One authorization model, two apps, one design document: not two systems that drift apart.
- Both apps promoted to production and verified live within a monitored parallel-run period.
- A fleet-wide, 100%-reproducible bug found and fixed within a day of shipping, before it could become a bug nobody noticed for weeks.
- An unrelated pre-existing display bug fixed as a byproduct of the same testing pass.
- A storage-security risk closed on paper before it could ever be built wrong.
- A new automated-testing initiative launched directly from a real incident.
What this demonstrates
- Automated checks prove a rule is written correctly. They don't prove it behaves correctly under a real sequence of actions. The bug passed every scripted check because none of them exercised "create, then immediately read your own new row back," the very first thing a real user does. That sequence needs its own explicit test; it doesn't fall out of general permission tests for free.
- A rule that re-checks its subject by re-querying the same table it protects is a latent trap. Rows created earlier in an operation aren't necessarily visible to a fresh query later in that same operation. Check against data already in hand, not a re-lookup, wherever both are available.
- Design once, apply as a matched pair. A single shared design document is what made same-day promotion of two apps possible: there was no second design decision left to make, only execution.
- Defer the platform that doesn't need the full feature yet. Scoping mobile to only what a first release required cut real risk, not just work.
- The best response to "a human found what automation missed" is funding the automation that would have found it, not just patching the one bug and moving on.
A companion piece on the earlier chapter of the shared production infrastructure this work promoted onto covers the platform migration itself.