Skip to content

CAP-CRM-DQ-013Resolve differences in the merge preview

Markdown

CAP-CRM-DQ-013

Resolve differences in the merge preview

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
Questions contain actual participant values rather than invented replacements.Version checks and source tracking prevent silent decision overwrite or reuse after value changes.The product should make every preview explanation readable without internal identifiers.
Surfaces
consoleapi
Intent sources
services-crm:docs/milestones/CRM-M4-duplicates-and-merge.md#D-33services-crm:docs/merging/README.md#Status (architecture and plan approved by Andrew 2026-10-11)services-crm:docs/merging/experience/functional-requirements.md#CNF-1 to CNF-10, INT-1, PRV-3 (package approved by Andrew 2026-10-13)

Controls

19 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-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

Permissions

KeyChecked atScope
crm.contacts.mergeapitenant
crm.organizations.mergeapitenant

Business Rules

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

IdRuleKindEnforced atProvenance
01must prove
Confirmed
Questions appear only for distinct values the survivor cannot retain together after ordinary save normalization; identical values cause no question and a sole supplied value fills an empty field.
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-fields.spec.js#is no conflict when only one participant holds a value, which the survivor then takes
02must prove
Confirmed
Merge choices come from participating records or an optional-field choice to retain no value; staff cannot type a new value into a merge.
validationservicetest
services-crm:modules/merges/tests/unit/services/planning/contact-fields.spec.js#offers clearing the field as well as each value held
03must prove
Confirmed
Defaults prefer the survivor's value, then a sole value, majority value, most recently changed field and most recently changed record, with the deciding criterion explained.
calculationservicetest
services-crm:modules/merges/tests/integration/services/merges/default-basis-and-recency.integration.spec.js#is the majority, with the records that agree counted, where more records hold one value than any other
04must prove
Confirmed
Required unanswered questions are open, accepted recommendations are defaulted and explicit answers are resolved; execution requires no open question or blocker.
origin: services-crm:docs/merging/README.md#Status (architecture and plan approved by Andrew 2026-10-11)
lifecycleservicetest
services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#refuses the execution request as a plan that is not ready
05must prove
Confirmed
Answers are merged by question and remain until explicitly cleared, while a request that answers and clears the same question is rejected.
policyapi, servicetest
services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#keeps the first answer when the second request answers only the other conflict
06must prove
Confirmed
Unknown questions and unavailable choices are rejected without saving; previously stored answers invalidated by changed records are instead dropped and reported.
validationapi, servicetest
services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#refuses it as an invalid resolution rather than storing a decision nobody can apply
07must prove
Confirmed
Changes require the current plan version, and an outdated version is refused without overwriting another administrator's work.
validationapi, servicetest
services-crm:modules/merges/tests/integration/services/merges/merge-plan-decisions.integration.spec.js#leaves both decisions on the plan, at the version it was refused against
08must prove
Confirmed
A value choice retains its source record; if that record changes the value, the plan shows and retains the new source value but requires confirmation or a replacement answer before execution.
policyservicetest
services-crm:modules/merges/tests/integration/services/merges/approval-binding.integration.spec.js#shows the record’s new value as what the merge would take, and proposes it as the choice to confirm
09
Confirmed
The service records answer author, time and source record, retaining the original attribution when the same answer is resubmitted unchanged.
policyservicetest
services-crm:modules/merges/tests/integration/services/merges/merge-outcome.integration.spec.js#keeps the reviewer’s choice with what it was, who made it, and the record it was taken from
10must prove
Confirmed
The product should describe plan values with workspace labels, archive indicators, record names and numbers and readable counts rather than internal references or storage terms.
origin: services-crm:docs/merging/api.md#4. Merge plans (lookup values in the workspace’s words, Andrew 2026-10-14)
policyservicedocumented
11must prove
Confirmed
Competing values and collection items show their last field change from history when available, otherwise the record creation time.
calculationservicetest
services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#says when each competing value last changed, so a reader can see which is freshest (gap G9)
12must prove
Confirmed
Explicit validation returns a preview recomputed from current records, and reading an open plan likewise refreshes it when records have changed.
lifecycleservicetest
services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#answers the validation with the plan as it is now, ready to execute
13
Confirmed
Plan fields include visibility markers so future field restrictions can omit hidden choices and preserve survivor defaults.
policyservicedocumented
services-crm:docs/merging/architecture.md#9. Security and tenant isolation

Scenarios

IdGivenWhenThenProvenance
01A plan contains two unresolved questions.Successive updates answer a different question each time.Both choices remain in the planned survivor.test
services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#plans the survivor with both chosen values, neither request having undone the other
02An administrator chooses a participant's job title and approves the preview.That participant receives another job title before execution.Execution rejects the stale preview and shows the old and new source values for renewed confirmation.test
services-crm:modules/merges/tests/integration/services/merges/approval-binding.integration.spec.js#refuses the approved execution as plan_stale, naming the old value and the new one

Edge Cases

IdGivenWhenThenProvenance
03Two administrators hold a plan affected by a participant edit.One read refreshes the stored preview before the other saves a decision.The older-version decision is rejected and its author reloads the plan.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.