---
id: DOM-CRM-REG-001
title: Region
realises: CON-CRM-REG-001
product_area: crm
module: regions
revision: 2
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-crm: a8d1364f1dd44b723bb5f9acba12f983e9ec8d69
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
owned_by: SVC-CRM-REG-regions
readable_by:
  - SVC-CRM-ENT-entities
  - SVC-PFM-MTD-metadata
  - SVC-PFM-QRY-data-exports
  - SVC-PFM-DJE-crm-data-jobs
lifecycle: STATE-CRM-REG-001
custom_fields: none
identity: >-
  Each region has a permanent workspace-specific identifier. A caller may supply it, and the service generates
  one otherwise. Letters, digits, underscores, hyphens and vertical bars are accepted. Reusing that identifier
  in another workspace identifies a different region.
attributes:
  - name: identifier
    kind: text
    required: true
    computed: false
    notes: The reference key cannot be edited and must use the accepted regional character set.
  - name: name
    kind: text
    required: true
    computed: false
    notes: Saving trims the name and rejects a value containing no visible characters.
  - name: description
    kind: text
    required: false
    computed: false
    notes: Staff may supply explanatory text; replacement clears it when omitted.
  - name: active
    kind: enum
    required: true
    computed: false
    notes: Creation defaults to active. Retirement keeps the definition and its existing references.
  - name: lock
    kind: enum
    required: false
    computed: false
    notes: >-
      An optional delete lock blocks removal; a full lock blocks updates too. Creation, replacement and
      imports currently accept the lock value.
  - name: external identifier
    kind: text
    required: false
    computed: false
    notes: An optional integration key links this regional definition to a record in another system.
  - name: version
    kind: number
    required: true
    computed: true
    notes: 'Every accepted replacement or patch increments this value, even when business fields stay the same.'
  - name: creation and modification stamps
    kind: computed
    required: true
    computed: true
    notes: The record identifies its creator and last editor and records the corresponding times.
  - name: dependants
    kind: computed
    required: false
    computed: true
    notes: >-
      Deletion failures identify the referencing record category. No dependant list is stored in the regional
      record.
relationships:
  - to: DOM-CRM-REG-002
    cardinality: A region can be targeted by any number of assignment rules.
    ownership: 'The policy holds the target reference, which prevents deleting its region.'
    cross_service: false
  - to: DOM-CRM-REG-003
    cardinality: Any number of record placements can use one region.
    ownership: 'The record holds the placement reference, which prevents deleting its region.'
    cross_service: false
  - to: DOM-CRM-ENT-001
    cardinality: Each contact has at most one regional reference; a region can serve many contacts.
    ownership: Entities owns the contact reference; new values must satisfy the workspace reference constraint.
    cross_service: false
  - to: DOM-CRM-ENT-002
    cardinality: Each organization has at most one regional reference; a region can serve many organizations.
    ownership: Entities owns the organization reference; new values must satisfy the workspace reference constraint.
    cross_service: false
