@maudecode/kanvil 0.0.0-stage → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -2
  3. package/apps/server/.env.example +41 -0
  4. package/apps/server/dist/auth-BscXb1NQ.mjs +2666 -0
  5. package/apps/server/dist/config-Qxr_7oqZ.mjs +575 -0
  6. package/apps/server/dist/configure.mjs +23 -0
  7. package/apps/server/dist/index.mjs +1754 -0
  8. package/apps/server/dist/migrate-C9f4ozB4.mjs +17 -0
  9. package/apps/server/dist/migrate.mjs +12 -0
  10. package/apps/server/dist/recover.mjs +52 -0
  11. package/apps/server/drizzle/0000_foundation.sql +437 -0
  12. package/apps/server/drizzle/0001_claim_identity.sql +1 -0
  13. package/apps/server/drizzle/0002_transactional_attachments.sql +6 -0
  14. package/apps/server/drizzle/0003_durable_claim_fence.sql +4 -0
  15. package/apps/server/drizzle/0004_lumpy_archangel.sql +6 -0
  16. package/apps/server/drizzle/0005_unique_toxin.sql +28 -0
  17. package/apps/server/drizzle/0006_instance_services.sql +48 -0
  18. package/apps/server/drizzle/0007_optional_broker.sql +6 -0
  19. package/apps/server/drizzle/0008_workspaces.sql +37 -0
  20. package/apps/server/drizzle/0009_project_icons.sql +6 -0
  21. package/apps/server/drizzle/0010_project_labels.sql +14 -0
  22. package/apps/server/drizzle/0011_due_dates.sql +1 -0
  23. package/apps/server/drizzle/0012_label_colors.sql +7 -0
  24. package/apps/server/drizzle/meta/0000_snapshot.json +3210 -0
  25. package/apps/server/drizzle/meta/0001_snapshot.json +3216 -0
  26. package/apps/server/drizzle/meta/0002_snapshot.json +3255 -0
  27. package/apps/server/drizzle/meta/0003_snapshot.json +3262 -0
  28. package/apps/server/drizzle/meta/0004_snapshot.json +3302 -0
  29. package/apps/server/drizzle/meta/0005_snapshot.json +3518 -0
  30. package/apps/server/drizzle/meta/0006_snapshot.json +3842 -0
  31. package/apps/server/drizzle/meta/0007_snapshot.json +3874 -0
  32. package/apps/server/drizzle/meta/0008_snapshot.json +4051 -0
  33. package/apps/server/drizzle/meta/0009_snapshot.json +4105 -0
  34. package/apps/server/drizzle/meta/0010_snapshot.json +4174 -0
  35. package/apps/server/drizzle/meta/0011_snapshot.json +4180 -0
  36. package/apps/server/drizzle/meta/0012_snapshot.json +4226 -0
  37. package/apps/server/drizzle/meta/_journal.json +97 -0
  38. package/apps/web/dist/apple-touch-icon.png +0 -0
  39. package/apps/web/dist/assets/CompositeItem-D9KvUNiq.js +1 -0
  40. package/apps/web/dist/assets/admin-settings-B0u2-aAK.js +1 -0
  41. package/apps/web/dist/assets/camera-Cv5wKkKn.js +1 -0
  42. package/apps/web/dist/assets/date-picker-lhXxKIlN.js +1 -0
  43. package/apps/web/dist/assets/ellipsis-CN74O_EP.js +1 -0
  44. package/apps/web/dist/assets/forms-456UbfIC.js +92 -0
  45. package/apps/web/dist/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  46. package/apps/web/dist/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  47. package/apps/web/dist/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  48. package/apps/web/dist/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  49. package/apps/web/dist/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  50. package/apps/web/dist/assets/index-CVzq9BMC.css +2 -0
  51. package/apps/web/dist/assets/index-Dt8wYIVA.js +51 -0
  52. package/apps/web/dist/assets/instance-BCNvOvYa.js +1 -0
  53. package/apps/web/dist/assets/list-order-1UoOT5nR.js +1 -0
  54. package/apps/web/dist/assets/lucide-U995NW8E.js +1 -0
  55. package/apps/web/dist/assets/member-directory-C81ugis6.js +1 -0
  56. package/apps/web/dist/assets/popover-BWk65ByY.js +1 -0
  57. package/apps/web/dist/assets/project-settings-DnpVfVf5.js +1 -0
  58. package/apps/web/dist/assets/rotate-ccw-BLeWpuu1.js +1 -0
  59. package/apps/web/dist/assets/settings-DUXuOgWn.js +1 -0
  60. package/apps/web/dist/assets/settings-layout-xR4hrfte.js +1 -0
  61. package/apps/web/dist/assets/table-BQbZG4BK.js +1 -0
  62. package/apps/web/dist/assets/ticket-detail-B9M_eaVu.js +2 -0
  63. package/apps/web/dist/assets/ticket-editor-Chg1lDuU.js +1 -0
  64. package/apps/web/dist/assets/ticket-list-C8500tXj.js +5 -0
  65. package/apps/web/dist/assets/ticket-tags-cbwQ93Gt.js +1 -0
  66. package/apps/web/dist/assets/upload-5Wg5ou_Z.js +1 -0
  67. package/apps/web/dist/assets/workspace-settings-Dte44Kkx.js +1 -0
  68. package/apps/web/dist/brand/icon-192.png +0 -0
  69. package/apps/web/dist/brand/icon-512.png +0 -0
  70. package/apps/web/dist/brand/mark-blue.svg +1 -0
  71. package/apps/web/dist/brand/mark-white.svg +1 -0
  72. package/apps/web/dist/brand/mark.svg +1 -0
  73. package/apps/web/dist/brand/maskable-512.png +0 -0
  74. package/apps/web/dist/brand/social.png +0 -0
  75. package/apps/web/dist/favicon.ico +0 -0
  76. package/apps/web/dist/favicon.svg +1 -0
  77. package/apps/web/dist/fonts/OFL.txt +93 -0
  78. package/apps/web/dist/fonts/ibm-plex-sans-latin.woff2 +0 -0
  79. package/apps/web/dist/icon.svg +1 -0
  80. package/apps/web/dist/index.html +31 -0
  81. package/apps/web/dist/site.webmanifest +29 -0
  82. package/apps/web/dist/third-party-icons.txt +64 -0
  83. package/apps/web/dist/third-party-themes.txt +548 -0
  84. package/bin/kanvil.mjs +27 -0
  85. package/compose.yml +66 -0
  86. package/docs/api.md +87 -0
  87. package/docs/branding.md +13 -0
  88. package/docs/design.md +37 -0
  89. package/docs/infrastructure.md +94 -0
  90. package/docs/mobile.md +77 -0
  91. package/docs/plan.md +111 -0
  92. package/docs/releasing.md +18 -0
  93. package/docs/self-hosting.md +204 -0
  94. package/docs/themes.md +38 -0
  95. package/docs/verification.md +83 -0
  96. package/docs/workspaces.md +21 -0
  97. package/package.json +45 -4
