Skip to content

CAP-CRM-ENT-006Share organization contact points with affiliated people

Markdown

CAP-CRM-ENT-006

Share organization contact points with affiliated people

Markdown
  • DocumentApproved
  • Product intentProposed
  • ImplementationPartially observed

KindCapabilityProduct areaCRMModuleEntitiesRevision1Approved byAndrewApproved at2026-10-22

Read atservices-crm 7ea48a41react-console da630758

The Formal Contract

The narrative above explains; the sections below are authoritative — the rules, scenarios and tests this document binds.

Outcomes
A linked row always displays the organization's current value while the affiliation is in effect, without rewriting the contact.No contact silently loses a value or preserves an unmarked stale one.A staff member chooses which of a affiliation's default links are made.
Surfaces
consoleapijob
Intent sources
services-crm:docs/milestones/CRM-M1-contacts-and-organizations.md#D-01services-crm:docs/milestones/CRM-M1-contacts-and-organizations.plan.md#A11services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.plan.md#A9services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.plan.md#A19services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.plan.md#A22services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.md#M2-D1services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.md#M2-D4services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.md#M2-D11

Controls

18 controls apply, from the corpus control catalogue.

TC-AZ-001 TC-AZ-002 TC-AZ-003 TC-AZ-004 TC-AZ-006 TC-DAT-001 TC-DAT-002 TC-DAT-003 TC-LOG-004 TC-LOG-005 TC-PI-001 TC-PI-003 TC-PI-005 TC-PRV-001 TC-PRV-002 TC-TEN-001 TC-TEN-002 TC-TEN-003

Repositories Read

RepositoryPaths
undefined:modules/entities/
undefined:docs/disconnected-information.md
undefined:modules/entities/tests/e2e/contacts-disconnected.e2e.spec.js
undefined:modules/entities/tests/integration/services/affiliations/affiliation-date-reconciliation.follow-ups.integration.spec.js
undefined:modules/entities/tests/integration/services/persistence/contact-information-sources.integration.spec.js
undefined:app/(console)/console/[tenantId]/crm/contacts/
undefined:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0185.spec.ts
undefined:acceptance/crm/playwright/journeys/organizations/CRM-ACC-0118.spec.ts

Where It Lives

Permissions

KeyChecked atScope
crm.contacts.updateapitenant
crm.organizations.updateapitenant

Business Rules

13 rules, 12 to be proved before approval. A rule's product intent is derived from its origin: 3 confirmed by a product decision, the rest inheriting this capability's proposed.

IdRuleKindEnforced atProvenance
01
Proposed
Contact addresses and phone numbers identify whether their values are owned, deliberately copied from an organization, linked to its current record or disconnected with the last value after their linked source disappears.
invariantservice, databasedocumented
02must prove
Proposed
A contact-information link must use an affiliation present after the save and a record or record type of that affiliation’s organization; another organization’s record or a missing source type is rejected.
validationservice, databasetest
03must prove
Proposed
Creating or redirecting a contact-information link requires an affiliation effective on the workspace’s current day.
validationservicetest
04must prove
Proposed
A linked element cannot store a value different from its organization source; whitespace-only differences are accepted and differences in letter case are rejected.
validationservice, databasetest
services-crm:modules/entities/tests/integration/services/persistence/contact-information-sources.integration.spec.js#refuses a value that differs from the organization’s in letter case, naming the field (A19)
05must prove
Proposed
An effective link resolves to the organization’s current value without changing the contact on an organization edit; an ineffective affiliation retains an unresolved link without a value.
calculationdatabase, servicetest
06must prove
Proposed
Removing a shared organization address or phone disconnects its contact links in the same transaction, preserves the last value with source, time and reason, marks verification as needed and advances the affected contacts’ versions.
lifecycledatabasetest
services-crm:modules/entities/tests/integration/services/persistence/contact-information-sources.integration.spec.js#turns the linked work address into a disconnected row holding its last value, not a copy (D-25)
07must prove
Proposed
Clients cannot create disconnected elements, and returning an existing disconnected element preserves its server-recorded provenance.
validationservicetest
services-crm:modules/entities/tests/e2e/contacts-disconnected.e2e.spec.js#refuses a client that asks for a row to be disconnected, naming the field
08must prove
Proposed
Version-checked verify, relink and remove actions respectively convert a disconnected element to an owned value, link it to exactly one current-affiliation source by id or type, or delete it; they reject a non-disconnected row, an unknown element and missing or stale versions.
lifecycleapi, servicetest
services-crm:modules/entities/tests/e2e/contacts-disconnected.e2e.spec.js#is refused 409 on a row that is no longer disconnected
09must prove
Proposed
Making a linked element independent stores a copy of its resolved organization value with the source organization and copy time, and subsequent source edits do not change it.
lifecycleservicetest
services-crm:modules/entities/tests/integration/services/persistence/contact-information-sources.integration.spec.js#makes an independent copy of the resolved value when the row is saved as copied with no value of its own
10must prove
Proposed
Removing an affiliation requires handling every information link it supplies in the same save, whereas ending it is allowed and leaves unresolved links.
invariantservicetest
services-crm:modules/entities/tests/integration/services/persistence/contact-information-sources.integration.spec.js#refuses a save that removes the affiliation and keeps the rows linked through it
11must prove
Confirmed
A new effective affiliation fills empty destination types from its selected default mappings without replacing existing values, uses every mapping when selection is omitted and uses none for an explicitly empty selection.
calculationservicetest
12must prove
Confirmed
Default mappings apply only through effective affiliations, including pending choices on a future affiliation’s start day and explicit reapplication to a current affiliation; ended affiliations create no links and changing type defaults does not rewrite existing contacts.
policyservicetest
13must prove
Confirmed
The product should show the number of affected people before an organization removes an address they share.
no proof recorded yet
policyunknown

Scenarios

IdGivenWhenThenProvenance
01Daniel's work address is linked to Bayview's main address through his Employer affiliation.Bayview's address is edited.Daniel's next read displays the new address and his record has no new revision.test
02Harbor Society removes the address three members link to.The members are read.Each preserves the last address, disconnected, needing verification, naming Harbor and the moment.test

Edge Cases

IdGivenWhenThenProvenance
03A staff member unticks the work-phone link when adding an Employer affiliation.The contact is saved.The work address is linked and the work phone is not.test

The Markdown files under specs/ in rhythmsoftware/rhythm-v2-docs are the canonical source of truth. This reader is a generated, read-only projection of them.