invariants:
  - id: INV-DOM-CRM-REG-001-01
    statement: 'Within a workspace, a regional identifier is unique and uses only the accepted legacy characters.'
    enforced_at:
      - api
      - service
      - database
    provenance: observed
    source: >-
      services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js#regions table
      (integration) › constraints › keys a region by tenant and id: the same id in two tenants;
      services-crm:modules/regions/db/regions.table.ts:REGION_ID_PATTERN
  - id: INV-DOM-CRM-REG-001-02
    statement: A regional name must contain at least one non-space character.
    enforced_at:
      - api
      - database
    provenance: test
    source: >-
      services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js#regions table
      (integration) › constraints › refuses a blank name
  - id: INV-DOM-CRM-REG-001-03
    statement: >-
      Deletion fails if a contact, organization or rule references the region, and the service reports the
      dependency category.
    enforced_at:
      - service
      - database
    provenance: observed
    source: >-
      services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js#regions table
      (integration) › references › refuses to delete a region an assignment rule names;
      services-crm:modules/regions/services/persistence/regions.ts:REGION_REFERENCES, regionRefusal
  - id: INV-DOM-CRM-REG-001-04
    statement: >-
      New references must resolve within the same workspace; older contact and organization references can
      remain unvalidated.
    enforced_at:
      - service
      - database
    provenance: observed
    source: >-
      services-crm:modules/regions/tests/integration/db/regions.table.integration.spec.js#regions table
      (integration) › references › refuses a contact naming a region its tenant does not have;
      services-crm:db/migrations/0019_regions.sql (contacts_region_fk and organizations_region_fk NOT VALID)
  - id: INV-DOM-CRM-REG-001-05
    statement: 'Full locks block region replacement and patching, and either lock kind blocks deletion.'
    enforced_at:
      - service
    provenance: observed
    source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegionRow, deleteRegionRow'
  - id: INV-DOM-CRM-REG-001-06
    statement: Replacement and patching must match the region’s current version.
    enforced_at:
      - api
      - service
    provenance: test
    source: >-
      services-crm:modules/regions/tests/e2e/regions.e2e.spec.js#the regions › answers 409 for a replace from
      a stale read
  - id: INV-DOM-CRM-REG-001-07
    statement: >-
      Retiring an enabled rule’s target increments the policy generation and stamps its change time in the
      regional save transaction.
    enforced_at:
      - service
    provenance: observed
    source: 'services-crm:modules/regions/services/persistence/regions.ts:updateRegion'
  - id: INV-DOM-CRM-REG-001-08
    statement: Regional requests accept no custom-field values.
    enforced_at:
      - api
    provenance: observed
    source: >-
      services-crm:docs/debt/region-custom-fields.md#Custom-field values of a region;
      services-crm:modules/regions/aws/api/regions.schemas.ts:regionRequestSchema;
      services-crm:modules/regions/metadata/regions.object.ts:regionsObject
physical:
  - crm.regions
evidence:
  - >-
    services-crm at a8d1364f: modules/regions/db/regions.table.ts; services/persistence/regions.ts;
    aws/api/regions.routes.ts (createRegion to deleteRegion, toWriteInput); aws/api/regions.schemas.ts;
    metadata/regions.object.ts; export/regions.dataset.ts, regions.reader.ts;
    tests/integration/db/regions.table.integration.spec.js; tests/e2e/regions.e2e.spec.js;
    docs/debt/region-custom-fields.md; docs/record-locks.md (Not covered yet).
  - 'react-console at baf6dae3: lib/configuration/regions.ts (createRegion, updateRegion, carriedThrough).'
---

# Region

## What It Models

A region gives staff a shared name for a chapter, territory or other grouping of people and organizations. Staff maintain these definitions in the regional catalogue. Geographic coverage belongs to the assignment policy; the definition supplies the target that records and rules reference.

## Identity and Attributes

The workspace and permanent identifier identify a definition. Its name is required, and its description is optional. An active flag marks availability, while an external identifier supports integration. Customer locks can block deletion or all ordinary editing. The version advances on accepted updates, including unchanged updates. Regions declare no custom-field capability.

## Relationships

Contacts, organizations and geographic rules hold references to the definition. The region does not own those records. References prevent deletion, and retirement preserves them. Older record references can survive the introduction of the regional constraints.

## Invariants

The structured invariants identify the enforcing boundaries. Locks and optimistic version checks belong to regional persistence; naming and reference checks also have database enforcement. Retiring a target used by an enabled rule records a policy change, although matching continues to accept that target.

## How It Is Stored and Shared

Regions owns the catalogue and supplies its record reads and writes. Metadata exposes the registered region as a reference target, exports include active and retired definitions, and imports call regional persistence. The workspace lifecycle participant removes regional data during reset or purge.

## Open Design Questions

Product must settle inactive-target matching, complete-payload replacement and audited lock actions. Ordinary regional edits retain only the last modification stamp, so history and recovery of earlier values remain unresolved.
