Openstatus
www.openstatus.dev
1import { relations, sql } from "drizzle-orm";
2import {
3 integer,
4 primaryKey,
5 sqliteTable,
6 text,
7} from "drizzle-orm/sqlite-core";
8
9import { monitor } from "../monitors";
10import { statusReportsToPageComponents } from "../page_components";
11import { page } from "../pages";
12import { workspace } from "../workspaces";
13
14export const statusReportStatus = [
15 "investigating",
16 "identified",
17 "monitoring",
18 "resolved",
19] as const;
20
21export const statusReport = sqliteTable("status_report", {
22 id: integer("id").primaryKey(),
23 status: text("status", { enum: statusReportStatus }).notNull(),
24 title: text("title", { length: 256 }).notNull(),
25
26 workspaceId: integer("workspace_id").references(() => workspace.id),
27
28 pageId: integer("page_id").references(() => page.id, { onDelete: "cascade" }),
29
30 createdAt: integer("created_at", { mode: "timestamp" }).default(
31 sql`(strftime('%s', 'now'))`,
32 ),
33 updatedAt: integer("updated_at", { mode: "timestamp" }).default(
34 sql`(strftime('%s', 'now'))`,
35 ),
36});
37
38export const statusReportUpdate = sqliteTable("status_report_update", {
39 id: integer("id").primaryKey(),
40
41 status: text("status", { enum: statusReportStatus }).notNull(),
42 date: integer("date", { mode: "timestamp" }).notNull(),
43 message: text("message").notNull(),
44
45 statusReportId: integer("status_report_id")
46 .references(() => statusReport.id, { onDelete: "cascade" })
47 .notNull(),
48 createdAt: integer("created_at", { mode: "timestamp" }).default(
49 sql`(strftime('%s', 'now'))`,
50 ),
51 updatedAt: integer("updated_at", { mode: "timestamp" }).default(
52 sql`(strftime('%s', 'now'))`,
53 ),
54});
55
56export const StatusReportRelations = relations(
57 statusReport,
58 ({ one, many }) => ({
59 // Legacy relation - will be deprecated after migration is complete
60 monitorsToStatusReports: many(monitorsToStatusReport),
61 // New relation using pageComponents architecture
62 statusReportsToPageComponents: many(statusReportsToPageComponents),
63 page: one(page, {
64 fields: [statusReport.pageId],
65 references: [page.id],
66 }),
67 statusReportUpdates: many(statusReportUpdate),
68 workspace: one(workspace, {
69 fields: [statusReport.workspaceId],
70 references: [workspace.id],
71 }),
72 }),
73);
74
75export const statusReportUpdateRelations = relations(
76 statusReportUpdate,
77 ({ one }) => ({
78 statusReport: one(statusReport, {
79 fields: [statusReportUpdate.statusReportId],
80 references: [statusReport.id],
81 }),
82 }),
83);
84
85export const monitorsToStatusReport = sqliteTable(
86 "status_report_to_monitors",
87 {
88 monitorId: integer("monitor_id")
89 .notNull()
90 .references(() => monitor.id, { onDelete: "cascade" }),
91 statusReportId: integer("status_report_id")
92 .notNull()
93 .references(() => statusReport.id, { onDelete: "cascade" }),
94 createdAt: integer("created_at", { mode: "timestamp" }).default(
95 sql`(strftime('%s', 'now'))`,
96 ),
97 },
98 (t) => ({
99 pk: primaryKey({ columns: [t.monitorId, t.statusReportId] }),
100 }),
101);
102
103export const monitorsToStatusReportRelations = relations(
104 monitorsToStatusReport,
105 ({ one }) => ({
106 monitor: one(monitor, {
107 fields: [monitorsToStatusReport.monitorId],
108 references: [monitor.id],
109 }),
110 statusReport: one(statusReport, {
111 fields: [monitorsToStatusReport.statusReportId],
112 references: [statusReport.id],
113 }),
114 }),
115);
116
117// FIXME: We might have to drop foreign key constraints for the following tables
118// export const pagesToStatusReports = sqliteTable(
119// "status_reports_to_pages",
120// {
121// pageId: integer("page_id")
122// .notNull()
123// .references(() => page.id, { onDelete: "cascade" }),
124// statusReportId: integer("status_report_id")
125// .notNull()
126// .references(() => statusReport.id, { onDelete: "cascade" }),
127// createdAt: integer("created_at", { mode: "timestamp" }).default(
128// sql`(strftime('%s', 'now'))`
129// ),
130// },
131// (t) => ({
132// pk: primaryKey(t.pageId, t.statusReportId),
133// })
134// );
135
136// export const pagesToStatusReportsRelations = relations(
137// pagesToStatusReports,
138// ({ one }) => ({
139// page: one(page, {
140// fields: [pagesToStatusReports.pageId],
141// references: [page.id],
142// }),
143// statusReport: one(statusReport, {
144// fields: [pagesToStatusReports.statusReportId],
145// references: [statusReport.id],
146// }),
147// })
148// );