---
id: WF-CRM-DQ-004
title: Decide about a pair or a group and regroup
trigger: >-
  A reviewer rejects or restores comparisons, undoes a group dismissal or
  confirms a missed duplicate.
product_area: crm
module: data-quality
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
implements:
  - CAP-CRM-DQ-008
  - CAP-CRM-DQ-009
  - CAP-CRM-DQ-007
  - CAP-CRM-DQ-010
moves:
  - STATE-CRM-DQ-001
  - STATE-CRM-DQ-002
crosses:
  - SVC-CRM-DQ-duplicates
idempotency: >-
  Repeated dismissal preserves and returns the prior decision. Restoration of a
  non-dismissed pair changes nothing, and confirmation updates the existing
  comparison rather than adding another row.
concurrency: >-
  Decision writes lock their target pairs, ordering group locks by identity.
  Group recomputation occurs within the same transaction; interactions with
  independent detector reads retain the documented concurrency qualification.
hops:
  - 'n': 1
    actor_or_service: Duplicates route
    action: >-
      Require review authority, validate record type and note, and locate the
      workspace pair or group.
    anchor: >-
      services-crm:modules/duplicates/aws/api/duplicates.routes.ts:dismissDuplicateGroup
    seam: sync
    on_failure: 'Return permission, not-found or validation refusal before writing.'
    left_inconsistent: No review decision is partially persisted.
    observer: reviewer.
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/e2e/duplicates.e2e.spec.js#answers
      403 to that reader dismissing a pair, which is a decision and not a read
  - 'n': 2
    actor_or_service: Duplicates persistence
    action: >-
      Persist dismissal attribution and evidence, clear it for restoration, or
      write full-score human confirmation.
    anchor: >-
      services-crm:modules/duplicates/services/persistence/duplicate-candidates.ts:dismissDuplicateCandidate
    seam: sync
    on_failure: Roll back the decision transaction.
    left_inconsistent: No partially recorded decision remains.
    observer: reviewer.
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/e2e/duplicates.e2e.spec.js#records
      the evidence the dismissal was made against, which a later score is
      compared with
  - 'n': 3
    actor_or_service: Duplicate groups
    action: >-
      Refresh the affected components, remove undersized groups and return the
      component produced by the decision.
    anchor: >-
      services-crm:modules/duplicates/services/persistence/duplicate-groups.ts:recomputeDuplicateGroups
    seam: sync
    on_failure: Abort with the decision if grouping fails.
    left_inconsistent: Pair and component changes commit together.
    observer: reviewer sees the resulting group.
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/integration/services/detection/duplicate-detection.integration.spec.js#grouped
      every pair it stored, the groups of a batch being written in the pass’s
      own transaction (§14)
  - 'n': 4
    actor_or_service: Console
    action: >-
      Display the decision and available undo, and refresh other pair displays
      through the console data layer.
    anchor: 'react-console:components/duplicates/data-quality/group-inspector.tsx'
    seam: sync
    on_failure: Display the service failure and refresh applicable review data.
    left_inconsistent: Other mounted displays may await data refresh.
    observer: reviewer.
    provenance: observed
    source: >-
      react-console:components/duplicates/indicator/use-record-duplicates.ts:useRecordDuplicates
branches:
  - >-
    A whole-group dismissal returns the resulting dismissed component, which has
    another identity.
  - >-
    Removing one displayed member submits dismissals for its comparisons with
    the other members; those separate requests are not one group transaction.
evidence:
  - >-
    services-crm at a8d1364f: modules/duplicates/aws/api/duplicates.routes.ts;
    services/persistence/duplicate-candidates.ts;
    services/persistence/duplicate-groups.ts;
    services/groups/group-components.ts.
  - >-
    react-console at baf6dae3:
    components/duplicates/data-quality/group-inspector.tsx, duplicate-queue.tsx;
    components/duplicates/indicator/record-duplicate-indicator.tsx.
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-IAM-001, TC-IAM-005, TC-IAM-006, TC-LOG-001, TC-LOG-002, TC-LOG-003, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003]
---

# Decide About A Pair Or A Group And Regroup

## What It Does

Review changes evidence standing through duplicate persistence and refreshes the groups affected by that change. Whole-group dismissal is one transaction; the console’s remove-member behavior instead calls pair decisions separately.

## The Flow

```mermaid
flowchart TD
  H1["Require review authority, validate record type and note, and locate the workspace pair or group."]
  H2["Persist dismissal attribution and evidence, clear it for restoration, or write full-score human confirmation."]
  H1 --> H2
  H3["Refresh the affected components, remove undersized groups and return the component produced by the decision."]
  H2 --> H3
  H4["Display the decision and available undo, and refresh other pair displays through the console data layer."]
  H3 --> H4
```

## When Something Fails

A failed pair or whole-group transaction leaves the prior decision and grouping intact. Restoring clears current dismissal data rather than retaining a history of earlier decisions. Separate member-removal requests can leave partial removal if one fails.

## Open Design Questions

The mounted queue does not supply the record picker needed for manual confirmation. That operation exists in the service but remains unavailable as a console review control.
