---
id: DOM-COM-ORD-004
title: Entitlement
realises: CON-COM-ORD-004
product_area: commerce
module: orders
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-commerce: c8b66a98e2490617aec38ba5c8165dd9bd0a8f9b
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-COM-ORD-entitlements
readable_by:
  - SVC-COM-ORD-orders
  - SVC-PFM-ELG-eligibility
  - SVC-PFM-QRY-data-exports
lifecycle: STATE-COM-ORD-008
custom_fields: none
identity: >-
  Each grant has a workspace identity, with uses numbered within that grant. Purchased grants are unique by
  order line and benefit kind.
attributes:
  - name: holder
    kind: reference
    required: true
    computed: false
    notes: The specification chooses the buyer or line recipient; recipients can be contacts or organizations.
  - name: kind
    kind: enum
    required: true
    computed: false
    notes: 'The benefit category is download, included registration, submission requirement or access.'
  - name: product
    kind: reference
    required: true
    computed: false
    notes: The Accounting product associated with the benefit.
  - name: origin
    kind: reference
    required: true
    computed: false
    notes: >-
      Purchased grants reference order, line and obligation; manual grants identify staff origin without
      purchase references.
  - name: allowance
    kind: number
    required: false
    computed: false
    notes: >-
      A finite grant allows one to ten thousand uses; unlimited grants omit that limit and remaining uses are
      derived.
  - name: availability window
    kind: date
    required: true
    computed: false
    notes: A required start and optional later end bound when consumption is allowed.
  - name: state
    kind: enum
    required: true
    computed: false
    notes: >-
      Active, revoked or expired, with applicable timestamps and reasons; exhausting uses does not change
      state.
  - name: uses
    kind: collection
    required: false
    computed: false
    notes: >-
      Consumption stores a row per unit with consumer, record reference, actor and time; restoration adds its
      actor, time and explanation.
relationships:
  - to: DOM-COM-ORD-002
    cardinality: 'A purchased right references one line, with at most one right of each kind on that line.'
    ownership: Entitlements retains its grant and reference to the retained purchased line.
    cross_service: false
  - to: DOM-COM-ORD-003
    cardinality: The seller supplies the frozen specification used to create a right.
    ownership: Commerce interprets grant declarations rather than allowing direct seller writes.
    cross_service: false
  - to: DOM-CRM-ENT-001
    cardinality: A contact may hold multiple benefit grants.
    ownership: CRM retains holder identity while Entitlements stores a reference.
    cross_service: true
  - to: DOM-CRM-ENT-002
    cardinality: An organization may hold multiple benefit grants.
    ownership: CRM remains the holder record owner.
    cross_service: true
  - to: DOM-PFM-ELG-003
    cardinality: Eligibility evaluations can consult a holder's current grants.
    ownership: Platform owns qualification decisions and Commerce supplies a restricted rights projection.
    cross_service: true
invariants:
  - id: INV-DOM-COM-ORD-004-01
    statement: A unique line-and-kind constraint prevents repeated grant obligations from creating duplicate rights.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-commerce:modules/entitlements/tests/e2e/entitlements.e2e.spec.js#grants ONE download right of
      two uses for the three copies, not six
  - id: INV-DOM-COM-ORD-004-02
    statement: >-
      Finite allowances must be between one and ten thousand, with consumed units no greater than the
      allowance.
    enforced_at:
      - database
    provenance: observed
    source: 'services-commerce:modules/entitlements/db/entitlements.table.ts:entitlements_quantity_check'
  - id: INV-DOM-COM-ORD-004-03
    statement: The consumption function recognizes a repeated consumer reference and returns its recorded uses.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-commerce:modules/entitlements/tests/e2e/entitlements.e2e.spec.js#gives the member a link and
      consumes one use per Idempotency-Key (the retry free), then refuses the third 409
      insufficient_entitlement
  - id: INV-DOM-COM-ORD-004-04
    statement: Consumption requires an active grant whose start has arrived and whose optional end has not passed.
    enforced_at:
      - database
    provenance: observed
    source: 'services-commerce:db/migrations/20261018130023_entitlements.sql:consume_entitlement'
  - id: INV-DOM-COM-ORD-004-05
    statement: 'Revoked grants require a revocation timestamp, and expired grants require an expiry timestamp.'
    enforced_at:
      - database
    provenance: observed
    source: >-
      services-commerce:modules/entitlements/db/entitlements.table.ts:entitlements_revocation_check,
      entitlements_expiry_check
  - id: INV-DOM-COM-ORD-004-06
    statement: Revoking a grant leaves its recorded consumption unchanged.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-commerce:modules/entitlements/tests/e2e/entitlements.e2e.spec.js#revokes it with the reason
      (the used quantity standing), replays the revoke under its key, refuses another 409
      entitlement_not_revocable
  - id: INV-DOM-COM-ORD-004-07
    statement: >-
      The consumption function is the insertion boundary for uses; restoring a use preserves the row and
      future draws continue numbering.
    enforced_at:
      - database
    provenance: observed
    source: 'services-commerce:modules/entitlements/services/persistence/entitlement-uses.ts'
  - id: INV-DOM-COM-ORD-004-08
    statement: An optional validity end must be later than the validity start.
    enforced_at:
      - database
    provenance: observed
    source: 'services-commerce:modules/entitlements/db/entitlements.table.ts:entitlements_validity_check'
  - id: INV-DOM-COM-ORD-004-09
    statement: >-
      Portal reads are restricted to the linked contact's grants, and staff intervention routes exclude portal
      callers.
    enforced_at:
      - api
      - service
    provenance: test
    source: >-
      services-commerce:modules/entitlements/tests/e2e/entitlements.e2e.spec.js#shows a stranger nothing of
      the member’s, and refuses the member’s grant by id 403
physical:
  - entitlements
  - entitlement_uses
  - entitlements_held_v
evidence:
  - >-
    services-commerce at c8b66a98: modules/entitlements/db/entitlements.table.ts, entitlement-uses.table.ts;
    services/register/*.ts; services/entitlements/*.ts; services/persistence/*.ts;
    aws/api/entitlements.routes.ts; services-commerce:db/migrations/20261018130023_entitlements.sql
    (consumption function, held view).
  - 'react-console at baf6dae3: lib/commerce/order-flows/live-order.ts (no live entitlement read).'
---

# Entitlement

## What It Models

An entitlement records a usable benefit held by a contact or organization. Purchases can grant downloads, included registrations, submission requirements or access; staff can also create a grant manually. Consumers draw units, and staff interventions can restore consumption or revoke a right.

## Identity and Attributes

A grant identifies holder, product, kind and origin, then records its allowance and validity window. Unlimited benefits omit the finite allowance. Each consumed unit retains the consumer's reference and attribution, including restoration information when staff return that unit.

## Relationships

Purchased grants point to the line and obligation whose frozen payload supplied their specification. Subsequent product configuration does not rewrite the grant. Holders remain CRM records, and eligibility obtains Commerce's active-rights projection.

## Invariants

Constraints enforce line-and-kind uniqueness, finite allowances, timestamp consistency and valid windows. The consumption function checks active status and time bounds while protecting replay and concurrent allowance use. Revocation preserves past consumption.

## How It Is Stored and Shared

Entitlements owns both grants and their use records. Consumers invoke the database consumption boundary inside their own transaction, under a dedicated execution role. Eligibility reads a view, and purchased-grant activity contributes to order history. No custom-field capability is declared.

## Open Design Questions

The console has no grant-configuration screen. Live Order 360 supplies no entitlement records, leaving its tab empty. Submission-requirement benefits exist in the contract, but the consuming workflow needs integration outside this module.
