Things I've shipped
Production systems, with the parts that were actually hard. Happy to walk through the architecture of any of these.
A coach marketplace on Stripe Connect
Customers browse coaches in-app, pay for a session, and are shown the coach's private booking link — but only once the payment has genuinely settled. Coaches onboard themselves and get paid through destination charges, which split a platform fee automatically and settle the remainder to their own connected account.
The design decision that mattered: a booking is marked paid only from a signature-verified webhook, never from the browser redirect. The redirect tells you the customer came back — it doesn't tell you the money arrived, and it can be forged. Settlement, expiry, async failure, refunds and account updates are all handled as separate events, and every amount is recomputed server-side from the stored offering rather than trusted from the client.
The backend alone came to 63 files and 25 integration specs, with the booking URL and connected-account ID kept off every public serializer.
A React Native app, empty repo to both stores
A professional networking app for iOS and Android, owned end to end — every version bump, signing certificate and store submission. Included an in-app video recorder with a scriptable teleprompter and AI-generated feedback on the recording.
The app was flagged by Google Play under the Photo and Video Permissions policy for requesting
READ_MEDIA_IMAGES, which carries a removal risk. I migrated it to the Android system
photo picker and capped the legacy storage permissions at the last API levels that honour them, so
the app stopped asking for anything it couldn't justify — without losing camera capture.
Also handled the Android 15 target migration, the move to vision-camera, New Architecture compatibility, deep linking on both platforms, and per-PR builds that post a Play Internal App Sharing link straight into the pull request.
Semantic search that stays fresh
Employers needed to find candidates by meaning rather than keywords — matching on skills, experience and behavioural signals. That only works if the embeddings stay current as profiles change, so I built the indexing system behind it.
One authoritative write path for embeddings, so nothing else in the codebase can write them inconsistently. A batch worker for backfill and refresh, plus real-time incremental indexing over BullMQ and Redis, deliberately kept off the request path. Validation, retries, debouncing and dead-letter handling on top — the debouncing specifically because a burst of profile edits shouldn't trigger a burst of paid embedding calls.
AI features that ship
An OpenAI ReAct engine that reads a résumé or LinkedIn profile and builds a structured candidate record from it, a streaming in-app AI companion, and a Gemini worker that analyses user video pitches and returns feedback.
A representative bug: deep search silently stopped reranking and returned raw vector order. The
configured model rejected the temperature parameter we always sent, so every
completion failed with a 400 — and three separate fallback paths each caught it, degraded quietly,
and logged at debug level. The system looked healthy end to end while doing none of the work.
Fixed the parameter handling and the JSON parsing behind it. The lesson stuck: a fallback should
emit a metric, not a debug log.
A multi-tenant hiring platform, from scratch
An employer-facing product: signup and email verification, organisation onboarding, job authoring with draft/publish and visibility controls, applicant review pipelines, and automated closure after the application deadline. Multi-tenant with role-based access throughout.
CI, Docker and end-to-end tests went in before the first feature — on a greenfield repository that's the cheapest it will ever be, and it means nothing ever ships manually.
I also ran a security pass across the wider API, closing broken object-level authorisation gaps in six subsystems by enforcing ownership at both the route and the service layer — because a check at the route alone is one forgotten decorator away from a breach.
Open source
automated-ai-code-review — a GitHub Action that runs AI-assisted review on pull requests.
html_to_quill_delta — a Python library converting HTML into Quill Delta rich-text format.
Plus upstream fixes to React Native libraries in production use — react-native-fast-image,
react-native-video, react-native-image-picker and
rollbar-react-native.