Transformation Accelerator
A programme platform for sensitive health-related data, where the database enforces privacy
How it works
A 90-day programme for sensitive health-related data, where protection lives in the database itself.
Locked by default
All 71 tables under row-level security; no role gets blanket access, not even the server's own key.
Narrow access
Clients can only call functions that identify them from their login, never one that takes a person's ID.
Dates, not counters
The programme day and progress count are calculated from dates, so a setback never resets the programme.
Safety screen
34 rules flag crisis and medical language.
A named person responds
A match is routed to a named person outside the normal queue. The system never replies or closes the case.
A person decides
Real erasure
A user can be deleted completely; the audit log survives without identifying anyone.
The outcome
Access control on all 71 tables, and two security defects caught before any real data existed, including one that would have let a client read another client's programme.
The problem
A 90-day programme platform with lessons, daily practices, measurements, a staff console and a safety screen. Its users would share sensitive health-related information, and a leak would do real harm. So data protection had to sit in the database itself, where an app bug can't bypass it.
What I decided
- EU hosting (Frankfurt), with no exceptions.
- Every table locked by default, with access granted narrowly.
- Real erasure. A user can be deleted completely, and the audit trail survives without identifying them.
- No automated response to a crisis. The system may flag a message and assign it to a named person. It never replies, refers or closes the case on its own.
- A setback never resets the programme. The programme day keeps counting even when a progress count resets.
How it was built
AI agents drafted each phase's spec, I reviewed and approved it before it was frozen, and Codex built against it.
- Access control on all 71 tables (row-level security: the database decides which rows each person can read or change). No role gets blanket access, not even the server's own key. Clients can only call functions that identify them from their login.
- Deletion is explicit. 148 links between tables refuse deletion by default, and only 2 cascade, both on the erasure path.
- The audit log records only named fields, leaves out sensitive notes and can't be edited or deleted. It has no links to the user tables, so it survives an erasure without identifying anyone.
- The programme day and the progress count are calculated from dates, never stored, so they can't drift out of step.
- A safety screen of 34 rules flags crisis and medical language and routes any match to a named person, outside the normal queue.
- "Refuse rather than guess." The building agent was told to stop and flag anything that looked wrong. Most stops caught errors in the spec. Two caught real security defects:
- A function with extra rights accepted any user's ID, so one client could look up another client's programme day, which alone reveals that someone is enrolled. It was fixed in the next database change, and clients can now never call a function that takes a person's ID.
- Two client functions couldn't be reached from the app, yet every database test passed, because the tests skipped the app's interface. Tests now go through it as a logged-in user.
Results
- Locked down: 71 of 71 tables under access control.
- Tested: 36 database test files with 1,425 checks, plus 89 application tests.
- The programme-day rule holds: 13 test cases and 1,000 simulated enrolments with 6,808 resets, with zero violations.
- Safety screen: all 55 of its test cases handled correctly.
- Spec checker: compares every figure a spec quotes against the programme source, and caught 7 of 8 planted faults.
Screens from the build

