Skip to content

[P0] Define plan entitlements and durable usage accounting #119

Description

@postigodev

Context

Billing status alone is not enough to authorize paid features. Preppie needs an explicit entitlement model that translates free, founding, standard, grace-period, and admin-granted access into concrete feature rights and measurable limits.

Provider-backed features must be accounted for using durable, auditable usage records rather than process-local counters or UI assumptions.

Initial entitlement direction

The founding plan target is $6.99/month, with local guided cooking and local timers remaining broadly available while remote AI and voice usage are bounded.

Initial limits are hypotheses and must remain configurable. Suggested starting points for beta validation:

  • Free: limited recipe generations/imports/pantry parsing, no normal remote voice allowance beyond a tiny demo.
  • Founding: higher AI limits plus a bounded remote voice allowance.
  • Standard: configurable successor plan after measured beta usage.
  • No unlimited remote voice entitlement.

Scope

Domain model

  • Define plan, feature, entitlement, quota, billing-cycle, usage-event, adjustment, and administrative-grant concepts.
  • Keep commercial plan names separate from internal feature keys.
  • Support boolean entitlements, count quotas, duration quotas, and optional rolling-window limits.
  • Model free, trialing, active, grace, canceled-at-period-end, expired, and admin-granted access.
  • Version entitlement configurations so historical decisions remain explainable after prices or limits change.

Usage categories

Track at minimum:

  • AI meal/recipe generation.
  • Recipe import by text/URL/image.
  • Pantry or spoken-inventory structuring.
  • AI chat and ingredient adaptation where separately limited.
  • Remote voice connected seconds, provider-billed seconds/minutes, or both when available.
  • Vision/provider calls where they create material cost.
  • Add-on or promotional usage grants.

Durable ledger

  • Record immutable usage events with user, category, quantity, unit, timestamp, billing period, request/idempotency key, source feature, provider where applicable, and sanitized metadata.
  • Support reservation/commit/release for operations whose final usage is known only after completion.
  • Prevent concurrent requests from consuming the same remaining allowance.
  • Support reversals/adjustments without mutating historical events.
  • Make cycle resets a query/projection concern rather than deleting usage history.

Entitlement resolution

  • Provide one server-side service that resolves effective entitlements from subscription state, plan version, trial/grace rules, add-ons, and admin grants.
  • Avoid scattered checks such as isPremium across controllers and frontend actions.
  • Return user-safe remaining-usage data without exposing provider internals or billing identifiers.
  • Define behavior when subscription state is stale or Stripe is unavailable.

Privacy and retention

  • Do not store prompts, transcripts, audio, images, or recipe content merely to meter usage.
  • Define retention for billing/usage evidence and deletion/anonymization behavior after account deletion.
  • Keep operational cost telemetry separable from user-visible quota records.

Acceptance criteria

  • Every paid feature is represented by a documented entitlement key and policy.
  • Usage survives deploys, replicas, retries, and application restarts.
  • Concurrent consumption cannot exceed a quota through races.
  • Duplicate requests do not create duplicate usage charges.
  • Voice is metered by duration rather than vague session counts.
  • Historical usage remains auditable after a plan’s price or limits change.
  • Trial, grace, cancel-at-period-end, expired, and admin-grant behavior are tested.
  • Usage records do not contain raw voice, prompt, image, or recipe content.
  • The frontend can retrieve current plan, period, allowance, used amount, and remaining amount through a safe API.

Dependencies

Out of scope

  • Permanent final quotas before beta measurement.
  • Charging users directly from individual raw provider events.
  • A generalized accounting ledger for company finances.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions