Skip to content

add optional dcb tags to schema#1

Open
GaryACraine wants to merge 1 commit into
dilgerma:mainfrom
GaryACraine:main
Open

add optional dcb tags to schema#1
GaryACraine wants to merge 1 commit into
dilgerma:mainfrom
GaryACraine:main

Conversation

@GaryACraine
Copy link
Copy Markdown

feat(schema): add optional consistencyTags to Element for DCB support
Body:

Motivation

Dynamic Consistency Boundary (DCB) is an event sourcing pattern that replaces
the single-aggregate-ID model with multi-dimensional tag-based consistency
scoping. Rather than routing commands to a single aggregate root, a DCB command
handler declares which tag combinations it requires consistency over, and the
event store guarantees no conflicting events exist for those tags since the
handler last read.

Axon Framework 5 implements this via @EventTag annotations on event record
fields (see AxonIQ/university-demo).
For example:

public record StudentSubscribedToCourse(
    @EventTag(key = "facultyId") FacultyId facultyId,
    @EventTag(key = "studentId") StudentId studentId,
    @EventTag(key = "courseId")  CourseId courseId
) {}
The event modeling spec had no way to capture this metadata. This change adds
that capability while preserving full backward compatibility with existing
aggregate-based models.

Changes
Two surgical additions to eventmodeling.schema.json:

New $defConsistencyTag:


"ConsistencyTag": {
  "type": "object",
  "properties": {
    "key":         { "type": "string" },
    "sourceField": { "type": "string" }
  },
  "required": ["key", "sourceField"],
  "additionalProperties": false
}
New optional property on ElementconsistencyTags:


"consistencyTags": {
  "type": "array",
  "items": { "$ref": "#/$defs/ConsistencyTag" }
}
Usage (DCB event)

{
  "id": "student-subscribed-to-course",
  "title": "Student Subscribed To Course",
  "type": "EVENT",
  "consistencyTags": [
    { "key": "facultyId", "sourceField": "facultyId" },
    { "key": "studentId", "sourceField": "studentId" },
    { "key": "courseId",  "sourceField": "courseId"  }
  ],
  "fields": [
    { "name": "facultyId", "type": "UUID" },
    { "name": "studentId", "type": "UUID" },
    { "name": "courseId",  "type": "UUID" }
  ],
  "dependencies": []
}
sourceField references Field.name within the same element's fields array,
mirroring the @EventTag annotation's relationship to its decorated field.

Backward compatibility
consistencyTags is optional and absent from requiredexisting aggregate-based models validate without change.
The existing tags: string[] property (used for UI labels) is untouched.
No existing properties are modified or removed.
additionalProperties: false is preserved throughout.
Design decisions
Why consistencyTags and not tags?

Element already has tags: string[] for UI categorisation. Overloading the
same name with a different shape would silently break validation for all
existing models.

Why on Element rather than a dedicated event type?

Introducing a separate schema type for DCB events would require a discriminated
union and oneOf/if-then branchingsignificant disruption. Placing the
optional field on Element is the least invasive option; convention and tooling
can restrict it to type: "EVENT" elements.

Why are both key and sourceField required within ConsistencyTag?

A tag without a sourceField has no runtime value source and would be
meaningless to code generators and validators. Both fields are necessary for
the tag to be actionable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant