// Schema for the {{projectName}} status page. // // These tables are PUBLIC and NOT tenant-scoped on purpose: a status page is // read by anyone, so the live queries must return rows for an anonymous caller. // (Adding `tenant()` here would AND-merge `tenantId = subject.tenantId` and an // anonymous visitor — tenantId null — would see nothing.) Write access is // controlled by the rbac `status:write` guard on the mutations instead. // // `actors` + `tenants` are the framework core tables. import { databaseHandle, id, table, text, timestamp, type InferRow, } from '@voltro/database' export const actors = table('actors', { id: id(), kind: text().oneOf(['user', 'serviceAccount', 'apiKey', 'system']), displayName: text().nullable(), createdAt: timestamp().default('now'), }) export const tenants = table('tenants', { id: id(), name: text(), createdAt: timestamp().default('now'), }) // A monitored service component (API, Dashboard, Webhooks, …). export const components = table('components', { id: id({ prefix: 'cmp' }), name: text(), status: text().oneOf(['operational', 'degraded', 'partial_outage', 'major_outage']), }) // An incident. `impact` drives the public banner colour; `status` walks the // lifecycle investigating → identified → monitoring → resolved. export const incidents = table('incidents', { id: id({ prefix: 'inc' }), title: text(), impact: text().oneOf(['minor', 'major', 'critical']), status: text().oneOf(['investigating', 'identified', 'monitoring', 'resolved']), startedAt: timestamp().default('now'), resolvedAt: timestamp().nullable(), }) // A timeline entry posted against an incident. The public page renders these in // order under each incident. export const incidentUpdates = table('incident_updates', { id: id({ prefix: 'iu' }), incidentId: text(), body: text(), status: text().oneOf(['investigating', 'identified', 'monitoring', 'resolved']), createdAt: timestamp().default('now'), }) export type Component = InferRow export type Incident = InferRow export type IncidentUpdate = InferRow export const database = databaseHandle({ actors, tenants, components, incidents, incidentUpdates, })