dynamic-consistency-boundary¶
Selector-based consistency unit whose scope is determined per Command. See Concepts: Dynamic Consistency Boundary.
Schema¶
properties:
scope:
type: object
properties:
domain:
type: string
pattern: "^[a-z][a-z0-9-]*$"
boundedContext:
type: string
pattern: "^[a-z][a-z0-9-]*$"
required: [domain, boundedContext]
additionalProperties: false
identifiedBy:
type: array
minItems: 1
items:
type: object
properties:
name:
type: string
pattern: "^[a-z][a-z0-9-]*$"
required: [name]
oneOf:
- properties:
source:
const: command-payload
field:
type: string
pattern: "^[a-z][a-z0-9-]*$"
required: [source, field]
- properties:
source:
const: static
value:
type: string
minLength: 1
required: [source, value]
- properties:
source:
const: generated
generator:
type: string
pattern: "^[a-z][a-z0-9-]*$"
required: [source, generator]
unevaluatedProperties: false
consults:
type: array
minItems: 1
items:
oneOf:
- type: object
properties:
boundedContext:
type: string
pattern: "^[a-z][a-z0-9-]*$"
aggregate:
type: string
pattern: "^[a-z][a-z0-9-]*$"
event:
type: string
pattern: "^[a-z][a-z0-9-]*$"
criteria:
type: string
required: [boundedContext, aggregate, event, criteria]
additionalProperties: false
- type: object
properties:
boundedContext:
type: string
pattern: "^[a-z][a-z0-9-]*$"
event:
type: string
pattern: "^[a-z][a-z0-9-]*$"
criteria:
type: string
required: [boundedContext, event, criteria]
additionalProperties: false
invariants:
type: array
items:
type: object
properties:
name:
type: string
pattern: "^[a-z][a-z0-9-]*$"
rule:
type: string
required: [name, rule]
additionalProperties: false
required: [scope, identifiedBy, consults]
Anatomy¶
A Dynamic Consistency Boundary scopes to a Bounded Context. The scope object carries domain and boundedContext, and no other fields are allowed. The DCB is the alternative to an Aggregate when the consistency unit cannot be expressed as a fixed container.
The identifiedBy array holds one or more identifier components. Each entry has a required name and a discriminated source. When source is command-payload, the entry pairs with field, naming a field on the triggering Command's data whose value provides the identifier component. When source is static, the entry pairs with value, a non-empty fixed string. When source is generated, the entry pairs with generator, the kebab-case name of a generation strategy such as uuid or ulid. The state source available on aggregate.identifiedBy is intentionally absent here – DCBs have no container-level state to draw from.
The consults array is the heart of a DCB. Each entry references an Event the DCB takes into account when forming its decision state, plus a prose criteria describing which occurrences are relevant. The Event reference is a discriminated oneOf: an Aggregate-bound entry carries boundedContext, aggregate, event, and criteria, while a free-standing entry omits aggregate. Both shapes require all four (or three) fields explicitly; partial entries are rejected.
The optional invariants array holds named rules over the consulted state. Each entry is { name, rule }, where the rule is prose and the name follows the kebab-case name pattern. The DCB itself carries no state object; its decision surface is the union of consulted Events filtered by the criteria.
description and metadata carry the usual free-form prose and non-semantic attachments. apiVersion is schema.esdm.io/core/v1, kind is dynamic-consistency-boundary, and name is the DCB's kebab-case identifier.