---
id: FEAT-CRM-ENT-04
title: Affiliations and Roles
product_area: crm
module: entities
revision: 1
status: approved
product_intent: proposed
source_sha:
  services-crm: 7ea48a414c42eade10d60753b8bcc323b1dd726f
  react-console: da63075876b2c5f4a6af07d457bb24ea8bf4c0c7
purpose: >-
  Staff record the organizations people belong to and the roles they hold. This feature groups the
  work of maintaining those relationships over time.
outcomes:
  - Staff record the organizations people belong to and the roles they hold.
concepts:
  - CON-CRM-ENT-003
actors:
  - ACT-CRM-001
  - ACT-CRM-002
  - ACT-CRM-003
  - ACT-CRM-004
  - ACT-CRM-005
acceptance: FAS-CRM-ENT-04
capabilities:
  - CAP-CRM-ENT-009
  - CAP-CRM-ENT-010
  - CAP-CRM-ENT-011
journeys:
  - JNY-CRM-ENT-002
approved_by: Andrew
approved_at: 2026-10-22T00:00:00.000Z
narrative:
  status: verified
  review: NARRATIVE-REVIEW-2026-10-23
narrative_sources:
  - section: Why It Exists
    provenance: inferred
    source: >-
      CAP-CRM-ENT-009; CAP-CRM-ENT-010; CAP-CRM-ENT-011;
      services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.md#M2-D3
    note: >-
      Operational consequences are the reviewer’s reading of the child contracts, not attributed
      historical motivation. The affiliation milestone supplies the current-membership distinction
      where named.
  - section: Decisions and Tradeoffs
    provenance: inferred
    source: "CAP-CRM-ENT-009; CAP-CRM-ENT-010; CAP-CRM-ENT-011"
    note: The tradeoffs interpret the child contracts; no historical motive is attributed.
  - section: How It Works
    provenance: observed
    source: services-crm:aws/lambda/JOB_RECONCILER.ts:handler
  - section: How It Works
    provenance: observed
    source: >-
      services-crm:modules/entities/tests/e2e/contact-affiliations.e2e.spec.js#answers 400 for an
      organization the tenant does not have;
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0202.spec.ts#CRM-ACC-0202;
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0177.spec.ts#CRM-ACC-0177;
      services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#refuses
      two affiliations newly marked primary at once;
      services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#refuses
      a primary affiliation that starts after today;
      services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.integration.spec.js#makes
      nothing primary in its place;
      services-crm:modules/entities/tests/integration/services/persistence/contacts.integration.spec.js#refuses
      an affiliation that ends before it starts;
      services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#finds
      periods that share their last and first day overlapping;
      services-crm:modules/entities/tests/integration/services/persistence/contacts.integration.spec.js#refuses
      to move the affiliation to another organization under the same id (docs/affiliations/README.md
      §0b.2);
      services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#counts
      only current and upcoming affiliations against the limit: ended history is unlimited (M2-D5);
      services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#ends
      the previous primary the day before the effective date by default, and its open roles with it;
      react-console:lib/affiliations/section.ts:affiliationBeingLeft;
      services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#gives
      the contact the primary affiliation's job title when the save changed only the affiliation's;
      services-crm:modules/entities/tests/e2e/contact-information-sources.e2e.spec.js#refuses 400 a
      second contact naming the same affiliation id, saying another affiliation has it;
      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;
      react-console:components/console/organization/affiliation-dialogs.tsx:ContactPrimaryInfo;
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0172.spec.ts#CRM-ACC-0172;
      services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#refuses
      a primary starting on the tenant's tomorrow, though it is already UTC's and Sydney's today;
      services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.business-dates.integration.spec.js#reads
      a tie ending on the tenant's today as current;
      react-console:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0186.spec.ts#CRM-ACC-0186;
      services-crm:modules/entities/tests/unit/services/affiliations/affiliation-date-window.spec.js#spans
      every day of a skipped weekend, so the next night makes them up;
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#takes
      the organization out of compliance the next morning, with no save of the contact;
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.integration.spec.js#finds
      the day settled and changes nothing, the organization’s version included;
      services-crm:modules/entities/tests/e2e/affiliation-date-reconciliation.e2e.spec.js#refuses a
      real run that names a day, 400 naming it; services-crm:docs/affiliations/README.md#5.6b The
      overnight date reconciliation (D-46; CRM-M2 A6 and A7);
      services-crm:modules/entities/services/persistence/contact-affiliations.ts:affiliationRefusal;
      services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#refuses
      a role whose dates lie outside its affiliation's;
      services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#refuses
      the same role overlapping itself on one affiliation;
      services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#ends
      the open roles of an affiliation the save ends, on the same day;
      services-crm:modules/entities/tests/integration/services/persistence/contact-affiliations.integration.spec.js#refuses
      a role outside the list added to an existing affiliation;
      services-crm:modules/entities/tests/integration/services/contacts/role-assignment/contact-role-assignment.integration.spec.js#gives
      the organization's first contact the automatic and first-contact roles, besides the roles it
      states;
      services-crm:modules/entities/tests/integration/services/contacts/role-assignment/automatic-role-reconciliation.integration.spec.js#gives
      the automatic and first-contact roles on the start day in the tenant calendar;
      services-crm:modules/entities/tests/integration/services/contacts/role-assignment/automatic-role-reconciliation.integration.spec.js#does
      not give back a role a person removed after it was given;
      services-crm:modules/entities/tests/integration/services/contacts/role-assignment/contact-role-assignment.integration.spec.js#counts
      an inactive contact as already belonging to the organization, so the next contact is not its
      first;
      services-crm:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.follow-ups.integration.spec.js#skips
      the forbidden role on the start day;
      services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.md#M2-D12;
      services-crm:modules/entities/tests/integration/services/contacts/role-assignment/contact-role-assignment.integration.spec.js#gives
      the first-contact roles to exactly one of several contacts joining an empty organization at
      once; react-console:components/affiliations/affiliation-editor.tsx:Add Period;
      services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.md#M2-D13
