@headless-lms/adapter-db 0.4.0 → 0.5.0

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 (90) hide show
  1. package/dist/client.d.ts +8 -2
  2. package/dist/client.js +10 -2
  3. package/dist/client.js.map +1 -1
  4. package/dist/index.d.ts +5 -4
  5. package/dist/index.js +4 -3
  6. package/dist/repositories/admin.d.ts +12 -4
  7. package/dist/repositories/admin.js +164 -22
  8. package/dist/repositories/admin.js.map +1 -1
  9. package/dist/repositories/assets.d.ts +2 -1
  10. package/dist/repositories/assets.js +11 -1
  11. package/dist/repositories/assets.js.map +1 -1
  12. package/dist/repositories/automations.js +1 -1
  13. package/dist/repositories/chats.d.ts +13 -4
  14. package/dist/repositories/chats.js +164 -70
  15. package/dist/repositories/chats.js.map +1 -1
  16. package/dist/repositories/content.d.ts +22 -5
  17. package/dist/repositories/content.js +198 -40
  18. package/dist/repositories/content.js.map +1 -1
  19. package/dist/repositories/credentials.js +1 -1
  20. package/dist/repositories/devices.js +1 -1
  21. package/dist/repositories/digest-runs.js +1 -1
  22. package/dist/repositories/discussion.d.ts +1 -1
  23. package/dist/repositories/discussion.js +9 -3
  24. package/dist/repositories/discussion.js.map +1 -1
  25. package/dist/repositories/entitlements.d.ts +10 -10
  26. package/dist/repositories/entitlements.js +47 -56
  27. package/dist/repositories/entitlements.js.map +1 -1
  28. package/dist/repositories/event-reports.d.ts +16 -0
  29. package/dist/repositories/event-reports.js +199 -0
  30. package/dist/repositories/event-reports.js.map +1 -0
  31. package/dist/repositories/grant-covers.d.ts +4 -3
  32. package/dist/repositories/grant-covers.js +7 -4
  33. package/dist/repositories/grant-covers.js.map +1 -1
  34. package/dist/repositories/identity.js +1 -1
  35. package/dist/repositories/integrations.js +1 -1
  36. package/dist/repositories/member.d.ts +12 -4
  37. package/dist/repositories/member.js +19 -7
  38. package/dist/repositories/member.js.map +1 -1
  39. package/dist/repositories/members.d.ts +2 -5
  40. package/dist/repositories/members.js +39 -94
  41. package/dist/repositories/members.js.map +1 -1
  42. package/dist/repositories/mentions.js +1 -1
  43. package/dist/repositories/notification-settings.js +1 -1
  44. package/dist/repositories/notifications.js +2 -2
  45. package/dist/repositories/notifications.js.map +1 -1
  46. package/dist/repositories/org-user-profile.d.ts +0 -17
  47. package/dist/repositories/org-user-profile.js +0 -1
  48. package/dist/repositories/org-user-profile.js.map +1 -1
  49. package/dist/repositories/organizations.d.ts +3 -4
  50. package/dist/repositories/organizations.js +21 -46
  51. package/dist/repositories/organizations.js.map +1 -1
  52. package/dist/repositories/outbox.d.ts +5 -1
  53. package/dist/repositories/outbox.js +12 -3
  54. package/dist/repositories/outbox.js.map +1 -1
  55. package/dist/repositories/posts.js +1 -1
  56. package/dist/repositories/progress.js +1 -1
  57. package/dist/repositories/roles.d.ts +35 -0
  58. package/dist/repositories/roles.js +244 -0
  59. package/dist/repositories/roles.js.map +1 -0
  60. package/dist/repositories/settings.js +1 -1
  61. package/dist/repositories/subscriptions.js +1 -1
  62. package/dist/schema/assets.d.ts +17 -0
  63. package/dist/schema/assets.js +1 -0
  64. package/dist/schema/assets.js.map +1 -1
  65. package/dist/schema/automations.d.ts +2 -2
  66. package/dist/schema/automations.js +1 -1
  67. package/dist/schema/automations.js.map +1 -1
  68. package/dist/schema/content.d.ts +437 -3
  69. package/dist/schema/content.js +70 -3
  70. package/dist/schema/content.js.map +1 -1
  71. package/dist/schema/discussion.d.ts +18 -1
  72. package/dist/schema/discussion.js +4 -2
  73. package/dist/schema/discussion.js.map +1 -1
  74. package/dist/schema/index.d.ts +4 -3
  75. package/dist/schema/index.js +7 -2
  76. package/dist/schema/index.js.map +1 -1
  77. package/dist/schema/organizations.d.ts +5 -22
  78. package/dist/schema/organizations.js +1 -13
  79. package/dist/schema/organizations.js.map +1 -1
  80. package/dist/schema/roles.d.ts +369 -0
  81. package/dist/schema/roles.js +71 -0
  82. package/dist/schema/roles.js.map +1 -0
  83. package/drizzle/0017_configurable_roles.sql +38 -0
  84. package/drizzle/0018_messages_client_id.sql +2 -0
  85. package/drizzle/0019_events.sql +44 -0
  86. package/drizzle/meta/0017_snapshot.json +9518 -0
  87. package/drizzle/meta/0018_snapshot.json +9557 -0
  88. package/drizzle/meta/0019_snapshot.json +9919 -0
  89. package/drizzle/meta/_journal.json +21 -0
  90. package/package.json +2 -2
