---
id: TST-CRM-DQ-182
title: Duplicate public API lifecycle
kind: api-lifecycle
product_area: crm
module: data-quality
revision: 1
status: draft
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  rhythm-v2-docs: 61315bb0538e230286687677da2b04b1d33f162b
repository: services-crm
files:
  - modules/duplicates/tests/e2e/duplicate-groups.e2e.spec.js
  - modules/duplicates/tests/e2e/duplicates.e2e.spec.js
  - modules/duplicates/tests/e2e/organization-block-rules.e2e.spec.js
implements:
  - ATS-CRM-DQ-003-06
  - ATS-CRM-DQ-003-08
  - ATS-CRM-DQ-004-02
  - ATS-CRM-DQ-004-03
  - ATS-CRM-DQ-004-06
  - ATS-CRM-DQ-004-08
  - ATS-CRM-DQ-004-09
  - ATS-CRM-DQ-005-01
  - ATS-CRM-DQ-007-05
  - ATS-CRM-DQ-007-06
  - ATS-CRM-DQ-007-07
  - ATS-CRM-DQ-008-01
  - ATS-CRM-DQ-008-02
  - ATS-CRM-DQ-008-07
  - ATS-CRM-DQ-009-03
  - ATS-CRM-DQ-009-04
  - ATS-CRM-DQ-010-01
  - ATS-CRM-DQ-011-03
environment: local
command: npx mocha --timeout 60000 'modules/duplicates/tests/e2e/**/*.spec.js'
gate: Prepare the test database first. This selection belongs to the local service API tier.
implementation_state: implemented
implementation_evidence: observed
latest_result: not-run
conformance: not-verified
estimated_minutes: 10
isolation: Use the suite fixture workspace and remove its test identities; run database selections sequentially.
retries: none
proves_controls: []
evidence:
  - provenance: test
    source:
      - 'services-crm:modules/duplicates/tests/e2e/duplicate-groups.e2e.spec.js'
      - 'services-crm:modules/duplicates/tests/e2e/duplicates.e2e.spec.js'
      - 'services-crm:modules/duplicates/tests/e2e/organization-block-rules.e2e.spec.js'
  - provenance: documented
    source: 'rhythm-v2-docs:specs/CONVENTIONS.md#10.6 Executable Test Suite'
lifecycles:
  create: partial
  change: partial
  archive: not-applicable
  delete: partial
  merge: not-applicable
  reconcile: not-applicable
lifecycle_gaps:
  - FND-CRM-DQ-074
lifecycle_notes:
  archive: Archiving ordinary CRM records belongs to Entities; these tests concern duplicate review and identity combination.
  reconcile: This runner does not establish deployed recovery.
---

# Duplicate public API lifecycle

## Verification Boundary

The signed local API harness, real route declarations and PostgreSQL establish dispatcher behavior. Hosted API Gateway, deployed queues and browser actions are outside this boundary.

## What This Suite Proves

The local dispatcher validates duplicate requests and permission combinations and returns candidate, group, rule and re-check results from the database. The scenario bindings identify the assertions inspected in this examination. No control claim is assigned without a check that fails when the control is removed.

## What It Does Not Prove

Local database assertions do not establish hosted console behavior, deployed message delivery or the policies of unavailable owner services.

## Level and Rationale

The real dispatcher is needed to check request validation and permission conjunctions. Direct service calls cannot establish the public refusal boundary.

## Lifecycle Coverage

Create, change and cleanup receive partial credit because these tests select data-quality behavior rather than the complete ordinary record lifecycle. Merge receives partial credit where it appears: a test selection does not establish every contact, organization and external participant variant. Archive belongs to the ordinary record module; deployed reconciliation remains outside these browser and local API selections. The lifecycle finding records these limits.

## Real Dependencies and Test Doubles

The signed local API harness, real route declarations and PostgreSQL establish dispatcher behavior. Hosted API Gateway, deployed queues and browser actions are outside this boundary.

## Must Not Be Doubled

Keep route dispatch, permission evaluation and database writes real; replacing them would hide the refusals and persisted outcomes.

## Fixtures and Isolation

Use the suite fixture workspace and remove its test identities; run database selections sequentially. The test support constructs fixture contexts and test-specific identities. Failure-injection participants belong to the run and must be removed with its fixtures.

## Determinism and Retries

The register records no new runtime result. Existing polling and fixture clocks remain part of the authored tests; polling for completion is not a retry of a failed case. Run with at most three workers and diagnose a failure before rerunning it.

## How It Runs

The frontmatter records the scoped command and its runner tier. Run the test-database preparation command before invoking this selection.

## Coverage Gaps

Mapped scenarios retain their exact execution sources for review; combined multi-source scenarios can still leave an ordered handoff unproved. The capability gap records identify unbound obligations, and the grouped-suite finding records incomplete lifecycle and runtime coverage.
