loading
Engineering notes Rev. 2026-09-04 Scope Production systems, Apr–Sep 2026 ← Portfolio

What I build, and what I refuse to let it do.

Most of what I shipped this year is under NDA. I can't name the clients, the products or the markets — so this page shows you the systems underneath instead: how they are structured, what holds them up, and the rules I hold every one of them to.

All of it comes from code I wrote and can walk you through line by line. Where a system isn't finished, it says so.

On naming. Mahramji appears by name because the site is public and the client is happy to be credited. Every other system here is described without its client, product name or market. Figures are counted from the repositories on 2026-09-04.

2,042 Commits authored
Apr–Sep 2026
7 Production
repositories
4 Languages shipped
TS · Python · SQL · HCL
2 Data-protection regimes
designed against
01

Systems

Five builds · client names withheld

Ordered by how much of the stack I owned. Each entry states what the system does, the parts that were genuinely hard, and where it stands today — including the ones that aren't deployed.

Live · one client
Role
Full-stack & platform
Period
May – Aug 2026
Team
Three
Authored
1,053 commits
Hosting
In-region, by requirement

AI marketing-intelligence platform

A platform that reads a client's analytics and commerce accounts, proposes campaigns against what it finds, and manages them on the ad accounts the client connects. I worked across the whole repository — the Python decisioning service, the web console, the mobile viewer, the schemas, the infrastructure and the deploy path.

The hard parts

  • Nothing reaches a live ad account without two separate human approvals: one on the campaign idea, one on the finished creative. The code on that path is held to a higher review bar than the rest of the repository.
  • Data residency is enforced at the call site rather than by where the box happens to sit, so the guarantee survives a migration between cloud providers instead of being re-argued.
  • Around a dozen platform connectors — ads, analytics, commerce, social — each with its own token custody, refresh path and failure mode.
  • Cities and sub-sectors come from closed registries. Free text there silently files a client under the wrong benchmark, and nobody finds out for a quarter.
  • A seasonal calendar anchored to the Hijri year, so campaign timing is computed rather than hand-maintained every year.
  • Nine CI/CD workflows and eleven architecture decision records, across two target clouds — one live, one staged for the cutover.
  • Python 3.13
  • FastAPI
  • LangGraph
  • PostgreSQL 16
  • pgvector
  • BigQuery
  • dbt
  • Cube
  • React 19
  • Vite
  • Motion
  • Expo
  • Terraform
  • Docker
  • GitHub Actions
Built end to end · not deployed
Role
Solo, full stack
Period
Aug – Sep 2026
Authored
501 commits
Counted
29 screens · 13 API routes · 23 migrations · 72 test suites

Bilingual AI voice-interview engine

An HR engine that conducts real voice interviews in Arabic and English and produces evidence-cited assessments — a candidate journey from application through a live interview room to a scorecard, plus a thirteen-screen operator console. It is built end to end and it is not deployed; nobody has yet sat an interview against a live model, and the project says so on its own front page.

The hard parts

  • A real-time voice pipeline: speech in, speech out, and a viseme-driven face that moves with what is being said.
  • Every conversational turn commits before the next is spoken, and position is derived from the transcript rather than a stored cursor — so a process killed mid-interview resumes exactly where it was.
  • Row-level security on every organisation-scoped table, and CI runs the whole suite a second time with the superuser bypass removed. A policy that only passes as superuser proves nothing.
  • Audit tables are append-only, enforced by trigger. Access is a capability grant checked server-side, not a URL somebody could guess.
  • Full right-to-left Arabic — a mirrored interface, not a translated string file — with bilingual PDF reports out the other end.
  • Bias monitoring by role family and interview language, a right of reply for anyone assessed, and a retention policy spoken aloud in the consent rather than buried in a footer.
  • Next.js 16
  • React 19
  • TypeScript
  • Drizzle
  • PostgreSQL
  • pgvector
  • better-auth
  • next-intl
  • Python
  • Pipecat
  • Recharts
  • Docker
Live demo
Role
Solo, schema to deploy
Period
Apr – Aug 2026
Authored
114 commits
Counted
13 screens · 22 API routes

Ordering & delivery platform

A restaurant ordering platform built end to end for a client: customer storefront, staff back-office, and the operational plumbing between them. Checkout hands off to WhatsApp and cash on delivery, because that is how the market it was built for actually pays — there is no card gateway, and pretending otherwise would have been the easier claim to make.

