← Back to work

Product · Systems·2026·Client — immigration firm

Relay: Operations Portal

Relay: a typographic cover for an internal operations portal build

01 · The problem

Immigration relationship managers run their entire practice through this portal: client records, document checklists, roadmap requests with legal deadlines, and the CRS score that decides what a client qualifies for. The system they had worked, mostly — until the details started to matter.

In the previous build, a single query that forgot its scope filter could list every client in the system. Not an attack — one missing WHERE clause out of thirty. But a client list is not something this system is allowed to leak, and “mostly” is not a security posture.

02 · The rebuild

A full rebuild on new foundations, with the business logic that had already earned trust ported rather than rewritten. The decisions that define it:

  • Roles are a table, not a boolean. Admin, RM, quality assurance and final-level are seeded rows; what a role can see is a column on the role, so narrowing one later is a seed change instead of a rewrite of every query.
  • A route’s path prefix is not a permission. Every data-layer function that reads or writes on someone’s behalf takes a request context and calls the permission check. A function that cannot be passed one cannot sit behind a guarded route.
  • The audit trail is append-only, enforced by Postgres. A trigger rejects updates and deletes; corrections are appended, never edited — and a script proves the guarantee against the live database rather than taking it on trust.
  • The SLA clock does not pause. Roadmap requests are due ten working days out — weekends and Nigerian public holidays excluded. Holidays are entered, not computed, because lunar-calendar dates are declared days in advance and a guessed holiday would silently shift every due date that spans it.
  • The CRS point tables are data. Every published number lives in one table file, and the calculator runs entirely in the browser: nothing is sent anywhere, nothing is stored.

03 · AI workflow

The one piece inherited rather than rebuilt was the assistant. Everything else in the AI column here is the database doing the guarding.

Groq + Tavily
The client-facing assistant, ported unchanged from the previous system because it worked.
Postgres itself
Append-only triggers, role visibility as data, cascade rules — the guarantees live in the database, and verify scripts prove them against a live instance.
Claude Code
Scaffolding and migration work, with the verify scripts as the definition of done: nothing counted as finished until the database could prove it.

No adoption metrics here — the honest number is zero, and the case for the work rests on the architecture, not on usage.

04 · The outcome

Designed, engineered, tested, and delivered as a complete rebuild. The firm did not adopt it before I left — what ships is their decision, and by then it was out of my hands. What carried forward is the thinking: several of the rebuild’s design decisions informed the CRM and mobile app the firm continued with.

For me it stands as the fullest expression of the range: not a landing page, not a bot — business software where the consequences of a wrong query are real, and the design work is making the correct behaviour the easy one.