---
id: ATS-CRM-DQ-012
scope: CAP-CRM-DQ-012
product_area: crm
module: data-quality
revision: 1
status: proposed
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-CRM-DQ-012-01
    title: Participant validation prevents invalid plans
    level: api
    proves:
      - BR-CAP-CRM-DQ-012-01
    preconditions: Prepare workspace records and an absorbed identity.
    steps: 'Try one participant, eleven, a repeat, an outside survivor and the absorbed record.'
    expected: Invalid selections fail and the absorbed participant reports its survivor.
    negative: true
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/merges/tests/integration/services/persistence/record-merge-plans.integration.spec.js#refuses
        a plan of one record, which is not a merge, as ObjectInvalid naming the field
      - >-
        services-crm:modules/merges/tests/integration/services/persistence/record-merge-plans.integration.spec.js#refuses
        more records than a merge takes
      - >-
        services-crm:modules/merges/tests/integration/services/persistence/record-merge-plans.integration.spec.js#refuses
        the same record named twice
      - >-
        services-crm:modules/merges/tests/integration/services/persistence/record-merge-plans.integration.spec.js#refuses
        a survivor that is not one of the records being merged
      - >-
        services-crm:modules/merges/tests/integration/services/merges/merge-execution.integration.spec.js#refuses
        to plan a merge of an id it has merged away, naming the merged record
    provenance: test
    source: >-
      services-crm:modules/merges/tests/integration/services/persistence/record-merge-plans.integration.spec.js#refuses
      a plan of one record, which is not a merge, as ObjectInvalid naming the field
  - id: ATS-CRM-DQ-012-02
    title: Plan authority requires the type's complete permission pair
    level: api
    proves:
      - BR-CAP-CRM-DQ-012-02
    preconditions: 'Prepare contact-only authority, organization merge-only, read-only and merge-without-read callers.'
    steps: Request contact and organization plans.
    expected: Every incomplete type-specific read-and-merge pair is refused.
    negative: true
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#refuses the plan to a caller who may merge
        contacts but not organizations
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#refuses the plan of contacts to a caller who
        may merge organizations alone
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#refuses an organization plan to a caller who
        may read organizations but not merge them
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#refuses every plan route to a caller who may
        read contacts but not merge them
    provenance: test
    source: >-
      services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#refuses the plan to a caller who may merge
      contacts but not organizations
  - id: ATS-CRM-DQ-012-03
    title: Survivor ranking explains the winning signal
    level: unit
    proves:
      - BR-CAP-CRM-DQ-012-03
      - BR-CAP-CRM-DQ-012-05
    preconditions: 'Prepare participants distinguished by login, integration identity, inbound references and creation age.'
    steps: Compute the recommendation.
    expected: >-
      Signals apply in that order, reasons use record names, age-only ranking is weak and recency or
      completeness does not win.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/merges/tests/unit/services/planning/survivor-recommendation.spec.js#keeps the
        only participant a portal login names
      - >-
        services-crm:modules/merges/tests/unit/services/planning/survivor-recommendation.spec.js#keeps the
        only participant an integration addresses, when no login separates them
      - >-
        services-crm:modules/merges/tests/unit/services/planning/survivor-recommendation.spec.js#keeps the
        participant the most rows outside the merge name, when no identity separates them
      - >-
        services-crm:modules/merges/tests/unit/services/planning/survivor-recommendation.spec.js#keeps the
        record created first, when nothing else separates them
      - >-
        services-crm:modules/merges/tests/unit/services/planning/survivor-recommendation.spec.js#is not
        decisive when the top two are still level after the references rule
      - >-
        services-crm:modules/merges/tests/unit/services/planning/survivor-recommendation.spec.js#never keeps
        the newest record, whatever it holds beyond the rules
      - >-
        services-crm:modules/merges/tests/unit/services/planning/survivor-recommendation.spec.js#never hands a
        reader a record id, the records being named by their names instead
    provenance: test
    source: >-
      services-crm:modules/merges/tests/unit/services/planning/survivor-recommendation.spec.js#keeps the only
      participant a portal login names
  - id: ATS-CRM-DQ-012-04
    title: Administrators can override the survivor suggestion
    level: api
    proves:
      - BR-CAP-CRM-DQ-012-04
    preconditions: A named participant differs from the recommendation.
    steps: Create plans with and without an explicit survivor.
    expected: 'The named selection remains, while omission uses the recommendation.'
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/merges/tests/integration/services/merges/survivor-recommendation.integration.spec.js#leaves
        the survivor the request named alone, the recommendation being advisory
      - >-
        services-crm:modules/merges/tests/integration/services/merges/survivor-recommendation.integration.spec.js#is
        the survivor of a plan that named none, the default being the recommendation
    provenance: test
    source: >-
      services-crm:modules/merges/tests/integration/services/merges/survivor-recommendation.integration.spec.js#leaves
      the survivor the request named alone, the recommendation being advisory
  - id: ATS-CRM-DQ-012-05
    title: Participant changes preserve only applicable decisions
    level: api
    proves:
      - BR-CAP-CRM-DQ-012-08
    preconditions: A three-record plan holds decisions.
    steps: Remove one participant and read again after data changes.
    expected: Two participants remain and invalidated decisions are removed with explanations.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#answers the change with the two records that
        are left, in record_ids and in records
      - >-
        services-crm:modules/merges/tests/unit/services/planning/merge-decisions.spec.js#is dropped and
        reported when the plan is simply read again after the data moved on
    provenance: test
    source: >-
      services-crm:modules/merges/tests/e2e/merges.e2e.spec.js#answers the change with the two records that
      are left, in record_ids and in records
  - id: ATS-CRM-DQ-012-06
    title: Expiry applies only to overdue open plans
    level: api
    proves:
      - BR-CAP-CRM-DQ-012-10
    preconditions: 'Prepare overdue open and blocked plans, an executed plan and a recent plan.'
    steps: Run expiry processing.
    expected: Only the two overdue open statuses expire.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/merges/tests/integration/services/merges/merge-plan-expiry.integration.spec.js#expires
        the plan whose seven days are up, which is what takes it off the reader’s list
      - >-
        services-crm:modules/merges/tests/integration/services/merges/merge-plan-expiry.integration.spec.js#expires
        a blocked plan too, a plan nobody cleared being as abandoned as one nobody decided
      - >-
        services-crm:modules/merges/tests/integration/services/merges/merge-plan-expiry.integration.spec.js#leaves
        a plan that has been executed, whose merge happened and is nothing to close out
      - >-
        services-crm:modules/merges/tests/integration/services/persistence/record-merge-plans.integration.spec.js#gives
        it the seven days a plan lives for when nobody states another
    provenance: test
    source: >-
      services-crm:modules/merges/tests/integration/services/merges/merge-plan-expiry.integration.spec.js#expires
      the plan whose seven days are up, which is what takes it off the reader’s list
  - id: ATS-CRM-DQ-012-07
    title: Queue launch displays survivor reasoning
    level: browser
    proves:
      - BR-CAP-CRM-DQ-012-03
      - BR-CAP-CRM-DQ-012-04
    preconditions: 'Prepare groups with login, external-identity, reference and age distinctions.'
    steps: Launch their plans from the queue.
    expected: The displayed recommendation and explanation follow the recorded ranking.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - 'react-console:acceptance/crm/playwright/journeys/merging/CRM-ACC-0248.spec.ts#CRM-ACC-0248'
      - 'react-console:acceptance/crm/playwright/journeys/merging/CRM-ACC-0285.spec.ts#CRM-ACC-0285'
    provenance: test
    source: 'react-console:acceptance/crm/playwright/journeys/merging/CRM-ACC-0248.spec.ts#CRM-ACC-0248'
