import { pgTable, text, integer, bigserial, jsonb, timestamp, index } from 'drizzle-orm/pg-core'; /** * Internal operational alerts (CLAUDE.md §170): connector failure, stale source, anomaly, schema * drift… One row per (kind, connector, message) while the alert is open or acknowledged; repeated * occurrences bump `count` and `last_seen_at` instead of creating new rows (see `raiseAlert`). * Resolved rows are kept for history (`resolveAlerts` on the next success). */ export const systemAlerts = pgTable( 'system_alerts', { id: bigserial('id', { mode: 'number' }).primaryKey(), kind: text('kind').notNull(), // connector_failure | connector_aborted | anomaly | schema_drift | source_failing | source_stale | ranking_anomaly | license_review_due … severity: text('severity').notNull().default('warn'), // info | warn | critical connectorId: text('connector_id'), message: text('message').notNull(), detail: jsonb('detail').$type>().notNull().default({}), firstSeenAt: timestamp('first_seen_at', { withTimezone: true }).notNull().defaultNow(), lastSeenAt: timestamp('last_seen_at', { withTimezone: true }).notNull().defaultNow(), count: integer('count').notNull().default(1), status: text('status').notNull().default('open'), // open | acknowledged | resolved resolvedAt: timestamp('resolved_at', { withTimezone: true }), }, (t) => [index('system_alerts_status_idx').on(t.status, t.kind, t.connectorId), index('system_alerts_seen_idx').on(t.lastSeenAt)], );