---
id: STATE-MBR-STR-002
title: Unit kind availability
object: DOM-MBR-STR-001
product_area: membership
module: structure
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-membership: 5994c270e8a37a30f848e99ba5b5ee6b87c08893
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
states:
  - name: active
    meaning: New units of this kind can be placed and existing units can move when other placement checks pass.
  - name: inactive
    meaning: >-
      Existing placements remain, but the service rejects new placement and movement of units of the retired
      kind.
  - name: removed
    meaning: The kind record is absent after reference checks permit deletion.
transitions:
  - from: active
    to: inactive
    trigger: Staff deactivate the kind or replace it with activity false.
    guard: The required version matches; replacement also preserves permissions required by existing placements.
    side_effects:
      - New placements and moves using this kind are rejected.
      - Existing units keep their placement.
    who: Structure administrator
    provenance: observed
    source: >-
      services-membership:modules/structure/services/persistence/organizational-unit-types.ts:deactivateOrganizationalUnitType
  - from: inactive
    to: active
    trigger: Staff replace a retired kind with activity true or omit activity.
    guard: >-
      The required version matches and the complete replacement preserves currently used root and parent
      permissions.
    side_effects:
      - Placement and movement are available again; omitted activity defaults to true.
    who: Structure administrator
    provenance: observed
    source: >-
      services-membership:modules/structure/services/persistence/organizational-unit-types.ts:updateOrganizationalUnitType
  - from: active
    to: removed
    trigger: Staff delete an active unused kind.
    guard: 'No unit, other kind or protected configuration reference holds it; deletion has no version parameter.'
    side_effects:
      - Its owned permitted-parent rows are also removed.
    who: Structure administrator
    provenance: test
    source: >-
      services-membership:tests/e2e/structure-api.e2e.spec.ts#the structure API, end to end in process ›
      refuses to delete a unit type in use, 409 unit_type_in_use
  - from: inactive
    to: removed
    trigger: Staff delete an inactive unused kind.
    guard: The ordinary kind-deletion reference checks pass.
    side_effects:
      - Deletion removes the kind and its permitted-parent rows.
    who: Structure administrator
    provenance: observed
    source: >-
      services-membership:modules/structure/services/persistence/organizational-unit-types.ts:deleteOrganizationalUnitType
invalid:
  - from: removed
    to: active
    why: >-
      Creation can reuse a deleted readable identifier, but creates a new record rather than reviving the
      deleted one.
concurrency: >-
  Kind writes lock or conditionally update the record version, so competing changes reject a stale version.
  They do not acquire the workspace tree lock. Their in-use checks and declared placement trigger do not
  establish a blanket serialization guarantee with concurrent tree edits.
invariants:
  - INV-DOM-MBR-STR-001-05
evidence:
  - >-
    services-membership at 5994c270: modules/structure/services/persistence/organizational-unit-types.ts
    (rowValues, updateOrganizationalUnitType, deactivateOrganizationalUnitType, deleteOrganizationalUnitType);
    services/tree/tree-edits.ts (validatePlacement).
---

# Unit kind availability

## The Lifecycle

```mermaid
stateDiagram-v2
  [*] --> active: default creation
  [*] --> inactive: created retired
  active --> inactive: activity disabled
  inactive --> active: replacement defaults or explicit activity
  active --> removed: no references
  inactive --> removed: no references
  removed --> [*]
```

## Transitions Explained

Creation defaults to active but can explicitly create an inactive kind. Retirement keeps current placements intact. Full replacement can reopen the kind, including accidentally when activity is omitted.

## What Cannot Happen

Deletion cannot bypass protected references. Replacement cannot remove a parent permission or root permission on which a current placement depends.

## Concurrency and Timing

Version checks protect competing kind changes, while placement operations use a separate tree lock. The examined code does not prove that every kind change and placement sees one serialized ordering.