The hard parts

  • A staff back-office with per-tab permissions carried in a signed token, so a floor account cannot reach the books.
  • Redis in front of the menu: the read path is hot and constant, the write path is one person editing prices once a week.
  • Web push and an installable PWA, so a phone propped on a counter behaves like a point-of-sale terminal.
  • Loyalty mechanics and a taste quiz that personalises the menu — the parts that make a second visit more likely than the first.
  • Next.js 16
  • React 19
  • Supabase
  • PostgreSQL
  • Redis
  • Web Push
  • JOSE
  • Resend
  • PostHog
Live · client domain
Role
Solo, design & build
Period
Aug 2026
Authored
172 commits
Counted
67 dishes · 9 migrations · 90 tests

Mahramji — Sea Food & Fish almahramji.com →

A seafood restaurant on the Mina corniche in Tripoli. Guests scan a QR code at the table and read the menu in English or Arabic, priced in dollars or lira. A waiter still takes the order — that is how the restaurant works, and the software had no business changing it. The owner runs the whole site from a dashboard: menu, prices, photographs, hours, hero video, without me.

The hard parts

  • Two currencies and two languages, with right-to-left treated as a first-class layout rather than a flipped stylesheet.
  • Time-based two-factor on the admin login, row-level security on every table, scoped storage policies, and a scheduled prune of login attempts.
  • Nine ordered migrations applied through the management API — no pasting SQL into a console, so the schema in the repository is the schema in production.
  • QR cards, print PDFs and app icons generated from the client's vector logo by script, so a logo revision is a re-run rather than an afternoon.
  • Ninety tests and a build that has to pass before anything ships.
  • Next.js 16
  • React 19
  • Supabase
  • PostgreSQL
  • RLS
  • TOTP 2FA
  • Web Push
  • Vercel
  • Python
Role closed · handed over
Role
Lead frontend
Period
Earlier engagement
Team
Founding, two engineers

Real-time AI trading platform

My first engineering role: leading the frontend of an AI trading platform through its early production build. A monorepo spanning web, mobile and rendered video; six OAuth sign-in strategies behind two-factor; payments; and market surfaces that had to stay correct while the data never stopped moving. The company handed the repository on when I left, so I can describe the work but not point you at a commit history — which is exactly why the rest of this page is written the way it is.

  • React
  • Next.js
  • TypeScript
  • Expo
  • Remotion
  • Stripe
  • WebSockets
02

The constraint ledger

Eight rules · enforced, not intended

A marketing platform, an interview engine and a restaurant menu have almost nothing in common. What they share is this list. Each rule is a thing the system is not allowed to do, and each one names the mechanism that stops it — because a rule enforced by good intentions is a rule you find out about in an incident report.

C-01

No automated system spends a client's money on its own.

Enforced byTwo human gates on the path to a live ad account — one approves the idea, one approves the finished creative. Neither can be skipped, and the code on that path carries a higher review bar than the rest of the repository.

C-02

Regulated data does not leave the jurisdiction it was collected in.

Enforced byA residency check at the call site rather than at the host. Moving the deployment between cloud providers cannot move the data, because the gate never depended on where the box was.

C-03

Row-level security nobody has attacked is a comment, not a control.

Enforced byA policy on every organisation-scoped table, and a CI job that runs the entire suite a second time with the superuser bypass removed. Tests that only pass as superuser prove nothing about what a tenant can reach.

C-04

History is append-only.

Enforced byAudit writes go through database triggers rather than application code. Nothing that records what happened is able to revise it afterwards, including me.

C-05

Access is a grant, never a URL somebody could guess.

Enforced byCapability records checked server-side on every read, and per-scope permission claims inside signed sessions. Knowing an identifier is not the same as being allowed to see what it points at.

C-06

A value that maps to money or to a benchmark comes from a closed registry.

Enforced byEnumerated cities, sectors and sub-sectors instead of free text. A typo in a free-text field files a record against the wrong comparison and reports it confidently for a quarter before anyone notices.

C-07

Long-running state is derived, never remembered.

Enforced byEach step commits before the next begins, and position is recomputed from what was written. A process killed mid-session resumes exactly where it stopped, because there was never a cursor to lose.

C-08

What isn't built is visibly absent, never simulated.

Enforced byNo placeholder that looks finished. Every project carries a written "what is not built, or not proven" section, and its status file is generated from a single source of truth by a CI job that fails when the two drift apart.

03

Stack, by layer

Shipped, not sampled

Listed only where I have run it in something real, and each line says what it actually did. A tool with nothing next to it doesn't belong on a page like this.

