---
id: WF-PFM-MTD-003
title: Save a field definition and its rules
trigger: The editor saves a field definition before its complete rules.
product_area: platform
module: metadata
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
inference: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
implements:
- CAP-PFM-MTD-005
- CAP-PFM-MTD-006
moves:
- STATE-PFM-MTD-002
crosses:
- SVC-PFM-MTD-metadata
- SVC-PFM-MTD-custom-objects
idempotency: Field creation rejects a reused key. Complete rule replacement can be repeated without adding kinds;
  versioned arrangement writes can become stale after an earlier success.
concurrency: Field creation rejects a reused key. Complete rule replacement can be repeated without adding kinds;
  versioned arrangement writes can become stale after an earlier success.
hops:
- n: 1
  actor_or_service: Console field editor
  action: The field editor creates a definition or replaces it at the version read, including presentation and configuration
    settings.
  anchor: react-console:lib/configuration/fields/live-adapter.ts
  seam: sync
  on_failure: Stop on definition refusal and show the editor’s validation or conflict message.
  left_inconsistent: No successful definition change precedes a refusal in this hop.
  observer: The initiating person or service and its operation logs.
  provenance: observed
  source: services-platform:modules/metadata/services/persistence/custom-fields.ts:createCustomField
- n: 2
  actor_or_service: Console field editor
  action: The client replaces the complete rules only when they differ from the loaded set.
  anchor: react-console:lib/configuration/fields/live-adapter.ts:saveRules
  seam: sync
  on_failure: Report that the field saved but its rules did not; do not undo the definition.
  left_inconsistent: The field has its new definition with earlier rules, or no rules after creation.
  observer: The initiating person or service and its operation logs.
  provenance: observed
  source: react-console:lib/configuration/fields/field-rules.ts:FieldRulesNotSavedError
- n: 3
  actor_or_service: Metadata rules replacement
  action: Metadata validates conditions, defaults, exposure and rule kinds, then atomically replaces the set and
    advances query description.
  anchor: services-platform:modules/metadata/services/persistence/custom-fields.ts:setFieldRules
  seam: sync
  on_failure: Roll back the rule change on invalid input.
  left_inconsistent: Any preceding definition save remains committed.
  observer: The initiating person or service and its operation logs.
  provenance: test
  source: services-platform:modules/metadata/tests/integration/services/persistence/custom-fields.rules.integration.spec.js#removes
    the kinds a replacement leaves out
- n: 4
  actor_or_service: Custom record store (registered check)
  action: When uniqueness is enabled, the record store rebuilds value reservations inside the rules transaction
    and counts duplicate values.
  anchor: services-platform:modules/custom-objects/services/persistence/custom-object-records.ts:rebuildUniqueValues
  seam: sync
  on_failure: Refuse enabling uniqueness until duplicates are resolved, preserving existing rules.
  left_inconsistent: The uniqueness change and reservation rebuild cannot partially commit.
  observer: The initiating person or service and its operation logs.
  provenance: test
  source: services-platform:modules/custom-objects/tests/integration/services/persistence/custom-object-records.integration.spec.js#refuses
    a unique rule on a property tw
- n: 5
  actor_or_service: Console field table
  action: Arrangement saves each changed property’s place or group sequentially at its freshly read version.
  anchor: react-console:lib/configuration/fields/live-adapter.ts:arrangeFields
  seam: sync
  on_failure: Stop the sequence at the first rejected replacement and display the error.
  left_inconsistent: Earlier property positions remain saved; later ones retain preceding values.
  observer: The initiating person or service and its operation logs.
  provenance: observed
  source: react-console:lib/configuration/fields/live-adapter.ts:arrangeFields
branches:
- The current rules editor is limited to custom-object properties; native field screens edit definitions only.
waits: []
evidence:
- 'react-console at baf6dae3: lib/configuration/fields/live-adapter.ts (saveRules, arrangeFields), field-rules.ts;
  components/configuration/fields/field-editor.tsx, field-table-screen.tsx'
- 'services-platform at ad3f6a65: modules/metadata/services/persistence/custom-fields.ts (createCustomField, updateCustomField,
  setFieldRules, registerUniqueRuleCheck); modules/custom-objects/services/persistence/custom-object-records.ts:rebuildUniqueValues'
controls: [TC-AVL-001, TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-DAT-001, TC-DAT-003, TC-DAT-004, TC-IAM-001, TC-IAM-002, TC-IAM-004, TC-IAM-005, TC-LOG-004, TC-LOG-005, TC-PI-001, TC-PI-002, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-TEN-004, TC-VEN-001, TC-VEN-002, TC-VEN-003]
---

# Save a field definition and its rules

## What It Does

The editor saves a field definition before its complete rules. Reordering properties likewise uses a sequence of independent replacements.

## The Flow

```mermaid
sequenceDiagram
  participant Admin as Administrator
  participant UI as Field editor
  participant Meta as Metadata
  participant Store as Custom record store
  Admin->>UI: save
  UI->>Meta: create or replace field (version)
  Meta-->>UI: saved field
  opt rules changed
    UI->>Meta: replace rule set
    Meta->>Store: rebuild unique reservations (unique rule only)
    Store-->>Meta: ok or duplicate count
    Meta-->>UI: rules or refusal
  end
  UI-->>Admin: saved, or "field saved, rules not"
```

## When Something Fails

Report that the field saved but its rules did not; do not undo the definition. The field has its new definition with earlier rules, or no rules after creation. Roll back the rule change on invalid input. Any preceding definition save remains committed. Refuse enabling uniqueness until duplicates are resolved, preserving existing rules. The uniqueness change and reservation rebuild cannot partially commit. Stop the sequence at the first rejected replacement and display the error. Earlier property positions remain saved; later ones retain preceding values.

## Open Design Questions

Andrew should decide whether field definitions and rules need one composite operation.
