Skip to content

Events

Snaapi automatically emits events whenever records are created, updated, or deleted. Events follow a Hasura-style data structure that captures the full before/after state of each change, along with session and trace context for auditing and distributed tracing.

Event Types

Events follow the resourceName.action naming convention:

Event Type Description
resource.created A new record was created
resource.updated An existing record was modified
resource.deleted A record was deleted (soft or hard)

For example, a resource named posts would emit posts.created, posts.updated, and posts.deleted events.

Event Data Structure

Each event record contains the following fields:

Field Type Description
id string Internal record ID
eventId string Unique event ID (UUID)
eventType string Event type (e.g., posts.created)
resourceName string Name of the resource (e.g., posts)
resourceId string ID of the affected resource record
createdAt string ISO 8601 timestamp of when the event occurred
dispatchedAt string | null Timestamp when dispatched to job executions
data EventData Hasura-style old/new/changes object
sessionVariables SessionVariables | null Request context (user, role, IP)
traceContext TraceContext | null Distributed tracing identifiers

Hasura-Style Data Object

The data field captures the full state change:

{
  "old": null,
  "new": { "id": "abc-123", "title": "Hello World" },
  "changes": {
    "added": ["id", "title", "created_at"],
    "updated": [],
    "removed": []
  }
}
Field Type Description
old object | null Previous state of the record (null for created)
new object | null Current state of the record (null for deleted)
changes EventChanges Arrays describing which fields changed

Changes Object

Field Type Description
added string[] Fields that were added
updated string[] Fields that were modified
removed string[] Fields that were removed

For created events, all fields appear in added. For deleted events, all fields appear in removed. For updated events, only modified fields appear in updated.

Session Variables

Session variables capture the request context at the time the event was emitted:

Field Type Description
userId string ID of the authenticated user
role string Role of the authenticated user
ip string Client IP address
userAgent string Client User-Agent header

Additional custom properties may also be present.

Trace Context

Trace context enables correlation with distributed tracing systems like OpenTelemetry:

Field Type Description
traceId string OpenTelemetry trace ID
spanId string OpenTelemetry span ID
parentSpanId string Parent span ID (if applicable)
requestId string Unique ID for the originating HTTP request
correlationId string Correlation ID for grouping related events

Additional custom properties may also be present.

EventEmitter Methods

The EventEmitter class provides methods for emitting and querying events:

Method Description
emit() Emit a custom event
emitCreated() Emit a created event (old: null, auto-populates changes.added)
emitUpdated() Emit an updated event (compares old/new, populates changes.updated)
emitDeleted() Emit a deleted event (new: null, auto-populates changes.removed)
query() Query events with filters (resourceName, resourceId, eventType, undispatched, limit)
findByEventId() Find a single event by its eventId
markDispatched() Mark an event as dispatched to job executions

Event Dispatch Flow

  1. Event emitted via EventEmitter.emit*()
  2. Stored in the _events table
  3. Broadcast to active SSE connections via EventBroadcaster
  4. Job registry processes event and creates JobExecution records for matching jobs
  5. Event marked as dispatched (dispatchedAt timestamp set)
  6. Job processors execute (e.g., webhook delivery)