Selected work

Retention flags

A subscription cancel flow that stopped being a one-way door, without shipping a discount to everyone who looked at it.

Client
RemedyMeds
Sector
Telehealth, GLP-1 weight care
Role
Software engineer, contract
Year
2025 to now
Stack
React, Next.js, TypeScript, PostHog
Result
Retention flow live, flag-gated

The problem

People leave a GLP-1 weight care subscription for reasons that have almost nothing to do with each other. The cost stops making sense. The side effects are not worth it this month. Or it worked, they got where they were going, and they are done. Three different situations, one button.

The cancel flow handled all three identically, because it had no opinion about who was leaving and nothing to offer them if it had. It worked exactly as designed, which was the problem: the last thing a subscriber saw before going was a confirmation dialog.

The constraint

Blanket discounts were off the table. Offering an incentive to everyone who reaches the cancel screen trains customers to reach the cancel screen. Whatever shipped had to be targeted, measurable, and reversible on short notice.

The second constraint was that subscription state did not live in the frontend. Eligibility depended on plan, tenure, and billing status, all of it server side. And an accepted offer is not finished when the subscriber sees a confirmation; it is finished when somebody's account actually changes, which meant the flow had to end inside the operations team's real work, not in a queue they might check.

TriggerCancel intent
GateFeature flag and eligibility check
OfferDiscount, fixed number of months
Hand offOps notified in Slack, with context

What I built

01

A flag, before a feature

The whole intervention shipped behind a PostHog feature flag wired to backend subscription state. That made the rollout a dial rather than a launch: eligibility could be narrowed, the offer repriced, or the whole thing turned down, none of it requiring a deploy.

02

Eligibility on the server, presentation on the client

The frontend never decided who deserved an offer. It asked, rendered what came back, and stayed dumb about pricing rules that change more often than the interface does.

03

The handoff, with the context attached

An accepted offer posted into Slack, where the operations team already works, carrying the account and the terms with it. A person still applies the adjustment, and that is the right division of labor when money is moving. What the automation removed was not the judgment. It was the remembering.

Result

LiveRetention flow

Eligible subscribers now see a discount for a fixed number of months at the moment they cancel, gated by a flag that can be turned down without a deploy.

End to endReferral system

A referral system built on the same engagement: frontend flows, backend tracking, and the discount logic underneath it.

15+Packages migrated

A separate migration from Bun to pnpm across the codebase, which removed a recurring class of CI failures and aligned local builds with cloud ones.

What this section does not have is a clean before and after number. The flag made a holdout possible and no one ever ran one, so what is claimed here is what the system does rather than what it moved. Any figure I gave you instead would be a guess wearing a decimal point.

What I would change

I built it around how one team worked. The operations process as it existed that quarter, who watched which channel, what they needed attached to act, all of it got encoded into the system without anybody deciding it should be permanent. It fit beautifully and it fit one shape.

The cost of that shows up later, when the team grows or reorganizes and discovers the software has opinions about how they should work that nobody chose. What I would do differently is draw a line between the decision and the delivery: the system decides who is eligible and what the offer is, and how that reaches a human is a swappable edge rather than a load-bearing assumption. Same code, one more seam, and the next reorganization is a configuration change instead of a rewrite.

Email me

If you are hiring for a senior full stack or frontend role, a line about the team and the stack is enough to start.

shabaneh.ahmad@gmail.com