Authoritative entitlement and quota design

Backend & Database Implementation Plan

Target architecture

RevenueCat projects commerce state; billing grants overlay it; backend resolves one effective access snapshot; immutable quota ledgers enforce every expensive or paid action. iOS never decides whether the backend should spend generation resources.

Retain and change

Existing componentDecision
billing_eventsRetain as immutable provider/client inbox; extend captured fields.
billing_accessRetain provider projection; add trial/access phase, product/offer identifiers, environment, and trial dates.
billing_grantsRetain overlay model; add optional permanent grant support and bulk-job provenance.
users.subscription_tier and legacy subscriptionsStop treating as writable truth. Migrate/derive or deprecate after consumers move.
plan-config.tsReplace provisional minute-centric values with versioned approved plan definitions.
Usage placeholdersReplace zeros with authoritative quota balance and immutable usage.

Required schema concepts

Meter definitions

MeterDebit momentRefund/release
Recurring generation creditReserve before scheduled job enqueueRelease terminal technical failure; consume on generation acceptance/completion per policy
One-time generation creditReserve before job enqueueRelease failed/canceled job; prevent duplicate debit with request id
Explore listening secondsDebit server-accepted playback heartbeat/progress deltasDeduplicate by session and monotonic position; no debit for seeks/replays already counted per policy
File upload creditReserve on upload session creationRelease failed/abandoned session after timeout; consume after validated object commit
Episode duration limitValidate before generationNo debit; structured denial

Enforcement checklist

Trial projection

Offer and nudge decision API

Backend returns the eligible paywall stage and offering reference; RevenueCat/StoreKit remains final price eligibility authority.

Subscription-change projection

Migration plan

  1. Add new fields/tables without removing legacy fields.
  2. Backfill billing access for known paid/granted users and produce mismatch report against legacy tier.
  3. Move read consumers to canonical access snapshot.
  4. Implement quota ledgers in observe-only mode and compare expected vs actual usage.
  5. Turn on backend denials behind per-capability flags.
  6. Run grandfather batch before enabling affected gates.
  7. Freeze legacy writes, then remove/deprecate legacy tier paths after one full subscription cycle.

API checklist

Backend acceptance criteria