import { IDomainEvent } from "./domain-event.js"; /** * Possible statuses for an outbox entry. * * - `pending`: The event has been persisted but not yet published. * - `published`: The event has been successfully published to the message broker. * - `failed`: The event failed to publish after the maximum number of retries. */ export type OutboxStatus = "pending" | "published" | "failed"; /** * The data shape of a single outbox entry returned by {@link IOutboxStore.fetchPending}. * This is the flat wire format — no class logic, just data. */ export interface OutboxEntryData { /** The event's own `eventId`, used as the primary key of the outbox table. */ id: string; /** The event class name (e.g. `"OrderPlaced"`). */ eventName: string; /** The event payload (the `P` generic from `DomainEvent
`). */
payload: unknown;
/** When the domain event was originally created. */
occurredOn: Date;
/** Current publish status. */
status: OutboxStatus;
/** Number of publish attempts so far. */
retries: number;
/** Error message from the most recent failed publish attempt, if any. */
lastError: string | null;
/** When this outbox row was inserted. */
createdAt: Date;
}
/**
* Result returned by {@link IOutboxStore.fetchPending}.
*/
export interface OutboxFetchResult {
entries: OutboxEntryData[];
}
/**
* Minimal, framework-agnostic contract for an outbox persistence store.
*
* Implementations exist for Prisma, Drizzle, TypeORM, and raw SQL.
* The interface lives in `@woltz/rich-domain` (core) so that the
* `@woltz/rich-domain-outbox` package can depend on it without
* coupling to any specific ORM or database.
*/
export interface IOutboxStore {
/**
* Persist one or more domain events to the outbox table.
*
* MUST be called within the same database transaction as the aggregate write
* so that both succeed or both roll back together.
*
* Each event's `eventId` becomes the primary key (`id`) of the outbox row.
* The `status` column is always set to `"pending"` initially.
*
* @param events - The domain events to persist.
* @param tx - Optional ORM-specific transaction context (e.g. a Prisma interactive tx client, a Drizzle tx, or a TypeORM EntityManager).
*/
save(events: IDomainEvent[], tx?: unknown): Promise