---
id: WF-MBR-MEM-007
title: Re-derive an organization's flow-down and assigned members
trigger: >-
  An organizational term changes or CRM delivers contact or organization change
  events.
product_area: membership
module: memberships
revision: 1
status: draft
design_intent: proposed
implementation_evidence: partially-observed
inference: []
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-MBR-MEM-006
moves:
  - STATE-MBR-MEM-003
crosses:
  - SVC-MBR-MEM-memberships
  - SVC-MBR-MEM-applications
  - SVC-MBR-MEM-events
idempotency: >-
  Recalculation compares the desired child set with current holdings; repeated
  CRM events read current facts instead of replaying old deltas.
concurrency: >-
  Each affected organizational membership is locked while its children are
  reconciled. A CRM batch handles the resulting parent work through its
  event-processing transactions.
hops:
  - 'n': 1
    actor_or_service: CRM change-event remote handler
    action: >-
      Receive the CRM contact and organization event batch through the
      registered handler.
    anchor: 'services-membership:modules/memberships/aws/lambda/CRM_CHANGE_HANDLER.ts'
    seam: event
    on_failure: >-
      CRM retries delivery failure; invalid batches are rejected at the
      boundary.
    left_inconsistent: Derived coverage can retain earlier facts until CRM delivery succeeds.
    observer: CRM delivery dead-letter evidence
    provenance: observed
    source: >-
      services-membership:modules/memberships/services/flowdown/crm-change-events.ts:handleCrmChangeEvents
  - 'n': 2
    actor_or_service: Memberships service
    action: >-
      Identify current affected organizations, ancestors and parents of the
      changed person’s derived holdings.
    anchor: >-
      services-membership:modules/memberships/services/flowdown/crm-change-events.ts:organizationsConcerned
    seam: sync
    on_failure: Return failure for the affected event so CRM can deliver it again.
    left_inconsistent: The former organizational parent can remain unreconciled after a move.
    observer: CRM per-event result
    provenance: observed
    source: >-
      services-membership:modules/memberships/services/flowdown/crm-change-events.ts:organizationsConcerned
  - 'n': 3
    actor_or_service: Memberships service
    action: >-
      Calculate eligible role holders and assigned contacts from the current
      owner records and decided applications.
    anchor: >-
      services-membership:modules/memberships/services/flowdown/organization-children.ts:wantedPeople
    seam: sync
    on_failure: >-
      Roll back reconciliation for every parent handled in this event
      transaction and report the event as failed for redelivery.
    left_inconsistent: >-
      Changes for this event are rolled back together; other events in the batch
      retain their own outcomes.
    observer: Per-event handler results
    provenance: observed
    source: >-
      services-membership:modules/memberships/services/flowdown/organization-children.ts:wantedPeople
  - 'n': 4
    actor_or_service: Memberships service
    action: >-
      Lock each organizational holding and create, update or close child
      periods, then refresh caches and events.
    anchor: >-
      services-membership:modules/memberships/services/flowdown/organization-children.ts:syncOrganizationChildren
    seam: sync
    on_failure: >-
      Roll back reconciliation for every parent handled in this event
      transaction and report the event as failed for redelivery.
    left_inconsistent: >-
      Changes for this event are rolled back together; other events in the batch
      retain their own outcomes.
    observer: Published business-event log
    provenance: observed
    source: >-
      services-membership:modules/memberships/services/flowdown/organization-children.ts:syncOrganizationChildren
branches:
  - >-
    When invoked by an organizational term writer, child reconciliation joins
    that writer’s transaction.
waits: []
evidence:
  - >-
    services-membership at 5994c270: modules/memberships/services/flowdown/*.ts;
    aws/lambda/CRM_CHANGE_HANDLER.ts;
    modules/applications/services/persistence/applications.ts:assignedContactsOfMembership
controls: [TC-AVL-002, TC-AVL-003, TC-AVL-004, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-CHG-001, TC-CHG-002, TC-CHG-003, TC-CHG-004, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-007, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-IAM-006, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-MON-001, TC-MON-002, TC-MON-004, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-004, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-SEC-001, TC-SEC-004, TC-TEN-001, TC-TEN-002, TC-TEN-003]
---

# Re-derive an organization's flow-down and assigned members

## What It Does

Organization coverage extends to eligible people through roles and assigned seats. Recalculation reads current CRM relationships and reconciles source-linked child periods.

## The Flow

```mermaid
flowchart TD
  H1["Receive the CRM contact and organization event batch through the registered handler"]
  H2["Identify current affected organizations, ancestors and parents of the changed person’s derived holdings"]
  H1 --> H2
  H3["Calculate eligible role holders and assigned contacts from the current owner records and decided applications"]
  H2 --> H3
  H4["Lock each organizational holding and create, update or close child periods, then refresh caches and events"]
  H3 --> H4
```

## When Something Fails

Failed CRM delivery leaves children unchanged until retry. Reading current ancestry can miss an organization’s former parent after a move. Removed eligibility ends coverage using the handler’s business date rather than the original CRM end date.

## Open Design Questions

Decide the withdrawal date policy, connect CRM subscriptions and cover old-parent reconciliation after organization moves.
