Skip to content

DOM-CRM-ENT-003Affiliation

Markdown

DOM-CRM-ENT-003

Affiliation

Markdown
  • DocumentDraft
  • ImplementationObserved

Planning

Specified by
CON-CRM-ENT-003

Design

Owned by
SVC-CRM-ENT-entities

KindDomain objectProduct areaCRMModuleEntitiesRevision1

Read atservices-crm a8d1364freact-console baf6dae3services-platform ad3f6a65

Relationships

ToCardinalityOwnershipCrosses a serviceOn archive or delete
DOM-CRM-ENT-001many-to-oneThe contact owns the affiliation and is its only save boundary.noContact archive retains ties; contact deletion cascades this affiliation and its roles.
DOM-CRM-ENT-002many-to-oneThe affiliation owns its reference to the organization.noOrganization archive retains labels; organization deletion is blocked while this affiliation exists.
DOM-CRM-ENT-033the contact's safeguards cover its affiliationsProtection and revisions apply through the owning contact rather than a separate affiliation version.noRemoving the affiliation is captured through contact history; contact deletion retains historical revisions.

Invariants

InvariantProtectsEnforced atProvenance
INV-DOM-CRM-ENT-003-01
Organization and affiliation-type references must resolve in the workspace; failure aborts the enclosing contact save.
A tie between real local identities rather than a cross-workspace relationship.api, service, databasetest
services-crm:modules/entities/tests/e2e/contact-affiliations.e2e.spec.js#answers 400 for an organization the tenant does not have
INV-DOM-CRM-ENT-003-02
A contact can designate only one primary affiliation, with a start date no later than today and no end date.
One prominent organization label that reflects an eligible relationship.service, database, consoletest
INV-DOM-CRM-ENT-003-03
For one contact, periods to the same organization with the same affiliation type cannot overlap, including shared boundary days and unbounded ends.
Distinct episodes of one kind of relationship without double-counted dates.service, databasetest
services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#finds periods that share their last and first day overlapping
INV-DOM-CRM-ENT-003-04
The relationship end date must not precede its start.
An interpretable inclusive relationship period.service, database, consoletest
INV-DOM-CRM-ENT-003-05
An existing affiliation cannot be reassigned to another organization.
Stable history of which organization a relationship concerns.servicetest
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)
INV-DOM-CRM-ENT-003-06
The limit of 100 affiliations counts current and future relationships and excludes ended ones.
Bounded current work without discarding ended history.servicetest
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)
INV-DOM-CRM-ENT-003-07
Role periods must fit inside the affiliation dates. Periods for the same role cannot overlap, and the list is limited to 25 entries.
Role coverage that never extends outside its parent tie or double-counts one period.service, databasetest
services-crm:modules/entities/tests/unit/services/persistence/contact-affiliations.spec.js#refuses the same role overlapping itself on one affiliation
INV-DOM-CRM-ENT-003-08
Assigned roles must belong to the workspace, even when the catalogue role is inactive.
Dated responsibilities backed by the workspace vocabulary.service, databaseobserved
INV-DOM-CRM-ENT-003-09
Saving preserves equality between the contact job title and primary affiliation title.
Agreement between the person’s prominent title and organizational context.servicetest
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
INV-DOM-CRM-ENT-003-10
Automatic assignment waits until the affiliation is due and does not duplicate an existing role or reassign a role after its pending assignment was settled.
User corrections that repeated automatic processing does not undo.servicetest
INV-DOM-CRM-ENT-003-11
Competing joins to an organization with no effective affiliates serialize first-contact assignment so only one contact receives those roles.
A single first-contact decision under simultaneous joins.service, databasetest
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
INV-DOM-CRM-ENT-003-12
Removal requires resolving every contact detail still linked through the affiliation in the submitted save.
Source links that do not outlive a removed authorization relationship.servicetest
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
INV-DOM-CRM-ENT-003-13
Deletion of an affiliation type is blocked by relationship references and by its use as the workspace default.
Existing affiliations and default commands backed by a surviving type.service, 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
INV-DOM-CRM-ENT-003-14
A contact role cannot be deleted while a role period or organization-type compliance rule references it.
Responsibility history and policy references backed by a surviving role.service, 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
INV-DOM-CRM-ENT-003-15
Affiliations and their type and role catalogues do not declare custom-field storage.
The intended extension boundary, with custom values remaining on people and organizations.apitest
services-crm:modules/entities/tests/e2e/contact-roles.e2e.spec.js#refuses a create that carries custom_fields, as an unknown property

Permissions

ActionPermissionWho holds itChecked atBy state
readcrm.contacts.readAdministrator, Power User, Standard User, Read Only
updatecrm.contacts.updateAdministrator, Power User, Standard UserOrdinary update refuses archived or fully locked records; archive actions also check full locks.

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.