Initial Commit

This commit is contained in:
2026-05-27 23:29:53 +01:00
commit fbc70f96e6
10000 changed files with 1102152 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
# 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
```ts
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
```ts
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.