related_concepts:
  - CON-CRM-ENT-004
  - CON-CRM-ENT-005
acceptance_suite: FAS-CRM-ENT-04
---

# Affiliations and Roles

## Overview

Affiliations and Roles explains a person's connections to organizations over time. A member can work for a firm, serve a chapter, and later leave one connection while keeping another. Each affiliation records one connection, and roles describe responsibilities held during it.

The primary affiliation supplies a prominent organizational label, but it does not erase secondary connections. Effective dates determine which ties and responsibilities apply on the workspace's current day, while ended ties preserve the context of earlier work.

## Why It Exists

Our reading is that one employer field cannot explain an association member's concurrent connections or earlier responsibilities. Lena can work for Harbor Engineering, serve a chapter and later move to Bayview Manufacturing. Replacing Harbor with Bayview as a text value loses when Lena served Harbor and can accidentally imply that her chapter work ended too.

Separate dated affiliations retain each connection, and role periods retain the responsibilities held within it. The primary label answers which organization is prominent on the person; current-affiliate discovery answers who belongs to a body today. Confusing those questions can exclude a valid secondary representative. The affiliations milestone records the common current-membership interpretation, while our reading explains why the distinction matters to coordinators investigating an employer move or a chapter roster.

## Who Uses It

The CRM Editor records affiliations, changes employers, and assigns dated responsibilities. The CRM Reader inspects current and past relationships. The CRM Administrator configures relationship types, roles, and organizational restrictions. The CRM System processes date boundaries, automatic roles, and compliance reactions. The Data Importer uses the same service-owned relationship model through authorized record operations.

## How It Works

Staff add an affiliation to a contact, choose the organization and affiliation type, and supply dates and responsibilities. The save validates the resulting set together, including primary selection, same-organization overlap, and role periods. Omitting affiliations preserves them; an explicit collection expresses the intended resulting relationships.

Dates use the workspace calendar. A scheduled future affiliation remains upcoming until its start; an ended tie remains available as history. Date reconciliation can apply pending default links and automatic roles and revisit affected compliance. Its date-window sweep is conditional on deployment configuration, with a disabled baseline switch. Automatic roles also have their own due-role pass. Elapsed time alone does not prove that either process completed its effects.

