173 lines
14 KiB
Markdown
173 lines
14 KiB
Markdown
# Glossary
|
|
|
|
**Purpose:** Cross-cutting vocabulary for the data model. This is the authoritative source for durable names; modules and documents should cite terms by their definition here rather than re-defining them in prose.
|
|
|
|
**Related:**
|
|
- [`CONVENTIONS.md`](CONVENTIONS.md) — structural conventions for module-level documentation
|
|
- [`../documents/doc-32-plan-management-framing.md`](../documents/doc-32-plan-management-framing.md) — the investigation that produced much of the plan-related vocabulary
|
|
- [`../documents/doc-28-grants-module-placement.md`](../documents/doc-28-grants-module-placement.md) — the definiteness test, which governs module placement for new entities
|
|
|
|
**Scope:** This glossary prioritizes terms that span modules or whose meaning is load-bearing. Single-module implementation details belong in the module's own reference.
|
|
|
|
---
|
|
|
|
## 1. Commercial catalog
|
|
|
|
### product
|
|
|
|
A commercial instrument — something the cooperative sells. Carries name, classification (`product_type`), visibility flags, and a reference to an entitlement set specifying the capabilities conferred. Table: `billing.products`.
|
|
|
|
A product is not a price (commercial terms attach separately, via `billing.prices`), not an entitlement set (capability specification is independently variable), and not a subscription (the recurring vehicle that pays for the product over time).
|
|
|
|
### price
|
|
|
|
Commercial terms attached to a product — amount, currency, billing schedule, trial period. Table: `billing.prices`. A product may carry multiple prices (e.g., monthly and annual pricing for identical capabilities).
|
|
|
|
### plan
|
|
|
|
A product that participates in a ladder. Ladder membership is the *structural* declaration of plan-ness; the `product_type = 'plan'` label is enforced (by CHECK) to be logically equivalent to `plan_ladder_id IS NOT NULL`. No product is a plan without a ladder; no ladder member has a non-plan `product_type`.
|
|
|
|
A plan is not a subscription — see §4 *Disambiguations*.
|
|
|
|
### plan ladder *(canonical)*, ladder *(prose shorthand)*
|
|
|
|
A named set of plan products declared mutually exclusive within a commercial domain. Tables: `billing.plan_ladders` (the named set), `billing.plan_ladder_tiers` (the ordered product memberships).
|
|
|
|
A plan ladder is a *catalog-shape* construct: it declares how products relate to one another commercially, not what capabilities they confer. Capability composition lives in `entitlement_sets`; the ladder says only "these plans are alternatives to each other."
|
|
|
|
### tier
|
|
|
|
A plan's ordered position within a ladder — the rung a product occupies. Expressed as a row in `billing.plan_ladder_tiers` with a `rank` column.
|
|
|
|
*Note — potential collision.* Stripe uses "tier" in `billing_scheme = 'tiered'` to refer to volume-bracketed pricing within a single price (e.g., first 100 units at $1, next 900 at $0.90). That is a different concept: Stripe tiers slice a *price*, while our tiers position a *product* within a *ladder*. Context should disambiguate; when in doubt, prefer "ladder tier" (our sense) and "pricing tier" (Stripe's sense).
|
|
|
|
*"Rung" is an acceptable synonym* when the ladder metaphor is active and precision matters (e.g., "the bundle occupies a rung on each ladder it participates in"). Prose should default to "tier"; "rung" is reserved for contexts where the distinction from pricing tiers is load-bearing.
|
|
|
|
### bundle
|
|
|
|
A plan product that occupies tiers on more than one ladder simultaneously. Not a separate `product_type`; bundle-ness is the emergent property of ladder multi-membership.
|
|
|
|
A bundle activation produces one `pool_provisions` row (the commercial fact) and N `pool_provision_ladders` junction rows (the catalog-shape facts, one per ladder the bundle occupies). The exclusion constraint on the junction guarantees that holding the bundle blocks any standalone tier on the ladders it covers.
|
|
|
|
---
|
|
|
|
## 2. Commercial vehicles
|
|
|
|
### subscription
|
|
|
|
A recurring commercial agreement — a stateful binding between a billing account and one or more priced products, generating invoices over time. Table: `billing.subscriptions`.
|
|
|
|
A subscription is a *vehicle*, not a *catalog position*. A subscription may carry a plan line-item and zero or more addon line-items; the plan is one item of the subscription, not the subscription itself. Two subscriptions carrying the same plan are two distinct commercial agreements that happen to reference the same catalog entry.
|
|
|
|
The `status` column admits `'trialing'` as a first-class state alongside `'active'`, `'paused'`, `'cancelled'`, and related lifecycle values. Trial specification is price-level (`prices.trial_period_days`) and trial-instance state is subscription-level (`trial_start`, `trial_end`); this separation — specification on the price, occurrence on the vehicle — is a deliberate architectural choice that preserves the expressiveness of monthly-with-trial vs. monthly-without-trial on identical products, documented in Document 34.
|
|
|
|
### subscription item
|
|
|
|
A line item within a subscription binding it to (price, quantity). Table: `billing.subscription_items`. The product identity of the line item is reached via the price's `product_id`.
|
|
|
|
### subscription change
|
|
|
|
An audit record of a mutation to a subscription, carrying `effective_at` for scheduled transitions. Table: `billing.subscription_changes`. The general audit log for all subscription lifecycle events; not specific to plan transitions.
|
|
|
|
**Canonicalization.** `billing.subscription_changes` is canonical for *commercial mutations of a subscription* — status transitions (`trialing`, `past_due`, `canceled`, and peers), period boundaries, amount changes. Plan-position history of a pool — which ladder tier it held, when, and under whose authority — is not this table's concern; that history is carried by `entitlements.pool_provision_transitions` (see §3). Subscription-driven ladder attachments are recorded in both tables, intentionally, because they answer different questions; neither is a substitute for the other.
|
|
|
|
### purchase
|
|
|
|
A completed one-time transaction — a billing account pays once and receives access. Table: `billing.purchases`. No recurring lifecycle, no state machine beyond completion and potential refund.
|
|
|
|
A purchase may reference a plan product (a "lifetime license"); the resulting provision is indistinguishable downstream from a subscription-sourced provision.
|
|
|
|
### grant
|
|
|
|
Non-commercial administrative or promotional access. Table: `entitlements.grants`. Conferred by decree; no money changes hands; no invoice generated.
|
|
|
|
A grant may reference a product (for audit clarity) or an entitlement set directly. See `../documents/doc-28-grants-module-placement.md` for the definiteness-test argument placing grants in entitlements.
|
|
|
|
---
|
|
|
|
## 3. Capability layer
|
|
|
|
### resource pool *(canonical)*, pool *(prose shorthand)*
|
|
|
|
A capability container that bridges billing and resources. Table: `entitlements.resource_pools`. Scoped to an organization via billing account. `pool_type` distinguishes `default` (auto-created per billing account, attached to all workspaces in the org), `shared` (explicit multi-workspace), and `dedicated` (explicit single-workspace).
|
|
|
|
The default pool is the org-scoped capability container by convention — see Constraint 7 (default-pool-as-org-scope).
|
|
|
|
### pool provision
|
|
|
|
A record that a pool has been provisioned from a specific source. The uniform convergence point for the three access mechanisms (subscription, purchase, grant). Table: `entitlements.pool_provisions`. Carries denormalized `entitlement_set_id` resolved at creation time.
|
|
|
|
The provision is the commercial-fact record of "this source activated this capability in this pool at this time." The catalog-shape fact of "that activation occupies these ladder rungs" is carried separately in `pool_provision_ladders`.
|
|
|
|
### pool provision ladder *(junction)*
|
|
|
|
A row linking a provision to a ladder tier. Table: `entitlements.pool_provision_ladders`. Carries denormalized `pool_id`, `status`, `activated_at`, `ended_at` (kept in sync with the parent provision via trigger) to support the GiST exclusion constraint enforcing tier exclusivity per pool.
|
|
|
|
### pool provision transition
|
|
|
|
An audit record of a ladder-position change affecting a pool provision — an initiation, upgrade, downgrade, or end. Table: `entitlements.pool_provision_transitions`. Carries actor attribution (`actor_type`, `actor_id`), the ladder context (`plan_ladder_id`), the rank delta (`from_rank`, `to_rank`), and the distinction between when the change took effect (`effective_at`) and when the row was recorded (`created_at`).
|
|
|
|
**Canonicalization.** `pool_provision_transitions` is canonical for *plan-position history of a pool*: what tier a pool held, when, who changed it, why. Commercial mutations of the subscription that may have driven a given transition — status changes, period boundaries, amount changes — remain the canonical concern of `billing.subscription_changes` (see §2). Subscription-driven ladder attachments are recorded in both tables, intentionally, because they answer different questions: an operator audit UI querying "how did this org arrive at Standard?" reads `pool_provision_transitions`; a billing audit UI querying "what happened to this subscription?" reads `subscription_changes`.
|
|
|
|
**Scope.** `transition_type` is strictly scoped to ladder-position changes: `initiate`, `upgrade`, `downgrade`, `end`. Suspension and resumption are *not* recorded here — those lifecycle events are carried by `pool_provisions.status` and, for subscription-driven suspensions, `subscription_changes`. This scope discipline keeps the table's semantics narrow and its eventual absorption into a generic `audit.log` module mechanical rather than semantic (the columns map directly onto a standard audit projection — see the model reference).
|
|
|
|
### entitlement set
|
|
|
|
The declarative specification of what capabilities a provision confers. Table: `entitlements.entitlement_sets`. Multiple products may reference the same set (capability-commercial separation, Decision 112).
|
|
|
|
### entitlement set rule
|
|
|
|
A single capability declaration within an entitlement set — a boolean flag, a numeric limit, a renewable quota, or a credit grant. Table: `entitlements.entitlement_set_rules`. Single-table inheritance via `rule_type` (Decision 107).
|
|
|
|
---
|
|
|
|
## 4. Derived relations
|
|
|
|
### enrollment
|
|
|
|
**A prose term with no direct structural referent.** An enrollment is the derived fact that an entity currently holds a tier on a ladder. It is not a table, not a column, not an entity. The canonical question "what plan is this organization on?" is answered by a constrained query over `entitlements.pool_provision_ladders`, whose cardinality per (pool, ladder) pair is guaranteed by an exclusion constraint.
|
|
|
|
The term is retained for prose convenience — "the org is enrolled in the Pro plan" is clearer than "the org's default pool holds an active provision occupying the Pro tier of the Nextcloud ladder." But documentation and code should treat "enrollment" as shorthand for the derivation, never as an entity to be stored.
|
|
|
|
---
|
|
|
|
## 5. Disambiguations
|
|
|
|
The following distinctions are load-bearing and recur throughout the data model.
|
|
|
|
### 5.1 Plan vs. subscription
|
|
|
|
A plan is a *catalog position* — a product on a ladder. A subscription is a *commercial vehicle* — an ongoing agreement that pays for things. The two are colloquially conflated because the simplest SaaS arrangement (one subscription carrying one plan line-item) makes them coextensive. They are categorially distinct:
|
|
|
|
- A subscription may carry a plan item plus several addon items; the plan is one item among many.
|
|
- A plan may be reached by a purchase (lifetime license) or a grant (board-conferred access) with no subscription involved.
|
|
- A subscription may exist without any plan (pure metered usage).
|
|
|
|
### 5.2 Ladder tier vs. pricing tier
|
|
|
|
See the `tier` entry in §1. Briefly: *our* tier is a ladder rung (a product's ordered position); Stripe's `billing_scheme = 'tiered'` tier is a volume bracket within a single price. Different concepts.
|
|
|
|
### 5.3 Product vs. entitlement set
|
|
|
|
A product is the *commercial instrument* (how something is sold). An entitlement set is the *capability specification* (what the sale confers). Multiple products may reference the same entitlement set — monthly and annual pricing of identical capabilities are two products sharing one set. The separation is by design (Decision 112) and allows pricing, packaging, and capability specification to vary independently.
|
|
|
|
### 5.4 Provision vs. enrollment
|
|
|
|
A provision is a *commercial fact* ("this source activated something in this pool at time T"). An enrollment is a *catalog-shape derivation* ("that activation occupies a rung on this ladder"). One provision can give rise to multiple enrollments (a bundle activation). Enrollments are derived from provisions plus ladder membership; they are not independently authored.
|
|
|
|
### 5.5 Default pool vs. organization
|
|
|
|
The default pool is auto-created per billing account and attached to all workspaces in the owning organization. In single-billing-account organizations, the default pool is operationally equivalent to the organization as a scope. In multi-billing-account organizations, each billing account has its own default pool — a structural recognition that the organization may hold distinct commercial arrangements per billing account (Constraint 7).
|
|
|
|
---
|
|
|
|
## 6. Deprecated or superseded terms
|
|
|
|
Terms previously used in prose or earlier document revisions that should no longer appear in new writing. If encountered in existing documents, they should be revised at next touch.
|
|
|
|
| Deprecated | Use instead | Reason |
|
|
|---|---|---|
|
|
| (none yet) | — | — |
|
|
|
|
*This section will accrete as durable vocabulary supersedes working terms.*
|