---
id: DOM-MBR-MEM-002
title: Membership Term
realises: CON-MBR-MEM-002
product_area: membership
module: memberships
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-MBR-MEM-memberships
readable_by:
  - SVC-MBR-MEM-commerce-participant
  - SVC-MBR-MEM-billing
  - SVC-MBR-MEM-applications
  - SVC-MBR-MEM-snapshots
  - SVC-MBR-MEM-events
  - SVC-MBR-MEM-history
lifecycle: STATE-MBR-MEM-003
custom_fields: none
identity: >-
  A term receives a stable identifier within its workspace and belongs to one
  membership and program. A purchased term also records a workspace-unique
  payment authorization for fulfilment deduplication.
attributes:
  - name: membership and program
    kind: reference
    required: true
    computed: false
    notes: >-
      The term belongs to the named holding and repeats its program reference
      for consistency checks.
  - name: membership type
    kind: reference
    required: true
    computed: false
    notes: >-
      The type belongs to that program; staff selection requires an active type.
      It determines benefits and can override program grace.
  - name: package
    kind: reference
    required: false
    computed: false
    notes: >-
      The package identifies the offer used for the period. Derived and some
      granted periods can omit it.
  - name: starts on and ends on
    kind: date
    required: true
    computed: false
    notes: >-
      Coverage uses inclusive dates in the customer’s time zone; an absent end
      represents an unlimited period.
  - name: planned end
    kind: date
    required: false
    computed: false
    notes: >-
      The original planned last day survives an early closure so the shortened
      and planned periods can be distinguished.
  - name: state
    kind: enum
    required: true
    computed: false
    notes: >-
      The stored lifecycle is pending, committed, superseded, terminated or
      cancelled.
  - name: operation
    kind: enum
    required: true
    computed: false
    notes: >-
      The operation classifies entry as enrolment, renewal, reinstatement,
      rejoin, upgrade, downgrade, transfer, grant, flow-down, assignment, import
      or staff.
  - name: committed at
    kind: date
    required: false
    computed: true
    notes: >-
      Pending terms have no commitment instant; effective terms record when
      commitment occurred.
  - name: closing facts
    kind: collection
    required: false
    computed: false
    notes: 'Closure records its reason where supplied, time and actor.'
  - name: supersession links
    kind: reference
    required: false
    computed: false
    notes: >-
      Predecessor and successor references support supersession; the current
      amendment operations refuse execution.
  - name: Commerce references
    kind: collection
    required: false
    computed: false
    notes: >-
      Order, line, authorization and amendment references identify Commerce work
      without owning it. The authorization identifies repeated fulfilment.
  - name: source term
    kind: reference
    required: false
    computed: false
    notes: >-
      Granted and derived periods can point to the term from which their
      coverage originates.
  - name: migration quality
    kind: enum
    required: false
    computed: false
    notes: 'The import producer labels date certainty as exact, inferred or synthetic.'
  - name: version
    kind: number
    required: true
    computed: true
    notes: >-
      Corrections and staff closures compare this version with the submitted
      version. Billing stores it when planning an action.
relationships:
  - to: DOM-MBR-MEM-001
    cardinality: many-to-one
    ownership: The holding owns and retains its periods.
    cross_service: false
  - to: DOM-MBR-MEM-002
    cardinality: one-to-many
    ownership: Linked grant and child periods refer to their source term.
    cross_service: false
  - to: DOM-MBR-MEM-003
    cardinality: one-to-many
    ownership: Affiliations are dependent records of the term and must fit its coverage.
    cross_service: false
  - to: DOM-MBR-MEM-005
    cardinality: one-to-many
    ownership: >-
      Billing actions retain the candidate term reference and the version used
      when planning.
    cross_service: false
