Designing Membership Lifecycles Instead of Mutating Subscriptions
A gym subscription is not just a row with a status. It can renew, expire, freeze, resume, refund, and interact with queued coverage, add-ons, and branch rules.
This note explains why freezes had to be modeled as policy-bound events instead of a new subscription status.
Members can ask to pause coverage for legitimate reasons, but a freeze affects dates, balances, approval rules, and future renewals.
A simple "frozen" subscription status hides the real question, which is how coverage windows changed and why.
The freeze model also had to respect plan rules and still allow admins to override them intentionally.
Freeze behavior depends on policy: minimum days, maximum days, cooldowns, approval requirements, and remaining balance.
Date shifts can collide with active subscriptions, queued renewals, add-ons, PT packages, and branch-specific rules.
Cancellation and rollback need inspectable recovery logic, not silent rewrites of old dates.
A freeze request becomes a ledger entry governed by plan policy and approval logic. "Member is frozen" is derived from live freeze windows, not stored as the subscription's identity.
Store freeze requests as ledger entries tied to plan policy and lifecycle context.
Reserve remaining freeze balance when the request is made, then confirm or restore it based on approval outcomes.
Shift coverage dates only after approval, and derive the runtime "member is frozen" state from live freeze windows.
Use rollback snapshots so cancellation or partial restoration can reverse date shifts cleanly.
Let admin-created freezes intentionally override member-facing policy limits when operations require it.
Freeze history becomes auditable because the event, policy, decision, and date shift are explicit records.
Runtime checks can answer whether a member is currently frozen without redefining what the subscription is.
The lifecycle model becomes easier to extend because freeze is handled as an event with consequences, not a new identity.
The ledger approach creates more records and more date logic than a simple status field.
Cron and reconciliation logic are needed to complete or reject stale freeze requests.
That complexity pays off by keeping lifecycle semantics much clearer.
AI-assisted implementation. Architecture, decisions, tradeoffs, and UX ownership were mine.
A gym subscription is not just a row with a status. It can renew, expire, freeze, resume, refund, and interact with queued coverage, add-ons, and branch rules.
The challenge was making Razorpay, Cashfree, and manual payments behave the same way operationally.
These notes are part of larger systems work. You can return to the related project context or reach out if you need someone who can reason through workflows, authorization, and operational software without making them harder to operate.