---
id: ATS-CRM-DQ-006
scope: CAP-CRM-DQ-006
product_area: crm
module: data-quality
revision: 1
status: proposed
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
scenarios:
  - id: ATS-CRM-DQ-006-01
    title: Registration suggestions use the medium floor and ranking
    level: api
    proves:
      - BR-CAP-CRM-DQ-006-01
      - BR-CAP-CRM-DQ-006-04
    preconditions: 'Prepare neighboring scores of 70, 50, 50, 50 and 38.'
    steps: Call candidate selection.
    expected: 'Three contacts appear, shared e-mail first and tied scores by number, with staff-equivalent scores.'
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#answers
        the three best contacts above the floor, the e-mail match first and a tie in contact-number order,
        with what Platform masks
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#leaves
        out a fourth contact at the floor, because a member is shown three
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#scores
        every contact of the neighbourhood with the score and the reasons the TypeScript scorer gives it
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#answers
      the three best contacts above the floor, the e-mail match first and a tie in contact-number order, with
      what Platform masks
  - id: ATS-CRM-DQ-006-02
    title: Unavailable registration identities are excluded
    level: api
    proves:
      - BR-CAP-CRM-DQ-006-02
    preconditions: 'Prepare linked, deleted and other-workspace matching contacts.'
    steps: Request candidates.
    expected: None of those contacts is offered.
    negative: true
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#never
        offers a contact a portal user of the tenant already links
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#never
        offers a contact that has been deleted, its keys gone with it
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#offers
        only the asking tenant's contacts, the same sign-up in the other tenant finding that tenant's own
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#never
      offers a contact a portal user of the tenant already links
  - id: ATS-CRM-DQ-006-03
    title: Declining a suggestion preserves a review pair
    level: api
    proves:
      - BR-CAP-CRM-DQ-006-05
      - BR-CAP-CRM-DQ-006-06
      - BR-CAP-CRM-DQ-006-07
    preconditions: Registration rejects an existing candidate.
    steps: Create the portal contact naming that candidate and detect the new record.
    expected: >-
      The contact has portal attribution and an open declined-match pair at 35 that remains grouped after
      detection.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#writes
        the contact with a UUIDv7 id, the next number, the names trimmed and computed and the stamps of
        portal-sign-up
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#records
        the declined pair, open, with origin portal_sign_up and the score and reasons the scorer gives it
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#keeps
        the declined pair through detection pass over the new contact, which groups it
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#writes
      the contact with a UUIDv7 id, the next number, the names trimmed and computed and the stamps of
      portal-sign-up
  - id: ATS-CRM-DQ-006-04
    title: Repeated registration reuses its recent contact
    level: api
    proves:
      - BR-CAP-CRM-DQ-006-08
    preconditions: A registration has just created a contact.
    steps: Repeat the submission within one minute.
    expected: The function returns that contact and performs no further creation.
    negative: false
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#answers
        the same contact for the same sign-up retried within a minute, and writes nothing more
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#answers
      the same contact for the same sign-up retried within a minute, and writes nothing more
  - id: ATS-CRM-DQ-006-05
    title: Registration honors contact validation
    level: api
    proves:
      - BR-CAP-CRM-DQ-006-09
    preconditions: An active contact reserves the intended primary e-mail.
    steps: 'Try creation with that address, then try creation without either name.'
    expected: Both requests are rejected.
    negative: true
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#refuses
        an address that is already the primary address of a contact it did not just create
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#refuses
        a sign-up with neither a first nor a last name
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#refuses
      an address that is already the primary address of a contact it did not just create
  - id: ATS-CRM-DQ-006-06
    title: Portal functions restrict their callers and workspace
    level: api
    proves:
      - BR-CAP-CRM-DQ-006-10
    preconditions: Use the CRM application role and a session outside the target workspace.
    steps: Attempt the registration functions.
    expected: The calls are denied.
    negative: true
    data_needs: The existing scenario setup supplies the required records.
    bound_to:
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#refuses
        CRM's own application role, which is not granted it
      - >-
        services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#refuses
        a session already acting in another tenant
    provenance: test
    source: >-
      services-crm:modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js#refuses
      CRM's own application role, which is not granted it
evidence:
  - repository: services-crm
    source_sha: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
    paths:
      - modules/duplicates/tests/integration/db/portal-sign-up-contacts.integration.spec.js
    note: Bindings identify authored proof; empty bindings remain proposed and findings record known limitations.
---

# Reuse a contact during portal registration: Acceptance Scenarios

## Coverage

| Required Rule | Acceptance Scenario |
|---|---|
| `BR-CAP-CRM-DQ-006-01` | `ATS-CRM-DQ-006-01` |
| `BR-CAP-CRM-DQ-006-02` | `ATS-CRM-DQ-006-02` |
| `BR-CAP-CRM-DQ-006-04` | `ATS-CRM-DQ-006-01` |
| `BR-CAP-CRM-DQ-006-05` | `ATS-CRM-DQ-006-03` |
| `BR-CAP-CRM-DQ-006-06` | `ATS-CRM-DQ-006-03` |
| `BR-CAP-CRM-DQ-006-07` | `ATS-CRM-DQ-006-03` |
| `BR-CAP-CRM-DQ-006-08` | `ATS-CRM-DQ-006-04` |
| `BR-CAP-CRM-DQ-006-09` | `ATS-CRM-DQ-006-05` |
| `BR-CAP-CRM-DQ-006-10` | `ATS-CRM-DQ-006-06` |
| `BR-CAP-CRM-DQ-006-03` | No scenario yet; `FND-CRM-DQ-032` records the proof gap. |
