Skip to content

CAP-CRM-ENT-017Configure affiliation types and contact roles

Markdown

CAP-CRM-ENT-017

Configure affiliation types and contact roles

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
Every affiliation and role names a type or role the tenant maintains.A type or role in use cannot be deleted.The workspace default type is chosen only by an administrator.
Surfaces
consoleapiportal
Intent sources
OQ-CRM-ENT-002 decided 2026-10-22 by Andrew: B (classification types and the role catalogue stay in Entities)services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.md#D-11services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.md#M2-D7services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.md#M2-D10services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.plan.md#A4services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.plan.md#A5services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.plan.md#A10services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.plan.md#A11services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.plan.md#A17services-crm:docs/milestones/CRM-M2-affiliations-roles-compliance.plan.md#A23

Controls

15 controls apply, from the corpus control catalogue.

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

Repositories Read

RepositoryPaths
undefined:modules/configuration-types/
undefined:modules/entities/
undefined:docs/milestones/CRM-M2-affiliations-roles-compliance.md
undefined:modules/entities/tests/e2e/affiliation-types.e2e.spec.js
undefined:modules/entities/tests/e2e/contact-roles.e2e.spec.js
undefined:modules/entities/tests/integration/services/persistence/affiliation-types.integration.spec.js
undefined:modules/entities/tests/integration/services/persistence/contact-roles.integration.spec.js
undefined:components/configuration/
undefined:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0196.spec.ts
undefined:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0197.spec.ts
undefined:acceptance/crm/playwright/journeys/affiliations/CRM-ACC-0199.spec.ts

Where It Lives

Permissions

KeyChecked atScope
crm.contact-roles.readapitenant
crm.contact-roles.createapitenant
crm.contact-roles.updateapitenant
crm.contact-roles.deleteapitenant
crm.affiliation-types.readapitenant
crm.affiliation-types.createapitenant
crm.affiliation-types.updateapitenant
crm.affiliation-types.deleteapitenant
crm.affiliation-types.set-defaultapitenant

Business Rules

11 rules, 9 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
01must prove
Proposed
Contact roles and affiliation types require trimmed nonblank names and reject blank input without creating a record.
validationapi, service, databasetest
services-crm:modules/entities/tests/e2e/affiliation-types.e2e.spec.js#answers 400 naming the field for a create whose name is nothing but spaces
02must prove
Proposed
Role and affiliation-type ids are unique immutable lowercase configuration ids up to 63 characters, may derive from the name and cannot use Rhythm’s reserved prefix.
validationapi, service, databasetest
services-crm:modules/entities/tests/e2e/affiliation-types.e2e.spec.js#answers 400 for an id that is not a configuration id, saying what an id may hold
03must prove
Proposed
Contact roles referenced by current or historical holders or organization-type compliance rules cannot be deleted, with holder counts or dependent type names included in the refusal.
validationservice, databasetest
services-crm:modules/entities/tests/integration/services/persistence/contact-roles.integration.spec.js#refuses it with the legacy words, naming the organization types whose rules depend on it
04must prove
Confirmed
Creating and editing roles or affiliation types is available to users, while deleting either requires administrator authority.
permissionapitest
05must prove
Proposed
Affiliation types cannot be deleted while referenced by an affiliation or selected as the workspace default.
validationservice, databasetest
services-crm:modules/entities/tests/e2e/affiliation-types.e2e.spec.js#refuses the delete (409) while an affiliation of a contact is of that type
06must prove
Proposed
The workspace default affiliation type is Other until configured, must exist in the tenant, supplies Organization-command affiliations and uses separate read and administrator set-default permissions.
permissionapi, servicetest
services-crm:modules/entities/tests/e2e/affiliation-types.e2e.spec.js#refuses a caller who may only read affiliation types the change of the default (403)
07must prove
Proposed
Affiliation default mappings use tenant source and destination types of the same address or phone kind, allow each destination once per kind and at most 20 mappings, preserve omitted mappings on replacement and clear them for null.
validationapi, service, databasetest
08must prove
Proposed
Contact-role reorder includes every tenant role once, assigns consecutive positions, rejects missing or unknown roles without partial movement, permits moving locked roles and lists never-ordered roles alphabetically.
validationapi, servicetest
services-crm:modules/entities/tests/e2e/contact-roles.e2e.spec.js#answers 400 for a reorder that leaves a role of the tenant out, naming it
09
Confirmed
The product should provide editable contact-role and affiliation-type descriptions in the shared configuration lists and forms.
policyconsoledocumented
10
Proposed
Tenant portal users can read contact-role lists paged in name order using an opaque cursor.
permissionapitest
11must prove
Confirmed
Deactivated affiliation types keep their dataset columns, with an inactive label.
policytest

Scenarios

IdGivenWhenThenProvenance
01An administrator in Settings.She adds "Term Treasurer" with a description, reorders it and deactivates it.The role is listed in its place, inactive, and pickers stop offering it.test
02Employer with address and phone default links.The administrator sets it as the workspace default.The Organization field creates Employer affiliations.test

Decision History

Product decisions recorded in this module's findings that bear on this specification, as recorded.

  1. OQ-CRM-ENT-002DecisionAndrew2026-10-22

    B: everything stays in Entities; no Configuration Types module. Entities owns contact, organization, address and phone number types, affiliation types and the contact-role catalogue and their rules.

    Applied to: Structured decision update record

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.