---
id: STATE-CRM-ACT-005
title: Activity type and outcome availability
object: DOM-CRM-ACT-001
product_area: crm
module: activities-tasks
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
states:
  - name: active
    meaning: The classification or result can be selected for new interactions.
    provenance: observed
    source: 'services-crm:modules/activities/services/persistence/activity-types.ts'
  - name: inactive
    meaning: >-
      Existing interactions can retain the classification or result, but new selections
      cannot use it.
    provenance: observed
    source: 'services-crm:modules/activities/services/persistence/activity-types.ts'
  - name: deleted
    meaning: The configuration entry has been removed after confirming it is unused.
    provenance: observed
    source: 'services-crm:modules/activities/services/persistence/activity-types.ts'
transitions:
  - from: active
    to: inactive
    trigger: Save the type or its result list with availability disabled.
    guard: The parent type’s read version matches and updates are unlocked.
    side_effects:
      - New selections are refused while existing interactions may retain the entry.
    who: A caller authorized to update activity types.
    provenance: test
    source: >-
      services-crm:modules/activities/tests/integration/services/persistence/activities.integration.spec.js#keeps
      an inactive type on an activity that already has it
  - from: inactive
    to: active
    trigger: Save the type or its result list with availability enabled.
    guard: The parent type’s read version matches and updates are unlocked.
    side_effects:
      - The entry becomes available for new selections.
    who: A caller authorized to update activity types.
    provenance: observed
    source: >-
      services-crm:modules/activities/services/persistence/activity-types.ts:updateActivityType
  - from: inactive
    to: deleted
    trigger: 'Delete an unused type, or save its result list with an unused result omitted.'
    guard: >-
      No interaction references the entry. Type deletion additionally requires a
      customer-defined type without either lock; result removal requires an
      update-unlocked parent and current read version. Unused results of baseline types
      may be removed.
    side_effects:
      - Removing a type also removes its owned results.
    who: 'A type-delete caller for a type, or a type-update caller for its result list.'
    provenance: test
    source: >-
      services-crm:modules/activities/tests/integration/services/persistence/activity-types.integration.spec.js#refuses
      to remove an outcome an activity has, saying to deactivate it instead
  - from: active
    to: deleted
    trigger: 'Delete an unused type, or save its result list with an unused result omitted.'
    guard: >-
      No interaction references the entry. Type deletion additionally requires a
      customer-defined type without either lock; result removal requires an
      update-unlocked parent and current read version. Unused results of baseline types
      may be removed.
    side_effects:
      - Removing a type also removes its owned results.
    who: 'A type-delete caller for a type, or a type-update caller for its result list.'
    provenance: observed
    source: >-
      services-crm:modules/activities/services/persistence/activity-types.ts:deleteActivityType
invalid:
  - from: active
    to: deleted
    why: >-
      Baseline types cannot be deleted, and referenced types or results cannot be removed;
      retirement is the supported alternative.
    provenance: observed
    source: 'services-crm:modules/activities/services/persistence/activity-types.ts'
  - from: inactive
    to: active
    why: >-
      Baseline adoption preserves existing configuration, including a customer’s disabled
      availability, rather than turning it back on.
    provenance: observed
    source: 'services-crm:modules/activities/services/persistence/activity-types.ts'
concurrency: >-
  A version-checked type save replaces a supplied result list transactionally. Restricting
  database references enforce deletion safety against concurrent interaction creation.
  Type deletion itself takes no read version.
invariants:
  - INV-DOM-CRM-ACT-001-03
  - INV-DOM-CRM-ACT-001-12
evidence:
  - >-
    services-crm at a8d1364f: modules/activities/services/persistence/activity-types.ts;
    services/persistence/activities.ts (requireActivityType); db/activities.table.ts
    (activities_activity_type_fk, activities_outcome_fk restrict);
    db/activity-outcomes.table.ts.
  - >-
    react-console at baf6dae3: components/configuration/resources/activity-types.tsx
    (system types cannot be deleted).
---

# Activity Type and Outcome Availability

## The Lifecycle

```mermaid
stateDiagram-v2
  active --> inactive: retire
  inactive --> active: enable
  inactive --> deleted: remove unused configuration
  active --> deleted: remove unused configuration
```

Availability separates retirement from removal. A retired choice remains valid on interactions that already carry it. Deleted describes the absence of configuration after its removal.

## Transitions Explained

The structured rows distinguish whole-type deletion from removal of an individual result during a type save. Baseline types remain present, but unused results belonging to them can be removed. Reapplying defaults adopts existing entries rather than overriding local administration.

## What Cannot Happen

New interactions cannot select inactive activity configuration, and references protect entries from deletion. Task configuration has a separately recorded inconsistency: inactive task types and queues continue accepting new work. This examination retains that planning question.

## Concurrency and Timing

Version checks protect type editing and result replacement. Database references arbitrate deletion against concurrent use. Removal of an entire type has no read-version argument.
