---
id: JNY-CRM-ENT-005
title: Find current affiliates across an organization hierarchy
product_area: crm
module: entities
revision: 1
status: approved
product_intent: proposed
implementation_evidence: observed
source_sha:
  react-console: da63075876b2c5f4a6af07d457bb24ea8bf4c0c7
  services-crm: 7ea48a414c42eade10d60753b8bcc323b1dd726f
actor: ACT-CRM-001
goal: >-
  Find people currently affiliated with an organization and its descendants, and
  distinguish that listing from dated affiliation views and primary search
  labels.
capabilities:
  - CAP-CRM-ENT-002
  - CAP-CRM-ENT-003
  - CAP-CRM-ENT-009
  - CAP-CRM-ENT-010
screens:
  - '/console/{tenantId}/crm/organizations/new'
  - '/console/{tenantId}/crm/organizations/{id}'
  - '/console/{tenantId}/crm/contacts'
steps:
  - 'n': 1
    surface: '/console/{tenantId}/crm/organizations/new'
    action: Create a national organization and a chapter beneath it.
    capability: CAP-CRM-ENT-002
    expected: >-
      The chapter identifies the national organization as its ancestor and
      top-level organization.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0112.spec.ts#CRM-ACC-0112
  - 'n': 2
    surface: listContacts
    action: Request contacts filtered to the chapter.
    capability: CAP-CRM-ENT-003
    expected: >-
      Each contact with a currently effective chapter affiliation appears once,
      whether primary or secondary.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0189.spec.ts#CRM-ACC-0189
  - 'n': 3
    surface: recursivelyListContactsForOrganizationId
    action: Request the national organization’s descendant contacts.
    capability: CAP-CRM-ENT-003
    expected: >-
      The hierarchy includes current chapter affiliates, including secondary
      affiliations.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0189.spec.ts#CRM-ACC-0189
  - 'n': 4
    surface: '/console/{tenantId}/crm/organizations/{id}'
    action: >-
      Inspect Current, Past, All and future As Of selections on the chapter’s
      Contacts tab.
    capability: CAP-CRM-ENT-009
    expected: >-
      Each selection returns its applicable affiliation rows, including separate
      rows for a person’s separate ties.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0143.spec.ts#CRM-ACC-0143
  - 'n': 5
    surface: Quick Search
    action: Find the chapter in Quick Search.
    capability: CAP-CRM-ENT-003
    expected: Contact results use the primary organization in their subtitle.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0189.spec.ts#CRM-ACC-0189
alternates:
  - from_step: 4
    condition: Staff choose a historical As Of date.
    path: The tab retrieves affiliations effective on that date.
    outcome: The historical members appear.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0143.spec.ts#CRM-ACC-0143
failures:
  - from_step: 2
    condition: >-
      The caller has organization read permission but lacks contact read
      permission.
    path: The people-list request is rejected.
    outcome: The tab receives no contact listing.
    provenance: test
    source: >-
      services-crm:modules/entities/tests/e2e/contact-affiliations.e2e.spec.js#answers
      403 permission_missing to a caller who may read organizations but not
      contacts
rules_in_play:
  - BR-CAP-CRM-ENT-003-03
  - BR-CAP-CRM-ENT-003-04
  - BR-CAP-CRM-ENT-009-15
  - BR-CAP-CRM-ENT-010-02
  - BR-CAP-CRM-ENT-002-06
  - BR-CAP-CRM-ENT-002-07
assertions:
  - id: AS-JNY-CRM-ENT-005-01
    statement: >-
      The chapter’s contact filter and descendant listing identify the same
      current people.
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0189.spec.ts#CRM-ACC-0189
  - id: AS-JNY-CRM-ENT-005-02
    statement: Upcoming and ended affiliations do not qualify as current membership.
    provenance: test
    source: >-
      services-crm:modules/entities/tests/integration/services/persistence/contacts.queries.integration.spec.js#leaves
      out a contact whose affiliation to the organization has ended
e2e_policy: optional
e2e_reason: >-
  Service proof covers affiliation membership and hierarchy traversal; the
  existing browser specification adds the Contacts tab and search label.
feature: FEAT-CRM-ENT-01
evidence:
  - >-
    `react-console` at `da63075876b2c5f4a6af07d457bb24ea8bf4c0c7`: examined
    `acceptance/crm/journeys/affiliations/CRM-ACC-0189.json`,
    `acceptance/crm/journeys/organizations/CRM-ACC-0112.json`, `CRM-ACC-0143.json`,
    `acceptance/crm/journeys/contacts/CRM-ACC-0040.json` and their Playwright specs.
  - >-
    `services-crm` at `7ea48a414c42eade10d60753b8bcc323b1dd726f`: examined
    `modules/entities/services/persistence/contacts.ts` (descendants),
    `contacts.queries.integration.spec.js`.
approved_by: Andrew
approved_at: 2026-10-22
narrative:
  status: verified
  review: NARRATIVE-REVIEW-2026-10-23
narrative_sources:
  - section: Story
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0112.spec.ts#CRM-ACC-0112;
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0189.spec.ts#CRM-ACC-0189;
      react-console:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0143.spec.ts#CRM-ACC-0143;
      services-crm:modules/entities/tests/e2e/contact-affiliations.e2e.spec.js#answers 403
      permission_missing to a caller who may read organizations but not contacts
  - section: What Is True Afterwards
    provenance: test
    source: >-
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0189.spec.ts#CRM-ACC-0189;
      services-crm:modules/entities/tests/integration/services/persistence/contacts.queries.integration.spec.js#leaves
      out a contact whose affiliation to the organization has ended
proved_by: []
---

# Find current affiliates across an organization hierarchy

## Story

A CRM Editor needs to identify people currently connected to a national body and its chapters. She establishes the national organization and a chapter beneath it, then checks the chapter's ancestor context. She requests current contacts for the chapter and descendant contacts for the national body, comparing people rather than relying on their primary-organization subtitle.

A member whose primary organization is a school can still appear through a current secondary chapter affiliation. The editor opens the chapter's Contacts tab to compare Current, Past, All, and dated selections, where separate relationship rows explain a person's several ties. She also checks Quick Search, whose contact subtitle uses the primary organization. That label supplies prominent context; it does not define all current organizational membership.

Choosing a historical as-of date shows affiliations effective then rather than the people connected today. A future selection similarly asks a dated relationship question. Organization-read authority without contact-read authority cannot retrieve the people listing. The recorded explorer exception means this journey does not promise a matching current-affiliation filter in every Platform explorer surface.

For Harbor National and Harbor West Chapter, Vic's school can remain his primary label while his chapter service qualifies him for the current people request. The coordinator compares the chapter and descendant results by person identity. She then uses the chapter's affiliation rows to inspect the ties supplying that membership. The hierarchy setup and some result checks combine browser and API evidence; this story does not establish that every branch executes successfully through the browser alone.

## What Is True Afterwards

Staff can identify current chapter affiliates and find qualifying people through the wider organization hierarchy without excluding secondary ties or counting one person several times in person discovery. They can distinguish those results from affiliation-row views and primary search labels. Upcoming and ended ties do not supply current membership, while dated views remain available for explaining earlier or planned relationships.