@@ -16,13 +16,6 @@ const orgUsers = pgTable("org_users", {
16
16
  orgId: text("org_id").notNull().references(() => organizations.id),
17
17
  id: text("id").notNull().$defaultFn(() => genId("orgUser")),
18
18
  userId: text("user_id").notNull().references(() => users.id),
19
- role: text("role", { enum: [
20
- "owner",
21
- "admin",
22
- "instructor",
23
- "moderator",
24
- "student"
25
- ] }).notNull(),
26
19
  status: text("status", { enum: ["invited", "active"] }).notNull().default("active"),
27
20
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
28
21
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
@@ -34,12 +27,7 @@ const invites = pgTable("invites", {
34
27
  orgId: text("org_id").notNull().references(() => organizations.id),
35
28
  id: text("id").notNull().$defaultFn(() => genId("invite")),
36
29
  email: text("email").notNull(),
37
- role: text("role", { enum: [
38
- "admin",
39
- "instructor",
40
- "moderator",
41
- "student"
42
- ] }).notNull(),
30
+ roleKey: text("role").notNull().default("member"),
43
31
  status: text("status", { enum: [
44
32
  "pending",
45
33
  "accepted",
@@ -1 +1 @@
1
- {"version":3,"file":"organizations.js","names":[],"sources":["../../src/schema/organizations.ts"],"sourcesContent":["import { sql } from \"drizzle-orm\";\nimport { pgTable, text, timestamp, primaryKey, unique, uniqueIndex } from \"drizzle-orm/pg-core\";\nimport type { Invite, Organization, OrgUser } from \"@headless-lms/core/schemas\";\nimport { genId } from \"@headless-lms/core/shared/id\";\nimport { users } from \"./identity.js\";\nimport type { Expect, NoDrift } from \"./drift.js\";\n\nexport const organizations = pgTable(\"organizations\", {\n id: text(\"id\")\n .primaryKey()\n .$defaultFn(() => genId(\"organization\")),\n // Links to the better-auth organization record.\n externalId: text(\"external_id\").unique(),\n name: text(\"name\").notNull(),\n slug: text(\"slug\").notNull().unique(),\n ownerId: text(\"owner_id\")\n .notNull()\n .references(() => users.id),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .notNull()\n .defaultNow()\n .$onUpdate(() => new Date()),\n});\n\n// A person's link to an organization under one role\nexport const orgUsers = pgTable(\n \"org_users\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"orgUser\")),\n\n userId: text(\"user_id\")\n .notNull()\n .references(() => users.id),\n role: text(\"role\", {\n enum: [\"owner\", \"admin\", \"instructor\", \"moderator\", \"student\"],\n }).notNull(),\n // 'invited' from the moment an admin adds a student until they accept.\n // Staff rows are mirrored from an auth member record that only exists once\n // they have joined, so they are created 'active'.\n status: text(\"status\", { enum: [\"invited\", \"active\"] })\n .notNull()\n .default(\"active\"),\n\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .notNull()\n .defaultNow()\n .$onUpdate(() => new Date()),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.id] }),\n userUq: unique().on(t.orgId, t.userId),\n }),\n);\n\nexport const invites = pgTable(\n \"invites\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"invite\")),\n email: text(\"email\").notNull(),\n role: text(\"role\", { enum: [\"admin\", \"instructor\", \"moderator\", \"student\"] }).notNull(),\n status: text(\"status\", {\n enum: [\"pending\", \"accepted\", \"rejected\", \"canceled\"],\n }).notNull(),\n invitedBy: text(\"invited_by\")\n .notNull()\n .references(() => users.id),\n tokenHash: text(\"token_hash\").unique(),\n expiresAt: timestamp(\"expires_at\", { withTimezone: true }),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .notNull()\n .defaultNow()\n .$onUpdate(() => new Date()),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.id] }),\n // One pending invite per (org, email) — the upsert's conflict target.\n pendingEmailUq: uniqueIndex(\"invites_pending_email_uq\")\n .on(t.orgId, t.email)\n .where(sql`${t.status} = 'pending'`),\n }),\n);\n\ntype _OrganizationsDrift = Expect<NoDrift<typeof organizations.$inferSelect, Organization>>;\ntype _OrgUsersDrift = Expect<NoDrift<typeof orgUsers.$inferSelect, OrgUser>>;\ntype _InvitesDrift = Expect<NoDrift<typeof invites.$inferSelect, Invite>>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"organizations.js","names":[],"sources":["../../src/schema/organizations.ts"],"sourcesContent":["import { sql } from \"drizzle-orm\";\nimport { pgTable, text, timestamp, primaryKey, unique, uniqueIndex } from \"drizzle-orm/pg-core\";\nimport type { Invite, Organization, OrgUser } from \"@headless-lms/core/schemas\";\nimport { genId } from \"@headless-lms/core/shared/id\";\nimport { users } from \"./identity.js\";\nimport type { Expect, NoDrift } from \"./drift.js\";\n\nexport const organizations = pgTable(\"organizations\", {\n id: text(\"id\")\n .primaryKey()\n .$defaultFn(() => genId(\"organization\")),\n // Links to the better-auth organization record.\n externalId: text(\"external_id\").unique(),\n name: text(\"name\").notNull(),\n slug: text(\"slug\").notNull().unique(),\n ownerId: text(\"owner_id\")\n .notNull()\n .references(() => users.id),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .notNull()\n .defaultNow()\n .$onUpdate(() => new Date()),\n});\n\n// A person's link to an organization\nexport const orgUsers = pgTable(\n \"org_users\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"orgUser\")),\n\n userId: text(\"user_id\")\n .notNull()\n .references(() => users.id),\n // 'invited' from the moment a person is invited until they accept.\n status: text(\"status\", { enum: [\"invited\", \"active\"] })\n .notNull()\n .default(\"active\"),\n\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .notNull()\n .defaultNow()\n .$onUpdate(() => new Date()),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.id] }),\n userUq: unique().on(t.orgId, t.userId),\n }),\n);\n\nexport const invites = pgTable(\n \"invites\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"invite\")),\n email: text(\"email\").notNull(),\n roleKey: text(\"role\").notNull().default(\"member\"),\n status: text(\"status\", {\n enum: [\"pending\", \"accepted\", \"rejected\", \"canceled\"],\n }).notNull(),\n invitedBy: text(\"invited_by\")\n .notNull()\n .references(() => users.id),\n tokenHash: text(\"token_hash\").unique(),\n expiresAt: timestamp(\"expires_at\", { withTimezone: true }),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .notNull()\n .defaultNow()\n .$onUpdate(() => new Date()),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.id] }),\n // One pending invite per (org, email) — the upsert's conflict target.\n pendingEmailUq: uniqueIndex(\"invites_pending_email_uq\")\n .on(t.orgId, t.email)\n .where(sql`${t.status} = 'pending'`),\n }),\n);\n\ntype _OrganizationsDrift = Expect<NoDrift<typeof organizations.$inferSelect, Organization>>;\ntype _OrgUsersDrift = Expect<NoDrift<typeof orgUsers.$inferSelect, OrgUser>>;\ntype _InvitesDrift = Expect<NoDrift<typeof invites.$inferSelect, Invite>>;\n"],"mappings":";;;;;AAOA,MAAa,gBAAgB,QAAQ,iBAAiB;CACpD,IAAI,KAAK,IAAI,CAAC,CACX,WAAW,CAAC,CACZ,iBAAiB,MAAM,cAAc,CAAC;CAEzC,YAAY,KAAK,aAAa,CAAC,CAAC,OAAO;CACvC,MAAM,KAAK,MAAM,CAAC,CAAC,QAAQ;CAC3B,MAAM,KAAK,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO;CACpC,SAAS,KAAK,UAAU,CAAC,CACtB,QAAQ,CAAC,CACT,iBAAiB,MAAM,EAAE;CAC5B,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;CAChF,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CACvD,QAAQ,CAAC,CACT,WAAW,CAAC,CACZ,gCAAgB,IAAI,KAAK,CAAC;AAC/B,CAAC;AAGD,MAAa,WAAW,QACtB,aACA;CACE,OAAO,KAAK,QAAQ,CAAC,CAClB,QAAQ,CAAC,CACT,iBAAiB,cAAc,EAAE;CACpC,IAAI,KAAK,IAAI,CAAC,CACX,QAAQ,CAAC,CACT,iBAAiB,MAAM,SAAS,CAAC;CAEpC,QAAQ,KAAK,SAAS,CAAC,CACpB,QAAQ,CAAC,CACT,iBAAiB,MAAM,EAAE;CAE5B,QAAQ,KAAK,UAAU,EAAE,MAAM,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAC,CACpD,QAAQ,CAAC,CACT,QAAQ,QAAQ;CAEnB,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;CAChF,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CACvD,QAAQ,CAAC,CACT,WAAW,CAAC,CACZ,gCAAgB,IAAI,KAAK,CAAC;AAC/B,IACC,OAAO;CACN,IAAI,WAAW,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;CAC3C,QAAQ,OAAO,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM;AACvC,EACF;AAEA,MAAa,UAAU,QACrB,WACA;CACE,OAAO,KAAK,QAAQ,CAAC,CAClB,QAAQ,CAAC,CACT,iBAAiB,cAAc,EAAE;CACpC,IAAI,KAAK,IAAI,CAAC,CACX,QAAQ,CAAC,CACT,iBAAiB,MAAM,QAAQ,CAAC;CACnC,OAAO,KAAK,OAAO,CAAC,CAAC,QAAQ;CAC7B,SAAS,KAAK,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,QAAQ;CAChD,QAAQ,KAAK,UAAU,EACrB,MAAM;EAAC;EAAW;EAAY;EAAY;CAAU,EACtD,CAAC,CAAC,CAAC,QAAQ;CACX,WAAW,KAAK,YAAY,CAAC,CAC1B,QAAQ,CAAC,CACT,iBAAiB,MAAM,EAAE;CAC5B,WAAW,KAAK,YAAY,CAAC,CAAC,OAAO;CACrC,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC;CACzD,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;CAChF,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CACvD,QAAQ,CAAC,CACT,WAAW,CAAC,CACZ,gCAAgB,IAAI,KAAK,CAAC;AAC/B,IACC,OAAO;CACN,IAAI,WAAW,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;CAE3C,gBAAgB,YAAY,0BAA0B,CAAC,CACpD,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CACpB,MAAM,GAAG,GAAG,EAAE,OAAO,aAAa;AACvC,EACF"}
@@ -0,0 +1,369 @@
1
+ //#region src/schema/roles.d.ts
2
+ declare const orgRoles: import("drizzle-orm/pg-core").PgTableWithColumns<{
3
+ name: "org_roles";
4
+ schema: undefined;
5
+ columns: {
6
+ orgId: import("drizzle-orm/pg-core").PgColumn<{
7
+ name: "org_id";
8
+ tableName: "org_roles";
9
+ dataType: "string";
10
+ columnType: "PgText";
11
+ data: string;
12
+ driverParam: string;
13
+ notNull: true;
14
+ hasDefault: false;
15
+ isPrimaryKey: false;
16
+ isAutoincrement: false;
17
+ hasRuntimeDefault: false;
18
+ enumValues: [string, ...string[]];
19
+ baseColumn: never;
20
+ identity: undefined;
21
+ generated: undefined;
22
+ }, {}, {}>;
23
+ id: import("drizzle-orm/pg-core").PgColumn<{
24
+ name: "id";
25
+ tableName: "org_roles";
26
+ dataType: "string";
27
+ columnType: "PgText";
28
+ data: string;
29
+ driverParam: string;
30
+ notNull: true;
31
+ hasDefault: true;
32
+ isPrimaryKey: false;
33
+ isAutoincrement: false;
34
+ hasRuntimeDefault: true;
35
+ enumValues: [string, ...string[]];
36
+ baseColumn: never;
37
+ identity: undefined;
38
+ generated: undefined;
39
+ }, {}, {}>;
40
+ key: import("drizzle-orm/pg-core").PgColumn<{
41
+ name: "key";
42
+ tableName: "org_roles";
43
+ dataType: "string";
44
+ columnType: "PgText";
45
+ data: string;
46
+ driverParam: string;
47
+ notNull: true;
48
+ hasDefault: false;
49
+ isPrimaryKey: false;
50
+ isAutoincrement: false;
51
+ hasRuntimeDefault: false;
52
+ enumValues: [string, ...string[]];
53
+ baseColumn: never;
54
+ identity: undefined;
55
+ generated: undefined;
56
+ }, {}, {}>;
57
+ name: import("drizzle-orm/pg-core").PgColumn<{
58
+ name: "name";
59
+ tableName: "org_roles";
60
+ dataType: "string";
61
+ columnType: "PgText";
62
+ data: string;
63
+ driverParam: string;
64
+ notNull: false;
65
+ hasDefault: false;
66
+ isPrimaryKey: false;
67
+ isAutoincrement: false;
68
+ hasRuntimeDefault: false;
69
+ enumValues: [string, ...string[]];
70
+ baseColumn: never;
71
+ identity: undefined;
72
+ generated: undefined;
73
+ }, {}, {}>;
74
+ description: import("drizzle-orm/pg-core").PgColumn<{
75
+ name: "description";
76
+ tableName: "org_roles";
77
+ dataType: "string";
78
+ columnType: "PgText";
79
+ data: string;
80
+ driverParam: string;
81
+ notNull: false;
82
+ hasDefault: false;
83
+ isPrimaryKey: false;
84
+ isAutoincrement: false;
85
+ hasRuntimeDefault: false;
86
+ enumValues: [string, ...string[]];
87
+ baseColumn: never;
88
+ identity: undefined;
89
+ generated: undefined;
90
+ }, {}, {}>;
91
+ base: import("drizzle-orm/pg-core").PgColumn<{
92
+ name: "base";
93
+ tableName: "org_roles";
94
+ dataType: "string";
95
+ columnType: "PgText";
96
+ data: string;
97
+ driverParam: string;
98
+ notNull: true;
99
+ hasDefault: false;
100
+ isPrimaryKey: false;
101
+ isAutoincrement: false;
102
+ hasRuntimeDefault: false;
103
+ enumValues: [string, ...string[]];
104
+ baseColumn: never;
105
+ identity: undefined;
106
+ generated: undefined;
107
+ }, {}, {}>;
108
+ levels: import("drizzle-orm/pg-core").PgColumn<{
109
+ name: "levels";
110
+ tableName: "org_roles";
111
+ dataType: "array";
112
+ columnType: "PgArray";
113
+ data: ("course" | "download" | "event" | "community" | "org")[];
114
+ driverParam: string | string[];
115
+ notNull: false;
116
+ hasDefault: false;
117
+ isPrimaryKey: false;
118
+ isAutoincrement: false;
119
+ hasRuntimeDefault: false;
120
+ enumValues: ["org", "course", "download", "community", "event"];
121
+ baseColumn: import("drizzle-orm").Column<{
122
+ name: "levels";
123
+ tableName: "org_roles";
124
+ dataType: "string";
125
+ columnType: "PgText";
126
+ data: "course" | "download" | "event" | "community" | "org";
127
+ driverParam: string;
128
+ notNull: false;
129
+ hasDefault: false;
130
+ isPrimaryKey: false;
131
+ isAutoincrement: false;
132
+ hasRuntimeDefault: false;
133
+ enumValues: ["org", "course", "download", "community", "event"];
134
+ baseColumn: never;
135
+ identity: undefined;
136
+ generated: undefined;
137
+ }, {}, {}>;
138
+ identity: undefined;
139
+ generated: undefined;
140
+ }, {}, {
141
+ size: undefined;
142
+ baseBuilder: import("drizzle-orm/pg-core").PgColumnBuilder<{
143
+ name: "levels";
144
+ dataType: "string";
145
+ columnType: "PgText";
146
+ data: "course" | "download" | "event" | "community" | "org";
147
+ enumValues: ["org", "course", "download", "community", "event"];
148
+ driverParam: string;
149
+ }, {}, {}, import("drizzle-orm").ColumnBuilderExtraConfig>;
150
+ }>;
151
+ permissions: import("drizzle-orm/pg-core").PgColumn<{
152
+ name: "permissions";
153
+ tableName: "org_roles";
154
+ dataType: "json";
155
+ columnType: "PgJsonb";
156
+ data: Record<string, boolean>;
157
+ driverParam: unknown;
158
+ notNull: true;
159
+ hasDefault: true;
160
+ isPrimaryKey: false;
161
+ isAutoincrement: false;
162
+ hasRuntimeDefault: false;
163
+ enumValues: undefined;
164
+ baseColumn: never;
165
+ identity: undefined;
166
+ generated: undefined;
167
+ }, {}, {
168
+ $type: Record<string, boolean>;
169
+ }>;
170
+ team: import("drizzle-orm/pg-core").PgColumn<{
171
+ name: "team";
172
+ tableName: "org_roles";
173
+ dataType: "boolean";
174
+ columnType: "PgBoolean";
175
+ data: boolean;
176
+ driverParam: boolean;
177
+ notNull: false;
178
+ hasDefault: false;
179
+ isPrimaryKey: false;
180
+ isAutoincrement: false;
181
+ hasRuntimeDefault: false;
182
+ enumValues: undefined;
183
+ baseColumn: never;
184
+ identity: undefined;
185
+ generated: undefined;
186
+ }, {}, {}>;
187
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
188
+ name: "created_at";
189
+ tableName: "org_roles";
190
+ dataType: "date";
191
+ columnType: "PgTimestamp";
192
+ data: Date;
193
+ driverParam: string;
194
+ notNull: true;
195
+ hasDefault: true;
196
+ isPrimaryKey: false;
197
+ isAutoincrement: false;
198
+ hasRuntimeDefault: false;
199
+ enumValues: undefined;
200
+ baseColumn: never;
201
+ identity: undefined;
202
+ generated: undefined;
203
+ }, {}, {}>;
204
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
205
+ name: "updated_at";
206
+ tableName: "org_roles";
207
+ dataType: "date";
208
+ columnType: "PgTimestamp";
209
+ data: Date;
210
+ driverParam: string;
211
+ notNull: true;
212
+ hasDefault: true;
213
+ isPrimaryKey: false;
214
+ isAutoincrement: false;
215
+ hasRuntimeDefault: false;
216
+ enumValues: undefined;
217
+ baseColumn: never;
218
+ identity: undefined;
219
+ generated: undefined;
220
+ }, {}, {}>;
221
+ };
222
+ dialect: "pg";
223
+ }>;
224
+ declare const roleAssignments: import("drizzle-orm/pg-core").PgTableWithColumns<{
225
+ name: "role_assignments";
226
+ schema: undefined;
227
+ columns: {
228
+ orgId: import("drizzle-orm/pg-core").PgColumn<{
229
+ name: "org_id";
230
+ tableName: "role_assignments";
231
+ dataType: "string";
232
+ columnType: "PgText";
233
+ data: string;
234
+ driverParam: string;
235
+ notNull: true;
236
+ hasDefault: false;
237
+ isPrimaryKey: false;
238
+ isAutoincrement: false;
239
+ hasRuntimeDefault: false;
240
+ enumValues: [string, ...string[]];
241
+ baseColumn: never;
242
+ identity: undefined;
243
+ generated: undefined;
244
+ }, {}, {}>;
245
+ id: import("drizzle-orm/pg-core").PgColumn<{
246
+ name: "id";
247
+ tableName: "role_assignments";
248
+ dataType: "string";
249
+ columnType: "PgText";
250
+ data: string;
251
+ driverParam: string;
252
+ notNull: true;
253
+ hasDefault: true;
254
+ isPrimaryKey: false;
255
+ isAutoincrement: false;
256
+ hasRuntimeDefault: true;
257
+ enumValues: [string, ...string[]];
258
+ baseColumn: never;
259
+ identity: undefined;
260
+ generated: undefined;
261
+ }, {}, {}>;
262
+ orgUserId: import("drizzle-orm/pg-core").PgColumn<{
263
+ name: "org_user_id";
264
+ tableName: "role_assignments";
265
+ dataType: "string";
266
+ columnType: "PgText";
267
+ data: string;
268
+ driverParam: string;
269
+ notNull: true;
270
+ hasDefault: false;
271
+ isPrimaryKey: false;
272
+ isAutoincrement: false;
273
+ hasRuntimeDefault: false;
274
+ enumValues: [string, ...string[]];
275
+ baseColumn: never;
276
+ identity: undefined;
277
+ generated: undefined;
278
+ }, {}, {}>;
279
+ roleKey: import("drizzle-orm/pg-core").PgColumn<{
280
+ name: "role_key";
281
+ tableName: "role_assignments";
282
+ dataType: "string";
283
+ columnType: "PgText";
284
+ data: string;
285
+ driverParam: string;
286
+ notNull: true;
287
+ hasDefault: false;
288
+ isPrimaryKey: false;
289
+ isAutoincrement: false;
290
+ hasRuntimeDefault: false;
291
+ enumValues: [string, ...string[]];
292
+ baseColumn: never;
293
+ identity: undefined;
294
+ generated: undefined;
295
+ }, {}, {}>;
296
+ contentId: import("drizzle-orm/pg-core").PgColumn<{
297
+ name: "content_id";
298
+ tableName: "role_assignments";
299
+ dataType: "string";
300
+ columnType: "PgText";
301
+ data: string;
302
+ driverParam: string;
303
+ notNull: false;
304
+ hasDefault: false;
305
+ isPrimaryKey: false;
306
+ isAutoincrement: false;
307
+ hasRuntimeDefault: false;
308
+ enumValues: [string, ...string[]];
309
+ baseColumn: never;
310
+ identity: undefined;
311
+ generated: undefined;
312
+ }, {}, {}>;
313
+ contentType: import("drizzle-orm/pg-core").PgColumn<{
314
+ name: "content_type";
315
+ tableName: "role_assignments";
316
+ dataType: "string";
317
+ columnType: "PgText";
318
+ data: "course" | "download" | "event" | "community";
319
+ driverParam: string;
320
+ notNull: false;
321
+ hasDefault: false;
322
+ isPrimaryKey: false;
323
+ isAutoincrement: false;
324
+ hasRuntimeDefault: false;
325
+ enumValues: ["course", "download", "community", "event"];
326
+ baseColumn: never;
327
+ identity: undefined;
328
+ generated: undefined;
329
+ }, {}, {}>;
330
+ assignedBy: import("drizzle-orm/pg-core").PgColumn<{
331
+ name: "assigned_by";
332
+ tableName: "role_assignments";
333
+ dataType: "string";
334
+ columnType: "PgText";
335
+ data: string;
336
+ driverParam: string;
337
+ notNull: true;
338
+ hasDefault: false;
339
+ isPrimaryKey: false;
340
+ isAutoincrement: false;
341
+ hasRuntimeDefault: false;
342
+ enumValues: [string, ...string[]];
343
+ baseColumn: never;
344
+ identity: undefined;
345
+ generated: undefined;
346
+ }, {}, {}>;
347
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
348
+ name: "created_at";
349
+ tableName: "role_assignments";
350
+ dataType: "date";
351
+ columnType: "PgTimestamp";
352
+ data: Date;
353
+ driverParam: string;
354
+ notNull: true;
355
+ hasDefault: true;
356
+ isPrimaryKey: false;
357
+ isAutoincrement: false;
358
+ hasRuntimeDefault: false;
359
+ enumValues: undefined;
360
+ baseColumn: never;
361
+ identity: undefined;
362
+ generated: undefined;
363
+ }, {}, {}>;
364
+ };
365
+ dialect: "pg";
366
+ }>;
367
+ //#endregion
368
+ export { orgRoles, roleAssignments };
369
+ //# sourceMappingURL=roles.d.ts.map
@@ -0,0 +1,71 @@
1
+ import { contentItems } from "./content.js";
2
+ import { orgUsers, organizations } from "./organizations.js";
3
+ import { sql } from "drizzle-orm";
4
+ import { boolean, foreignKey, index, jsonb, pgTable, primaryKey, text, timestamp, unique, uniqueIndex } from "drizzle-orm/pg-core";
5
+ import { genId } from "@headless-lms/core/shared/id";
6
+ //#region src/schema/roles.ts
7
+ const orgRoles = pgTable("org_roles", {
8
+ orgId: text("org_id").notNull().references(() => organizations.id, { onDelete: "cascade" }),
9
+ id: text("id").notNull().$defaultFn(() => genId("orgRole")),
10
+ key: text("key").notNull(),
11
+ name: text("name"),
12
+ description: text("description"),
13
+ base: text("base").notNull(),
14
+ levels: text("levels", { enum: [
15
+ "org",
16
+ "course",
17
+ "download",
18
+ "community",
19
+ "event"
20
+ ] }).array(),
21
+ permissions: jsonb("permissions").$type().notNull().default({}),
22
+ team: boolean("team"),
23
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
24
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
25
+ }, (t) => ({
26
+ pk: primaryKey({ columns: [t.orgId, t.id] }),
27
+ keyUq: unique("org_roles_key_uq").on(t.orgId, t.key),
28
+ nameUq: uniqueIndex("org_roles_name_uq").on(t.orgId, sql`lower(${t.name})`).where(sql`${t.name} is not null`)
29
+ }));
30
+ const roleAssignments = pgTable("role_assignments", {
31
+ orgId: text("org_id").notNull(),
32
+ id: text("id").notNull().$defaultFn(() => genId("roleAssignment")),
33
+ orgUserId: text("org_user_id").notNull(),
34
+ roleKey: text("role_key").notNull(),
35
+ contentId: text("content_id"),
36
+ contentType: text("content_type", { enum: [
37
+ "course",
38
+ "download",
39
+ "community",
40
+ "event"
41
+ ] }),
42
+ assignedBy: text("assigned_by").notNull(),
43
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
44
+ }, (t) => ({
45
+ pk: primaryKey({ columns: [t.orgId, t.id] }),
46
+ orgUserFk: foreignKey({
47
+ name: "role_assignments_org_user_fk",
48
+ columns: [t.orgId, t.orgUserId],
49
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
50
+ }).onDelete("cascade"),
51
+ contentFk: foreignKey({
52
+ name: "role_assignments_content_fk",
53
+ columns: [
54
+ t.orgId,
55
+ t.contentId,
56
+ t.contentType
57
+ ],
58
+ foreignColumns: [
59
+ contentItems.orgId,
60
+ contentItems.id,
61
+ contentItems.type
62
+ ]
63
+ }).onDelete("cascade"),
64
+ scopeUq: unique("role_assignments_scope_uq").on(t.orgId, t.orgUserId, t.contentId).nullsNotDistinct(),
65
+ ownerUq: uniqueIndex("role_assignments_owner_uq").on(t.orgId).where(sql`${t.roleKey} = 'owner'`),
66
+ contentIdx: index("role_assignments_content_idx").on(t.orgId, t.contentId)
67
+ }));
68
+ //#endregion
69
+ export { orgRoles, roleAssignments };
70
+
71
+ //# sourceMappingURL=roles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roles.js","names":[],"sources":["../../src/schema/roles.ts"],"sourcesContent":["import { sql } from \"drizzle-orm\";\nimport {\n pgTable,\n text,\n boolean,\n jsonb,\n timestamp,\n foreignKey,\n unique,\n uniqueIndex,\n index,\n primaryKey,\n} from \"drizzle-orm/pg-core\";\nimport type { OrgRoleRow, RoleAssignment } from \"@headless-lms/core/schemas\";\nimport { genId } from \"@headless-lms/core/shared/id\";\nimport { organizations, orgUsers } from \"./organizations.js\";\nimport { contentItems } from \"./content.js\";\nimport type { Expect, NoDrift } from \"./drift.js\";\n\nexport const orgRoles = pgTable(\n \"org_roles\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id, { onDelete: \"cascade\" }),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"orgRole\")),\n key: text(\"key\").notNull(),\n name: text(\"name\"),\n description: text(\"description\"),\n base: text(\"base\").notNull(),\n levels: text(\"levels\", { enum: [\"org\", \"course\", \"download\", \"community\", \"event\"] }).array(),\n permissions: jsonb(\"permissions\").$type<Record<string, boolean>>().notNull().default({}),\n team: boolean(\"team\"),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp(\"updated_at\", { withTimezone: true })\n .notNull()\n .defaultNow()\n .$onUpdate(() => new Date()),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.id] }),\n keyUq: unique(\"org_roles_key_uq\").on(t.orgId, t.key),\n nameUq: uniqueIndex(\"org_roles_name_uq\")\n .on(t.orgId, sql`lower(${t.name})`)\n .where(sql`${t.name} is not null`),\n }),\n);\n\nexport const roleAssignments = pgTable(\n \"role_assignments\",\n {\n orgId: text(\"org_id\").notNull(),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"roleAssignment\")),\n orgUserId: text(\"org_user_id\").notNull(),\n roleKey: text(\"role_key\").notNull(),\n contentId: text(\"content_id\"),\n contentType: text(\"content_type\", { enum: [\"course\", \"download\", \"community\", \"event\"] }),\n assignedBy: text(\"assigned_by\").notNull(),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.id] }),\n orgUserFk: foreignKey({\n name: \"role_assignments_org_user_fk\",\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n contentFk: foreignKey({\n name: \"role_assignments_content_fk\",\n columns: [t.orgId, t.contentId, t.contentType],\n foreignColumns: [contentItems.orgId, contentItems.id, contentItems.type],\n }).onDelete(\"cascade\"),\n scopeUq: unique(\"role_assignments_scope_uq\")\n .on(t.orgId, t.orgUserId, t.contentId)\n .nullsNotDistinct(),\n ownerUq: uniqueIndex(\"role_assignments_owner_uq\")\n .on(t.orgId)\n .where(sql`${t.roleKey} = 'owner'`),\n contentIdx: index(\"role_assignments_content_idx\").on(t.orgId, t.contentId),\n }),\n);\n\ntype _OrgRolesDrift = Expect<NoDrift<typeof orgRoles.$inferSelect, OrgRoleRow>>;\ntype _RoleAssignmentsDrift = Expect<NoDrift<typeof roleAssignments.$inferSelect, RoleAssignment>>;\n"],"mappings":";;;;;;AAmBA,MAAa,WAAW,QACtB,aACA;CACE,OAAO,KAAK,QAAQ,CAAC,CAClB,QAAQ,CAAC,CACT,iBAAiB,cAAc,IAAI,EAAE,UAAU,UAAU,CAAC;CAC7D,IAAI,KAAK,IAAI,CAAC,CACX,QAAQ,CAAC,CACT,iBAAiB,MAAM,SAAS,CAAC;CACpC,KAAK,KAAK,KAAK,CAAC,CAAC,QAAQ;CACzB,MAAM,KAAK,MAAM;CACjB,aAAa,KAAK,aAAa;CAC/B,MAAM,KAAK,MAAM,CAAC,CAAC,QAAQ;CAC3B,QAAQ,KAAK,UAAU,EAAE,MAAM;EAAC;EAAO;EAAU;EAAY;EAAa;CAAO,EAAE,CAAC,CAAC,CAAC,MAAM;CAC5F,aAAa,MAAM,aAAa,CAAC,CAAC,MAA+B,CAAC,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;CACvF,MAAM,QAAQ,MAAM;CACpB,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;CAChF,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CACvD,QAAQ,CAAC,CACT,WAAW,CAAC,CACZ,gCAAgB,IAAI,KAAK,CAAC;AAC/B,IACC,OAAO;CACN,IAAI,WAAW,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;CAC3C,OAAO,OAAO,kBAAkB,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG;CACnD,QAAQ,YAAY,mBAAmB,CAAC,CACrC,GAAG,EAAE,OAAO,GAAG,SAAS,EAAE,KAAK,EAAE,CAAC,CAClC,MAAM,GAAG,GAAG,EAAE,KAAK,aAAa;AACrC,EACF;AAEA,MAAa,kBAAkB,QAC7B,oBACA;CACE,OAAO,KAAK,QAAQ,CAAC,CAAC,QAAQ;CAC9B,IAAI,KAAK,IAAI,CAAC,CACX,QAAQ,CAAC,CACT,iBAAiB,MAAM,gBAAgB,CAAC;CAC3C,WAAW,KAAK,aAAa,CAAC,CAAC,QAAQ;CACvC,SAAS,KAAK,UAAU,CAAC,CAAC,QAAQ;CAClC,WAAW,KAAK,YAAY;CAC5B,aAAa,KAAK,gBAAgB,EAAE,MAAM;EAAC;EAAU;EAAY;EAAa;CAAO,EAAE,CAAC;CACxF,YAAY,KAAK,aAAa,CAAC,CAAC,QAAQ;CACxC,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,WAAW;AAClF,IACC,OAAO;CACN,IAAI,WAAW,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;CAC3C,WAAW,WAAW;EACpB,MAAM;EACN,SAAS,CAAC,EAAE,OAAO,EAAE,SAAS;EAC9B,gBAAgB,CAAC,SAAS,OAAO,SAAS,EAAE;CAC9C,CAAC,CAAC,CAAC,SAAS,SAAS;CACrB,WAAW,WAAW;EACpB,MAAM;EACN,SAAS;GAAC,EAAE;GAAO,EAAE;GAAW,EAAE;EAAW;EAC7C,gBAAgB;GAAC,aAAa;GAAO,aAAa;GAAI,aAAa;EAAI;CACzE,CAAC,CAAC,CAAC,SAAS,SAAS;CACrB,SAAS,OAAO,2BAA2B,CAAC,CACzC,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,CAAC,CACrC,iBAAiB;CACpB,SAAS,YAAY,2BAA2B,CAAC,CAC9C,GAAG,EAAE,KAAK,CAAC,CACX,MAAM,GAAG,GAAG,EAAE,QAAQ,WAAW;CACpC,YAAY,MAAM,8BAA8B,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS;AAC3E,EACF"}
@@ -0,0 +1,38 @@
1
+ CREATE TABLE "org_roles" (
2
+ "org_id" text NOT NULL,
3
+ "id" text NOT NULL,
4
+ "key" text NOT NULL,
5
+ "name" text,
6
+ "description" text,
7
+ "base" text NOT NULL,
8
+ "levels" text[],
9
+ "permissions" jsonb DEFAULT '{}'::jsonb NOT NULL,
10
+ "team" boolean,
11
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
12
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
13
+ CONSTRAINT "org_roles_org_id_id_pk" PRIMARY KEY("org_id","id"),
14
+ CONSTRAINT "org_roles_key_uq" UNIQUE("org_id","key")
15
+ );
16
+ --> statement-breakpoint
17
+ CREATE TABLE "role_assignments" (
18
+ "org_id" text NOT NULL,
19
+ "id" text NOT NULL,
20
+ "org_user_id" text NOT NULL,
21
+ "role_key" text NOT NULL,
22
+ "content_id" text,
23
+ "content_type" text,
24
+ "assigned_by" text NOT NULL,
25
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
26
+ CONSTRAINT "role_assignments_org_id_id_pk" PRIMARY KEY("org_id","id"),
27
+ CONSTRAINT "role_assignments_scope_uq" UNIQUE NULLS NOT DISTINCT("org_id","org_user_id","content_id")
28
+ );
29
+ --> statement-breakpoint
30
+ ALTER TABLE "invites" ALTER COLUMN "role" SET DEFAULT 'member';--> statement-breakpoint
31
+ ALTER TABLE "assets" ADD COLUMN "content_id" text;--> statement-breakpoint
32
+ ALTER TABLE "org_roles" ADD CONSTRAINT "org_roles_org_id_organizations_id_fk" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
33
+ ALTER TABLE "role_assignments" ADD CONSTRAINT "role_assignments_org_user_fk" FOREIGN KEY ("org_id","org_user_id") REFERENCES "public"."org_users"("org_id","id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
34
+ ALTER TABLE "role_assignments" ADD CONSTRAINT "role_assignments_content_fk" FOREIGN KEY ("org_id","content_id","content_type") REFERENCES "public"."content_items"("org_id","id","type") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
35
+ CREATE UNIQUE INDEX "org_roles_name_uq" ON "org_roles" USING btree ("org_id",lower("name")) WHERE "org_roles"."name" is not null;--> statement-breakpoint
36
+ CREATE UNIQUE INDEX "role_assignments_owner_uq" ON "role_assignments" USING btree ("org_id") WHERE "role_assignments"."role_key" = 'owner';--> statement-breakpoint
37
+ CREATE INDEX "role_assignments_content_idx" ON "role_assignments" USING btree ("org_id","content_id");--> statement-breakpoint
38
+ ALTER TABLE "org_users" DROP COLUMN "role";
@@ -0,0 +1,2 @@
1
+ ALTER TABLE "messages" ADD COLUMN "client_id" uuid;--> statement-breakpoint
2
+ CREATE UNIQUE INDEX "messages_client_id_uq" ON "messages" USING btree ("org_id","chat_id","org_user_id","client_id");
@@ -0,0 +1,44 @@
1
+ CREATE TABLE "event_assets" (
2
+ "org_id" text NOT NULL,
3
+ "id" text NOT NULL,
4
+ "event_id" text NOT NULL,
5
+ "asset_id" text NOT NULL,
6
+ "seq" integer DEFAULT 0 NOT NULL,
7
+ "display_name" text,
8
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
9
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
10
+ CONSTRAINT "event_assets_org_id_id_pk" PRIMARY KEY("org_id","id"),
11
+ CONSTRAINT "event_assets_org_id_event_id_asset_id_unique" UNIQUE("org_id","event_id","asset_id")
12
+ );
13
+ --> statement-breakpoint
14
+ CREATE TABLE "events" (
15
+ "org_id" text NOT NULL,
16
+ "id" text NOT NULL,
17
+ "type" text GENERATED ALWAYS AS ('event') STORED NOT NULL,
18
+ "title" text NOT NULL,
19
+ "description" text DEFAULT '' NOT NULL,
20
+ "thumbnail_asset_id" text,
21
+ "status" text DEFAULT 'draft' NOT NULL,
22
+ "starts_at" timestamp with time zone NOT NULL,
23
+ "ends_at" timestamp with time zone NOT NULL,
24
+ "time_zone" text NOT NULL,
25
+ "location" jsonb DEFAULT '{"venue":null,"online":null}'::jsonb NOT NULL,
26
+ "recording" jsonb,
27
+ "created_at" timestamp with time zone DEFAULT now() NOT NULL,
28
+ "updated_at" timestamp with time zone DEFAULT now() NOT NULL,
29
+ CONSTRAINT "events_org_id_id_pk" PRIMARY KEY("org_id","id"),
30
+ CONSTRAINT "events_times_check" CHECK ("events"."ends_at" > "events"."starts_at")
31
+ );
32
+ --> statement-breakpoint
33
+ ALTER TABLE "content_items" DROP CONSTRAINT "content_items_type_check";--> statement-breakpoint
34
+ ALTER TABLE "event_assets" ADD CONSTRAINT "event_assets_org_id_organizations_id_fk" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
35
+ ALTER TABLE "event_assets" ADD CONSTRAINT "event_assets_org_id_event_id_events_org_id_id_fk" FOREIGN KEY ("org_id","event_id") REFERENCES "public"."events"("org_id","id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
36
+ ALTER TABLE "event_assets" ADD CONSTRAINT "event_assets_org_id_asset_id_assets_org_id_id_fk" FOREIGN KEY ("org_id","asset_id") REFERENCES "public"."assets"("org_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
37
+ ALTER TABLE "events" ADD CONSTRAINT "events_org_id_organizations_id_fk" FOREIGN KEY ("org_id") REFERENCES "public"."organizations"("id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
38
+ ALTER TABLE "events" ADD CONSTRAINT "events_org_id_id_type_content_items_org_id_id_type_fk" FOREIGN KEY ("org_id","id","type") REFERENCES "public"."content_items"("org_id","id","type") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
39
+ ALTER TABLE "events" ADD CONSTRAINT "events_org_id_thumbnail_asset_id_assets_org_id_id_fk" FOREIGN KEY ("org_id","thumbnail_asset_id") REFERENCES "public"."assets"("org_id","id") ON DELETE no action ON UPDATE no action;--> statement-breakpoint
40
+ CREATE INDEX "event_assets_asset_idx" ON "event_assets" USING btree ("org_id","asset_id");--> statement-breakpoint
41
+ CREATE INDEX "events_thumbnail_idx" ON "events" USING btree ("org_id","thumbnail_asset_id");--> statement-breakpoint
42
+ CREATE INDEX "events_status_starts_idx" ON "events" USING btree ("org_id","status","starts_at");--> statement-breakpoint
43
+ ALTER TABLE "content_items" ADD CONSTRAINT "content_items_type_check" CHECK ("content_items"."type" in ('course', 'download', 'community', 'event'));--> statement-breakpoint
44
+ ALTER TABLE "notifications" RENAME COLUMN "actor_org_user_id" TO "actor_id";