---
id: WF-CRM-ACT-002
title: Correct or remove an activity
trigger: >-
  A user corrects or removes an interaction, or an API caller replaces or patches its
  values.
product_area: crm
module: activities-tasks
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
  - CAP-CRM-ACT-003
  - CAP-CRM-ACT-004
  - CAP-CRM-ACT-006
moves:
  - STATE-CRM-ACT-001
crosses:
  - SVC-CRM-ACT-activities
idempotency: >-
  A committed edit advances the version, making repetition with the old version stale.
  After an ambiguous response the console rereads and compares submitted values. An
  unchanged form sends no edit; repeated deletion returns not found.
concurrency: >-
  The service locks the interaction and compares its read version for edits. A later edit
  from the same version cannot overwrite the first. Matching links by their related record
  preserves the identity of retained associations; deletion takes no version.
hops:
  - 'n': 1
    actor_or_service: Activity correction form
    action: >-
      Send changed form values as a patch with its read-version test; request confirmation
      before deletion.
    anchor: 'react-console:lib/activities/api.ts:createActivitiesApi'
    seam: sync
    on_failure: Display version conflicts and resolve uncertain saves by rereading the interaction.
    left_inconsistent: >-
      An ambiguous response may leave the form uncertain about an already committed
      change.
    observer: The user receives save or conflict feedback.
    provenance: test
    source: >-
      react-console:lib/activities/retry-safe-writes.test.ts#is saved when its answer is
      lost but the activity holds what was sent
  - 'n': 2
    actor_or_service: Activities API
    action: >-
      Authorize the selected write, apply a patch to the current read or validate a
      complete replacement, and reject extra properties.
    anchor: >-
      services-crm:modules/activities/aws/api/activity-api-mapper.ts:mapReplaceActivityRequest
    seam: sync
    on_failure: Reject incomplete replacements or invalid bodies before persistence.
    left_inconsistent: No record write survives request validation failure.
    observer: The caller receives the response.
    provenance: test
    source: >-
      services-crm:modules/activities/tests/e2e/activities.e2e.spec.js#refuses a
      replacement missing a property: 400 naming it
  - 'n': 3
    actor_or_service: Shared file preparation
    action: >-
      Prepare added permanent files before the record transaction and attach changed
      associations through the shared pipeline within it.
    anchor: 'services-crm:modules/activities/services/persistence/activities.ts:updateActivity'
    seam: sync
    on_failure: Refuse a failed preparation without changing saved attachments.
    left_inconsistent: >-
      Unreferenced prepared copies await external cleanup with no locally established
      deadline.
    observer: Shared asset records expose preparation and cleanup.
    provenance: observed
    source: 'services-crm:modules/activities/services/persistence/activities.ts:assetChanges'
  - 'n': 4
    actor_or_service: Activity persistence transaction
    action: >-
      Lock the interaction, apply write safeguards and version checks, validate changed
      configuration and fields, then replace link and file sets; deletion instead removes
      the record and its import matching entries.
    anchor: 'services-crm:modules/activities/services/persistence/activities.ts:updateActivity'
    seam: sync
    on_failure: 'Roll back on locks, stale versions, invalid fields or unresolved references.'
    left_inconsistent: Only preparation performed outside the transaction can remain.
    observer: The caller receives the corresponding write refusal.
    provenance: test
    source: >-
      services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#replaces
      the links as a set on update, keeping the row of a record still linked
  - 'n': 5
    actor_or_service: Activity change settlement
    action: >-
      Refresh link time, status and type copies and settle the attributed edit or deletion
      revision at commit.
    anchor: 'services-crm:aws/crm.change-events.ts:crmChangeEventStreams'
    seam: sync
    on_failure: Capture failure prevents the transaction from committing.
    left_inconsistent: No partial interaction change survives the transaction failure.
    observer: History readers can inspect the revision after deletion.
    provenance: test
    source: >-
      services-crm:modules/activities/tests/e2e/activities.e2e.spec.js#answers its
      history, newest first: the update and the create
  - 'n': 6
    actor_or_service: Shared released-file cleanup
    action: >-
      Submit released file references for shared cleanup after their record associations
      are removed.
    anchor: 'services-crm:modules/activities/services/persistence/activities.ts:deleteActivity'
    seam: queue
    on_failure: The external file owner controls retries and cleanup outcomes.
    left_inconsistent: Physical copies may remain without a live activity reference.
    observer: Shared asset processing records provide external visibility.
    provenance: observed
    source: 'services-crm:modules/activities/services/persistence/activities.ts:deleteActivity'
branches:
  - >-
    A replacement must include its complete mapped payload; a patch alters only submitted
    values.
  - >-
    A patch omitting attachments preserves them, whereas a submitted list removes omitted
    entries.
waits: []
evidence:
  - >-
    services-crm at a8d1364f: modules/activities/aws/api/activities.routes.ts
    (updateActivity, patchActivity, deleteActivity); activity-api-mapper.ts;
    services/persistence/activities.ts (updateActivity, deleteActivity,
    replaceActivityLinks, assetChanges);
    modules/data-jobs/services/persistence/data-id-mappings.ts
    (deleteDataIdMappingsOfRecords).
  - >-
    react-console at baf6dae3: lib/activities/api.ts (updateActivity, deleteActivity);
    components/activities/activity-timeline.tsx (DeleteActivityDialog).
controls: [TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-AZ-006, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-005, TC-IAM-006, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-PRV-003, TC-TEN-001, TC-TEN-002, TC-TEN-003]
---

# Correct or remove an activity

## What It Does

Correction changes an interaction and its owned context under a read-version check. Deletion removes its timeline presence but retains its revision history. Both paths delegate file lifecycle handling to shared infrastructure.

## The Flow

```mermaid
flowchart TD
  A[Submit correction or confirmed removal] --> B[Authorize and map request]
  B --> C[Prepare added files when correcting]
  C --> D[Lock interaction and apply write safeguards]
  D --> E{Correction or removal?}
  E -->|Correction| F[Check version and save owned context]
  E -->|Removal| G[Remove live record and import matching]
  F --> H[Settle revision and commit]
  G --> H
  H --> I[Delegate released-file cleanup]
```

The numbered hops specify the request, persistence and integration boundaries in order. Each hop identifies its evidence anchor, synchronization seam and observable failure outcome. Branches distinguish optional and delegated paths.

## When Something Fails

Refused writes preserve the earlier record. A lost edit response is checked against saved values before the console reports success. Deletion drops import matching references, permitting a later import to create a fresh interaction. Prepared or released file copies can outlast the record transaction.

## Open Design Questions

The planned authorized lock-management actions still need implementation; ordinary writes can currently set a full lock without a supported clearing action.
