Skip to content

Relationships

The database separates reusable definitions, customer agreements, and accounting history. Public methods take stable string keys; internal numeric IDs join the tables.

Catalog and subscriptions

Relationship Meaning
Feature ↔ product Many-to-many. The association stores feature-resolution rules.
Product → plan A plan belongs to one product.
Plan ↔ feature value One configured value per plan and associated feature.
Plan → billing cycle A billing cycle belongs to one plan and defines cadence.
Customer → subscription A customer can have several subscriptions, including several to the same product.
Subscription → billing cycle and plan Selecting a cycle determines the plan and product. The database also retains the plan reference.
Subscription → feature override At most one override per feature; another write replaces it.
Product → add-on A package belongs to one product and supplies values for its associated features.
Subscription ↔ add-on An attachment stores quantity and active/cancelled state, unique per subscription and add-on.

Plan and add-on values are strings validated according to the feature type. A feature can be reused across products, but an add-on belongs to a specific product. Plans and packages use features already associated with that product.

flowchart LR
  F[Feature] --- PF[Product-feature association]
  P[Product] --- PF
  P --> PL[Plan]
  PL --> BC[Billing cycle]
  C[Customer] --> S[Subscription]
  S --> BC
  P --> A[Add-on]
  A --> AV[Add-on feature values]
  AV --> F
  S --> SA[Add-on attachment]
  SA --> A
  S --> O[Feature override]
  O --> F

The diagram shows ownership and references, not a sequence of API calls. See How Feature Values Are Calculated for how these values combine.

Keys and ownership

Use your application's stable account identifier as the customer key. A customer can represent an organization or an individual; Subscrio does not decide which users may act for it. Enforce that mapping in your application.

Catalog keys are globally unique within their object type. A plan key is not scoped to its product, and a billing-cycle key is not scoped to its plan. Keys on existing records are immutable through ordinary update methods. Hooks can adjust supported fields during creation, so inspect the returned record if you install custom handlers.

Metered usage

metered_feature_config stores a feature's scope, aggregation, enforcement, and reset period. A usage balance identifies the customer, product, feature, period start, and optional subscription. Customer-scoped counters omit that subscription reference.

usage_events records accepted reports, request fingerprints, and saved responses. A key is unique per customer across usage reports. It is not the same namespace as credit-operation keys. History remains when the current period changes.

Credits

Tables Role
credit_currencies Global wallet currencies.
plan_credit_grants, credit_consumption_rules Recurring plan allowances and per-feature costs.
credit_wallets Customer/currency ownership and accounting coordination.
credit_grants Original and remaining amounts, expiry, priority, and optional subscription attribution.
credit_operations Idempotency keys, request fingerprints, and result snapshots, including spending allocations.
credit_ledger_entries Recorded movements against individual grants.
subscription_credit_grant_states Scheduling anchors and the next due grant boundary.

Wallets are shared across a customer's products. Subscription attribution explains where a grant came from and allows subscription-specific expiration; it does not make a separate wallet.

History and deletion

Accounting and attachment references can block deletion of customers, subscriptions, features, products, or currencies. Detaching an add-on preserves a cancelled attachment rather than removing its row. Service-level checks also require certain catalog records to be archived before deletion.

Some original catalog relationships use database cascades. Do not infer that every delete is blocked or that a cascade makes deleting history safe. Use the owning library method, inspect its documented conditions, and archive records that should remain available for historical explanation.

Core tables live in the subscrio schema. The PostgreSQL audit-log and payments extensions add their own tables there and manage their schemas separately. See Schema Upgrade before changing an existing installation.