Files
suaveplan/packages/api-stack/api/api-schemas/src/events/domain-event.md
2026-05-27 23:29:53 +01:00

3.4 KiB

domain-event

Purpose

Defines the DomainEvent Zod schema — the canonical wire format for immutable domain events flowing through the Suaveplan event-sourcing and event-driven integration infrastructure. Domain events record facts about things that happened within a bounded context: "UserRegistered", "OrderPlaced", "PaymentFailed". This schema provides the structural envelope; the domain-specific payload schema is defined and validated by each aggregate separately.

Features

  • DomainEvent schema — {id, type, aggregateId, aggregateType, payload, occurredAt} fully typed
  • type as a dot-separated event-type name (e.g. "user.registered") — convention over constraint
  • aggregateId + aggregateType together identify which aggregate instance raised the event
  • payload typed as z.unknown() — the envelope is payload-agnostic; aggregate event types carry their own Zod schema
  • occurredAt as an ISO 8601 string with timezone offset — the moment in domain time when the event occurred
  • Full TypeScript inference via z.infer<> — no manual interface duplication
  • Zod v4 compatible

Usage: Basic Example

import { DomainEvent } from "@suaveplan/api-schemas/events";

const event = DomainEvent.parse({
  id: "evt_01J8ZGCZ7ECTFAKEUID123456",
  type: "user.registered",
  aggregateId: "user_abc123",
  aggregateType: "User",
  payload: { email: "alice@example.com", name: "Alice" },
  occurredAt: "2024-06-01T12:00:00Z",
});

Usage: Advanced Example

import { DomainEvent } from "@suaveplan/api-schemas/events";
import z from "zod";

// Narrow the payload for a specific event type
const UserRegisteredPayload = z.object({
  email: z.string().email(),
  name: z.string(),
});

function handleUserRegistered(raw: unknown) {
  const event = DomainEvent.parse(raw);
  if (event.type !== "user.registered") return;
  const payload = UserRegisteredPayload.parse(event.payload);
  console.log(`New user: ${payload.name} (${payload.email})`);
}

API Reference

DomainEvent

Zod object schema — immutable domain event record.

Field Type Description
id string (min 1) Unique event identifier
type string (min 1) Event type name (e.g. "user.registered")
aggregateId string (min 1) Identifier of the source aggregate
aggregateType string (min 1) Type name of the source aggregate
payload unknown Domain-specific event data
occurredAt string (ISO 8601 with offset) Domain time when the event occurred

Type export: type DomainEvent = z.infer<typeof DomainEvent>

Implementation Notes

payload is z.unknown() intentionally — the base schema validates the event envelope, not the payload contents. Each aggregate type defines its own Zod schema for each of its event types; payload validation is performed after routing by event type. This pattern keeps the event bus loosely coupled and avoids a centralised schema registry for domain events, which would become a bottleneck in a large bounded-context landscape.