Interface
  • React 19 · TypeScript every frontend here — 315 components in the largest console alone
  • Next.js 16 App Router, server actions and server components across four of the systems above
  • Vite the build for the console that isn't on Next
  • Motion · GSAP · Lenis interface motion, including the page you're reading
  • Base UI · Radix · shadcn headless primitives styled into an existing design system rather than replacing it
  • Recharts data-dense operator dashboards
  • Expo the read-only mobile viewer on the marketing platform
  • Three.js · React Three Fiber the 3D and generative work
  • next-intl bilingual English/Arabic with full right-to-left
  • PWA · Web Push installable storefronts, notifications to a phone on a counter
Runtime & services
  • Node.js 22 API routes, server actions, background work
  • Python 3.13 · FastAPI the decisioning service — 346 modules behind one contract
  • LangGraph agent graphs where a decision needs steps, state and a place to stop
  • Pipecat the real-time voice pipeline — transport-agnostic by design so the vendor can change
  • NestJS · Prisma service structure on earlier platform work
  • REST · OpenAPI · JSON Schema contracts kept in their own package so the client and the service can't drift
  • WebSockets · Server-Sent Events live surfaces that stay correct while the data moves
Data
  • PostgreSQL 16 the default — row-level security, triggers, ordered migrations, nothing typed into a console
  • pgvector retrieval sitting beside the relational data instead of in a second system
  • Drizzle · Supabase · Prisma schema and access, chosen per project rather than by habit
  • Redis read-path caching where reads dwarf writes, and rate limiting where they don't
  • Neo4j graph retrieval where the relationships are the query
  • BigQuery · dbt · Cube the analytics side — staging models, marts and a semantic layer over them
AI & agents
  • Claude SDK the model layer across the AI work, with token spend metered per tenant
  • Retrieval vector where meaning matters, graph where structure does, SQL where neither is needed
  • Human-in-the-loop approval gates, evidence citation, and a right of reply for the person being assessed
  • Evaluation rubric-scored outputs and calibration that feeds the next cycle rather than a vibe check
  • n8n scheduled and event-driven automation around the model, not through it
Infrastructure
  • Docker · Compose every service runs locally the way it runs in production
  • Terraform infrastructure as code, separate dev and prod environments, reviewed like application code
  • GCP · Oracle Cloud · Vercel · Supabase picked for data residency and running cost, not familiarity
  • GitHub Actions nine workflows on the largest repository, third-party actions pinned to a commit SHA
  • Cloud Run jobs six scheduled ingestion jobs feeding the warehouse
  • DNS · TLS · environment config the unglamorous half of a launch, which is still mine
Security & compliance
  • Access model row-level security, append-only audit, capability grants, per-scope claims in signed sessions
  • Authentication TOTP two-factor, JOSE-signed sessions, OAuth across a dozen third-party platforms with token custody and refresh
  • Gitleaks secret scanning across the entire git history on every push, not just the diff
  • Semgrep static analysis as a CI gate
  • Dependency floors vulnerable ranges pinned out explicitly, with the advisory ID written next to the pin so the next person knows why
  • Data protection residency gates, consent ledger, data-subject requests, pseudonymisation and redaction as code paths rather than policy documents
Quality
  • Pytest · Vitest 667 Python test modules and 72 TypeScript suites across the two largest systems
  • Typecheck · lint · test · build all four gate every merge; nothing lands red
  • pnpm workspaces · Turborepo monorepos that stay navigable past the first ten packages
  • Architecture decision records eleven on the largest repository — the reasoning outlives the argument
  • Generated documentation status written from one source of truth, with a CI job that fails when it drifts
04

How the work runs

What you get, beyond the code

Decisions are written down

Anything that would be expensive to reverse becomes an architecture decision record: the options, the trade-off, the call. Six months later the reasoning is still there, which is the only reason a team can revisit a decision instead of re-litigating it.

The spec doesn't drift

The agreed scope is fingerprinted and checked in CI. When the code and the specification disagree, that's a conversation before a merge — not a discovery at handover.

Documentation can't go stale

Status, phases and blockers are generated from a single state file on every commit. There is no README anyone has to remember to update, because remembering is not a control.

The supply chain is pinned

Third-party CI actions pinned to commit SHAs, dependency versions floored above known advisories, tool installers checksum-verified. A build that can change under you isn't reproducible.

You're told what isn't done

Every project I run carries a written list of what is unbuilt or unproven, kept beside the list of what works. A stub that looks finished costs more than a gap that's labelled.

Handover is the deliverable

Migrations in order, secrets documented, environments reproducible, the local setup a single command. Restaurant owners run their own dashboards. The measure of the work is whether it survives me leaving.

If this is the kind of engineering you need, I have room for it.

Contract and freelance, remote, EMEA-friendly hours. I take the systems where being wrong has a cost — money, personal data, a hiring decision — and I stay with them after launch. Happy to walk through any of the above in a call, at whatever depth your team wants.