// runtime/subsystems/events/domain-events.schema.ts
import {
  check,
  index,
  jsonb,
  pgTable,
  text,
  timestamp,
  uuid
} from "drizzle-orm/pg-core";
import { sql } from "drizzle-orm";
var domainEvents = pgTable(
  "domain_events",
  {
    id: uuid("id").primaryKey(),
    type: text("type").notNull(),
    aggregateId: text("aggregate_id").notNull(),
    aggregateType: text("aggregate_type").notNull(),
    payload: jsonb("payload").notNull().$type(),
    occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull(),
    processedAt: timestamp("processed_at", { withTimezone: true }),
    /** Lifecycle status: pending | processed | failed */
    status: text("status").notNull().default("pending"),
    /** Error message from the last failed dispatch attempt. */
    error: text("error"),
    metadata: jsonb("metadata").$type(),
    /** Routing pool (e.g. `events_inbound`, `events_change`, `events_outbound`). Populated by DrizzleEventBus.publish() in EVT-4. NULL when `tier='audit'`. */
    pool: text("pool"),
    /** Routing direction: `inbound` | `change` | `outbound`. Populated by DrizzleEventBus.publish() in EVT-4. NULL when `tier='audit'`. */
    direction: text("direction"),
    /**
     * Event tier: `'domain'` (default) or `'audit'`. Audit-tier rows are
     * observability-only and have null `pool`/`direction` by construction —
     * enforced by the `domain_events_tier_routing_check` CHECK constraint
     * declared below. (AUDIT-1)
     */
    tier: text("tier").notNull().default("domain"),
    // conditional: emitted only when events.multi_tenant: true
    tenantId: text("tenant_id")
  },
  (t) => ({
    /** Polling drain filter (existing — promoted from comment to declaration in EVT-1). */
    idxDomainEventsStatusOccurredAt: index("idx_domain_events_status_occurred_at").on(
      t.status,
      t.occurredAt
    ),
    /** Event replay per aggregate (existing — promoted from comment to declaration in EVT-1). */
    idxDomainEventsAggregate: index("idx_domain_events_aggregate").on(
      t.aggregateId,
      t.aggregateType
    ),
    /** Per-pool drain filter (EVT-1). Enables DrizzleEventBus to drain a single pool without scanning all events. */
    idxDomainEventsPoolStatusOccurredAt: index(
      "idx_domain_events_pool_status_occurred_at"
    ).on(t.pool, t.status, t.occurredAt),
    /** Per-tier filter (AUDIT-1). Backs the observability viewer's tier toggle. */
    idxDomainEventsTierStatusOccurredAt: index(
      "idx_domain_events_tier_status_occurred_at"
    ).on(t.tier, t.status, t.occurredAt),
    /**
     * Tier ↔ routing-fields invariant (AUDIT-1):
     *   - `tier` is one of `'domain' | 'audit'`.
     *   - `tier='audit'` ⇔ `pool IS NULL AND direction IS NULL`.
     *   - `tier='domain'` ⇒ `pool` and `direction` are populated (the
     *     DrizzleEventBus inserts always supply them; the bus stamps them
     *     in AUDIT-3).
     */
    tierRoutingCheck: check(
      "domain_events_tier_routing_check",
      sql`${t.tier} in ('domain','audit') AND ((${t.tier} = 'audit') = (${t.pool} is null and ${t.direction} is null))`
    )
  })
);

export {
  domainEvents
};
//# sourceMappingURL=chunk-OFRRBC7M.js.map