---
id: WF-CMT-MTG-002
title: Materialize Recurring Meetings
trigger: >-
  Staff create, update or explicitly materialize a series, or the daily job
  processes it.
product_area: committees
module: meetings
revision: 1
status: draft
design_intent: proposed
implementation_evidence: inconsistent
inference: []
source_sha:
  services-committees: 36129c24daeaadcdb339218c38cdeaff9861359d
implements:
  - CAP-CMT-MTG-002
moves:
  - STATE-CMT-MTG-003
  - STATE-CMT-MTG-001
crosses:
  - SVC-CMT-MTG-meetings
idempotency: >-
  The database permits one occurrence per series and local date. Existing dates
  are reused, including cancelled occurrences; unchanged time, title and zone
  need no rewrite.
concurrency: >-
  One series lock covers expansion and occurrence changes. Series saving commits
  before materialization begins.
hops:
  - 'n': 1
    actor_or_service: Meetings API or daily job
    action: >-
      Validate recurrence and zone, then save the series; creation checks that
      the committee is not dissolved.
    anchor: >-
      services-committees:modules/meetings/services/persistence/meeting-series.ts:createSeries
    seam: sync
    on_failure: Reject invalid input.
    left_inconsistent: No new series on a failed save.
    observer: The operation response.
    provenance: observed
    source: >-
      services-committees:modules/meetings/services/persistence/meeting-series.ts:createSeries
  - 'n': 2
    actor_or_service: Series materialisation
    action: >-
      Lock the saved series and expand its active dates through the rolling
      eighteen-month window.
    anchor: >-
      services-committees:modules/meetings/services/persistence/meeting-series.ts:materializeSeries
    seam: sync
    on_failure: Roll back materialization.
    left_inconsistent: The series edit remains committed without its occurrence changes.
    observer: Materialization results and job logs.
    provenance: observed
    source: >-
      services-committees:modules/meetings/services/persistence/meeting-series.ts:materializeSeries
  - 'n': 3
    actor_or_service: Series materialisation
    action: >-
      During an edit, update future draft or scheduled occurrences still wanted
      and cancel dates removed from the rule.
    anchor: >-
      services-committees:modules/meetings/services/persistence/meetings.ts:rewriteMeetingDetails
    seam: sync
    on_failure: Roll back the occurrence transaction.
    left_inconsistent: The saved rule can disagree with existing meetings until recovery.
    observer: Materialization counters.
    provenance: observed
    source: >-
      services-committees:modules/meetings/services/persistence/meetings.ts:rewriteMeetingDetails
  - 'n': 4
    actor_or_service: Series materialisation
    action: >-
      Insert missing dates as scheduled meetings, copying defaults and the
      roster and preparing notices.
    anchor: >-
      services-committees:modules/meetings/services/persistence/meetings.ts:insertMeeting
    seam: sync
    on_failure: >-
      Roll back the run; daily processing records the failed series and
      continues.
    left_inconsistent: Missing dates await another materialization.
    observer: Failed-series results and error logs.
    provenance: observed
    source: >-
      services-committees:modules/meetings/services/persistence/meetings.ts:insertMeeting
  - 'n': 5
    actor_or_service: Meetings jobs
    action: >-
      Process active series for each active workspace in the daily pass at 06:41
      UTC.
    anchor: >-
      services-committees:modules/meetings/services/jobs/meetings-jobs.ts:runMeetingsDaily
    seam: schedule
    on_failure: >-
      Record workspace or series failures and continue where the job catches
      them.
    left_inconsistent: Failed work waits for another pass.
    observer: Job failure results and scheduled invocation dead letters.
    provenance: observed
    source: >-
      services-committees:modules/meetings/services/jobs/meetings-jobs.ts:runMeetingsDaily
branches: []
waits:
  - The daily pass advances the rolling eighteen-month horizon.
evidence:
  - >-
    services-committees at 36129c24:
    modules/meetings/services/persistence/meeting-series.ts, meetings.ts;
    services/recurrence/recurrence-rule.ts; services/jobs/meetings-jobs.ts;
    docs/milestones/CMTE-M3-meetings-and-minutes.md (D3, D12)
controls:
  - TC-IAM-006
  - TC-AZ-001
  - TC-AZ-002
  - TC-AZ-003
  - TC-AZ-004
  - TC-AZ-006
  - TC-TEN-001
  - TC-TEN-002
  - TC-TEN-003
  - TC-SEC-001
  - TC-SEC-004
  - TC-DAT-001
  - TC-DAT-002
  - TC-DAT-003
  - TC-LOG-002
  - TC-LOG-003
  - TC-LOG-004
  - TC-LOG-005
  - TC-AVL-004
  - TC-MON-001
  - TC-MON-002
  - TC-PI-001
  - TC-PI-002
  - TC-PI-003
  - TC-PI-004
  - TC-PI-005
  - TC-PRV-001
  - TC-PRV-002
---
# Materialize Recurring Meetings

## What It Does

Staff create, update or explicitly materialize a series, or the daily job processes it. The implementation calls every new occurrence immediately. Product has instead chosen drafts followed by a call near the meeting date. Pausing cancels future editable occurrences, and resuming does not restore those cancelled records; hand-moved dates are also rewritten today.

## The Flow

```mermaid
flowchart TD
  H1["Validate recurrence and zone, then save the series"]

  H2["Lock the saved series and expand its active dates through the rolling eighteen-month window."]
  H3["During an edit, update future draft or scheduled occurrences still wanted and cancel dates removed from the ru"]
  H4["Insert missing dates as scheduled meetings, copying defaults and the roster and preparing notices."]
  H5["Process active series for each active workspace in the daily pass at 06:41 UTC."]
  H1 --> H2
  H2 --> H3
  H3 --> H4
  H4 --> H5
```

Validate recurrence and zone, then save the series; creation checks that the committee is not dissolved. Lock the saved series and expand its active dates through the rolling eighteen-month window. During an edit, update future draft or scheduled occurrences still wanted and cancel dates removed from the rule. Insert missing dates as scheduled meetings, copying defaults and the roster and preparing notices. Process active series for each active workspace in the daily pass at 06:41 UTC.

## When Something Fails

Reject invalid input. No new series on a failed save. Roll back materialization. The series edit remains committed without its occurrence changes. Roll back the occurrence transaction. The saved rule can disagree with existing meetings until recovery. Roll back the run; daily processing records the failed series and continues. Missing dates await another materialization. Record workspace or series failures and continue where the job catches them. Failed work waits for another pass.

## Open Design Questions

The implementation calls every new occurrence immediately. Product has instead chosen drafts followed by a call near the meeting date. Pausing cancels future editable occurrences, and resuming does not restore those cancelled records; hand-moved dates are also rewritten today.
