@headless-lms/adapter-db 0.2.0 → 0.4.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 (134) hide show
  1. package/dist/index.d.ts +12 -6
  2. package/dist/index.js +12 -6
  3. package/dist/repositories/admin.d.ts +23 -0
  4. package/dist/repositories/admin.js +393 -0
  5. package/dist/repositories/admin.js.map +1 -0
  6. package/dist/repositories/assets.d.ts +6 -3
  7. package/dist/repositories/assets.js +46 -9
  8. package/dist/repositories/assets.js.map +1 -1
  9. package/dist/repositories/automations.d.ts +5 -2
  10. package/dist/repositories/automations.js +29 -2
  11. package/dist/repositories/automations.js.map +1 -1
  12. package/dist/repositories/chats.d.ts +55 -0
  13. package/dist/repositories/chats.js +469 -0
  14. package/dist/repositories/chats.js.map +1 -0
  15. package/dist/repositories/content.d.ts +24 -1
  16. package/dist/repositories/content.js +316 -9
  17. package/dist/repositories/content.js.map +1 -1
  18. package/dist/repositories/devices.d.ts +17 -0
  19. package/dist/repositories/devices.js +75 -0
  20. package/dist/repositories/devices.js.map +1 -0
  21. package/dist/repositories/digest-runs.d.ts +14 -0
  22. package/dist/repositories/digest-runs.js +39 -0
  23. package/dist/repositories/digest-runs.js.map +1 -0
  24. package/dist/repositories/discussion.d.ts +16 -4
  25. package/dist/repositories/discussion.js +78 -18
  26. package/dist/repositories/discussion.js.map +1 -1
  27. package/dist/repositories/entitlements.d.ts +31 -9
  28. package/dist/repositories/entitlements.js +213 -17
  29. package/dist/repositories/entitlements.js.map +1 -1
  30. package/dist/repositories/grant-covers.d.ts +20 -0
  31. package/dist/repositories/grant-covers.js +55 -0
  32. package/dist/repositories/grant-covers.js.map +1 -0
  33. package/dist/repositories/identity.d.ts +4 -2
  34. package/dist/repositories/identity.js +32 -1
  35. package/dist/repositories/identity.js.map +1 -1
  36. package/dist/repositories/inserted-row.d.ts +5 -0
  37. package/dist/repositories/inserted-row.js +7 -0
  38. package/dist/repositories/inserted-row.js.map +1 -0
  39. package/dist/repositories/member.d.ts +16 -0
  40. package/dist/repositories/member.js +63 -0
  41. package/dist/repositories/member.js.map +1 -0
  42. package/dist/repositories/members.js +2 -2
  43. package/dist/repositories/members.js.map +1 -1
  44. package/dist/repositories/mentions.d.ts +17 -0
  45. package/dist/repositories/mentions.js +55 -0
  46. package/dist/repositories/mentions.js.map +1 -0
  47. package/dist/repositories/notification-settings.d.ts +19 -0
  48. package/dist/repositories/notification-settings.js +67 -0
  49. package/dist/repositories/notification-settings.js.map +1 -0
  50. package/dist/repositories/notifications.d.ts +30 -0
  51. package/dist/repositories/notifications.js +178 -0
  52. package/dist/repositories/notifications.js.map +1 -0
  53. package/dist/repositories/org-user-profile.d.ts +214 -1
  54. package/dist/repositories/org-user-profile.js +23 -2
  55. package/dist/repositories/org-user-profile.js.map +1 -1
  56. package/dist/repositories/organizations.d.ts +4 -2
  57. package/dist/repositories/organizations.js +23 -8
  58. package/dist/repositories/organizations.js.map +1 -1
  59. package/dist/repositories/pg-errors.js +3 -1
  60. package/dist/repositories/pg-errors.js.map +1 -1
  61. package/dist/repositories/posts.d.ts +35 -0
  62. package/dist/repositories/posts.js +252 -0
  63. package/dist/repositories/posts.js.map +1 -0
  64. package/dist/repositories/subscriptions.d.ts +18 -0
  65. package/dist/repositories/subscriptions.js +72 -0
  66. package/dist/repositories/subscriptions.js.map +1 -0
  67. package/dist/schema/assets.d.ts +19 -2
  68. package/dist/schema/assets.js +10 -4
  69. package/dist/schema/assets.js.map +1 -1
  70. package/dist/schema/automations.d.ts +545 -2
  71. package/dist/schema/automations.js +73 -3
  72. package/dist/schema/automations.js.map +1 -1
  73. package/dist/schema/better-auth.d.ts +1613 -238
  74. package/dist/schema/better-auth.js +107 -22
  75. package/dist/schema/better-auth.js.map +1 -1
  76. package/dist/schema/content.d.ts +642 -5
  77. package/dist/schema/content.js +119 -10
  78. package/dist/schema/content.js.map +1 -1
  79. package/dist/schema/discussion.d.ts +2182 -42
  80. package/dist/schema/discussion.js +461 -11
  81. package/dist/schema/discussion.js.map +1 -1
  82. package/dist/schema/entitlements.d.ts +432 -1
  83. package/dist/schema/entitlements.js +109 -4
  84. package/dist/schema/entitlements.js.map +1 -1
  85. package/dist/schema/identity.d.ts +517 -1
  86. package/dist/schema/identity.js +76 -2
  87. package/dist/schema/identity.js.map +1 -1
  88. package/dist/schema/index.d.ts +7 -7
  89. package/dist/schema/index.js +35 -8
  90. package/dist/schema/organizations.d.ts +4 -4
  91. package/dist/schema/organizations.js +2 -0
  92. package/dist/schema/organizations.js.map +1 -1
  93. package/drizzle/0003_community.sql +340 -0
  94. package/drizzle/0004_assets_sources.sql +1 -0
  95. package/drizzle/0005_notices_and_seed_index.sql +12 -0
  96. package/drizzle/0006_community_review_fixes.sql +24 -0
  97. package/drizzle/0007_notifications.sql +37 -0
  98. package/drizzle/0008_content_access.sql +13 -0
  99. package/drizzle/0009_community_indexes.sql +56 -0
  100. package/drizzle/0010_mcp_access.sql +114 -0
  101. package/drizzle/0011_digest_runs.sql +8 -0
  102. package/drizzle/0012_subscriptions.sql +16 -0
  103. package/drizzle/0013_mentions.sql +10 -0
  104. package/drizzle/0014_notification_settings_devices.sql +36 -0
  105. package/drizzle/0015_automations_drop_source.sql +2 -0
  106. package/drizzle/0016_notifications_automations.sql +48 -0
  107. package/drizzle/meta/0003_snapshot.json +7061 -0
  108. package/drizzle/meta/0004_snapshot.json +7068 -0
  109. package/drizzle/meta/0005_snapshot.json +7180 -0
  110. package/drizzle/meta/0006_snapshot.json +7298 -0
  111. package/drizzle/meta/0007_snapshot.json +7620 -0
  112. package/drizzle/meta/0008_snapshot.json +7666 -0
  113. package/drizzle/meta/0009_snapshot.json +8185 -0
  114. package/drizzle/meta/0010_snapshot.json +8813 -0
  115. package/drizzle/meta/0011_snapshot.json +8868 -0
  116. package/drizzle/meta/0012_snapshot.json +8873 -0
  117. package/drizzle/meta/0013_snapshot.json +8943 -0
  118. package/drizzle/meta/0014_snapshot.json +9305 -0
  119. package/drizzle/meta/0015_snapshot.json +9270 -0
  120. package/drizzle/meta/0016_snapshot.json +9230 -0
  121. package/drizzle/meta/_journal.json +99 -1
  122. package/package.json +2 -2
  123. package/dist/repositories/course-analytics.d.ts +0 -15
  124. package/dist/repositories/course-analytics.js +0 -137
  125. package/dist/repositories/course-analytics.js.map +0 -1
  126. package/dist/repositories/dashboard.d.ts +0 -14
  127. package/dist/repositories/dashboard.js +0 -57
  128. package/dist/repositories/dashboard.js.map +0 -1
  129. package/dist/repositories/learn.d.ts +0 -19
  130. package/dist/repositories/learn.js +0 -56
  131. package/dist/repositories/learn.js.map +0 -1
  132. package/dist/repositories/students.d.ts +0 -16
  133. package/dist/repositories/students.js +0 -160
  134. package/dist/repositories/students.js.map +0 -1
