feat(event sourcing): Publish EventStored event after successful SaveEvent
Some checks failed
CI / build (pull_request) Successful in 21s
CI / integration (pull_request) Failing after 2m1s

Implement EventStored infrastructure event that notifies subscribers when an event
is successfully persisted. This enables observability and triggers downstream
workflows (caching, metrics, projections) without coupling to application events.

Changes:
- Add EventStored type to event.go containing EventID, ActorID, Version, Timestamp
- Update InMemoryEventStore with optional EventBus and metrics support via builder methods
- Update JetStreamEventStore with optional EventBus and metrics support via builder methods
- Publish EventStored to __internal__ namespace after successful SaveEvent
- EventStored not published if SaveEvent fails (e.g., version conflict)
- EventStored publishing is optional - stores work without EventBus configured
- Metrics are recorded for each EventStored publication
- Add comprehensive test suite covering all acceptance criteria

Meets acceptance criteria:
- EventStored published after SaveEvent succeeds
- EventStored contains EventID, ActorID, Version, Timestamp
- No EventStored published if SaveEvent fails
- EventBus receives EventStored in same operation
- Metrics increment for each EventStored published

Closes #61

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
Claude Code
2026-01-13 21:25:51 +01:00
parent bcbec9ab94
commit 0f89b07c0b
4 changed files with 488 additions and 0 deletions

View File

@@ -166,6 +166,17 @@ func (e *Event) WithMetadataFrom(source *Event) {
}
}
// EventStored is an internal infrastructure event published after an event is successfully persisted.
// It allows observability and trigger downstream workflows without coupling to application events.
// EventStored is not published to external systems (Phase 2) - only to local EventBus subscribers.
type EventStored struct {
EventID string `json:"eventId"` // ID of the event that was stored
ActorID string `json:"actorId"` // Actor that owns the stored event
Version int64 `json:"version"` // Version of the stored event
Timestamp time.Time `json:"timestamp"` // When the event was stored
}
// ActorSnapshot represents a point-in-time state snapshot
type ActorSnapshot struct {
ActorID string `json:"actorId"`