invariants:
  - id: INV-DOM-MBR-MEM-002-01
    statement: >-
      The service rejects shared days between effective or pending terms of a
      holding; the database exclusion independently protects effective terms.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-membership:modules/memberships/tests/integration/services/term-concurrency.integration.spec.ts#is
      backed by the migration’s exclusion when the persistence check is bypassed
  - id: INV-DOM-MBR-MEM-002-02
    statement: Neither the actual nor planned last day may precede the first day.
    enforced_at:
      - database
    provenance: observed
    source: 'services-membership:modules/terms/db/term-columns.ts:termChecks'
  - id: INV-DOM-MBR-MEM-002-03
    statement: >-
      Pending periods cannot carry a commitment instant, while committed,
      superseded and terminated periods require one.
    enforced_at:
      - database
    provenance: observed
    source: >-
      services-membership:modules/terms/db/term-columns.ts:termChecks
      (committed_at_check)
  - id: INV-DOM-MBR-MEM-002-04
    statement: >-
      Closing reasons are permitted only for terminated or cancelled periods,
      and successor references only for superseded periods.
    enforced_at:
      - database
    provenance: observed
    source: 'services-membership:modules/terms/db/term-columns.ts:termChecks'
  - id: INV-DOM-MBR-MEM-002-05
    statement: >-
      Classification and package references must agree with the program of the
      owning holding.
    enforced_at:
      - database
      - service
    provenance: observed
    source: >-
      services-membership:modules/memberships/db/membership-terms.table.ts:membership_terms_membership_fk;
      modules/memberships/services/operations/staff-operations.ts:requirePackageOf
  - id: INV-DOM-MBR-MEM-002-06
    statement: >-
      A payment authorization can identify only one committed term within a
      workspace.
    enforced_at:
      - database
    provenance: observed
    source: >-
      services-membership:modules/memberships/db/membership-terms.table.ts:membership_terms_commerce_authorization_uidx
  - id: INV-DOM-MBR-MEM-002-07
    statement: >-
      The implemented term-writing paths acquire the membership row lock to
      order changes to the same holding.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-membership:modules/memberships/services/persistence/memberships.ts:lockMembership;
      modules/memberships/services/operations/term-writes.ts
  - id: INV-DOM-MBR-MEM-002-08
    statement: >-
      Staff correction and termination require the current term version,
      committed state and a principal owning membership.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-membership:modules/memberships/services/operations/staff-operations.ts:lockTerm
  - id: INV-DOM-MBR-MEM-002-09
    statement: >-
      Child periods copy the source period; an own-rule package grant can
      outlast it, while source closure follows linked terms.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-membership:modules/memberships/services/grants/grant-plan.ts:grantPlanOf;
      modules/memberships/services/operations/staff-operations.ts:followParent
  - id: INV-DOM-MBR-MEM-002-10
    statement: >-
      Overlapping coverage across an owner’s exclusive programs is an intended
      restriction with known enforcement gaps.
    enforced_at:
      - service
    provenance: unknown
    source: FND-MBR-MEM-008
  - id: INV-DOM-MBR-MEM-002-11
    statement: >-
      The reservation index limits each term to one claim record but does not
      require a claim for every pending term.
    enforced_at:
      - database
    provenance: observed
    source: >-
      services-membership:modules/commerce-participant/db/commerce-claims.table.ts:commerce_claims_term_uidx
physical:
  - membership.membership_terms
  - membership.membership_terms_versions
  - membership.commerce_claims
evidence:
  - >-
    services-membership at 5994c270:
    modules/memberships/db/membership-terms.table.ts,
    membership-terms-versions.table.ts; modules/terms/db/term-columns.ts;
    modules/terms/services/status.ts; services/operations/staff-operations.ts,
    term-writes.ts, term-events.ts; services/grants/apply-grants.ts;
    modules/commerce-participant/db/commerce-claims.table.ts;
    services/fulfilment/fulfill.ts.
---

# Membership Term

## What It Models

A term records one period of membership coverage and the type and offer that define it. Keeping separate periods allows staff to distinguish renewals, gaps and later corrections without replacing the lasting membership.

## Identity and Attributes

Start and end dates are inclusive; unlimited terms have no end. Commitment, closure and supersession facts explain how the period changed. Commerce references support fulfilment and cancellation, while a source-term reference connects grants and organizational children to the period that produced them.

## Relationships

The membership owns the term and the term owns its unit affiliations. Grants and child periods reference a source term. Billing points to a candidate period and its reviewed version without acquiring ownership.

## Invariants

Overlap checks and the effective-period exclusion protect coverage within one holding. Database checks validate dates and state-dependent facts. Staff operations check versions and lifecycle eligibility. An own-rule grant has a distinct period calculation and must not be described as always bounded by the source end.

## How It Is Stored and Shared

Memberships owns live periods and their temporal versions. The Commerce participant also maintains reservation records whose references survive removal of an unfulfilled period. Billing selects periods, and history and snapshots reconstruct their earlier values.

## Open Design Questions

Cross-program exclusivity needs protection during concurrent additions and corrections. Amendments remain unavailable, despite the stored supersession fields. The import path can create facts that the staff path would reject.
