01Problem
A multi-branch auto parts shop tracked stock and sales in Excel sheets. Each branch had its own copy, and the copies drifted apart.
02My role
Sole developer: requirements with the owner, design, build, a security audit and delivery. Version 1 (July 2025) was a C# WinForms app on SQL Server with barcode scanners. Version 2 (March 2026 onward) moved it to the web.
03Approach
- Access control lives in the database.Four roles enforced with Row Level Security, so a tampered UI or a direct API call gets the same answer.
- Stock that can't silently drift.Barcode stock-in and stock-out, transfers between branches with approvals, and an audit log.
- Privileged work goes through Edge Functions.They check that the caller's account is still active before doing anything.
- Tests that attack.Playwright end-to-end specs, including RLS specs that replay the attacks below.
04The audit
Before launch I went after my own app as a malicious staff account. Everything below is fixed, each with its own database migration.
- Found
FixedThe role helper trusted a profile claim that any user can rewrite. That's a privilege-escalation path.Roles are read from the users table only.
- Found
FixedSignup copied the role from the signup request, so anyone could create an admin.New accounts can no longer choose their role.
- Found
FixedStaff could move themselves to another branch, or reactivate a disabled account, by editing their own profile.Branch and account status are pinned on self-update.
- Found
FixedReceipts could be rewritten after the sale: items, totals, payment method.Receipts are immutable once issued.
- Found
FixedDeleting a branch silently wiped its inventory. The guard only existed in the browser.The database refuses the delete while stock remains.
- Found
FixedStock adjustments and some deletions left no audit trail.Audit triggers now cover them.
05Result
The shop runs on one system instead of drifting spreadsheets, and the security and data-loss defects above were closed before launch.
06Links
The repo is private and the client is confidential. I can walk you through the code and the audit on a call: Jimenezaerroljj@gmail.com.