
Highlights#
Role: Consulting tech lead (remote) · Team: 2 engineers · Timeline: joined March 2026, launched May 2026 · Live: reg.thedopple.com
- Hired as consulting tech lead by a US startup to take over their product mid-build; owned every technical decision from that point through launch, and the platform now processes real payments in production.
- Redesigned checkout while the product was live, moving payments onto Stripe’s hosted pages in staged, reversible steps so buyers were never interrupted — retiring ~10,000 lines of checkout code in the process.
- Re-architected the partner benefit system from snapshot balances to a transaction ledger, ending a class of money bugs where failed or canceled payments corrupted campaign budgets.
- Worked as the founders’ technical partner, meeting three or more times a week to turn business ideas (partner-matched gifting, group funding) into shipped features.
- Replaced the ORM-generated admin panel (SQLAdmin) the operations team was stuck on with purpose-built back-office tools — order tracking, item actions, payouts, benefit credits, promotions — so daily operations stopped depending on an engineer.
How it works#

Portfolio Case Study#
Problem. New parents need things they can’t always afford, and the people around them want to help. The Dopple’s registry lets a parent list what their child needs, and friends fund items in $25 slices instead of buying whole products. Partner organizations can also run matching campaigns: a provider puts up a budget, say $1,000 at a one-to-one match, and every dollar a parent spends draws a matching dollar from it. By early 2026 the product had outgrown its one-person engineering team. The startup hired me in March as consulting tech lead: from that point the technical decisions were mine, and so were the parts where mistakes cost money. My co-developer Muja carried most of the product screens while I ran engineering, deployment, and a three-meetings-a-week rhythm with the founders.
Approach. The biggest call I made was rebuilding how people pay, while they were paying. The original checkout kept card entry inside our own app. Stripe’s hosted checkout was the recommended path for their newer API; we’d initially stayed on the custom flow, but the hosted version would give us promo codes, tax handling, and shipping collection out of the box instead of building each one ourselves. Moving payment onto Stripe’s own pages also meant card data stopped touching our servers, and we later deleted around ten thousand lines of checkout code we no longer had to maintain. Because real customers were buying throughout, the switch went one purchase flow at a time behind feature flags, every step reversible, rehearsed on staging before anything real moved.
The other big call was fixing how benefit money was tracked. When I joined, a campaign’s remaining budget was a snapshot, recomputed on the fly from whatever the orders and registries looked like at that moment. That worked until a payment failed or got canceled: nothing recorded what should go back, so budgets drifted, and the bug reports kept coming from exactly those paths. I re-architected it as a ledger. Every reservation, capture, release, and refund becomes its own permanent row, matching the lifecycle Stripe reports payments in, and a balance is simply the sum of a campaign’s history. We backfilled the existing data into it, the database itself enforces that a hold can be released only once, and that whole class of bug ended. Of everything we shipped, this is the piece the founders were happiest about.
The ledger from the inside: reserve, capture, and release each append a permanent row mirroring Stripe’s payment lifecycle, so a failed or abandoned payment writes back exactly the release the old snapshot design never recorded — a balance is just the sum of a campaign’s rows.

The email system got a similar treatment: when SendGrid receipts started landing in spam and the bill was too high, I swapped the provider for Brevo without touching the rest of the codebase, and every email goes through a queue with retries so an outage never silently loses one.
I also rebuilt the back office. Before I was hired, the operations team ran the business on an ORM-generated admin panel (SQLAdmin) — essentially raw database tables with very little business logic on top — so routine work meant hand-editing rows or waiting on an engineer, and it was blocking the team’s productivity. I replaced it with purpose-built consoles shaped around what the team actually does: tracking orders, acting on the items inside them, settling provider payouts, checking and setting benefit credits, adding promotions, and managing the catalog, transactions, and registries. Day-to-day operations never need an engineer or direct database access.
What was hard. Group gifting means several people can pay toward the same item at the same moment. Get that wrong and someone gets charged for a slice that no longer exists, or charged twice. We caught exactly that in staging: a buyer retrying at the wrong moment could be double-charged, and an abandoned checkout could leave an item locked so nobody else could fund it. Those two bugs shaped the final design — every payment attempt is fingerprinted so a retry is recognized as the same purchase rather than a new one, and only one process can ever release a hold on an item, no matter how many are racing.
Outcome. The platform is live with real transactions, and real partner organizations run pilot benefit programs on it. I joined in March 2026 and we launched in May — about ten weeks from taking over the codebase to real payments in production, with two engineers. The money-handling paths are guarded by an automated test suite that runs on every change, which is what made changing the payment system in place a calculated risk instead of a gamble. And the part that doesn’t show up in the code: this was remote delivery work for an American startup, where keeping the founders informed and involved every week mattered as much as shipping.
Deliberate trade-offs. Chat and notifications refresh on a timer rather than instantly; realtime infrastructure was complexity the product didn’t need yet. Payouts to providers on Zelle or Cash App settle manually through the admin console, a deliberate choice to keep the automated path small.
Screenshots#



Stack#
FastAPI, PostgreSQL, SQLAlchemy, Stripe (hosted checkout, Connect payouts, webhooks), Brevo, Docker, DigitalOcean, React 19, TypeScript, Vite, TanStack Query, Tailwind, Cloudflare, GitHub Actions, GA4.
