---
id: DOM-CMT-MTG-005
title: Opening
realises: CON-CMT-MTG-005
product_area: committees
module: meetings
revision: 3
status: draft
design_intent: proposed
implementation_evidence: inconsistent
source_sha:
  services-committees: 36129c24daeaadcdb339218c38cdeaff9861359d
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-CMT-MTG-recruitment
readable_by:
  - SVC-PFM-QRY-queries
lifecycle: STATE-CMT-MTG-008
custom_fields: none
identity: >-
  Each opening receives its own record identity when drafted. An interest uses
  opening and contact as its unique pair, while a review-created alternate is
  unique to its delivered decision.
attributes:
  - name: committee
    kind: reference
    required: true
    computed: false
    notes: >-
      The recruiting committee, checked live at creation and publication and
      closed by dissolution cleanup.
  - name: seat and position
    kind: reference
    required: false
    computed: false
    notes: >-
      Optional seat and position references; a named seat must be the
      committee’s and supplies the compatible position.
  - name: places
    kind: number
    required: true
    computed: false
    notes: 'The number of places offered, constrained to 1–100.'
  - name: window
    kind: date
    required: false
    computed: false
    notes: >-
      Optional start and deadline dates in nondecreasing order; these dates do
      not gate filling.
  - name: status
    kind: enum
    required: true
    computed: false
    notes: 'The recruitment stage: draft, open, closed, filled or cancelled.'
  - name: description and eligibility rule
    kind: text
    required: false
    computed: false
    notes: The advertised description and an optional eligibility-rule reference.
  - name: filled by
    kind: collection
    required: true
    computed: true
    notes: >-
      Appointment references already counted toward filling, stored without
      duplicates by the fill rule.
  - name: published and closed at
    kind: date
    required: false
    computed: true
    notes: Instants recording publication and departure from open status.
  - name: outside references
    kind: reference
    required: false
    computed: false
    notes: >-
      Reserved opportunity and process references; no production operation
      invokes those systems through them.
  - name: interest
    kind: collection
    required: false
    computed: false
    notes: >-
      A member’s expression of interest and optional note, updated on repeated
      interest.
  - name: alternate
    kind: collection
    required: false
    computed: false
    notes: >-
      A review-selected reserve applicant retained when later withdrawn by
      supersession.
relationships:
  - to: DOM-CMT-MTG-006
    cardinality: one-to-many
    ownership: >-
      A nomination owns its optional opening link and can inherit the opening’s
      seat and position target.
    cross_service: false
invariants:
  - id: INV-DOM-CMT-MTG-005-01
    statement: >-
      The database declares 1–100 places and an end date no earlier than the
      start when both exist.
    enforced_at:
      - database
    provenance: observed
    source: >-
      services-committees:modules/recruitment/db/openings.table.ts:openings_count_check;
      openings_dates_check
  - id: INV-DOM-CMT-MTG-005-02
    statement: >-
      The service checks a supplied seat against the committee and a supplied
      position against that seat.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-committees:modules/recruitment/services/persistence/openings.ts
      (seat_not_of_committee, position_not_seat_position)
  - id: INV-DOM-CMT-MTG-005-03
    statement: >-
      Staff may edit draft or open recruitment only, and closed, filled and
      cancelled statuses have no reopening move.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-committees:modules/recruitment/services/rules/opening-lifecycle.ts:decideOpeningAction
  - id: INV-DOM-CMT-MTG-005-04
    statement: >-
      The fill rule counts each matching appointment once and marks recruitment
      filled when the count reaches its places.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-committees:modules/recruitment/services/rules/fill-rule.ts:fillOpening
  - id: INV-DOM-CMT-MTG-005-05
    statement: The database declares one interest record for each opening and member.
    enforced_at:
      - database
    provenance: observed
    source: >-
      services-committees:modules/recruitment/db/opening-interests.table.ts:opening_interests_contact_uq
  - id: INV-DOM-CMT-MTG-005-06
    statement: The database declares one alternate row per delivered review decision.
    enforced_at:
      - database
    provenance: observed
    source: >-
      services-committees:modules/recruitment/db/opening-alternates.table.ts:opening_alternates_decision_uq
  - id: INV-DOM-CMT-MTG-005-07
    statement: >-
      Outside staff reads show only open openings of undissolved committees with
      allowed listings and an unelapsed deadline; a future opening date does not
      hide them.
    enforced_at:
      - service
    provenance: observed
    source: >-
      services-committees:modules/recruitment/services/portal/portal-openings.ts;
      services/persistence/openings.ts:publishedOpenings
physical:
  - committees.openings
  - committees.opening_interests
  - committees.opening_alternates
evidence:
  - >-
    services-committees at 36129c24: modules/recruitment/db/openings.table.ts,
    opening-interests.table.ts, opening-alternates.table.ts;
    services/persistence/openings.ts, opening-interests.ts;
    services/rules/opening-lifecycle.ts, fill-rule.ts, forecast-rule.ts,
    dissolved-recruitment.ts; services/openings/*.ts;
    services/forecast/vacancy-forecast.ts; services/portal/portal-openings.ts;
    modules/tenant-lifecycle/participants.ts
---
# Opening

## What It Models

An opening describes recruitment for a committee vacancy, whether tied to a particular seat, position or any seat-holder place. It includes the interest and alternate records for that vacancy. The forecast is a calculation over appointment endings that can create drafts.

## Identity and Attributes

The record identity persists through publication and filling. The place count and dates describe the advertised opportunity, while counted appointment references provide deduplication for event delivery. Deadline visibility does not imply automatic closure.

## Relationships

An opening belongs to a committee and can be referenced by several nominations. A matching seat-holder appointment may fill it. Seats, positions and appointments are separate records owned by the committee module.

## Invariants

Creation checks place count, date ordering and target compatibility. Staff lifecycle actions refuse final records. Filling deduplicates appointment starts, and member interest is updated within its unique opening-contact pair.

## How It Is Stored and Shared

The recruitment service owns openings, interests and alternates, with Queries exposing the opening dataset. Its workspace lifecycle declarations purge openings under the committees participant, a boundary mismatch already recorded. Openings declare no custom fields.

## Open Design Questions

Filling ignores the advertised date window and no scheduled job closes expired recruitment. Publication notices target chair and liaison rather than responsibility holders. Product must decide the date policy and notice audience before a staff surface relies on them.