@@ -0,0 +1,17 @@
1
+ import { drizzle } from "drizzle-orm/node-postgres";
2
+ import { migrate } from "drizzle-orm/node-postgres/migrator";
3
+ import { fileURLToPath } from "node:url";
4
+ //#region src/migrate.ts
5
+ async function migrateDatabase(database) {
6
+ const client = await database.pool.connect();
7
+ try {
8
+ await client.query("SELECT pg_advisory_lock(7361081)");
9
+ await migrate(drizzle(client), { migrationsFolder: fileURLToPath(new URL("../drizzle", import.meta.url)) });
10
+ await client.query("INSERT INTO event_clock (id, value, floor) VALUES (1, 0, 0) ON CONFLICT DO NOTHING");
11
+ } finally {
12
+ await client.query("SELECT pg_advisory_unlock(7361081)");
13
+ client.release();
14
+ }
15
+ }
16
+ //#endregion
17
+ export { migrateDatabase as t };
@@ -0,0 +1,12 @@
1
+ import { t as readConfig, u as createDatabase } from "./config-Qxr_7oqZ.mjs";
2
+ import { t as migrateDatabase } from "./migrate-C9f4ozB4.mjs";
3
+ //#region src/cli/migrate.ts
4
+ const database = createDatabase(readConfig().DATABASE_URL);
5
+ try {
6
+ await migrateDatabase(database);
7
+ console.info("Kanvil database is current.");
8
+ } finally {
9
+ await database.pool.end();
10
+ }
11
+ //#endregion
12
+ export {};
@@ -0,0 +1,52 @@
1
+ import { d as account, h as user, m as session, t as readConfig, u as createDatabase } from "./config-Qxr_7oqZ.mjs";
2
+ import { i as fail, t as createAuth } from "./auth-BscXb1NQ.mjs";
3
+ import { and, eq } from "drizzle-orm";
4
+ import { z } from "zod";
5
+ import { parseArgs } from "node:util";
6
+ import passwordPrompt from "@inquirer/password";
7
+ import { readFileSync } from "node:fs";
8
+ //#region src/recover-account.ts
9
+ const localPasswordSchema = z.string().min(12).max(128);
10
+ async function recoverLocalPassword(database, config, email, password) {
11
+ const normalizedEmail = z.email().parse(email.trim().toLowerCase());
12
+ localPasswordSchema.parse(password);
13
+ const hash = await (await createAuth(database, config).$context).password.hash(password);
14
+ return database.db.transaction(async (tx) => {
15
+ const identity = (await tx.select().from(user).where(eq(user.email, normalizedEmail)).for("update"))[0];
16
+ if (!identity) fail(404, "not_found", "No account has this email address");
17
+ const where = and(eq(account.userId, identity.id), eq(account.providerId, "credential"));
18
+ if ((await tx.select().from(account).where(where))[0]) await tx.update(account).set({
19
+ password: hash,
20
+ updatedAt: /* @__PURE__ */ new Date()
21
+ }).where(where);
22
+ else await tx.insert(account).values({
23
+ id: crypto.randomUUID(),
24
+ accountId: identity.id,
25
+ userId: identity.id,
26
+ providerId: "credential",
27
+ password: hash,
28
+ updatedAt: /* @__PURE__ */ new Date()
29
+ });
30
+ await tx.delete(session).where(eq(session.userId, identity.id));
31
+ return identity.id;
32
+ });
33
+ }
34
+ //#endregion
35
+ //#region src/cli/recover.ts
36
+ const { values } = parseArgs({ options: { email: { type: "string" } } });
37
+ if (!values.email) throw new Error("Pass --email <account-email>. The new password is read privately from the terminal or stdin.");
38
+ const password = process.stdin.isTTY ? await passwordPrompt({
39
+ message: "New local password",
40
+ mask: true,
41
+ validate: (value) => localPasswordSchema.safeParse(value).success || "Use 12 to 128 characters"
42
+ }) : readFileSync(0, "utf8").replace(/\r?\n$/, "");
43
+ const config = readConfig();
44
+ const database = createDatabase(config.DATABASE_URL);
45
+ try {
46
+ await recoverLocalPassword(database, config, values.email, password);
47
+ console.info("Local password replaced and account sessions revoked. API credentials and linked OIDC accounts are retained.");
48
+ } finally {
49
+ await database.pool.end();
50
+ }
51
+ //#endregion
52
+ export {};
@@ -0,0 +1,437 @@
1
+ CREATE TABLE "account" (
2
+ "id" text PRIMARY KEY NOT NULL,
3
+ "account_id" text NOT NULL,
4
+ "provider_id" text NOT NULL,
5
+ "user_id" text NOT NULL,
6
+ "access_token" text,
7
+ "refresh_token" text,
8
+ "id_token" text,
9
+ "access_token_expires_at" timestamp,
10
+ "refresh_token_expires_at" timestamp,
11
+ "scope" text,
12
+ "password" text,
13
+ "created_at" timestamp DEFAULT now() NOT NULL,
14
+ "updated_at" timestamp NOT NULL
15
+ );
16
+ --> statement-breakpoint
17
+ CREATE TABLE "apikey" (
18
+ "id" text PRIMARY KEY NOT NULL,
19
+ "config_id" text DEFAULT 'default' NOT NULL,
20
+ "name" text,
21
+ "start" text,
22
+ "reference_id" text NOT NULL,
23
+ "prefix" text,
24
+ "key" text NOT NULL,
25
+ "refill_interval" integer,
26
+ "refill_amount" integer,
27
+ "last_refill_at" timestamp,
28
+ "enabled" boolean DEFAULT true,
29
+ "rate_limit_enabled" boolean DEFAULT true,
30
+ "rate_limit_time_window" integer DEFAULT 86400000,
31
+ "rate_limit_max" integer DEFAULT 10,
32
+ "request_count" integer DEFAULT 0,
33
+ "remaining" integer,
34
+ "last_request" timestamp,
35
+ "expires_at" timestamp,
36
+ "created_at" timestamp NOT NULL,
37
+ "updated_at" timestamp NOT NULL,
38
+ "permissions" text,
39
+ "metadata" text
40
+ );
41
+ --> statement-breakpoint
42
+ CREATE TABLE "jwks" (
43
+ "id" text PRIMARY KEY NOT NULL,
44
+ "public_key" text NOT NULL,
45
+ "private_key" text NOT NULL,
46
+ "created_at" timestamp NOT NULL,
47
+ "expires_at" timestamp,
48
+ "alg" text,
49
+ "crv" text
50
+ );
51
+ --> statement-breakpoint
52
+ CREATE TABLE "oauth_access_token" (
53
+ "id" text PRIMARY KEY NOT NULL,
54
+ "token" text NOT NULL,
55
+ "client_id" text NOT NULL,
56
+ "session_id" text,
57
+ "user_id" text,
58
+ "reference_id" text,
59
+ "authorization_code_id" text,
60
+ "resources" text[],
61
+ "requested_user_info_claims" text[],
62
+ "refresh_id" text,
63
+ "expires_at" timestamp NOT NULL,
64
+ "created_at" timestamp NOT NULL,
65
+ "revoked" timestamp,
66
+ "confirmation" jsonb,
67
+ "scopes" text[] NOT NULL,
68
+ CONSTRAINT "oauth_access_token_token_unique" UNIQUE("token")
69
+ );
70
+ --> statement-breakpoint
71
+ CREATE TABLE "oauth_client" (
72
+ "id" text PRIMARY KEY NOT NULL,
73
+ "client_id" text NOT NULL,
74
+ "client_secret" text,
75
+ "client_discovery_id" text,
76
+ "disabled" boolean DEFAULT false,
77
+ "skip_consent" boolean,
78
+ "enable_end_session" boolean,
79
+ "subject_type" text,
80
+ "scopes" text[],
81
+ "client_credentials_scopes" text[] DEFAULT '{}',
82
+ "user_id" text,
83
+ "created_at" timestamp,
84
+ "updated_at" timestamp,
85
+ "name" text,
86
+ "uri" text,
87
+ "icon" text,
88
+ "contacts" text[],
89
+ "tos" text,
90
+ "policy" text,
91
+ "software_id" text,
92
+ "software_version" text,
93
+ "software_statement" text,
94
+ "redirect_uris" text[] NOT NULL,
95
+ "post_logout_redirect_uris" text[],
96
+ "backchannel_logout_uri" text,
97
+ "backchannel_logout_session_required" boolean,
98
+ "token_endpoint_auth_method" text,
99
+ "application_type" text,
100
+ "jwks" text,
101
+ "jwks_uri" text,
102
+ "grant_types" text[],
103
+ "response_types" text[],
104
+ "require_pkce" boolean,
105
+ "dpop_bound_access_tokens" boolean DEFAULT false,
106
+ "reference_id" text,
107
+ "metadata" jsonb,
108
+ CONSTRAINT "oauth_client_client_id_unique" UNIQUE("client_id")
109
+ );
110
+ --> statement-breakpoint
111
+ CREATE TABLE "oauth_client_assertion" (
112
+ "id" text PRIMARY KEY NOT NULL,
113
+ "expires_at" timestamp NOT NULL
114
+ );
115
+ --> statement-breakpoint
116
+ CREATE TABLE "oauth_client_resource" (
117
+ "id" text PRIMARY KEY NOT NULL,
118
+ "client_id" text NOT NULL,
119
+ "resource_id" text NOT NULL,
120
+ "metadata" jsonb,
121
+ "created_at" timestamp
122
+ );
123
+ --> statement-breakpoint
124
+ CREATE TABLE "oauth_consent" (
125
+ "id" text PRIMARY KEY NOT NULL,
126
+ "client_id" text NOT NULL,
127
+ "user_id" text,
128
+ "reference_id" text,
129
+ "resources" text[],
130
+ "requested_user_info_claims" text[],
131
+ "scopes" text[] NOT NULL,
132
+ "created_at" timestamp NOT NULL,
133
+ "updated_at" timestamp NOT NULL
134
+ );
135
+ --> statement-breakpoint
136
+ CREATE TABLE "oauth_refresh_token" (
137
+ "id" text PRIMARY KEY NOT NULL,
138
+ "token" text NOT NULL,
139
+ "client_id" text NOT NULL,
140
+ "session_id" text,
141
+ "user_id" text NOT NULL,
142
+ "reference_id" text,
143
+ "authorization_code_id" text,
144
+ "resources" text[],
145
+ "requested_user_info_claims" text[],
146
+ "expires_at" timestamp NOT NULL,
147
+ "created_at" timestamp NOT NULL,
148
+ "revoked" timestamp,
149
+ "rotated_at" timestamp,
150
+ "rotation_replay_response" text,
151
+ "rotation_replay_expires_at" timestamp,
152
+ "auth_time" timestamp,
153
+ "confirmation" jsonb,
154
+ "scopes" text[] NOT NULL,
155
+ CONSTRAINT "oauth_refresh_token_token_unique" UNIQUE("token")
156
+ );
157
+ --> statement-breakpoint
158
+ CREATE TABLE "oauth_resource" (
159
+ "id" text PRIMARY KEY NOT NULL,
160
+ "identifier" text NOT NULL,
161
+ "name" text NOT NULL,
162
+ "access_token_ttl" integer,
163
+ "refresh_token_ttl" integer,
164
+ "signing_algorithm" text,
165
+ "signing_key_id" text,
166
+ "allowed_scopes" text[],
167
+ "custom_claims" jsonb,
168
+ "dpop_bound_access_tokens_required" boolean DEFAULT false,
169
+ "disabled" boolean DEFAULT false,
170
+ "created_at" timestamp,
171
+ "updated_at" timestamp,
172
+ "policy_version" integer DEFAULT 1,
173
+ "metadata" jsonb,
174
+ CONSTRAINT "oauth_resource_identifier_unique" UNIQUE("identifier")
175
+ );
176
+ --> statement-breakpoint
177
+ CREATE TABLE "session" (
178
+ "id" text PRIMARY KEY NOT NULL,
179
+ "expires_at" timestamp NOT NULL,
180
+ "token" text NOT NULL,
181
+ "created_at" timestamp DEFAULT now() NOT NULL,
182
+ "updated_at" timestamp NOT NULL,
183
+ "ip_address" text,
184
+ "user_agent" text,
185
+ "user_id" text NOT NULL,
186
+ "impersonated_by" text,
187
+ CONSTRAINT "session_token_unique" UNIQUE("token")
188
+ );
189
+ --> statement-breakpoint
190
+ CREATE TABLE "user" (
191
+ "id" text PRIMARY KEY NOT NULL,
192
+ "name" text NOT NULL,
193
+ "email" text NOT NULL,
194
+ "email_verified" boolean DEFAULT false NOT NULL,
195
+ "image" text,
196
+ "created_at" timestamp DEFAULT now() NOT NULL,
197
+ "updated_at" timestamp DEFAULT now() NOT NULL,
198
+ "role" text,
199
+ "banned" boolean DEFAULT false,
200
+ "ban_reason" text,
201
+ "ban_expires" timestamp,
202
+ CONSTRAINT "user_email_unique" UNIQUE("email")
203
+ );
204
+ --> statement-breakpoint
205
+ CREATE TABLE "verification" (
206
+ "id" text PRIMARY KEY NOT NULL,
207
+ "identifier" text NOT NULL,
208
+ "value" text NOT NULL,
209
+ "expires_at" timestamp NOT NULL,
210
+ "created_at" timestamp DEFAULT now() NOT NULL,
211
+ "updated_at" timestamp DEFAULT now() NOT NULL
212
+ );
213
+ --> statement-breakpoint
214
+ CREATE TABLE "attachments" (
215
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
216
+ "project_id" uuid NOT NULL,
217
+ "ticket_id" uuid NOT NULL,
218
+ "actor_id" text NOT NULL,
219
+ "name" text NOT NULL,
220
+ "content_type" text NOT NULL,
221
+ "size" integer NOT NULL,
222
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
223
+ );
224
+ --> statement-breakpoint
225
+ CREATE TABLE "claims" (
226
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
227
+ "project_id" uuid NOT NULL,
228
+ "ticket_id" uuid NOT NULL,
229
+ "actor_id" text NOT NULL,
230
+ "worker_id" text NOT NULL,
231
+ "expires_at" timestamp with time zone NOT NULL,
232
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
233
+ CONSTRAINT "claims_ticket_id_unique" UNIQUE("ticket_id")
234
+ );
235
+ --> statement-breakpoint
236
+ CREATE TABLE "comments" (
237
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
238
+ "project_id" uuid NOT NULL,
239
+ "ticket_id" uuid NOT NULL,
240
+ "actor_id" text NOT NULL,
241
+ "body" text NOT NULL,
242
+ "version" integer DEFAULT 1 NOT NULL,
243
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
244
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL
245
+ );
246
+ --> statement-breakpoint
247
+ CREATE TABLE "event_clock" (
248
+ "id" integer PRIMARY KEY NOT NULL,
249
+ "value" bigint DEFAULT 0 NOT NULL,
250
+ "floor" bigint DEFAULT 0 NOT NULL
251
+ );
252
+ --> statement-breakpoint
253
+ CREATE TABLE "events" (
254
+ "id" bigint PRIMARY KEY NOT NULL,
255
+ "project_id" uuid NOT NULL,
256
+ "ticket_id" uuid,
257
+ "actor_id" text NOT NULL,
258
+ "type" text NOT NULL,
259
+ "data" jsonb NOT NULL,
260
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
261
+ );
262
+ --> statement-breakpoint
263
+ CREATE TABLE "evidence" (
264
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
265
+ "project_id" uuid NOT NULL,
266
+ "ticket_id" uuid NOT NULL,
267
+ "actor_id" text NOT NULL,
268
+ "title" text NOT NULL,
269
+ "kind" text NOT NULL,
270
+ "url" text NOT NULL,
271
+ "commit" text,
272
+ "outcome" text NOT NULL,
273
+ "note" text NOT NULL,
274
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
275
+ );
276
+ --> statement-breakpoint
277
+ CREATE TABLE "project_members" (
278
+ "project_id" uuid NOT NULL,
279
+ "user_id" text NOT NULL,
280
+ "role" text NOT NULL,
281
+ CONSTRAINT "project_members_project_id_user_id_pk" PRIMARY KEY("project_id","user_id")
282
+ );
283
+ --> statement-breakpoint
284
+ CREATE TABLE "notifications" (
285
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
286
+ "user_id" text NOT NULL,
287
+ "project_id" uuid NOT NULL,
288
+ "event_id" bigint NOT NULL,
289
+ "read_at" timestamp with time zone,
290
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
291
+ );
292
+ --> statement-breakpoint
293
+ CREATE TABLE "projects" (
294
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
295
+ "key" text NOT NULL,
296
+ "name" text NOT NULL,
297
+ "description" text DEFAULT '' NOT NULL,
298
+ "next_number" integer DEFAULT 1 NOT NULL,
299
+ "version" integer DEFAULT 1 NOT NULL,
300
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
301
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
302
+ CONSTRAINT "projects_key_unique" UNIQUE("key")
303
+ );
304
+ --> statement-breakpoint
305
+ CREATE TABLE "mutation_receipts" (
306
+ "actor_id" text NOT NULL,
307
+ "request_id" uuid NOT NULL,
308
+ "operation" text NOT NULL,
309
+ "hash" text NOT NULL,
310
+ "result" jsonb NOT NULL,
311
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
312
+ CONSTRAINT "mutation_receipts_actor_id_request_id_pk" PRIMARY KEY("actor_id","request_id")
313
+ );
314
+ --> statement-breakpoint
315
+ CREATE TABLE "ticket_relations" (
316
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
317
+ "project_id" uuid NOT NULL,
318
+ "source_id" uuid NOT NULL,
319
+ "target_id" uuid NOT NULL,
320
+ "type" text NOT NULL,
321
+ CONSTRAINT "ticket_relation_edge" UNIQUE("source_id","target_id","type")
322
+ );
323
+ --> statement-breakpoint
324
+ CREATE TABLE "subscriptions" (
325
+ "project_id" uuid NOT NULL,
326
+ "ticket_id" uuid NOT NULL,
327
+ "user_id" text NOT NULL,
328
+ CONSTRAINT "subscriptions_ticket_id_user_id_pk" PRIMARY KEY("ticket_id","user_id")
329
+ );
330
+ --> statement-breakpoint
331
+ CREATE TABLE "tickets" (
332
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
333
+ "project_id" uuid NOT NULL,
334
+ "key" text NOT NULL,
335
+ "number" integer NOT NULL,
336
+ "title" text NOT NULL,
337
+ "description" text DEFAULT '' NOT NULL,
338
+ "acceptance_criteria" text DEFAULT '' NOT NULL,
339
+ "status" text DEFAULT 'todo' NOT NULL,
340
+ "priority" text DEFAULT 'medium' NOT NULL,
341
+ "kind" text DEFAULT 'feature' NOT NULL,
342
+ "difficulty" text,
343
+ "labels" text[] DEFAULT '{}' NOT NULL,
344
+ "scopes" text[] DEFAULT '{}' NOT NULL,
345
+ "assignee_id" text,
346
+ "parent_id" uuid,
347
+ "automation_ready" boolean DEFAULT false NOT NULL,
348
+ "hold_reason" text,
349
+ "archived" boolean DEFAULT false NOT NULL,
350
+ "created_by" text NOT NULL,
351
+ "version" integer DEFAULT 1 NOT NULL,
352
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
353
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
354
+ CONSTRAINT "tickets_key_unique" UNIQUE("key"),
355
+ CONSTRAINT "ticket_project_number" UNIQUE("project_id","number")
356
+ );
357
+ --> statement-breakpoint
358
+ CREATE TABLE "saved_views" (
359
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
360
+ "project_id" uuid NOT NULL,
361
+ "user_id" text NOT NULL,
362
+ "name" text NOT NULL,
363
+ "filters" jsonb NOT NULL
364
+ );
365
+ --> statement-breakpoint
366
+ ALTER TABLE "account" ADD CONSTRAINT "account_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
367
+ ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_client_id_oauth_client_client_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."oauth_client"("client_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
368
+ ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_session_id_session_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."session"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
369
+ ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
370
+ ALTER TABLE "oauth_access_token" ADD CONSTRAINT "oauth_access_token_refresh_id_oauth_refresh_token_id_fk" FOREIGN KEY ("refresh_id") REFERENCES "public"."oauth_refresh_token"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
371
+ ALTER TABLE "oauth_client" ADD CONSTRAINT "oauth_client_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
372
+ ALTER TABLE "oauth_client_resource" ADD CONSTRAINT "oauth_client_resource_client_id_oauth_client_client_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."oauth_client"("client_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
373
+ ALTER TABLE "oauth_client_resource" ADD CONSTRAINT "oauth_client_resource_resource_id_oauth_resource_identifier_fk" FOREIGN KEY ("resource_id") REFERENCES "public"."oauth_resource"("identifier") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
374
+ ALTER TABLE "oauth_consent" ADD CONSTRAINT "oauth_consent_client_id_oauth_client_client_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."oauth_client"("client_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
375
+ ALTER TABLE "oauth_consent" ADD CONSTRAINT "oauth_consent_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
376
+ ALTER TABLE "oauth_refresh_token" ADD CONSTRAINT "oauth_refresh_token_client_id_oauth_client_client_id_fk" FOREIGN KEY ("client_id") REFERENCES "public"."oauth_client"("client_id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
377
+ ALTER TABLE "oauth_refresh_token" ADD CONSTRAINT "oauth_refresh_token_session_id_session_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."session"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
378
+ ALTER TABLE "oauth_refresh_token" ADD CONSTRAINT "oauth_refresh_token_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
379
+ ALTER TABLE "session" ADD CONSTRAINT "session_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
380
+ ALTER TABLE "attachments" ADD CONSTRAINT "attachments_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
381
+ ALTER TABLE "attachments" ADD CONSTRAINT "attachments_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
382
+ ALTER TABLE "attachments" ADD CONSTRAINT "attachments_actor_id_user_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
383
+ ALTER TABLE "claims" ADD CONSTRAINT "claims_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
384
+ ALTER TABLE "claims" ADD CONSTRAINT "claims_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
385
+ ALTER TABLE "claims" ADD CONSTRAINT "claims_actor_id_user_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
386
+ ALTER TABLE "comments" ADD CONSTRAINT "comments_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
387
+ ALTER TABLE "comments" ADD CONSTRAINT "comments_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
388
+ ALTER TABLE "comments" ADD CONSTRAINT "comments_actor_id_user_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
389
+ ALTER TABLE "events" ADD CONSTRAINT "events_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
390
+ ALTER TABLE "events" ADD CONSTRAINT "events_actor_id_user_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
391
+ ALTER TABLE "evidence" ADD CONSTRAINT "evidence_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
392
+ ALTER TABLE "evidence" ADD CONSTRAINT "evidence_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
393
+ ALTER TABLE "evidence" ADD CONSTRAINT "evidence_actor_id_user_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
394
+ ALTER TABLE "project_members" ADD CONSTRAINT "project_members_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
395
+ ALTER TABLE "project_members" ADD CONSTRAINT "project_members_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
396
+ ALTER TABLE "notifications" ADD CONSTRAINT "notifications_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
397
+ ALTER TABLE "notifications" ADD CONSTRAINT "notifications_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
398
+ ALTER TABLE "mutation_receipts" ADD CONSTRAINT "mutation_receipts_actor_id_user_id_fk" FOREIGN KEY ("actor_id") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
399
+ ALTER TABLE "ticket_relations" ADD CONSTRAINT "ticket_relations_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
400
+ ALTER TABLE "ticket_relations" ADD CONSTRAINT "ticket_relations_source_id_tickets_id_fk" FOREIGN KEY ("source_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
401
+ ALTER TABLE "ticket_relations" ADD CONSTRAINT "ticket_relations_target_id_tickets_id_fk" FOREIGN KEY ("target_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
402
+ ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
403
+ ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_ticket_id_tickets_id_fk" FOREIGN KEY ("ticket_id") REFERENCES "public"."tickets"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
404
+ ALTER TABLE "subscriptions" ADD CONSTRAINT "subscriptions_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
405
+ ALTER TABLE "tickets" ADD CONSTRAINT "tickets_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
406
+ ALTER TABLE "tickets" ADD CONSTRAINT "tickets_assignee_id_user_id_fk" FOREIGN KEY ("assignee_id") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
407
+ ALTER TABLE "tickets" ADD CONSTRAINT "tickets_created_by_user_id_fk" FOREIGN KEY ("created_by") REFERENCES "public"."user"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
408
+ ALTER TABLE "saved_views" ADD CONSTRAINT "saved_views_project_id_projects_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."projects"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
409
+ ALTER TABLE "saved_views" ADD CONSTRAINT "saved_views_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
410
+ CREATE INDEX "account_userId_idx" ON "account" USING btree ("user_id");--> statement-breakpoint
411
+ CREATE INDEX "apikey_configId_idx" ON "apikey" USING btree ("config_id");--> statement-breakpoint
412
+ CREATE INDEX "apikey_referenceId_idx" ON "apikey" USING btree ("reference_id");--> statement-breakpoint
413
+ CREATE INDEX "apikey_key_idx" ON "apikey" USING btree ("key");--> statement-breakpoint
414
+ CREATE INDEX "oauthAccessToken_clientId_idx" ON "oauth_access_token" USING btree ("client_id");--> statement-breakpoint
415
+ CREATE INDEX "oauthAccessToken_sessionId_idx" ON "oauth_access_token" USING btree ("session_id");--> statement-breakpoint
416
+ CREATE INDEX "oauthAccessToken_userId_idx" ON "oauth_access_token" USING btree ("user_id");--> statement-breakpoint
417
+ CREATE INDEX "oauthAccessToken_authorizationCodeId_idx" ON "oauth_access_token" USING btree ("authorization_code_id");--> statement-breakpoint
418
+ CREATE INDEX "oauthAccessToken_refreshId_idx" ON "oauth_access_token" USING btree ("refresh_id");--> statement-breakpoint
419
+ CREATE INDEX "oauthClient_userId_idx" ON "oauth_client" USING btree ("user_id");--> statement-breakpoint
420
+ CREATE UNIQUE INDEX "oauthClientResource_clientId_resourceId_uidx" ON "oauth_client_resource" USING btree ("client_id","resource_id");--> statement-breakpoint
421
+ CREATE INDEX "oauthClientResource_clientId_idx" ON "oauth_client_resource" USING btree ("client_id");--> statement-breakpoint
422
+ CREATE INDEX "oauthClientResource_resourceId_idx" ON "oauth_client_resource" USING btree ("resource_id");--> statement-breakpoint
423
+ CREATE INDEX "oauthConsent_clientId_idx" ON "oauth_consent" USING btree ("client_id");--> statement-breakpoint
424
+ CREATE INDEX "oauthConsent_userId_idx" ON "oauth_consent" USING btree ("user_id");--> statement-breakpoint
425
+ CREATE INDEX "oauthRefreshToken_clientId_idx" ON "oauth_refresh_token" USING btree ("client_id");--> statement-breakpoint
426
+ CREATE INDEX "oauthRefreshToken_sessionId_idx" ON "oauth_refresh_token" USING btree ("session_id");--> statement-breakpoint
427
+ CREATE INDEX "oauthRefreshToken_userId_idx" ON "oauth_refresh_token" USING btree ("user_id");--> statement-breakpoint
428
+ CREATE INDEX "oauthRefreshToken_authorizationCodeId_idx" ON "oauth_refresh_token" USING btree ("authorization_code_id");--> statement-breakpoint
429
+ CREATE INDEX "session_userId_idx" ON "session" USING btree ("user_id");--> statement-breakpoint
430
+ CREATE INDEX "verification_identifier_idx" ON "verification" USING btree ("identifier");--> statement-breakpoint
431
+ CREATE INDEX "comment_ticket" ON "comments" USING btree ("ticket_id");--> statement-breakpoint
432
+ CREATE INDEX "event_project_cursor" ON "events" USING btree ("project_id","id");--> statement-breakpoint
433
+ CREATE INDEX "event_ticket" ON "events" USING btree ("ticket_id","id");--> statement-breakpoint
434
+ CREATE INDEX "member_user" ON "project_members" USING btree ("user_id");--> statement-breakpoint
435
+ CREATE INDEX "relation_target" ON "ticket_relations" USING btree ("target_id");--> statement-breakpoint
436
+ CREATE INDEX "ticket_project_status" ON "tickets" USING btree ("project_id","status");--> statement-breakpoint
437
+ CREATE INDEX "ticket_parent" ON "tickets" USING btree ("parent_id");
@@ -0,0 +1 @@
1
+ ALTER TABLE "claims" ADD COLUMN "owner_id" text NOT NULL;
@@ -0,0 +1,6 @@
1
+ CREATE TABLE "attachment_content" (
2
+ "id" uuid PRIMARY KEY NOT NULL,
3
+ "data" "bytea" NOT NULL
4
+ );
5
+ --> statement-breakpoint
6
+ ALTER TABLE "attachment_content" ADD CONSTRAINT "attachment_content_id_attachments_id_fk" FOREIGN KEY ("id") REFERENCES "public"."attachments"("id") ON DELETE cascade ON UPDATE no action;
@@ -0,0 +1,4 @@
1
+ ALTER TABLE "tickets" ADD COLUMN "claim_required" boolean DEFAULT false NOT NULL;--> statement-breakpoint
2
+ UPDATE "tickets" SET "claim_required" = true
3
+ WHERE "id" IN (SELECT "ticket_id" FROM "claims")
4
+ OR "id" IN (SELECT "ticket_id" FROM "events" WHERE "type" IN ('ticket.claimed', 'claim.recovered', 'claim.released'));
@@ -0,0 +1,6 @@
1
+ CREATE TABLE "notification_preferences" (
2
+ "user_id" text PRIMARY KEY NOT NULL,
3
+ "in_app" boolean DEFAULT true NOT NULL
4
+ );
5
+ --> statement-breakpoint
6
+ ALTER TABLE "notification_preferences" ADD CONSTRAINT "notification_preferences_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;
@@ -0,0 +1,28 @@
1
+ CREATE TABLE "push_deliveries" (
2
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3
+ "notification_id" uuid NOT NULL,
4
+ "device_id" uuid NOT NULL,
5
+ "attempts" integer DEFAULT 0 NOT NULL,
6
+ "available_at" timestamp with time zone DEFAULT now() NOT NULL,
7
+ "receipt_id" text,
8
+ "finished_at" timestamp with time zone,
9
+ "error" text,
10
+ CONSTRAINT "push_deliveries_notification_id_device_id_unique" UNIQUE("notification_id","device_id")
11
+ );
12
+ --> statement-breakpoint
13
+ CREATE TABLE "push_devices" (
14
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
15
+ "user_id" text NOT NULL,
16
+ "session_id" text NOT NULL,
17
+ "token" text NOT NULL,
18
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
19
+ CONSTRAINT "push_devices_token_unique" UNIQUE("token")
20
+ );
21
+ --> statement-breakpoint
22
+ ALTER TABLE "notification_preferences" ADD COLUMN "push" boolean DEFAULT false NOT NULL;--> statement-breakpoint
23
+ ALTER TABLE "notifications" ADD COLUMN "inbox" boolean DEFAULT true NOT NULL;--> statement-breakpoint
24
+ ALTER TABLE "push_deliveries" ADD CONSTRAINT "push_deliveries_notification_id_notifications_id_fk" FOREIGN KEY ("notification_id") REFERENCES "public"."notifications"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
25
+ ALTER TABLE "push_deliveries" ADD CONSTRAINT "push_deliveries_device_id_push_devices_id_fk" FOREIGN KEY ("device_id") REFERENCES "public"."push_devices"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
26
+ ALTER TABLE "push_devices" ADD CONSTRAINT "push_devices_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
27
+ ALTER TABLE "push_devices" ADD CONSTRAINT "push_devices_session_id_session_id_fk" FOREIGN KEY ("session_id") REFERENCES "public"."session"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
28
+ CREATE INDEX "push_pending_idx" ON "push_deliveries" USING btree ("finished_at","available_at");
@@ -0,0 +1,48 @@
1
+ CREATE TABLE "blob_objects" (
2
+ "id" uuid PRIMARY KEY NOT NULL,
3
+ "backend_id" uuid,
4
+ "object_key" text,
5
+ "data" "bytea",
6
+ "content_type" text NOT NULL,
7
+ "size" integer NOT NULL,
8
+ "sha256" text NOT NULL,
9
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL
10
+ );
11
+ --> statement-breakpoint
12
+ CREATE TABLE "instance_settings" (
13
+ "id" integer PRIMARY KEY DEFAULT 1 NOT NULL,
14
+ "identity" uuid DEFAULT gen_random_uuid() NOT NULL,
15
+ "version" integer DEFAULT 1 NOT NULL,
16
+ "name" text DEFAULT 'Kanvil' NOT NULL,
17
+ "description" text DEFAULT 'Ticketing for people and agents' NOT NULL,
18
+ "storage_backend_id" uuid,
19
+ "search_config" text
20
+ );
21
+ --> statement-breakpoint
22
+ CREATE TABLE "profile_photos" (
23
+ "user_id" text PRIMARY KEY NOT NULL,
24
+ "object_id" uuid NOT NULL
25
+ );
26
+ --> statement-breakpoint
27
+ CREATE TABLE "search_state" (
28
+ "id" integer PRIMARY KEY DEFAULT 1 NOT NULL,
29
+ "config_hash" text DEFAULT '' NOT NULL,
30
+ "cursor" bigint DEFAULT 0 NOT NULL,
31
+ "error" text
32
+ );
33
+ --> statement-breakpoint
34
+ CREATE TABLE "storage_backends" (
35
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
36
+ "identity" text NOT NULL,
37
+ "config" text NOT NULL,
38
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
39
+ CONSTRAINT "storage_backends_identity_unique" UNIQUE("identity")
40
+ );
41
+ --> statement-breakpoint
42
+ ALTER TABLE "attachments" ADD COLUMN "object_id" uuid;--> statement-breakpoint
43
+ ALTER TABLE "blob_objects" ADD CONSTRAINT "blob_objects_backend_id_storage_backends_id_fk" FOREIGN KEY ("backend_id") REFERENCES "public"."storage_backends"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
44
+ ALTER TABLE "instance_settings" ADD CONSTRAINT "instance_settings_storage_backend_id_storage_backends_id_fk" FOREIGN KEY ("storage_backend_id") REFERENCES "public"."storage_backends"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
45
+ ALTER TABLE "profile_photos" ADD CONSTRAINT "profile_photos_user_id_user_id_fk" FOREIGN KEY ("user_id") REFERENCES "public"."user"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
46
+ ALTER TABLE "profile_photos" ADD CONSTRAINT "profile_photos_object_id_blob_objects_id_fk" FOREIGN KEY ("object_id") REFERENCES "public"."blob_objects"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
47
+ CREATE INDEX "blob_objects_created" ON "blob_objects" USING btree ("created_at");--> statement-breakpoint
48
+ ALTER TABLE "attachments" ADD CONSTRAINT "attachments_object_id_blob_objects_id_fk" FOREIGN KEY ("object_id") REFERENCES "public"."blob_objects"("id") ON DELETE no action ON UPDATE no action;
@@ -0,0 +1,6 @@
1
+ CREATE TABLE "delivery_checkpoints" (
2
+ "destination" text PRIMARY KEY NOT NULL,
3
+ "cursor" bigint DEFAULT 0 NOT NULL
4
+ );
5
+ --> statement-breakpoint
6
+ ALTER TABLE "instance_settings" ADD COLUMN "broker_config" text;