@@ -1,13 +1,156 @@
1
+ import { assets } from "./assets.js";
2
+ import { activities, communities, spaceTopics, spaces } from "./content.js";
1
3
  import { orgUsers, organizations } from "./organizations.js";
2
- import { activities } from "./content.js";
3
- import { sql } from "drizzle-orm";
4
- import { check, foreignKey, index, pgTable, primaryKey, text, timestamp, unique } from "drizzle-orm/pg-core";
4
+ import { desc, sql } from "drizzle-orm";
5
+ import { boolean, check, foreignKey, index, integer, jsonb, pgTable, primaryKey, text, timestamp, unique } from "drizzle-orm/pg-core";
5
6
  import { genId } from "@headless-lms/core/shared/id";
6
7
  //#region src/schema/discussion.ts
8
+ const posts = pgTable("posts", {
9
+ orgId: text("org_id").notNull().references(() => organizations.id),
10
+ id: text("id").notNull().$defaultFn(() => genId("post")),
11
+ communityId: text("community_id").notNull(),
12
+ spaceId: text("space_id").notNull(),
13
+ orgUserId: text("org_user_id").notNull(),
14
+ topicId: text("topic_id"),
15
+ title: text("title").notNull(),
16
+ body: text("body").notNull(),
17
+ extra: jsonb("extra").$type().notNull().default({}),
18
+ coverAssetId: text("cover_asset_id"),
19
+ status: text("status", { enum: [
20
+ "draft",
21
+ "scheduled",
22
+ "pending",
23
+ "published",
24
+ "removed"
25
+ ] }).notNull().default("draft"),
26
+ scheduledAt: timestamp("scheduled_at", { withTimezone: true }),
27
+ publishedAt: timestamp("published_at", { withTimezone: true }),
28
+ removedBy: text("removed_by"),
29
+ pinned: boolean("pinned").notNull().default(false),
30
+ commentsClosed: boolean("comments_closed"),
31
+ reactionsEnabled: boolean("reactions_enabled"),
32
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
33
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
34
+ }, (t) => ({
35
+ pk: primaryKey({ columns: [t.orgId, t.id] }),
36
+ spaceFk: foreignKey({
37
+ columns: [
38
+ t.orgId,
39
+ t.spaceId,
40
+ t.communityId
41
+ ],
42
+ foreignColumns: [
43
+ spaces.orgId,
44
+ spaces.id,
45
+ spaces.communityId
46
+ ]
47
+ }).onDelete("cascade"),
48
+ authorFk: foreignKey({
49
+ columns: [t.orgId, t.orgUserId],
50
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
51
+ }),
52
+ topicFk: foreignKey({
53
+ columns: [
54
+ t.orgId,
55
+ t.spaceId,
56
+ t.topicId
57
+ ],
58
+ foreignColumns: [
59
+ spaceTopics.orgId,
60
+ spaceTopics.spaceId,
61
+ spaceTopics.id
62
+ ]
63
+ }),
64
+ coverAssetFk: foreignKey({
65
+ columns: [t.orgId, t.coverAssetId],
66
+ foreignColumns: [assets.orgId, assets.id]
67
+ }),
68
+ removedByFk: foreignKey({
69
+ columns: [t.orgId, t.removedBy],
70
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
71
+ }).onDelete("set null"),
72
+ removedCk: check("posts_removed_by_check", sql`${t.removedBy} is null or ${t.status} = 'removed'`),
73
+ scheduledCk: check("posts_scheduled_check", sql`${t.status} <> 'scheduled' or ${t.scheduledAt} is not null`),
74
+ feedIdx: index("posts_feed_idx").on(t.orgId, t.spaceId, t.status, desc(t.pinned), desc(t.publishedAt)),
75
+ dueIdx: index("posts_due_idx").on(t.orgId, t.status, t.scheduledAt),
76
+ authorIdx: index("posts_author_idx").on(t.orgId, t.orgUserId, t.createdAt),
77
+ coverAssetIdx: index("posts_cover_asset_idx").on(t.orgId, t.coverAssetId)
78
+ }));
79
+ const postReactions = pgTable("post_reactions", {
80
+ orgId: text("org_id").notNull().references(() => organizations.id),
81
+ postId: text("post_id").notNull(),
82
+ orgUserId: text("org_user_id").notNull(),
83
+ emoji: text("emoji").notNull(),
84
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
85
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
86
+ }, (t) => ({
87
+ pk: primaryKey({ columns: [
88
+ t.orgId,
89
+ t.postId,
90
+ t.orgUserId
91
+ ] }),
92
+ postFk: foreignKey({
93
+ columns: [t.orgId, t.postId],
94
+ foreignColumns: [posts.orgId, posts.id]
95
+ }).onDelete("cascade"),
96
+ orgUserFk: foreignKey({
97
+ columns: [t.orgId, t.orgUserId],
98
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
99
+ }).onDelete("cascade")
100
+ }));
101
+ const postBookmarks = pgTable("post_bookmarks", {
102
+ orgId: text("org_id").notNull().references(() => organizations.id),
103
+ postId: text("post_id").notNull(),
104
+ orgUserId: text("org_user_id").notNull(),
105
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
106
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
107
+ }, (t) => ({
108
+ pk: primaryKey({ columns: [
109
+ t.orgId,
110
+ t.postId,
111
+ t.orgUserId
112
+ ] }),
113
+ postFk: foreignKey({
114
+ columns: [t.orgId, t.postId],
115
+ foreignColumns: [posts.orgId, posts.id]
116
+ }).onDelete("cascade"),
117
+ orgUserFk: foreignKey({
118
+ columns: [t.orgId, t.orgUserId],
119
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
120
+ }).onDelete("cascade"),
121
+ userIdx: index("post_bookmarks_user_idx").on(t.orgId, t.orgUserId, t.createdAt)
122
+ }));
123
+ const postFlags = pgTable("post_flags", {
124
+ orgId: text("org_id").notNull().references(() => organizations.id),
125
+ id: text("id").notNull().$defaultFn(() => genId("postFlag")),
126
+ postId: text("post_id").notNull(),
127
+ orgUserId: text("org_user_id").notNull(),
128
+ reason: text("reason").notNull().default(""),
129
+ resolvedAt: timestamp("resolved_at", { withTimezone: true }),
130
+ resolution: text("resolution", { enum: ["dismissed", "removed"] }),
131
+ resolvedBy: text("resolved_by"),
132
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
133
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
134
+ }, (t) => ({
135
+ pk: primaryKey({ columns: [t.orgId, t.id] }),
136
+ reporterUq: unique().on(t.orgId, t.postId, t.orgUserId),
137
+ postFk: foreignKey({
138
+ columns: [t.orgId, t.postId],
139
+ foreignColumns: [posts.orgId, posts.id]
140
+ }).onDelete("cascade"),
141
+ reporterFk: foreignKey({
142
+ columns: [t.orgId, t.orgUserId],
143
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
144
+ }).onDelete("cascade"),
145
+ resolvedCk: check("post_flags_resolved_check", sql`(${t.resolvedAt} is null) = (${t.resolution} is null) and (${t.resolvedAt} is null) = (${t.resolvedBy} is null)`),
146
+ openIdx: index("post_flags_open_idx").on(t.orgId, t.postId, t.resolvedAt)
147
+ }));
7
148
  const comments = pgTable("comments", {
8
149
  orgId: text("org_id").notNull().references(() => organizations.id),
9
150
  id: text("id").notNull().$defaultFn(() => genId("comment")),
10
- activityId: text("activity_id").notNull(),
151
+ activityId: text("activity_id"),
152
+ postId: text("post_id"),
153
+ communityId: text("community_id"),
11
154
  parentId: text("parent_id"),
12
155
  orgUserId: text("org_user_id").notNull(),
13
156
  body: text("body").notNull(),
@@ -25,6 +168,14 @@ const comments = pgTable("comments", {
25
168
  columns: [t.orgId, t.activityId],
26
169
  foreignColumns: [activities.orgId, activities.id]
27
170
  }).onDelete("cascade"),
171
+ postFk: foreignKey({
172
+ columns: [t.orgId, t.postId],
173
+ foreignColumns: [posts.orgId, posts.id]
174
+ }).onDelete("cascade"),
175
+ communityFk: foreignKey({
176
+ columns: [t.orgId, t.communityId],
177
+ foreignColumns: [communities.orgId, communities.id]
178
+ }).onDelete("cascade"),
28
179
  authorFk: foreignKey({
29
180
  columns: [t.orgId, t.orgUserId],
30
181
  foreignColumns: [orgUsers.orgId, orgUsers.id]
@@ -32,14 +183,19 @@ const comments = pgTable("comments", {
32
183
  removedByFk: foreignKey({
33
184
  columns: [t.orgId, t.removedBy],
34
185
  foreignColumns: [orgUsers.orgId, orgUsers.id]
35
- }),
186
+ }).onDelete("set null"),
36
187
  parentFk: foreignKey({
37
188
  columns: [t.orgId, t.parentId],
38
189
  foreignColumns: [t.orgId, t.id]
39
190
  }),
40
- removedCk: check("comments_removed_by_check", sql`(${t.status} = 'removed') = (${t.removedBy} is not null)`),
191
+ removedCk: check("comments_removed_by_check", sql`${t.removedBy} is null or ${t.status} = 'removed'`),
192
+ targetCk: check("comments_target_check", sql`num_nonnulls(${t.activityId}, ${t.postId}) = 1`),
193
+ communityCk: check("comments_community_check", sql`${t.postId} is null or ${t.communityId} is not null`),
41
194
  activityIdx: index("comments_activity_idx").on(t.orgId, t.activityId, t.status, t.createdAt),
42
- queueIdx: index("comments_queue_idx").on(t.orgId, t.status, t.createdAt)
195
+ postIdx: index("comments_post_idx").on(t.orgId, t.postId, t.status, t.createdAt),
196
+ queueIdx: index("comments_queue_idx").on(t.orgId, t.status, t.createdAt),
197
+ communityIdx: index("comments_community_idx").on(t.orgId, t.communityId),
198
+ parentIdx: index("comments_parent_idx").on(t.orgId, t.parentId, t.createdAt)
43
199
  }));
44
200
  const commentReactions = pgTable("comment_reactions", {
45
201
  orgId: text("org_id").notNull().references(() => organizations.id),
@@ -61,15 +217,17 @@ const commentReactions = pgTable("comment_reactions", {
61
217
  authorFk: foreignKey({
62
218
  columns: [t.orgId, t.orgUserId],
63
219
  foreignColumns: [orgUsers.orgId, orgUsers.id]
64
- })
220
+ }).onDelete("cascade")
65
221
  }));
