---
id: WF-CRM-DQ-003
title: Check a draft and create past a block
trigger: >-
  A console user enters a new record, or a client submits contact or
  organization creation.
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-004
  - CAP-CRM-DQ-003
moves: []
crosses:
  - SVC-CRM-DQ-duplicates
  - SVC-CRM-ENT-entities
idempotency: >-
  Draft matching is repeatable and read-only. Entities decides create retry
  behavior; unique exception identity prevents a second audit row for the same
  created record.
concurrency: >-
  The creation block guard precedes the record transaction and does not
  serialize simultaneous creates. Two matching records can therefore pass
  preflight together and require later review.
hops:
  - 'n': 1
    actor_or_service: Console create form
    action: Request up to five draft matches while record details are entered.
    anchor: 'react-console:lib/duplicates/checks.ts'
    seam: sync
    on_failure: Suppress unavailable suggestions without disabling creation.
    left_inconsistent: A failed hint leaves no persisted duplicate work.
    observer: person creating the record.
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/integration/services/detection/duplicate-checks.integration.spec.js#answers
      at most the five a form shows, however many the tenant holds
  - 'n': 2
    actor_or_service: Duplicates route
    action: >-
      Score the draft within the workspace, excluding its edited identity, and
      return matches and blocking context without writing.
    anchor: >-
      services-crm:modules/duplicates/services/detection/duplicate-checks.ts:checkForDuplicates
    seam: sync
    on_failure: Refuse unsupported record types or missing duplicate-read authority.
    left_inconsistent: The check creates no record or comparison rows.
    observer: caller.
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/e2e/duplicates.e2e.spec.js#writes
      nothing: the draft is not a record, so the queue is as it was
  - 'n': 3
    actor_or_service: Entities create
    action: >-
      Evaluate active block rules before creation and require override
      authority, confirmation and a reason when a block applies.
    anchor: >-
      services-crm:modules/duplicates/services/detection/duplicate-checks.ts:refuseBlockedDuplicateCreate
    seam: sync
    on_failure: Return the duplicate conflict or an invalid explanation refusal.
    left_inconsistent: No new business record is committed by refusal.
    observer: caller and the console refusal dialog.
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/e2e/organization-block-rules.e2e.spec.js#audits
      the override with its reason, its rule and the organization it was let
      past
  - 'n': 4
    actor_or_service: Entities persistence
    action: >-
      Create the business record and authorized exception atomically with its
      author, rules and bypassed matches.
    anchor: >-
      services-crm:modules/entities/services/persistence/contacts.ts:createContact
    seam: sync
    on_failure: 'Roll back creation if any write, including the exception, fails.'
    left_inconsistent: The record and exception cannot partially commit.
    observer: caller.
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/integration/services/persistence/duplicate-block-overrides.integration.spec.js#leaves
      no contact behind, the record and its audit sharing one transaction
  - 'n': 5
    actor_or_service: Duplicate detection
    action: >-
      Process the new record’s change event through ordinary duplicate
      detection.
    anchor: >-
      services-crm:modules/duplicates/services/detection/duplicate-change-events.ts:detectForChangeEvents
    seam: event
    on_failure: Use the detection delivery and recovery policy.
    left_inconsistent: The new pair can be absent or stale until background detection finishes.
    observer: Reviewers.
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/unit/services/detection/duplicate-rule-actions.spec.js#stores
      the candidate for a block rule too, the block acting at the create and
      never on the queue (D-32)
branches:
  - Confirmation without override authority remains a duplicate-block refusal.
  - >-
    Organization creation evaluates organization rules and its separate override
    key.
evidence:
  - >-
    services-crm at a8d1364f:
    modules/duplicates/services/detection/duplicate-checks.ts,
    duplicate-rule-actions.ts, duplicate-refusals.ts;
    services/persistence/duplicate-block-overrides.ts;
    modules/entities/services/contacts/contact-create.ts;
    modules/entities/aws/api/organizations.routes.ts.
  - >-
    react-console at baf6dae3: lib/duplicates/checks.ts, create-block.ts;
    components/records/create/duplicate-block-refusal.tsx.
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-005, 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-003, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003]
---

# Check A Draft And Create Past A Block

## What It Does

Draft hints help staff choose an existing record before submitting creation. A firing block requires an authorized, explained exception; the accepted record and its exception are committed together.

## The Flow

```mermaid
flowchart TD
  H1["Request up to five draft matches while record details are entered."]
  H2["Score the draft within the workspace, excluding its edited identity, and return matches and blocking context without writing."]
  H1 --> H2
  H3["Evaluate active block rules before creation and require override authority, confirmation and a reason when a block applies."]
  H2 --> H3
  H4["Create the business record and authorized exception atomically with its author, rules and bypassed matches."]
  H3 --> H4
  H5["Process the new record’s change event through ordinary duplicate detection."]
  H4 --> H5
```

## When Something Fails

A refused create leaves no new record. Failed draft hints do not disable submission, and concurrent creates are not serialized by the preflight comparison. Background detection is responsible for finding duplicates that still enter the workspace.

## Open Design Questions

The older browser journey contradicts the recorded blocking decision by expecting hidden pairs and an organization bypass. Its assertions must be repaired before serving as acceptance evidence.