evidence:
  - repository: services-crm
    source_sha: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
    paths:
      - modules/merges/tests/e2e/merges.e2e.spec.js
      - modules/merges/tests/integration/services/merges/merge-execution.integration.spec.js
      - modules/merges/tests/integration/services/merges/merge-plan-expiry.integration.spec.js
      - modules/merges/tests/integration/services/merges/survivor-recommendation.integration.spec.js
      - modules/merges/tests/integration/services/persistence/record-merge-plans.integration.spec.js
      - modules/merges/tests/unit/services/planning/merge-decisions.spec.js
      - modules/merges/tests/unit/services/planning/survivor-recommendation.spec.js
    note: Bindings identify authored proof; empty bindings remain proposed and findings record known limitations.
  - repository: react-console
    source_sha: baf6dae382d6f41dce976c7f848667ccc37e076f
    paths:
      - acceptance/crm/playwright/journeys/merging/CRM-ACC-0248.spec.ts
      - acceptance/crm/playwright/journeys/merging/CRM-ACC-0285.spec.ts
    note: Bindings identify authored proof; empty bindings remain proposed and findings record known limitations.
---

# Prepare a merge and choose its survivor: Acceptance Scenarios

## Coverage

| Required Rule | Acceptance Scenario |
|---|---|
| `BR-CAP-CRM-DQ-012-01` | `ATS-CRM-DQ-012-01` |
| `BR-CAP-CRM-DQ-012-02` | `ATS-CRM-DQ-012-02` |
| `BR-CAP-CRM-DQ-012-03` | `ATS-CRM-DQ-012-03`, `ATS-CRM-DQ-012-07` |
| `BR-CAP-CRM-DQ-012-04` | `ATS-CRM-DQ-012-04`, `ATS-CRM-DQ-012-07` |
| `BR-CAP-CRM-DQ-012-05` | `ATS-CRM-DQ-012-03` |
| `BR-CAP-CRM-DQ-012-08` | `ATS-CRM-DQ-012-05` |
| `BR-CAP-CRM-DQ-012-10` | `ATS-CRM-DQ-012-06` |