66
- const commentReports = pgTable("comment_reports", {
222
+ const commentFlags = pgTable("comment_flags", {
67
223
  orgId: text("org_id").notNull().references(() => organizations.id),
68
224
  id: text("id").notNull().$defaultFn(() => genId("commentReport")),
69
225
  commentId: text("comment_id").notNull(),
70
226
  orgUserId: text("org_user_id").notNull(),
71
227
  reason: text("reason").notNull().default(""),
72
228
  resolvedAt: timestamp("resolved_at", { withTimezone: true }),
229
+ resolution: text("resolution", { enum: ["dismissed", "removed"] }),
230
+ resolvedBy: text("resolved_by"),
73
231
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
74
232
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
75
233
  }, (t) => ({
@@ -82,10 +240,302 @@ const commentReports = pgTable("comment_reports", {
82
240
  reporterFk: foreignKey({
83
241
  columns: [t.orgId, t.orgUserId],
84
242
  foreignColumns: [orgUsers.orgId, orgUsers.id]
243
+ }).onDelete("cascade"),
244
+ resolvedCk: check("comment_flags_resolved_check", sql`(${t.resolvedAt} is null) = (${t.resolution} is null) and (${t.resolvedBy} is null or ${t.resolvedAt} is not null)`),
245
+ openIdx: index("comment_flags_open_idx").on(t.orgId, t.commentId, t.resolvedAt)
246
+ }));
247
+ const chats = pgTable("chats", {
248
+ orgId: text("org_id").notNull().references(() => organizations.id),
249
+ id: text("id").notNull().$defaultFn(() => genId("chat")),
250
+ communityId: text("community_id").notNull(),
251
+ kind: text("kind", { enum: ["direct", "group"] }).notNull(),
252
+ status: text("status", { enum: [
253
+ "pending",
254
+ "open",
255
+ "closed"
256
+ ] }).notNull().default("open"),
257
+ createdBy: text("created_by"),
258
+ lockedAt: timestamp("locked_at", { withTimezone: true }),
259
+ lockedBy: text("locked_by"),
260
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
261
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
262
+ }, (t) => ({
263
+ pk: primaryKey({ columns: [t.orgId, t.id] }),
264
+ communityUq: unique().on(t.orgId, t.id, t.communityId),
265
+ communityFk: foreignKey({
266
+ columns: [t.orgId, t.communityId],
267
+ foreignColumns: [communities.orgId, communities.id]
268
+ }).onDelete("cascade"),
269
+ createdByFk: foreignKey({
270
+ columns: [t.orgId, t.createdBy],
271
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
272
+ }).onDelete("set null"),
273
+ lockedByFk: foreignKey({
274
+ columns: [t.orgId, t.lockedBy],
275
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
276
+ }).onDelete("set null"),
277
+ lockedCk: check("chats_locked_check", sql`${t.lockedBy} is null or ${t.lockedAt} is not null`)
278
+ }));
279
+ const chatUsers = pgTable("chat_users", {
280
+ orgId: text("org_id").notNull().references(() => organizations.id),
281
+ communityId: text("community_id").notNull(),
282
+ chatId: text("chat_id").notNull(),
283
+ orgUserId: text("org_user_id").notNull(),
284
+ joinedAt: timestamp("joined_at", { withTimezone: true }).notNull().defaultNow(),
285
+ leftAt: timestamp("left_at", { withTimezone: true }),
286
+ lastReadMessageId: text("last_read_message_id"),
287
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
288
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
289
+ }, (t) => ({
290
+ pk: primaryKey({ columns: [
291
+ t.orgId,
292
+ t.chatId,
293
+ t.orgUserId
294
+ ] }),
295
+ chatFk: foreignKey({
296
+ columns: [
297
+ t.orgId,
298
+ t.chatId,
299
+ t.communityId
300
+ ],
301
+ foreignColumns: [
302
+ chats.orgId,
303
+ chats.id,
304
+ chats.communityId
305
+ ]
306
+ }).onDelete("cascade"),
307
+ orgUserFk: foreignKey({
308
+ columns: [t.orgId, t.orgUserId],
309
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
310
+ }).onDelete("cascade"),
311
+ userIdx: index("chat_users_user_idx").on(t.orgId, t.communityId, t.orgUserId)
312
+ }));
313
+ const messages = pgTable("messages", {
314
+ orgId: text("org_id").notNull().references(() => organizations.id),
315
+ id: text("id").notNull().$defaultFn(() => genId("message")),
316
+ communityId: text("community_id").notNull(),
317
+ chatId: text("chat_id").notNull(),
318
+ orgUserId: text("org_user_id").notNull(),
319
+ body: text("body").notNull(),
320
+ replyToId: text("reply_to_id"),
321
+ editedAt: timestamp("edited_at", { withTimezone: true }),
322
+ deletedAt: timestamp("deleted_at", { withTimezone: true }),
323
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
324
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
325
+ }, (t) => ({
326
+ pk: primaryKey({ columns: [t.orgId, t.id] }),
327
+ communityUq: unique().on(t.orgId, t.id, t.communityId),
328
+ chatFk: foreignKey({
329
+ columns: [
330
+ t.orgId,
331
+ t.chatId,
332
+ t.communityId
333
+ ],
334
+ foreignColumns: [
335
+ chats.orgId,
336
+ chats.id,
337
+ chats.communityId
338
+ ]
339
+ }).onDelete("cascade"),
340
+ authorFk: foreignKey({
341
+ columns: [t.orgId, t.orgUserId],
342
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
343
+ }),
344
+ replyFk: foreignKey({
345
+ columns: [t.orgId, t.replyToId],
346
+ foreignColumns: [t.orgId, t.id]
85
347
  }),
86
- openIdx: index("comment_reports_open_idx").on(t.orgId, t.commentId, t.resolvedAt)
348
+ chatIdx: index("messages_chat_idx").on(t.orgId, t.chatId, t.createdAt),
349
+ replyIdx: index("messages_reply_idx").on(t.orgId, t.replyToId)
350
+ }));
351
+ const messageAttachments = pgTable("message_attachments", {
352
+ orgId: text("org_id").notNull().references(() => organizations.id),
353
+ communityId: text("community_id").notNull(),
354
+ messageId: text("message_id").notNull(),
355
+ assetId: text("asset_id").notNull(),
356
+ seq: integer("seq").notNull().default(0),
357
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
358
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
359
+ }, (t) => ({
360
+ pk: primaryKey({ columns: [
361
+ t.orgId,
362
+ t.messageId,
363
+ t.assetId
364
+ ] }),
365
+ messageFk: foreignKey({
366
+ columns: [
367
+ t.orgId,
368
+ t.messageId,
369
+ t.communityId
370
+ ],
371
+ foreignColumns: [
372
+ messages.orgId,
373
+ messages.id,
374
+ messages.communityId
375
+ ]
376
+ }).onDelete("cascade"),
377
+ assetFk: foreignKey({
378
+ columns: [t.orgId, t.assetId],
379
+ foreignColumns: [assets.orgId, assets.id]
380
+ }),
381
+ assetIdx: index("message_attachments_asset_idx").on(t.orgId, t.assetId)
382
+ }));
383
+ const messageReactions = pgTable("message_reactions", {
384
+ orgId: text("org_id").notNull().references(() => organizations.id),
385
+ communityId: text("community_id").notNull(),
386
+ messageId: text("message_id").notNull(),
387
+ orgUserId: text("org_user_id").notNull(),
388
+ emoji: text("emoji").notNull(),
389
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
390
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
391
+ }, (t) => ({
392
+ pk: primaryKey({ columns: [
393
+ t.orgId,
394
+ t.messageId,
395
+ t.orgUserId
396
+ ] }),
397
+ messageFk: foreignKey({
398
+ columns: [
399
+ t.orgId,
400
+ t.messageId,
401
+ t.communityId
402
+ ],
403
+ foreignColumns: [
404
+ messages.orgId,
405
+ messages.id,
406
+ messages.communityId
407
+ ]
408
+ }).onDelete("cascade"),
409
+ orgUserFk: foreignKey({
410
+ columns: [t.orgId, t.orgUserId],
411
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
412
+ }).onDelete("cascade")
413
+ }));
414
+ const messageFlags = pgTable("message_flags", {
415
+ orgId: text("org_id").notNull().references(() => organizations.id),
416
+ id: text("id").notNull().$defaultFn(() => genId("messageFlag")),
417
+ communityId: text("community_id").notNull(),
418
+ messageId: text("message_id").notNull(),
419
+ orgUserId: text("org_user_id").notNull(),
420
+ reason: text("reason").notNull().default(""),
421
+ resolvedAt: timestamp("resolved_at", { withTimezone: true }),
422
+ resolution: text("resolution", { enum: [
423
+ "dismissed",
424
+ "deleted",
425
+ "locked"
426
+ ] }),
427
+ resolvedBy: text("resolved_by"),
428
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
429
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
430
+ }, (t) => ({
431
+ pk: primaryKey({ columns: [t.orgId, t.id] }),
432
+ reporterUq: unique().on(t.orgId, t.messageId, t.orgUserId),
433
+ messageFk: foreignKey({
434
+ columns: [
435
+ t.orgId,
436
+ t.messageId,
437
+ t.communityId
438
+ ],
439
+ foreignColumns: [
440
+ messages.orgId,
441
+ messages.id,
442
+ messages.communityId
443
+ ]
444
+ }).onDelete("cascade"),
445
+ reporterFk: foreignKey({
446
+ columns: [t.orgId, t.orgUserId],
447
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
448
+ }).onDelete("cascade"),
449
+ resolvedCk: check("message_flags_resolved_check", sql`(${t.resolvedAt} is null) = (${t.resolution} is null) and (${t.resolvedAt} is null) = (${t.resolvedBy} is null)`),
450
+ openIdx: index("message_flags_open_idx").on(t.orgId, t.communityId, t.messageId, t.resolvedAt)
451
+ }));
452
+ const blockedUsers = pgTable("blocked_users", {
453
+ orgId: text("org_id").notNull().references(() => organizations.id),
454
+ communityId: text("community_id").notNull(),
455
+ blockerOrgUserId: text("blocker_org_user_id").notNull(),
456
+ blockedOrgUserId: text("blocked_org_user_id").notNull(),
457
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
458
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow().$onUpdate(() => /* @__PURE__ */ new Date())
459
+ }, (t) => ({
460
+ pk: primaryKey({ columns: [
461
+ t.orgId,
462
+ t.communityId,
463
+ t.blockerOrgUserId,
464
+ t.blockedOrgUserId
465
+ ] }),
466
+ communityFk: foreignKey({
467
+ columns: [t.orgId, t.communityId],
468
+ foreignColumns: [communities.orgId, communities.id]
469
+ }).onDelete("cascade"),
470
+ blockerFk: foreignKey({
471
+ columns: [t.orgId, t.blockerOrgUserId],
472
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
473
+ }).onDelete("cascade"),
474
+ blockedFk: foreignKey({
475
+ columns: [t.orgId, t.blockedOrgUserId],
476
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
477
+ }).onDelete("cascade"),
478
+ blockedIdx: index("blocked_users_blocked_idx").on(t.orgId, t.communityId, t.blockedOrgUserId)
479
+ }));
480
+ const digestRuns = pgTable("digest_runs", {
481
+ orgId: text("org_id").notNull(),
482
+ communityId: text("community_id").notNull(),
483
+ lastDueAt: timestamp("last_due_at", { withTimezone: true }).notNull()
484
+ }, (t) => ({
485
+ pk: primaryKey({ columns: [t.orgId, t.communityId] }),
486
+ communityFk: foreignKey({
487
+ columns: [t.orgId, t.communityId],
488
+ foreignColumns: [communities.orgId, communities.id]
489
+ }).onDelete("cascade")
490
+ }));
491
+ const subscriptions = pgTable("subscriptions", {
492
+ orgId: text("org_id").notNull(),
493
+ orgUserId: text("org_user_id").notNull(),
494
+ itemType: text("item_type", { enum: [
495
+ "post",
496
+ "space",
497
+ "chat"
498
+ ] }).notNull(),
499
+ itemId: text("item_id").notNull(),
500
+ state: text("state", { enum: ["following", "muted"] }).notNull(),
501
+ mutedUntil: timestamp("muted_until", { withTimezone: true }),
502
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
503
+ }, (t) => ({
504
+ pk: primaryKey({ columns: [
505
+ t.orgId,
506
+ t.orgUserId,
507
+ t.itemType,
508
+ t.itemId
509
+ ] }),
510
+ orgUserFk: foreignKey({
511
+ columns: [t.orgId, t.orgUserId],
512
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
513
+ }).onDelete("cascade"),
514
+ itemIdx: index("subscriptions_item_idx").on(t.orgId, t.itemType, t.itemId, t.state)
515
+ }));
516
+ const mentions = pgTable("mentions", {
517
+ orgId: text("org_id").notNull(),
518
+ itemType: text("item_type", { enum: [
519
+ "post",
520
+ "comment",
521
+ "message"
522
+ ] }).notNull(),
523
+ itemId: text("item_id").notNull(),
524
+ orgUserId: text("org_user_id").notNull(),
525
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow()
526
+ }, (t) => ({
527
+ pk: primaryKey({ columns: [
528
+ t.orgId,
529
+ t.itemType,
530
+ t.itemId,
531
+ t.orgUserId
532
+ ] }),
533
+ orgUserFk: foreignKey({
534
+ columns: [t.orgId, t.orgUserId],
535
+ foreignColumns: [orgUsers.orgId, orgUsers.id]
536
+ }).onDelete("cascade")
87
537
  }));
88
538
  //#endregion
89
- export { commentReactions, commentReports, comments };
539
+ export { blockedUsers, chatUsers, chats, commentFlags, commentReactions, comments, digestRuns, mentions, messageAttachments, messageFlags, messageReactions, messages, postBookmarks, postFlags, postReactions, posts, subscriptions };
90
540
 
91
541
  //# sourceMappingURL=discussion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"discussion.js","names":[],"sources":["../../src/schema/discussion.ts"],"sourcesContent":["// discussion tables — comments on an activity, their reactions and reports.\n// Configuration is not here: the course's comment settings ride on the course's\n// `content` settings row, and an activity's override rides on the activity's\n// own settings blob.\n//\n// The author is always an org user, so one column covers both\n// learners and staff. Staff-ness is NOT stored — it is read from the author's\n// current role. A removed comment keeps its row so replies below it survive;\n// only the body stops being served.\n//\n// No course_id: which course an activity sits in is content's fact and changes\n// when a course is restructured. The staff comment list joins to modules to\n// scope by course.\nimport {\n pgTable,\n text,\n timestamp,\n primaryKey,\n foreignKey,\n unique,\n index,\n check,\n} from \"drizzle-orm/pg-core\";\nimport { sql } from \"drizzle-orm\";\nimport type { Comment, CommentReaction, CommentReport } from \"@headless-lms/core/schemas\";\nimport { genId } from \"@headless-lms/core/shared/id\";\nimport { organizations, orgUsers } from \"./organizations.js\";\nimport { activities } from \"./content.js\";\nimport type { Expect, NoDrift } from \"./drift.js\";\n\nexport const comments = pgTable(\n \"comments\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"comment\")),\n activityId: text(\"activity_id\").notNull(),\n parentId: text(\"parent_id\"),\n orgUserId: text(\"org_user_id\").notNull(),\n body: text(\"body\").notNull(),\n status: text(\"status\", { enum: [\"pending\", \"published\", \"removed\"] })\n .notNull()\n .default(\"published\"),\n removedBy: text(\"removed_by\"),\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 // Removing an activity removes its discussion (spec, boundary 1).\n activityFk: foreignKey({\n columns: [t.orgId, t.activityId],\n foreignColumns: [activities.orgId, activities.id],\n }).onDelete(\"cascade\"),\n authorFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }),\n removedByFk: foreignKey({\n columns: [t.orgId, t.removedBy],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }),\n // No cascade: removing a parent must not delete its replies.\n parentFk: foreignKey({\n columns: [t.orgId, t.parentId],\n foreignColumns: [t.orgId, t.id],\n }),\n // removed_by is set if and only if the comment is removed.\n removedCk: check(\n \"comments_removed_by_check\",\n sql`(${t.status} = 'removed') = (${t.removedBy} is not null)`,\n ),\n activityIdx: index(\"comments_activity_idx\").on(t.orgId, t.activityId, t.status, t.createdAt),\n // The staff list filters by status org-wide, then narrows by course through\n // the activity join — so the index leads on status, not on a stored course.\n queueIdx: index(\"comments_queue_idx\").on(t.orgId, t.status, t.createdAt),\n }),\n);\n\nexport const commentReactions = pgTable(\n \"comment_reactions\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n commentId: text(\"comment_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n emoji: text(\"emoji\").notNull(),\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 // One reaction per person, per comment.\n pk: primaryKey({ columns: [t.orgId, t.commentId, t.orgUserId] }),\n commentFk: foreignKey({\n columns: [t.orgId, t.commentId],\n foreignColumns: [comments.orgId, comments.id],\n }).onDelete(\"cascade\"),\n authorFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }),\n }),\n);\n\nexport const commentReports = pgTable(\n \"comment_reports\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"commentReport\")),\n commentId: text(\"comment_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n reason: text(\"reason\").notNull().default(\"\"),\n resolvedAt: timestamp(\"resolved_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 report per person, per comment.\n reporterUq: unique().on(t.orgId, t.commentId, t.orgUserId),\n commentFk: foreignKey({\n columns: [t.orgId, t.commentId],\n foreignColumns: [comments.orgId, comments.id],\n }).onDelete(\"cascade\"),\n reporterFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }),\n openIdx: index(\"comment_reports_open_idx\").on(t.orgId, t.commentId, t.resolvedAt),\n }),\n);\n\ntype _CommentsDrift = Expect<NoDrift<typeof comments.$inferSelect, Comment>>;\ntype _CommentReactionsDrift = Expect<\n NoDrift<typeof commentReactions.$inferSelect, CommentReaction>\n>;\ntype _CommentReportsDrift = Expect<NoDrift<typeof commentReports.$inferSelect, CommentReport>>;\n"],"mappings":"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"}
1
+ {"version":3,"file":"discussion.js","names":[],"sources":["../../src/schema/discussion.ts"],"sourcesContent":["// discussion tables — comments on an activity, their reactions and reports.\n// Configuration is not here: the course's comment settings ride on the course's\n// `content` settings row, and an activity's override rides on the activity's\n// own settings blob.\n//\n// The author is always an org user, so one column covers both\n// learners and staff. Staff-ness is NOT stored — it is read from the author's\n// current role. A removed comment keeps its row so replies below it survive;\n// only the body stops being served.\n//\n// No course_id: which course an activity sits in is content's fact and changes\n// when a course is restructured. The staff comment list joins to modules to\n// scope by course.\nimport { desc, sql } from \"drizzle-orm\";\nimport {\n pgTable,\n text,\n integer,\n boolean,\n jsonb,\n timestamp,\n primaryKey,\n foreignKey,\n unique,\n index,\n check,\n} from \"drizzle-orm/pg-core\";\nimport type {\n BlockedUser,\n Chat,\n ChatUser,\n Comment,\n CommentReaction,\n CommentReport,\n DigestRun,\n Mention,\n Message,\n MessageAttachment,\n MessageFlag,\n MessageReaction,\n Post,\n PostBookmark,\n PostFlag,\n PostReaction,\n Subscription,\n} from \"@headless-lms/core/schemas\";\nimport { genId } from \"@headless-lms/core/shared/id\";\nimport { organizations, orgUsers } from \"./organizations.js\";\nimport { activities, communities, spaceTopics, spaces } from \"./content.js\";\nimport { assets } from \"./assets.js\";\nimport type { Expect, NoDrift } from \"./drift.js\";\n\nexport const posts = pgTable(\n \"posts\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"post\")),\n communityId: text(\"community_id\").notNull(),\n spaceId: text(\"space_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n topicId: text(\"topic_id\"),\n title: text(\"title\").notNull(),\n body: text(\"body\").notNull(),\n extra: jsonb(\"extra\").$type<Post[\"extra\"]>().notNull().default({}),\n coverAssetId: text(\"cover_asset_id\"),\n status: text(\"status\", {\n enum: [\"draft\", \"scheduled\", \"pending\", \"published\", \"removed\"],\n })\n .notNull()\n .default(\"draft\"),\n scheduledAt: timestamp(\"scheduled_at\", { withTimezone: true }),\n publishedAt: timestamp(\"published_at\", { withTimezone: true }),\n removedBy: text(\"removed_by\"),\n pinned: boolean(\"pinned\").notNull().default(false),\n commentsClosed: boolean(\"comments_closed\"),\n reactionsEnabled: boolean(\"reactions_enabled\"),\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 spaceFk: foreignKey({\n columns: [t.orgId, t.spaceId, t.communityId],\n foreignColumns: [spaces.orgId, spaces.id, spaces.communityId],\n }).onDelete(\"cascade\"),\n authorFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }),\n topicFk: foreignKey({\n columns: [t.orgId, t.spaceId, t.topicId],\n foreignColumns: [spaceTopics.orgId, spaceTopics.spaceId, spaceTopics.id],\n }),\n coverAssetFk: foreignKey({\n columns: [t.orgId, t.coverAssetId],\n foreignColumns: [assets.orgId, assets.id],\n }),\n // SET NULL is narrowed to the nullable column in 0009_community_indexes.sql; drizzle cannot express it.\n removedByFk: foreignKey({\n columns: [t.orgId, t.removedBy],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"set null\"),\n removedCk: check(\n \"posts_removed_by_check\",\n sql`${t.removedBy} is null or ${t.status} = 'removed'`,\n ),\n scheduledCk: check(\n \"posts_scheduled_check\",\n sql`${t.status} <> 'scheduled' or ${t.scheduledAt} is not null`,\n ),\n feedIdx: index(\"posts_feed_idx\").on(\n t.orgId,\n t.spaceId,\n t.status,\n desc(t.pinned),\n desc(t.publishedAt),\n ),\n dueIdx: index(\"posts_due_idx\").on(t.orgId, t.status, t.scheduledAt),\n authorIdx: index(\"posts_author_idx\").on(t.orgId, t.orgUserId, t.createdAt),\n coverAssetIdx: index(\"posts_cover_asset_idx\").on(t.orgId, t.coverAssetId),\n }),\n);\n\nexport const postReactions = pgTable(\n \"post_reactions\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n postId: text(\"post_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n emoji: text(\"emoji\").notNull(),\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.postId, t.orgUserId] }),\n postFk: foreignKey({\n columns: [t.orgId, t.postId],\n foreignColumns: [posts.orgId, posts.id],\n }).onDelete(\"cascade\"),\n orgUserFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n }),\n);\n\nexport const postBookmarks = pgTable(\n \"post_bookmarks\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n postId: text(\"post_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\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.postId, t.orgUserId] }),\n postFk: foreignKey({\n columns: [t.orgId, t.postId],\n foreignColumns: [posts.orgId, posts.id],\n }).onDelete(\"cascade\"),\n orgUserFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n userIdx: index(\"post_bookmarks_user_idx\").on(t.orgId, t.orgUserId, t.createdAt),\n }),\n);\n\nexport const postFlags = pgTable(\n \"post_flags\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"postFlag\")),\n postId: text(\"post_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n reason: text(\"reason\").notNull().default(\"\"),\n resolvedAt: timestamp(\"resolved_at\", { withTimezone: true }),\n resolution: text(\"resolution\", { enum: [\"dismissed\", \"removed\"] }),\n resolvedBy: text(\"resolved_by\"),\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 reporterUq: unique().on(t.orgId, t.postId, t.orgUserId),\n postFk: foreignKey({\n columns: [t.orgId, t.postId],\n foreignColumns: [posts.orgId, posts.id],\n }).onDelete(\"cascade\"),\n reporterFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n resolvedCk: check(\n \"post_flags_resolved_check\",\n sql`(${t.resolvedAt} is null) = (${t.resolution} is null) and (${t.resolvedAt} is null) = (${t.resolvedBy} is null)`,\n ),\n openIdx: index(\"post_flags_open_idx\").on(t.orgId, t.postId, t.resolvedAt),\n }),\n);\n\nexport const comments = pgTable(\n \"comments\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"comment\")),\n activityId: text(\"activity_id\"),\n postId: text(\"post_id\"),\n communityId: text(\"community_id\"),\n parentId: text(\"parent_id\"),\n orgUserId: text(\"org_user_id\").notNull(),\n body: text(\"body\").notNull(),\n status: text(\"status\", { enum: [\"pending\", \"published\", \"removed\"] })\n .notNull()\n .default(\"published\"),\n removedBy: text(\"removed_by\"),\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 activityFk: foreignKey({\n columns: [t.orgId, t.activityId],\n foreignColumns: [activities.orgId, activities.id],\n }).onDelete(\"cascade\"),\n postFk: foreignKey({\n columns: [t.orgId, t.postId],\n foreignColumns: [posts.orgId, posts.id],\n }).onDelete(\"cascade\"),\n communityFk: foreignKey({\n columns: [t.orgId, t.communityId],\n foreignColumns: [communities.orgId, communities.id],\n }).onDelete(\"cascade\"),\n authorFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }),\n // SET NULL is narrowed to the nullable column in 0009_community_indexes.sql; drizzle cannot express it.\n removedByFk: foreignKey({\n columns: [t.orgId, t.removedBy],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"set null\"),\n parentFk: foreignKey({\n columns: [t.orgId, t.parentId],\n foreignColumns: [t.orgId, t.id],\n }),\n removedCk: check(\n \"comments_removed_by_check\",\n sql`${t.removedBy} is null or ${t.status} = 'removed'`,\n ),\n targetCk: check(\"comments_target_check\", sql`num_nonnulls(${t.activityId}, ${t.postId}) = 1`),\n communityCk: check(\n \"comments_community_check\",\n sql`${t.postId} is null or ${t.communityId} is not null`,\n ),\n activityIdx: index(\"comments_activity_idx\").on(t.orgId, t.activityId, t.status, t.createdAt),\n postIdx: index(\"comments_post_idx\").on(t.orgId, t.postId, t.status, t.createdAt),\n queueIdx: index(\"comments_queue_idx\").on(t.orgId, t.status, t.createdAt),\n communityIdx: index(\"comments_community_idx\").on(t.orgId, t.communityId),\n parentIdx: index(\"comments_parent_idx\").on(t.orgId, t.parentId, t.createdAt),\n }),\n);\n\nexport const commentReactions = pgTable(\n \"comment_reactions\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n commentId: text(\"comment_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n emoji: text(\"emoji\").notNull(),\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.commentId, t.orgUserId] }),\n commentFk: foreignKey({\n columns: [t.orgId, t.commentId],\n foreignColumns: [comments.orgId, comments.id],\n }).onDelete(\"cascade\"),\n authorFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n }),\n);\n\nexport const commentFlags = pgTable(\n \"comment_flags\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"commentReport\")),\n commentId: text(\"comment_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n reason: text(\"reason\").notNull().default(\"\"),\n resolvedAt: timestamp(\"resolved_at\", { withTimezone: true }),\n resolution: text(\"resolution\", { enum: [\"dismissed\", \"removed\"] }),\n resolvedBy: text(\"resolved_by\"),\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 reporterUq: unique().on(t.orgId, t.commentId, t.orgUserId),\n commentFk: foreignKey({\n columns: [t.orgId, t.commentId],\n foreignColumns: [comments.orgId, comments.id],\n }).onDelete(\"cascade\"),\n reporterFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n resolvedCk: check(\n \"comment_flags_resolved_check\",\n sql`(${t.resolvedAt} is null) = (${t.resolution} is null) and (${t.resolvedBy} is null or ${t.resolvedAt} is not null)`,\n ),\n openIdx: index(\"comment_flags_open_idx\").on(t.orgId, t.commentId, t.resolvedAt),\n }),\n);\n\nexport const chats = pgTable(\n \"chats\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"chat\")),\n communityId: text(\"community_id\").notNull(),\n kind: text(\"kind\", { enum: [\"direct\", \"group\"] }).notNull(),\n status: text(\"status\", { enum: [\"pending\", \"open\", \"closed\"] })\n .notNull()\n .default(\"open\"),\n createdBy: text(\"created_by\"),\n lockedAt: timestamp(\"locked_at\", { withTimezone: true }),\n lockedBy: text(\"locked_by\"),\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 communityUq: unique().on(t.orgId, t.id, t.communityId),\n communityFk: foreignKey({\n columns: [t.orgId, t.communityId],\n foreignColumns: [communities.orgId, communities.id],\n }).onDelete(\"cascade\"),\n // SET NULL is narrowed to the nullable column in 0009_community_indexes.sql; drizzle cannot express it.\n createdByFk: foreignKey({\n columns: [t.orgId, t.createdBy],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"set null\"),\n lockedByFk: foreignKey({\n columns: [t.orgId, t.lockedBy],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"set null\"),\n lockedCk: check(\"chats_locked_check\", sql`${t.lockedBy} is null or ${t.lockedAt} is not null`),\n }),\n);\n\nexport const chatUsers = pgTable(\n \"chat_users\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n communityId: text(\"community_id\").notNull(),\n chatId: text(\"chat_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n joinedAt: timestamp(\"joined_at\", { withTimezone: true }).notNull().defaultNow(),\n leftAt: timestamp(\"left_at\", { withTimezone: true }),\n lastReadMessageId: text(\"last_read_message_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 (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.chatId, t.orgUserId] }),\n chatFk: foreignKey({\n columns: [t.orgId, t.chatId, t.communityId],\n foreignColumns: [chats.orgId, chats.id, chats.communityId],\n }).onDelete(\"cascade\"),\n orgUserFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n userIdx: index(\"chat_users_user_idx\").on(t.orgId, t.communityId, t.orgUserId),\n }),\n);\n\nexport const messages = pgTable(\n \"messages\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"message\")),\n communityId: text(\"community_id\").notNull(),\n chatId: text(\"chat_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n body: text(\"body\").notNull(),\n replyToId: text(\"reply_to_id\"),\n editedAt: timestamp(\"edited_at\", { withTimezone: true }),\n deletedAt: timestamp(\"deleted_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 communityUq: unique().on(t.orgId, t.id, t.communityId),\n chatFk: foreignKey({\n columns: [t.orgId, t.chatId, t.communityId],\n foreignColumns: [chats.orgId, chats.id, chats.communityId],\n }).onDelete(\"cascade\"),\n authorFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }),\n replyFk: foreignKey({\n columns: [t.orgId, t.replyToId],\n foreignColumns: [t.orgId, t.id],\n }),\n chatIdx: index(\"messages_chat_idx\").on(t.orgId, t.chatId, t.createdAt),\n replyIdx: index(\"messages_reply_idx\").on(t.orgId, t.replyToId),\n }),\n);\n\nexport const messageAttachments = pgTable(\n \"message_attachments\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n communityId: text(\"community_id\").notNull(),\n messageId: text(\"message_id\").notNull(),\n assetId: text(\"asset_id\").notNull(),\n seq: integer(\"seq\").notNull().default(0),\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.messageId, t.assetId] }),\n messageFk: foreignKey({\n columns: [t.orgId, t.messageId, t.communityId],\n foreignColumns: [messages.orgId, messages.id, messages.communityId],\n }).onDelete(\"cascade\"),\n assetFk: foreignKey({\n columns: [t.orgId, t.assetId],\n foreignColumns: [assets.orgId, assets.id],\n }),\n assetIdx: index(\"message_attachments_asset_idx\").on(t.orgId, t.assetId),\n }),\n);\n\nexport const messageReactions = pgTable(\n \"message_reactions\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n communityId: text(\"community_id\").notNull(),\n messageId: text(\"message_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n emoji: text(\"emoji\").notNull(),\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.messageId, t.orgUserId] }),\n messageFk: foreignKey({\n columns: [t.orgId, t.messageId, t.communityId],\n foreignColumns: [messages.orgId, messages.id, messages.communityId],\n }).onDelete(\"cascade\"),\n orgUserFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n }),\n);\n\nexport const messageFlags = pgTable(\n \"message_flags\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n id: text(\"id\")\n .notNull()\n .$defaultFn(() => genId(\"messageFlag\")),\n communityId: text(\"community_id\").notNull(),\n messageId: text(\"message_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n reason: text(\"reason\").notNull().default(\"\"),\n resolvedAt: timestamp(\"resolved_at\", { withTimezone: true }),\n resolution: text(\"resolution\", { enum: [\"dismissed\", \"deleted\", \"locked\"] }),\n resolvedBy: text(\"resolved_by\"),\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 reporterUq: unique().on(t.orgId, t.messageId, t.orgUserId),\n messageFk: foreignKey({\n columns: [t.orgId, t.messageId, t.communityId],\n foreignColumns: [messages.orgId, messages.id, messages.communityId],\n }).onDelete(\"cascade\"),\n reporterFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n resolvedCk: check(\n \"message_flags_resolved_check\",\n sql`(${t.resolvedAt} is null) = (${t.resolution} is null) and (${t.resolvedAt} is null) = (${t.resolvedBy} is null)`,\n ),\n openIdx: index(\"message_flags_open_idx\").on(t.orgId, t.communityId, t.messageId, t.resolvedAt),\n }),\n);\n\nexport const blockedUsers = pgTable(\n \"blocked_users\",\n {\n orgId: text(\"org_id\")\n .notNull()\n .references(() => organizations.id),\n communityId: text(\"community_id\").notNull(),\n blockerOrgUserId: text(\"blocker_org_user_id\").notNull(),\n blockedOrgUserId: text(\"blocked_org_user_id\").notNull(),\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({\n columns: [t.orgId, t.communityId, t.blockerOrgUserId, t.blockedOrgUserId],\n }),\n communityFk: foreignKey({\n columns: [t.orgId, t.communityId],\n foreignColumns: [communities.orgId, communities.id],\n }).onDelete(\"cascade\"),\n blockerFk: foreignKey({\n columns: [t.orgId, t.blockerOrgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n blockedFk: foreignKey({\n columns: [t.orgId, t.blockedOrgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n blockedIdx: index(\"blocked_users_blocked_idx\").on(t.orgId, t.communityId, t.blockedOrgUserId),\n }),\n);\n\nexport const digestRuns = pgTable(\n \"digest_runs\",\n {\n orgId: text(\"org_id\").notNull(),\n communityId: text(\"community_id\").notNull(),\n lastDueAt: timestamp(\"last_due_at\", { withTimezone: true }).notNull(),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.communityId] }),\n communityFk: foreignKey({\n columns: [t.orgId, t.communityId],\n foreignColumns: [communities.orgId, communities.id],\n }).onDelete(\"cascade\"),\n }),\n);\n\nexport const subscriptions = pgTable(\n \"subscriptions\",\n {\n orgId: text(\"org_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n itemType: text(\"item_type\", { enum: [\"post\", \"space\", \"chat\"] }).notNull(),\n itemId: text(\"item_id\").notNull(),\n state: text(\"state\", { enum: [\"following\", \"muted\"] }).notNull(),\n mutedUntil: timestamp(\"muted_until\", { withTimezone: true }),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.orgUserId, t.itemType, t.itemId] }),\n orgUserFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n itemIdx: index(\"subscriptions_item_idx\").on(t.orgId, t.itemType, t.itemId, t.state),\n }),\n);\n\nexport const mentions = pgTable(\n \"mentions\",\n {\n orgId: text(\"org_id\").notNull(),\n itemType: text(\"item_type\", { enum: [\"post\", \"comment\", \"message\"] }).notNull(),\n itemId: text(\"item_id\").notNull(),\n orgUserId: text(\"org_user_id\").notNull(),\n createdAt: timestamp(\"created_at\", { withTimezone: true }).notNull().defaultNow(),\n },\n (t) => ({\n pk: primaryKey({ columns: [t.orgId, t.itemType, t.itemId, t.orgUserId] }),\n orgUserFk: foreignKey({\n columns: [t.orgId, t.orgUserId],\n foreignColumns: [orgUsers.orgId, orgUsers.id],\n }).onDelete(\"cascade\"),\n }),\n);\n\ntype _PostsDrift = Expect<NoDrift<typeof posts.$inferSelect, Post>>;\ntype _PostReactionsDrift = Expect<NoDrift<typeof postReactions.$inferSelect, PostReaction>>;\ntype _PostBookmarksDrift = Expect<NoDrift<typeof postBookmarks.$inferSelect, PostBookmark>>;\ntype _PostFlagsDrift = Expect<NoDrift<typeof postFlags.$inferSelect, PostFlag>>;\ntype _CommentsDrift = Expect<NoDrift<typeof comments.$inferSelect, Comment>>;\ntype _CommentReactionsDrift = Expect<\n NoDrift<typeof commentReactions.$inferSelect, CommentReaction>\n>;\ntype _CommentFlagsDrift = Expect<NoDrift<typeof commentFlags.$inferSelect, CommentReport>>;\ntype _ChatsDrift = Expect<NoDrift<typeof chats.$inferSelect, Chat>>;\ntype _ChatUsersDrift = Expect<NoDrift<typeof chatUsers.$inferSelect, ChatUser>>;\ntype _MessagesDrift = Expect<NoDrift<typeof messages.$inferSelect, Message>>;\ntype _MessageAttachmentsDrift = Expect<\n NoDrift<typeof messageAttachments.$inferSelect, MessageAttachment>\n>;\ntype _MessageReactionsDrift = Expect<\n NoDrift<typeof messageReactions.$inferSelect, MessageReaction>\n>;\ntype _MessageFlagsDrift = Expect<NoDrift<typeof messageFlags.$inferSelect, MessageFlag>>;\ntype _BlockedUsersDrift = Expect<NoDrift<typeof blockedUsers.$inferSelect, BlockedUser>>;\ntype _DigestRunsDrift = Expect<NoDrift<typeof digestRuns.$inferSelect, DigestRun>>;\ntype _SubscriptionsDrift = Expect<NoDrift<typeof subscriptions.$inferSelect, Subscription>>;\ntype _MentionsDrift = Expect<NoDrift<typeof mentions.$inferSelect, Mention>>;\n"],"mappings":"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"}