Skip to content

CAP-CRM-DQ-014Preserve the right information on the surviving contact

Markdown

CAP-CRM-DQ-014

Preserve the right information on the surviving contact

Markdown
  • DocumentDraft
  • Product intentConfirmed
  • ImplementationObserved

KindCapabilityProduct areaCRMModuleDuplicate Review and Record MergingRevision1

Read atservices-crm a8d1364freact-console baf6dae3

The Formal Contract

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

Outcomes
The survivor retains the contact details, affiliations and custom values selected by the preview.Consent cannot be widened by combining records.Omitted values retain an explanation of the responsible decision or rule.
Surfaces
consoleapi
Intent sources
services-crm:docs/merging/decisions.md#D6 (decided 2026-10-12: most restrictive wins)services-crm:docs/merging/README.md#Status (architecture and plan approved by Andrew 2026-10-11)services-crm:docs/merging/experience/functional-requirements.md#AUTO-1 to AUTO-4, CON-2 to CON-5, CFM-3 (package approved by Andrew 2026-10-13)

Controls

23 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-002 TC-DAT-003 TC-IAM-001 TC-IAM-002 TC-IAM-004 TC-IAM-005 TC-IAM-006 TC-LOG-004 TC-LOG-005 TC-PI-001 TC-PI-003 TC-PRV-001 TC-PRV-002 TC-TEN-001 TC-TEN-002 TC-TEN-003

Permissions

KeyChecked atScope
crm.contacts.mergeapitenant

Business Rules

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

IdRuleKindEnforced atProvenance
01must prove
Confirmed
Consent takes the most restrictive result without a choice: any mail, call or e-mail prohibition applies, subscriptions rank unsubscribed before digest before subscribed and communication enablement requires every participant to enable it.
origin: services-crm:docs/merging/decisions.md#D6 (decided 2026-10-12: most restrictive wins)
calculationservicetest
services-crm:modules/merges/tests/unit/services/planning/contact-collections.spec.js#combines two preferences of one type to the most restrictive status, and offers no choice about it
02must prove
Confirmed
Contacts retain one address and one phone per type, collapse identical items and ask about different same-type items with the survivor default; rejected items are dropped rather than retyped, while identical addresses under different types remain separate.
origin: services-crm:docs/merging/README.md#Status (architecture and plan approved by Andrew 2026-10-11)
calculationservicetest
services-crm:modules/merges/tests/unit/services/planning/contact-collections.spec.js#writes the other address when staff choose it, and attributes the survivor’s to the slot conflict
03must prove
Confirmed
Contacts retain no more than three distinct e-mails and one chosen primary, selecting excess addresses with survivor-first and frequency defaults; an outside holder of the chosen primary blocks the merge.
validationservice, databasetest
services-crm:modules/merges/tests/unit/services/planning/contact-collections.spec.js#blocks the merge when the primary address belongs to a contact outside the merge
04must prove
Confirmed
The result has at most one preferred address and phone, defaults to the survivor's preference, allows no preferred address and excludes seasonal addresses from preference.
validationservicetest
services-crm:modules/merges/tests/unit/services/planning/contact-collections.spec.js#never prefers a seasonal address, which the table refuses
05must prove
Confirmed
A disagreement over deceased status requires an answer without a recommendation, and the death date follows that answer.
validationservicetest
services-crm:modules/merges/tests/unit/services/planning/contact-fields.spec.js#offers that question no default, because neither state may be assumed
06must prove
Confirmed
A spouse connection between participants is removed with a warning to prevent a self-link, while outside spouse references to absorbed records follow the survivor.
policyservicetest
services-crm:modules/merges/tests/unit/services/planning/contact-fields.spec.js#is cleared when the survivor itself is the spouse a participant names, which no contact may be
07must prove
Confirmed
Overlapping or touching affiliations across records with one organization and type combine using earliest start, latest or open end, survivor title and notes and widest role spans; discarded information is listed and the contact limit remains 100 affiliations.
origin: services-crm:docs/merging/README.md#Status (architecture and plan approved by Andrew 2026-10-11)
calculationservicetest
services-crm:modules/merges/tests/integration/services/merges/merge-execution.integration.spec.js#combines the two Acme affiliations into one, from the earliest start, open, with the survivor’s title and both roles
08must prove
Confirmed
Competing primary affiliations at different organizations create a survivor-defaulted choice with none available; a sole primary from an absorbed record fills the gap, and future or ended affiliations are excluded.
policyservicetest
services-crm:modules/merges/tests/unit/services/planning/contact-collections.spec.js#keeps the merged contact’s primary as the primary organization when the survivor has none, without asking
09must prove
Confirmed
Linked details follow retained affiliations and identical organization sources collapse; unresolved links are not defaults and are dropped as replaced, while details losing their affiliation become copies.
origin: services-crm:docs/merging/README.md#Status (architecture and plan approved by Andrew 2026-10-11)
calculationservicetest
services-crm:modules/merges/tests/unit/services/planning/linked-contact-information.spec.js#turns a linked item whose affiliation the merged contact does not keep into a copy of its value
10must prove
Confirmed
Names, automatic region and compliance are recomputed without choices; the survivor retains its number, identity, creation time and external identity, with absorbed identities retained in aliases.
calculationservicetest
services-crm:modules/merges/tests/unit/services/planning/contact-fields.spec.js#recalculates the region rather than choosing between two, and says so
11must prove
Confirmed
The chosen photo attaches to the survivor; unused photos are detached for deletion after 30 days and produce a preview warning.
lifecycleservicetest
services-crm:modules/merges/tests/unit/services/planning/merge-decisions.spec.js#says so when the survivor keeps its own photo and a participant’s is dropped
12must prove
Confirmed
Custom fields are decided independently; archived definitions offer no choice or write, preserving survivor values and listing absorbed-only values as discarded.
policyservicetest
services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#offers no conflict about the archived field
13must prove
Confirmed
The ordinary survivor save receives only changed custom values, allowing previously missing required fields to remain missing but rejecting removal of an existing required value.
validationservicetest
services-crm:modules/merges/tests/integration/services/merges/merge-execution.integration.spec.js#refuses the merge that would clear a required field a record does hold a value for
14must prove
Confirmed
Every absorbed value missing from the result is listed with its sources, reason and responsible choice or rule, and console confirmation requires acknowledgement.
invariantservice, consoletest
services-crm:modules/merges/tests/unit/services/planning/merge-decisions.spec.js#names a conflict, a default or a rule for every value it drops, over a snapshot of every kind of difference

Scenarios

IdGivenWhenThenProvenance
01Four member records disagree on names, contact details and communication choices.The worked merge applies the reviewer's selections.Selected values survive, newsletter consent remains unsubscribed and discarded values retain attribution.test
services-crm:modules/merges/tests/unit/services/planning/worked-example.spec.js#attributes every value the survivor will not hold to the conflict or the rule that dropped it
02A sparse unsubscribed record contains a birth date absent from a fuller member record.The sparse record is absorbed into the member.The birth date fills the gap and the member stays unsubscribed, as shown before confirmation.test

Edge Cases

IdGivenWhenThenProvenance
03Two participant records disagree on deceased status and are linked as spouses.The administrator plans their merge.Status needs an answer, their internal spouse link clears and an outside spouse reference follows the survivor.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.