Product Systems Engineer · ZA → Remote

I build complete product systems.Data layer to shipped app.

Most engineers build a screen. I own the whole vertical — acquiring data, moving it, architecting the backend, integrating AI, shipping to real users. The graph beside this is a real system I built — drag it.

~120K/day
products from an automated retail price pipeline
4retailers
normalised into one product schema
auto+monitored
daily run, self-reporting
gracefulfallback
degrades, stays usable on partial failure
// case studies

Real systems, with the reasoning intact.

Not screenshots — the decisions. Where the trade-offs were, why I chose what I chose, and what it took to survive contact with reality.

case_01 · com.ubicorp.milkza · v1.2.0 · flagship

milk — grocery price intelligence, shipped end-to-end

A solo vertical build: scrape four SA retailers, normalise messy product data, serve it through a resilient backend, layer AI recipe generation on top, ship a real Flutter app to the Play Store.
● live · beta
the hard problem

Four retailers, four undocumented APIs, all changing without notice. Prices must stay correct or the product is worthless.

Built FallbackProductService — when a live API fails, it auto-fails-over to a cached Supabase table. The app stays usable even when a retailer breaks upstream.

stack & surface

Offline-first with optimistic UI, real-time shared lists, GPS store selection, AI recipe → auto-matched to in-stock products.

FlutterRiverpodSupabasePostgres·RLSEdge FnsGemini AIRealtimeHive offline
case_02 · multi-tenant SaaS · architecture

pettlo — multi-tenant SaaS, architecture documented

A veterinary clinic platform demonstrating production-grade multi-tenancy: RLS-enforced isolation, edge deployment, and decisions written down the way a staff engineer documents them.
◆ architecture
the judgment on display

Two-layer tenant isolation, redundant by design. RLS at the database layer + explicit app-level scoping — defence-in-depth, so a forgotten filter yields an empty result, never a data leak.

Chose the service-role pattern because Cloudflare Workers can't reliably refresh JWT cookies mid-request. The decision is documented with its trade-offs.

stack & surface

This is what "I document architecture" looks like — the why, not just the what. Diátaxis-structured docs ship with the repo.

Next.js 15React 19TypeScriptZodPostgres·RLSCloudflare Edgepnpm monorepoResend
case_03 · data engineering + security

Log normalisation pipeline — data engineering meets SecOps

A containerised pipeline that ingests raw Fortigate firewall logs, normalises events to a defined schema via Vector, sinks to Elasticsearch, and self-validates with automated tests.
▣ data · security
the system

Raw logs → Vector transform pipeline → Elasticsearch + Kibana, fully orchestrated with Docker Compose. One `docker-compose up` runs the whole stack.

The pipeline validates itself — pytest runs automatically against expected output once logs land, so correctness is enforced, not assumed.

the range it proves

Beyond product apps — comfortable in data engineering and security tooling, the unglamorous infrastructure founders actually need.

VectorElasticsearchKibanaDocker ComposePythonpytest
// how I work

Senior habits, not just shipped features.

decisions, documented

I write down the why — trade-offs, rejected options, the constraint that forced the call. Diátaxis docs ship with the code, not after it.

resilient by default

Upstream things break. I design for graceful degradation — fallbacks, cached layers, partial-failure handling — so the product survives contact with reality.

disciplined delivery

Conventional commits, linting, typed end-to-end. The repo reads like a senior engineer maintained it, because that lowers the cost of everything after me.

Have a system that needs building?

APIs, automation, AI workflows, scraping, backend infrastructure, data pipelines — if it spans the whole stack, that's exactly the kind of problem I take on. The fastest way to talk is a WhatsApp message.