---
id: DOM-MBR-MEM-006
title: Membership History
realises: CON-MBR-MEM-006
product_area: membership
module: memberships
revision: 1
status: draft
design_intent: proposed
implementation_evidence: partially-observed
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-MBR-MEM-history
readable_by:
  - SVC-MBR-MEM-memberships
  - SVC-MBR-MEM-snapshots
  - SVC-MBR-MEM-events
lifecycle: STATE-MBR-MEM-012
custom_fields: none
identity: >-
  Temporal versions identify a record and recorded interval; timeline revisions
  use a record and sequence. Snapshot rows identify their workspace, month, run
  version and membership. Business events keep a stable delivery identifier.
attributes:
  - name: versions
    kind: collection
    required: true
    computed: true
    notes: >-
      Database capture retains previous membership, term, affiliation and
      custom-value facts with recorded intervals and attribution.
  - name: revisions
    kind: collection
    required: true
    computed: true
    notes: >-
      Commit-time settlement produces an attributed timeline entry for each
      relevant record change, grouped into changed sections.
  - name: as-of reconstruction
    kind: computed
    required: false
    computed: true
    notes: >-
      Reconstruction combines the requested business date and recording instant
      with period, standing, unit, custom-value and available committee facts;
      contact details are captured from current data.
  - name: dimension settings
    kind: collection
    required: false
    computed: false
    notes: >-
      The ordered settings select contact fields, contact custom fields or
      membership custom fields to retain in monthly reporting.
  - name: monthly snapshot
    kind: collection
    required: false
    computed: true
    notes: >-
      A published version stores members, units and ancestors, selected
      characteristics and grouped counts with movement totals.
  - name: business events
    kind: collection
    required: true
    computed: false
    notes: >-
      The event log retains nine strict versioned event shapes and their record
      references and attribution.
relationships:
  - to: DOM-MBR-MEM-001
    cardinality: many-to-one
    ownership: History provides evidence about holdings without modifying them.
    cross_service: false
  - to: DOM-MBR-MEM-002
    cardinality: many-to-one
    ownership: Periods retain their own revision timeline as well as temporal versions.
    cross_service: false
  - to: DOM-MBR-MEM-003
    cardinality: many-to-one
    ownership: Monthly reporting freezes unit connections and their dated ancestry.
    cross_service: false
invariants:
  - id: INV-DOM-MBR-MEM-006-01
    statement: >-
      Relevant membership and collection changes settle as a revision at commit;
      changes confined to cached standing produce no revision.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#records
      nothing for a change of the cached status alone
  - id: INV-DOM-MBR-MEM-006-02
    statement: >-
      Commit rejects a history change whose attribution supplies neither actor
      nor source.
    enforced_at:
      - database
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-history.integration.spec.ts#refuses
      at commit a write that names no source and no actor
  - id: INV-DOM-MBR-MEM-006-03
    statement: >-
      Revision source must be one of the accepted interactive, integration, job,
      maintenance or service sources.
    enforced_at:
      - database
    provenance: observed
    source: >-
      services-membership:modules/history/db/record-revisions.table.ts:record_revisions_sys_source_check
  - id: INV-DOM-MBR-MEM-006-04
    statement: >-
      Without a recording instant, reconstruction agrees with a live dated read
      for the tested fixtures.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-membership:modules/history/tests/integration/membership-as-of.integration.spec.ts#answers
      every FAA membership as the live read does
  - id: INV-DOM-MBR-MEM-006-05
    statement: >-
      Publication requires successful snapshot checks; failed generation leaves
      the earlier current version in place.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-membership:modules/snapshots/tests/integration/membership-snapshot.integration.spec.ts#fails
      the run on the counts check, publishes nothing
  - id: INV-DOM-MBR-MEM-006-06
    statement: >-
      The tested rerun at the original recording instant reproduces member,
      affiliation and count rows.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-membership:modules/snapshots/tests/integration/membership-snapshot.integration.spec.ts#writes
      identical member, affiliation and count rows with the original known_at
  - id: INV-DOM-MBR-MEM-006-07
    statement: >-
      Event publication participates in the business transaction, so rollback
      also removes the stated event.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-membership:modules/events/tests/integration/business-events.integration.spec.ts#leaves
      no event when the operation that stated it rolls back
  - id: INV-DOM-MBR-MEM-006-08
    statement: >-
      Payload validation rejects a business event that does not meet its
      versioned schema before insertion.
    enforced_at:
      - service
      - database
    provenance: test
    source: >-
      services-membership:modules/events/tests/unit/business-event-schemas.spec.ts#refuses
      a termination that names no last day
  - id: INV-DOM-MBR-MEM-006-09
    statement: >-
      The supported snapshot purge path requires workspace deletion and
      processes rows in batches.
    enforced_at:
      - service
    provenance: test
    source: >-
      services-membership:modules/snapshots/tests/integration/membership-snapshot.integration.spec.ts#refuses
      to purge the tenant while Platform holds it active
physical:
  - membership.memberships_versions
  - membership.membership_terms_versions
  - membership.membership_term_organizational_units_versions
  - membership.membership_custom_field_values_versions
  - membership.record_revisions
  - membership.snapshot_dimension_settings
  - membership.membership_snapshot_members
  - membership.membership_snapshot_affiliations
  - membership.membership_snapshot_dimensions
  - membership.membership_snapshot_counts
  - membership.snapshot_run_jobs
  - membership.snapshot_run_job_steps
  - membership.snapshot_run_job_events
  - membership.published_events
evidence:
  - >-
    services-membership at 5994c270: modules/history
    (db/change-event-streams.ts, record-revisions.table.ts, history
    configurations, services/persistence/membership-versions.ts,
    reconstruction/membership-as-of.ts); modules/snapshots (db,
    services/types/membership-snapshot.ts, generation, persistence, settings);
    modules/events (contracts/business-events.ts, db/published-events.table.ts,
    services/publishing/publish-business-event.ts); docs/migrations/history,
    events.
---

# Membership History

## What It Models

History makes membership changes explainable. Temporal versions support reconstruction, revisions give staff an attributed timeline, monthly snapshots support stable reporting, and published events tell partner applications about committed changes.

## Identity and Attributes

Versions carry recorded intervals rather than just business dates. Revision settlement occurs at commit, giving the timeline the same durability boundary as the write. Snapshots distinguish successive publications of a month, while business events preserve identifiers across delivery attempts.

## Relationships

History describes holdings, periods and units without changing their ownership. Snapshot affiliations retain ancestry at the reporting date. Event payloads describe business changes independently of the transport rows used to deliver them.

## Invariants

Attribution is checked before commit. Cache-only refreshes do not create timeline noise. Snapshot validation controls publication, and business-event insertion rolls back with its source write. These mechanisms do not establish that every possible stored fact is exposed by the timeline.

## How It Is Stored and Shared

The history service implements versions, timelines and reconstruction for the broad history concept. Snapshots and Events implement its reporting and partner-delivery facets. Query permissions control dataset reads, and deletion participants remove snapshot data only during workspace removal.

## Open Design Questions

The existing findings cover missing timeline details, automation attribution, reduced timestamp precision and reporting after migration. Product decisions remain open for officer access to history and event catalogue ownership and retention.
