Manish Shetty

All systems

Transformation Accelerator

A programme platform for sensitive health-related data, where the database enforces privacy

Walkthrough3:46
Role
Founder; AI Systems and Automation Lead, Phalanx Labs (2021 to present). Product owner: I made every product, safety, scope and money decision, and reviewed and approved each spec before it was built.
Built with
AI agents (specs) and Codex (code); Next.js, TypeScript, Supabase (EU region), pgTAP and Vitest for tests, GitHub Actions.

How it works

A 90-day programme for sensitive health-related data, where protection lives in the database itself.

  1. Locked by default

    All 71 tables under row-level security; no role gets blanket access, not even the server's own key.

  2. Narrow access

    Clients can only call functions that identify them from their login, never one that takes a person's ID.

  3. Dates, not counters

    The programme day and progress count are calculated from dates, so a setback never resets the programme.

  4. Safety screen

    34 rules flag crisis and medical language.

  5. 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

  6. 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

  1. EU hosting (Frankfurt), with no exceptions.
  2. Every table locked by default, with access granted narrowly.
  3. Real erasure. A user can be deleted completely, and the audit trail survives without identifying them.
  4. 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.
  5. 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:
    1. 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.
    2. 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

Two SQL migrations: an event trigger that switches on row-level security for every new table, and a policy that lets a client read only the lessons unlocked for their own login
The first migration locks every new table by default; client access is then granted narrowly, with the person identified from their login.
Terminal output from GitHub Actions showing six green runs, all nine required checks passing, and the database suite reporting 36 files, 1,425 tests and a pass
Every change ran nine required checks in GitHub Actions. The database suite alone was 36 files and 1,425 checks.