spb/cancerindex
Public
TypeScript 97.2%
SQL 1.5%
CSS 0.6%
JavaScript 0.5%
1import { pgTable, text, integer, bigserial, jsonb, timestamp, index } from 'drizzle-orm/pg-core';23/**4 * Internal operational alerts (CLAUDE.md §170): connector failure, stale source, anomaly, schema5 * drift… One row per (kind, connector, message) while the alert is open or acknowledged; repeated6 * occurrences bump `count` and `last_seen_at` instead of creating new rows (see `raiseAlert`).7 * Resolved rows are kept for history (`resolveAlerts` on the next success).8 */9export const systemAlerts = pgTable(10 'system_alerts',11 {12 id: bigserial('id', { mode: 'number' }).primaryKey(),13 kind: text('kind').notNull(), // connector_failure | connector_aborted | anomaly | schema_drift | source_failing | source_stale | ranking_anomaly | license_review_due …14 severity: text('severity').notNull().default('warn'), // info | warn | critical15 connectorId: text('connector_id'),16 message: text('message').notNull(),17 detail: jsonb('detail').$type<Record<string, unknown>>().notNull().default({}),18 firstSeenAt: timestamp('first_seen_at', { withTimezone: true }).notNull().defaultNow(),19 lastSeenAt: timestamp('last_seen_at', { withTimezone: true }).notNull().defaultNow(),20 count: integer('count').notNull().default(1),21 status: text('status').notNull().default('open'), // open | acknowledged | resolved22 resolvedAt: timestamp('resolved_at', { withTimezone: true }),23 },24 (t) => [index('system_alerts_status_idx').on(t.status, t.kind, t.connectorId), index('system_alerts_seen_idx').on(t.lastSeenAt)],25);26