An affiliation connects two existing identities and gives the connection its own meaning through an Affiliation Type. The contact remains the write owner when staff start from an organization's people list. That ownership lets one save validate all intended ties and responsibilities together. Staff can preserve concurrent ties, end a relationship, or add a later return, but cannot relabel an existing affiliation as a connection to a different organization.

The primary choice is deliberately narrower than current membership. It must have begun and remain open-ended. Making a different tie primary removes the old primary designation in the same save. Adding a new primary can ask whether the person left the old organization; retaining the old tie keeps it current without keeping it primary. Making an already existing affiliation primary uses its separate interaction. Ending a primary leaves no automatically invented successor. The contact job title follows the primary title, while an ended affiliation keeps its historical title.

Dates include their end day, so a return of the same type to the same organization must begin after the previous end rather than on it. Different relationship types can express distinct concurrent connections. Roles add dated responsibilities inside the affiliation. Staff choose permitted roles, with role periods constrained by the parent relationship; ending and adding a responsibility preserves a meaningful sequence instead of changing an old role identity to represent a different duty. Effective organization-type restrictions govern changed responsibilities, while unchanged historical information has its stated preservation boundary.

Future appointments require two kinds of inspection. A read can classify a future tie as upcoming and later as current on the workspace calendar. Reconciliation applies start-day automatic roles and pending contact-point defaults and reevaluates affected compliance. Those side effects are conditional on the enabled worker or an authorized on-demand run; the disabled scheduler default does not make the date label wrong or establish that the deferred work ran.

## Examples

A coordinator records Lena Park's move from a member firm to another employer. Adding the new primary affiliation prompts the coordinator about leaving the old one. Ending the former tie retains its roles as dated history, while the new affiliation describes Lena's current responsibilities. A concurrent chapter affiliation can remain current and continue to qualify Lena for that chapter's people list.

On October 23, Lena Park joins Bayview Manufacturing as a director after serving Harbor Engineering. The coordinator creates a Bayview primary affiliation starting that day and confirms departure. Harbor ends on October 22, preserving its title and responsibilities; Bayview supplies the current primary label and title. Reading Harbor's Past relationships explains the earlier employment, and reading Bayview's Current list shows the new connection.

If Lena still consults for Harbor, the coordinator instead retains that affiliation. Bayview becomes primary while Harbor remains a current secondary relationship. Her chapter connection also remains current. A proposed return to Harbor of the same type that shares the old tie's final day is refused; the coordinator corrects the start date rather than deletes the old history. A future chapter responsibility can be recorded, but staff inspect its effective date and reconciliation outcome separately before assuming it supplies today's compliance coverage.

## Decisions and Tradeoffs

Our reading is that multiple dated relationships preserve both concurrent participation and history that a single employer field cannot express. Primary selection remains useful for a compact label, but using it as the sole membership test would exclude current secondary representatives. Inclusive dates make the last day meaningful and also require deliberate nonoverlapping boundaries for a return.

Contact-owned transactional writes avoid two independent authorities editing the same tie from opposite record pages. The cost is that organization-side additions still need the contact's version and validation. Reconciliation separates date interpretation from resulting mutations, avoiding daily no-op revisions while making missed-day recovery explicit. The deployment switch is therefore a real operational boundary to explain, not a hidden assumption that calendar passage alone completes every effect.

## Scope and Boundaries

This feature owns contact-held organizational ties, their effective-date interpretation, and dated role assignments. Organization Records owns the organizations themselves. Classification Types and CRM Settings owns the role and affiliation-type catalogues. Organization Compliance consumes effective role coverage, while Contact Details and Communication Preferences uses eligible affiliations to resolve shared information. Platform owns broader query execution and presentation infrastructure.

## Outcomes

Staff can change current circumstances without losing earlier organizational context and can distinguish the primary label from all effective relationships. The Affiliations and Roles acceptance suite covers relationship changes, workspace dates, role periods, and relevant follow-ups. The employer-change journey demonstrates the complete staff process while retaining the stated limitations on automated and browser proof.

## Its Capabilities

Maintain a person’s organizational relationships records ties and primary selection without silently erasing omitted affiliations. Keep dated relationships current applies the workspace calendar and reconciles boundary side effects. Maintain responsibilities on organizational relationships records role periods and eligible automatic assignments. Record an employer change while retaining the previous affiliation connects the three in a coordinator's workflow.
