---
id: JNY-PFM-MTD-005
title: Apply deletion policies and consolidate duplicate endpoints
feature: FEAT-PFM-MTD-06
product_area: platform
module: metadata
revision: 1
status: draft
product_intent: confirmed
implementation_evidence: observed
supersedes:
  - PLAT-M6-S08
  - PLAT-M6-S11
  - CO-ACC-0149
  - CO-ACC-0248
  - CO-ACC-0252
  - CO-ACC-0256
  - CO-ACC-0450
source_sha:
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
actor: ACT-PFM-010
goal: Remove linked records and merge duplicate contacts while preserving restrictions and survivor references.
capabilities:
  - CAP-PFM-MTD-013
  - CAP-PFM-MTD-019
  - CAP-PFM-MTD-014
screens:
  - '/console/{tenantId}/objects/{objectKey}/{recordId}'
  - '/console/{tenantId}/crm/contacts/{id}'
steps:
  - 'n': 1
    surface: deleteCustomObjectRecord
    action: Attempt Osprey’s deletion while its insurance restricts removal.
    capability: CAP-PFM-MTD-013
    expected: The confirmation explains the restriction and the boat remains.
    provenance: test
    source: >-
      react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S08.spec.ts#PLAT-M6-S08: an insured
      boat cannot be deleted and a builder's deletion takes its boats except the refused one
  - 'n': 2
    surface: deleteCustomObjectRecord
    action: Attempt deleting the builder whose cascade includes protected Osprey.
    capability: CAP-PFM-MTD-013
    expected: The refusal preserves the builder and every dependent boat.
    provenance: test
    source: >-
      react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S08.spec.ts#PLAT-M6-S08: an insured
      boat cannot be deleted and a builder's deletion takes its boats except the refused one
  - 'n': 3
    surface: deleteCustomObjectRecord
    action: End the protecting insurance and retry builder deletion.
    capability: CAP-PFM-MTD-019
    expected: The builder and its dependent boats are removed.
    provenance: test
    source: >-
      react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S08.spec.ts#PLAT-M6-S08: an insured
      boat cannot be deleted and a builder's deletion takes its boats except the refused one
  - 'n': 4
    surface: CRM deleteContact (MOD-CRM-ENT)
    action: Delete Ola through CRM while Fulmar follows its owner’s cascade.
    capability: CAP-PFM-MTD-019
    expected: Both endpoints disappear and no association retains Ola.
    provenance: test
    source: >-
      services-platform:tests/acceptance/custom-objects/deployed/associations/CO-ACC-0256.spec.js#step 3:
      Fulmar answers 404 and its associations are gone
  - 'n': 5
    surface: CRM merge of duplicate contacts (MOD-CRM-DQ)
    action: Merge Jane’s duplicate into the surviving Jane.
    capability: CAP-PFM-MTD-019
    expected: 'Crew, ownership and Previous Owner references use the survivor.'
    provenance: test
    source: >-
      react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S11.spec.ts#PLAT-M6-S11: after CRM
      merges Jane's duplicate her crew places, her boats and Osprey's Previous Owner name the surviving Jane
  - 'n': 6
    surface: listCustomObjectRecordHistory
    action: Inspect Osprey’s resulting revision.
    capability: CAP-PFM-MTD-014
    expected: The merge is recorded once with attribution and the previous reference.
    provenance: test
    source: >-
      services-platform:modules/custom-objects/tests/integration/db/custom-object-records-merge.integration.spec.js#attributes
      the change to the merge: its source, its actor and its merge id
alternates: []
failures:
  - from_step: 2
    condition: A cascade exceeds the supported ten-level depth.
    path: Deletion rejects the excessive chain.
    outcome: Every record in the rejected transaction remains.
    provenance: test
    source: >-
      services-platform:modules/associations/tests/integration/db/apply-endpoint-deletion.integration.spec.js#refuses
      a chain of eleven with SQLSTATE AE409 and removes nothing of it
rules_in_play:
  - BR-CAP-PFM-MTD-013-04
  - BR-CAP-PFM-MTD-013-05
  - BR-CAP-PFM-MTD-019-01
  - BR-CAP-PFM-MTD-019-03
  - BR-CAP-PFM-MTD-019-07
  - BR-CAP-PFM-MTD-019-08
  - BR-CAP-PFM-MTD-014-06
assertions:
  - id: AS-JNY-PFM-MTD-005-01
    statement: A refused endpoint policy rolls back the entire deletion.
    provenance: test
    source: >-
      react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S08.spec.ts#PLAT-M6-S08: an insured
      boat cannot be deleted and a builder's deletion takes its boats except the refused one
  - id: AS-JNY-PFM-MTD-005-02
    statement: CRM contact removal invokes the shared relationship protocol.
    provenance: test
    source: >-
      services-platform:tests/acceptance/custom-objects/deployed/associations/CO-ACC-0256.spec.js#step 5: no
      association names Ola any more
  - id: AS-JNY-PFM-MTD-005-03
    statement: Duplicate consolidation redirects connections and reference values to the survivor.
    provenance: test
    source: >-
      react-console:acceptance/custom-objects/playwright/journeys/PLAT-M6-S11.spec.ts#PLAT-M6-S11: after CRM
      merges Jane's duplicate her crew places, her boats and Osprey's Previous Owner name the surviving Jane
e2e_policy: required
e2e_reason: >-
  The connected work includes console presentation and interactions across record surfaces. Browser acceptance
  complements service proof for those visible outcomes.
proved_by: []
---

# Apply deletion policies and consolidate duplicate endpoints

Remove linked records and merge duplicate contacts while preserving restrictions and survivor references.

## Journey

The steps identify the participating capabilities and their expected outcomes. Alternatives and refusals retain their own evidence so a successful route does not imply that every branch has been demonstrated.
