Task 2:
- lib/billing/config.ts: reads 4 Razorpay env vars (throws at call time, not
boot), premium grant constants (50GB / 6 members / 3 children / ₹199),
razorpayAuthHeader() Basic-auth helper
- POST /api/admin/seed-plan: admin-only idempotent upsert of the Premium plan
row from env + constants (GET shows current plans). Re-runnable, no DB shell
Task 3:
- lib/billing/entitlements.ts: grantPremium() / revokeToFree() sync onto
families.tier + max_members + max_children. Existing quota.ts guards UNCHANGED
— they already read these via isPaidFamily(). revoke = limit downgrade only,
data untouched (freeze-not-demote)
- ENTITLED_STATUSES (active/authenticated/pending=grace) + TERMINAL_STATUSES
No guard refactor needed: chosen "sync to families.tier" approach means the
3 existing guards (storage/member/child) keep working as-is.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>