Scope financial visibility by role at the query layer, not just the UI
Don't rely on hiding UI elements to protect financial data from the wrong role — enforce the boundary where the data is fetched. Staff cash visibility is filtered to their own entries at the query level; bank data is rejected outright for staff before any query runs. The trade-off: it's a per-endpoint discipline, not one central gate.
Pujan Motiwala ·
Context
Staff need to log day-to-day cash transactions, but shouldn't see the business's full financial picture. Bank data is for owners only.
Decision
The boundary is enforced where the data is fetched, not just in what the interface shows. A staff member's view of cash entries is filtered to only the entries they created, at the point the data is queried. Bank data isn't filtered at all — every bank-related request from a staff account is rejected outright, before any query runs.
Why
Hiding a UI element doesn't stop someone from calling the underlying endpoint directly. Enforcing the boundary at the point requests reach the server means the restriction holds regardless of what client is asking.
Trade-off
There's no single central gate doing this for the whole app — no row-level security at the database, just a rule applied at each relevant endpoint. Every new finance-adjacent feature has to remember to apply the same check. It's a discipline the team has to keep, not a guarantee the system enforces on its own.
- cash visibility scope for staff
- own entries only, enforced in the API query
- bank visibility for staff
- none — every bank API route rejects staff requests
Seen in practice
Talk to us about your systems.
Tell us what's held together with workarounds right now. We reply to every message ourselves.