@studious-lms/server 1.13.0 → 1.15.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 (375) hide show
  1. package/.dockerignore +28 -0
  2. package/.env.example +5 -0
  3. package/.github/workflows/deploy.yml +123 -0
  4. package/Dockerfile +54 -0
  5. package/dist/index.js +5 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/instrument.js +3 -3
  8. package/dist/instrument.js.map +1 -1
  9. package/dist/lib/config/cors.d.ts.map +1 -1
  10. package/dist/lib/config/cors.js +31 -11
  11. package/dist/lib/config/cors.js.map +1 -1
  12. package/dist/lib/config/env.d.ts +17 -0
  13. package/dist/lib/config/env.d.ts.map +1 -1
  14. package/dist/lib/config/env.js +8 -2
  15. package/dist/lib/config/env.js.map +1 -1
  16. package/dist/lib/googleCloudStorage.d.ts +10 -0
  17. package/dist/lib/googleCloudStorage.d.ts.map +1 -1
  18. package/dist/lib/googleCloudStorage.js +22 -2
  19. package/dist/lib/googleCloudStorage.js.map +1 -1
  20. package/dist/lib/inferDocumentFormat.d.ts +10 -0
  21. package/dist/lib/inferDocumentFormat.d.ts.map +1 -0
  22. package/dist/lib/inferDocumentFormat.js +48 -0
  23. package/dist/lib/inferDocumentFormat.js.map +1 -0
  24. package/dist/lib/legal.d.ts +3 -0
  25. package/dist/lib/legal.d.ts.map +1 -0
  26. package/dist/lib/legal.js +6 -0
  27. package/dist/lib/legal.js.map +1 -0
  28. package/dist/lib/prisma.d.ts +104 -5
  29. package/dist/lib/prisma.d.ts.map +1 -1
  30. package/dist/lib/prisma.js +33 -2
  31. package/dist/lib/prisma.js.map +1 -1
  32. package/dist/models/agenda.d.ts +20 -20
  33. package/dist/models/announcement.d.ts +211 -101
  34. package/dist/models/announcement.d.ts.map +1 -1
  35. package/dist/models/assignment.d.ts +560 -362
  36. package/dist/models/assignment.d.ts.map +1 -1
  37. package/dist/models/attendance.d.ts +197 -71
  38. package/dist/models/attendance.d.ts.map +1 -1
  39. package/dist/models/auth.d.ts +356 -114
  40. package/dist/models/auth.d.ts.map +1 -1
  41. package/dist/models/auth.js +4 -2
  42. package/dist/models/auth.js.map +1 -1
  43. package/dist/models/class.d.ts +327 -201
  44. package/dist/models/class.d.ts.map +1 -1
  45. package/dist/models/class.js +2 -2
  46. package/dist/models/class.js.map +1 -1
  47. package/dist/models/cloudStorage.d.ts +146 -56
  48. package/dist/models/cloudStorage.d.ts.map +1 -1
  49. package/dist/models/comment.d.ts +262 -110
  50. package/dist/models/comment.d.ts.map +1 -1
  51. package/dist/models/conversation.d.ts +206 -80
  52. package/dist/models/conversation.d.ts.map +1 -1
  53. package/dist/models/department.d.ts +196 -70
  54. package/dist/models/department.d.ts.map +1 -1
  55. package/dist/models/event.d.ts +305 -141
  56. package/dist/models/event.d.ts.map +1 -1
  57. package/dist/models/file.d.ts +422 -272
  58. package/dist/models/file.d.ts.map +1 -1
  59. package/dist/models/folder.d.ts +433 -181
  60. package/dist/models/folder.d.ts.map +1 -1
  61. package/dist/models/labChat.d.ts +205 -79
  62. package/dist/models/labChat.d.ts.map +1 -1
  63. package/dist/models/marketing.d.ts +79 -38
  64. package/dist/models/marketing.d.ts.map +1 -1
  65. package/dist/models/marketing.js +12 -4
  66. package/dist/models/marketing.js.map +1 -1
  67. package/dist/models/message.d.ts +97 -43
  68. package/dist/models/message.d.ts.map +1 -1
  69. package/dist/models/newtonChat.d.ts +84 -30
  70. package/dist/models/newtonChat.d.ts.map +1 -1
  71. package/dist/models/notification.d.ts +57 -21
  72. package/dist/models/notification.d.ts.map +1 -1
  73. package/dist/models/school.d.ts +349 -133
  74. package/dist/models/school.d.ts.map +1 -1
  75. package/dist/models/section.d.ts +216 -72
  76. package/dist/models/section.d.ts.map +1 -1
  77. package/dist/models/tag.d.ts +156 -48
  78. package/dist/models/tag.d.ts.map +1 -1
  79. package/dist/models/user.d.ts +82 -28
  80. package/dist/models/user.d.ts.map +1 -1
  81. package/dist/models/worksheet.d.ts +1032 -423
  82. package/dist/models/worksheet.d.ts.map +1 -1
  83. package/dist/models/worksheet.js +8 -2
  84. package/dist/models/worksheet.js.map +1 -1
  85. package/dist/pipelines/aiLabChat.d.ts +7 -9
  86. package/dist/pipelines/aiLabChat.d.ts.map +1 -1
  87. package/dist/pipelines/aiLabChat.js +194 -125
  88. package/dist/pipelines/aiLabChat.js.map +1 -1
  89. package/dist/pipelines/aiLabChatContract.d.ts +233 -389
  90. package/dist/pipelines/aiLabChatContract.d.ts.map +1 -1
  91. package/dist/pipelines/aiLabChatContract.js +54 -70
  92. package/dist/pipelines/aiLabChatContract.js.map +1 -1
  93. package/dist/pipelines/aiNewtonChat.d.ts.map +1 -1
  94. package/dist/pipelines/aiNewtonChat.js +41 -41
  95. package/dist/pipelines/aiNewtonChat.js.map +1 -1
  96. package/dist/pipelines/gradeWorksheet.d.ts +8 -8
  97. package/dist/pipelines/labChatPrompt.d.ts +18 -11
  98. package/dist/pipelines/labChatPrompt.d.ts.map +1 -1
  99. package/dist/pipelines/labChatPrompt.js +93 -75
  100. package/dist/pipelines/labChatPrompt.js.map +1 -1
  101. package/dist/pipelines/pdfToWorksheet.d.ts +1 -1
  102. package/dist/routers/_app.d.ts +2601 -2151
  103. package/dist/routers/_app.d.ts.map +1 -1
  104. package/dist/routers/_app.js +4 -2
  105. package/dist/routers/_app.js.map +1 -1
  106. package/dist/routers/admin.d.ts +13 -13
  107. package/dist/routers/agenda.d.ts +18 -18
  108. package/dist/routers/announcement.d.ts +60 -60
  109. package/dist/routers/assignment.d.ts +393 -383
  110. package/dist/routers/assignment.d.ts.map +1 -1
  111. package/dist/routers/attendance.d.ts +10 -10
  112. package/dist/routers/auth.d.ts +4 -2
  113. package/dist/routers/auth.d.ts.map +1 -1
  114. package/dist/routers/auth.js +15 -2
  115. package/dist/routers/auth.js.map +1 -1
  116. package/dist/routers/class.d.ts +157 -153
  117. package/dist/routers/class.d.ts.map +1 -1
  118. package/dist/routers/comment.d.ts +18 -18
  119. package/dist/routers/conversation.d.ts +11 -11
  120. package/dist/routers/department.d.ts +34 -34
  121. package/dist/routers/discussion.d.ts +68 -56
  122. package/dist/routers/discussion.d.ts.map +1 -1
  123. package/dist/routers/discussion.js +6 -2
  124. package/dist/routers/discussion.js.map +1 -1
  125. package/dist/routers/embedding.d.ts +73 -0
  126. package/dist/routers/embedding.d.ts.map +1 -0
  127. package/dist/routers/embedding.js +151 -0
  128. package/dist/routers/embedding.js.map +1 -0
  129. package/dist/routers/event.d.ts +57 -55
  130. package/dist/routers/event.d.ts.map +1 -1
  131. package/dist/routers/file.d.ts +14 -14
  132. package/dist/routers/folder.d.ts +38 -38
  133. package/dist/routers/labChat.d.ts +16 -16
  134. package/dist/routers/marketing.d.ts +1 -14
  135. package/dist/routers/marketing.d.ts.map +1 -1
  136. package/dist/routers/message.d.ts +13 -13
  137. package/dist/routers/newtonChat.d.ts +4 -4
  138. package/dist/routers/notifications.d.ts +5 -5
  139. package/dist/routers/permissions.d.ts +14 -14
  140. package/dist/routers/school.d.ts +59 -55
  141. package/dist/routers/school.d.ts.map +1 -1
  142. package/dist/routers/search.d.ts +22 -1
  143. package/dist/routers/search.d.ts.map +1 -1
  144. package/dist/routers/search.js +9 -3
  145. package/dist/routers/search.js.map +1 -1
  146. package/dist/routers/section.d.ts +4 -4
  147. package/dist/routers/studentProgress.d.ts +1 -1
  148. package/dist/routers/tag.d.ts +7 -7
  149. package/dist/routers/user.d.ts +99 -10
  150. package/dist/routers/user.d.ts.map +1 -1
  151. package/dist/routers/user.js +19 -2
  152. package/dist/routers/user.js.map +1 -1
  153. package/dist/routers/worksheet.d.ts +93 -55
  154. package/dist/routers/worksheet.d.ts.map +1 -1
  155. package/dist/routers/worksheet.js +26 -2
  156. package/dist/routers/worksheet.js.map +1 -1
  157. package/dist/routes/aiStream.d.ts +2 -0
  158. package/dist/routes/aiStream.d.ts.map +1 -0
  159. package/dist/routes/aiStream.js +726 -0
  160. package/dist/routes/aiStream.js.map +1 -0
  161. package/dist/seedDatabase.d.ts +3 -1
  162. package/dist/seedDatabase.d.ts.map +1 -1
  163. package/dist/seedDatabase.js +6 -6
  164. package/dist/seedDatabase.js.map +1 -1
  165. package/dist/services/adminInstitution.d.ts +8 -8
  166. package/dist/services/adminRunJob.d.ts +4 -4
  167. package/dist/services/agenda.d.ts +18 -18
  168. package/dist/services/aiChatStream.d.ts +88 -0
  169. package/dist/services/aiChatStream.d.ts.map +1 -0
  170. package/dist/services/aiChatStream.js +254 -0
  171. package/dist/services/aiChatStream.js.map +1 -0
  172. package/dist/services/aiModifierTools.d.ts +16 -0
  173. package/dist/services/aiModifierTools.d.ts.map +1 -0
  174. package/dist/services/aiModifierTools.js +274 -0
  175. package/dist/services/aiModifierTools.js.map +1 -0
  176. package/dist/services/aiProposalTools.d.ts +32 -0
  177. package/dist/services/aiProposalTools.d.ts.map +1 -0
  178. package/dist/services/aiProposalTools.js +207 -0
  179. package/dist/services/aiProposalTools.js.map +1 -0
  180. package/dist/services/aiStream.d.ts +22 -0
  181. package/dist/services/aiStream.d.ts.map +1 -0
  182. package/dist/services/aiStream.js +142 -0
  183. package/dist/services/aiStream.js.map +1 -0
  184. package/dist/services/aiTools.d.ts +16 -0
  185. package/dist/services/aiTools.d.ts.map +1 -0
  186. package/dist/services/aiTools.js +271 -0
  187. package/dist/services/aiTools.js.map +1 -0
  188. package/dist/services/announcement.d.ts +42 -42
  189. package/dist/services/announcement.d.ts.map +1 -1
  190. package/dist/services/announcement.js +7 -2
  191. package/dist/services/announcement.js.map +1 -1
  192. package/dist/services/assignment.d.ts +355 -345
  193. package/dist/services/assignment.d.ts.map +1 -1
  194. package/dist/services/assignment.js +30 -9
  195. package/dist/services/assignment.js.map +1 -1
  196. package/dist/services/attendance.d.ts +10 -10
  197. package/dist/services/auth.d.ts +4 -2
  198. package/dist/services/auth.d.ts.map +1 -1
  199. package/dist/services/auth.js +13 -4
  200. package/dist/services/auth.js.map +1 -1
  201. package/dist/services/class.d.ts +146 -142
  202. package/dist/services/class.d.ts.map +1 -1
  203. package/dist/services/class.js +24 -4
  204. package/dist/services/class.js.map +1 -1
  205. package/dist/services/comment.d.ts +18 -18
  206. package/dist/services/conversation.d.ts +11 -11
  207. package/dist/services/department.d.ts +33 -33
  208. package/dist/services/discussion.d.ts +58 -58
  209. package/dist/services/discussion.d.ts.map +1 -1
  210. package/dist/services/discussion.js +15 -8
  211. package/dist/services/discussion.js.map +1 -1
  212. package/dist/services/discussionSummary.d.ts +21 -0
  213. package/dist/services/discussionSummary.d.ts.map +1 -0
  214. package/dist/services/discussionSummary.js +179 -0
  215. package/dist/services/discussionSummary.js.map +1 -0
  216. package/dist/services/embedding.d.ts +85 -0
  217. package/dist/services/embedding.d.ts.map +1 -0
  218. package/dist/services/embedding.js +372 -0
  219. package/dist/services/embedding.js.map +1 -0
  220. package/dist/services/event.d.ts +55 -53
  221. package/dist/services/event.d.ts.map +1 -1
  222. package/dist/services/file.d.ts +28 -28
  223. package/dist/services/folder.d.ts +36 -36
  224. package/dist/services/folder.d.ts.map +1 -1
  225. package/dist/services/folder.js +32 -2
  226. package/dist/services/folder.js.map +1 -1
  227. package/dist/services/labChat.d.ts +16 -16
  228. package/dist/services/marketing.d.ts +2 -15
  229. package/dist/services/marketing.d.ts.map +1 -1
  230. package/dist/services/marketing.js +5 -5
  231. package/dist/services/marketing.js.map +1 -1
  232. package/dist/services/message.d.ts +11 -11
  233. package/dist/services/message.d.ts.map +1 -1
  234. package/dist/services/message.js +2 -2
  235. package/dist/services/message.js.map +1 -1
  236. package/dist/services/newtonChat.d.ts +4 -4
  237. package/dist/services/notification.d.ts +5 -5
  238. package/dist/services/notification.d.ts.map +1 -1
  239. package/dist/services/openaiDocumentGen.d.ts +37 -0
  240. package/dist/services/openaiDocumentGen.d.ts.map +1 -0
  241. package/dist/services/openaiDocumentGen.js +262 -0
  242. package/dist/services/openaiDocumentGen.js.map +1 -0
  243. package/dist/services/permissions.d.ts +14 -14
  244. package/dist/services/school.d.ts +54 -50
  245. package/dist/services/school.d.ts.map +1 -1
  246. package/dist/services/search.d.ts +13 -1
  247. package/dist/services/search.d.ts.map +1 -1
  248. package/dist/services/search.js +145 -2
  249. package/dist/services/search.js.map +1 -1
  250. package/dist/services/section.d.ts +3 -3
  251. package/dist/services/tag.d.ts +4 -4
  252. package/dist/services/user.d.ts +4 -4
  253. package/dist/services/user.d.ts.map +1 -1
  254. package/dist/services/user.js +10 -15
  255. package/dist/services/user.js.map +1 -1
  256. package/dist/services/userPrivacy.d.ts +86 -0
  257. package/dist/services/userPrivacy.d.ts.map +1 -0
  258. package/dist/services/userPrivacy.js +184 -0
  259. package/dist/services/userPrivacy.js.map +1 -0
  260. package/dist/services/worksheet.d.ts +86 -57
  261. package/dist/services/worksheet.d.ts.map +1 -1
  262. package/dist/services/worksheet.js +57 -5
  263. package/dist/services/worksheet.js.map +1 -1
  264. package/dist/utils/email.d.ts.map +1 -1
  265. package/dist/utils/email.js +7 -3
  266. package/dist/utils/email.js.map +1 -1
  267. package/dist/utils/streamBroadcast.d.ts +11 -0
  268. package/dist/utils/streamBroadcast.d.ts.map +1 -0
  269. package/dist/utils/streamBroadcast.js +32 -0
  270. package/dist/utils/streamBroadcast.js.map +1 -0
  271. package/dist/workers/connection.d.ts +15 -0
  272. package/dist/workers/connection.d.ts.map +1 -1
  273. package/dist/workers/connection.js +20 -2
  274. package/dist/workers/connection.js.map +1 -1
  275. package/dist/workers/index.js +4 -2
  276. package/dist/workers/index.js.map +1 -1
  277. package/dist/workers/processors/createRunJobWorker.d.ts.map +1 -1
  278. package/dist/workers/processors/createRunJobWorker.js +31 -8
  279. package/dist/workers/processors/createRunJobWorker.js.map +1 -1
  280. package/dist/workers/processors/embedContent.d.ts +8 -0
  281. package/dist/workers/processors/embedContent.d.ts.map +1 -0
  282. package/dist/workers/processors/embedContent.js +67 -0
  283. package/dist/workers/processors/embedContent.js.map +1 -0
  284. package/dist/workers/queues.d.ts +6 -0
  285. package/dist/workers/queues.d.ts.map +1 -1
  286. package/dist/workers/queues.js +5 -3
  287. package/dist/workers/queues.js.map +1 -1
  288. package/package.json +5 -1
  289. package/prisma/migrations/20260609215135_init/migration.sql +1412 -0
  290. package/prisma/migrations/20260610130000_add_worksheet_tags/migration.sql +13 -0
  291. package/prisma/migrations/20260610140000_expand_embedding_source_types/migration.sql +4 -0
  292. package/prisma/migrations/20260611120000_add_user_terms_acceptance/migration.sql +3 -0
  293. package/prisma/schema.prisma +44 -7
  294. package/src/index.ts +4 -0
  295. package/src/instrument.ts +1 -1
  296. package/src/lib/config/cors.ts +32 -9
  297. package/src/lib/config/env.ts +6 -0
  298. package/src/lib/googleCloudStorage.ts +21 -0
  299. package/src/lib/inferDocumentFormat.ts +58 -0
  300. package/src/lib/legal.ts +2 -0
  301. package/src/lib/prisma.ts +40 -1
  302. package/src/models/auth.ts +4 -0
  303. package/src/models/class.ts +3 -2
  304. package/src/models/marketing.ts +10 -2
  305. package/src/models/worksheet.ts +5 -2
  306. package/src/pipelines/aiLabChat.ts +245 -146
  307. package/src/pipelines/aiLabChatContract.ts +59 -69
  308. package/src/pipelines/aiNewtonChat.ts +46 -43
  309. package/src/pipelines/labChatPrompt.ts +115 -90
  310. package/src/routers/_app.ts +2 -0
  311. package/src/routers/auth.ts +13 -0
  312. package/src/routers/discussion.ts +7 -0
  313. package/src/routers/embedding.ts +164 -0
  314. package/src/routers/search.ts +10 -1
  315. package/src/routers/user.ts +26 -0
  316. package/src/routers/worksheet.ts +27 -0
  317. package/src/routes/aiStream.ts +827 -0
  318. package/src/seedDatabase.ts +4 -4
  319. package/src/services/aiChatStream.ts +341 -0
  320. package/src/services/aiModifierTools.ts +341 -0
  321. package/src/services/aiProposalTools.ts +274 -0
  322. package/src/services/aiStream.ts +175 -0
  323. package/src/services/aiTools.ts +290 -0
  324. package/src/services/announcement.ts +7 -0
  325. package/src/services/assignment.ts +31 -7
  326. package/src/services/auth.ts +14 -2
  327. package/src/services/class.ts +27 -2
  328. package/src/services/discussion.ts +22 -8
  329. package/src/services/discussionSummary.ts +226 -0
  330. package/src/services/embedding.ts +446 -0
  331. package/src/services/folder.ts +31 -0
  332. package/src/services/marketing.ts +3 -3
  333. package/src/services/message.ts +2 -2
  334. package/src/services/openaiDocumentGen.ts +319 -0
  335. package/src/services/search.ts +163 -1
  336. package/src/services/user.ts +9 -17
  337. package/src/services/userPrivacy.ts +196 -0
  338. package/src/services/worksheet.ts +77 -3
  339. package/src/utils/email.ts +5 -1
  340. package/src/utils/streamBroadcast.ts +48 -0
  341. package/src/workers/connection.ts +19 -0
  342. package/src/workers/index.ts +2 -0
  343. package/src/workers/processors/createRunJobWorker.ts +32 -6
  344. package/src/workers/processors/embedContent.ts +86 -0
  345. package/src/workers/queues.ts +5 -1
  346. package/tests/helpers/registerInput.ts +20 -0
  347. package/tests/integration/globalSetup.ts +10 -18
  348. package/tests/integration/routers/auth.test.ts +13 -18
  349. package/tests/unit/lib/inferDocumentFormat.test.ts +33 -0
  350. package/tests/unit/pipelines/aiLabChatContract.test.ts +38 -21
  351. package/tests/unit/pipelines/labChatPrompt.test.ts +23 -36
  352. package/tests/unit/services/aiChatStream.test.ts +92 -0
  353. package/tests/unit/services/openaiDocumentGen.test.ts +65 -0
  354. package/prisma/migrations/20250807062924_init/migration.sql +0 -436
  355. package/prisma/migrations/20250919063704_init2/migration.sql +0 -24
  356. package/prisma/migrations/20250920143543_add_profile_fields/migration.sql +0 -15
  357. package/prisma/migrations/20250922165147_add_chat_models/migration.sql +0 -68
  358. package/prisma/migrations/20250922165314_add_chat_roles/migration.sql +0 -5
  359. package/prisma/migrations/20250922171242_refactor_notification_system/migration.sql +0 -20
  360. package/prisma/migrations/20250922172208_add_mentions_system/migration.sql +0 -21
  361. package/prisma/migrations/20250925072732_add_lab_chat_system/migration.sql +0 -25
  362. package/prisma/migrations/20251020151505_add_upload_tracking_fields/migration.sql +0 -57
  363. package/prisma/migrations/20251109122857_annuoncements_comments/migration.sql +0 -30
  364. package/prisma/migrations/20251109135555_reactions_announcements_comments/migration.sql +0 -35
  365. package/prisma/migrations/20260410124000_add_submission_recommendation_state/migration.sql +0 -14
  366. package/prisma/migrations/20260415103500_add_session_type/migration.sql +0 -33
  367. package/prisma/migrations/20260415133000_add_ai_usage_logs/migration.sql +0 -19
  368. package/prisma/migrations/20260417083000_add_conversation_member_hidden_at/migration.sql +0 -2
  369. package/prisma/migrations/20260502230500_assignment_submission_comments/migration.sql +0 -60
  370. package/prisma/migrations/20260504071500_school_memberships/migration.sql +0 -81
  371. package/prisma/migrations/20260506162500_consolidate_run_job_and_unify_job_status/migration.sql +0 -166
  372. package/prisma/migrations/20260509220000_institution_overhaul/migration.sql +0 -184
  373. package/prisma/migrations/20260510170000_add_folder_permissions/migration.sql +0 -93
  374. package/prisma/migrations/20260510183000_add_discussions/migration.sql +0 -151
  375. /package/.github/workflows/{npm.yml → npm-publish.yml} +0 -0
@@ -1,11 +1,12 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b10e68f8-0106-57a7-be41-a32938701565")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9ce66b69-3963-5ac9-91a6-6aa8b6d86a75")}catch(e){}}();
3
3
  import { TRPCError } from "@trpc/server";
4
4
  import { prisma } from "../lib/prisma.js";
5
5
  import { discussionChannel, pusher } from "../lib/pusher.js";
6
6
  import { logger } from "../utils/logger.js";
7
7
  import { classMemberOrSchoolAdminWhere, classTeacherOrSchoolAdminWhere } from "../models/access.js";
8
8
  import { sendNotification } from "./notification.js";
9
+ import { enqueueEmbedding } from "./embedding.js";
9
10
  const authorSelect = {
10
11
  id: true,
11
12
  username: true,
@@ -377,6 +378,8 @@ export async function createDiscussion(userId, input) {
377
378
  });
378
379
  triggerDiscussionEvent(input.classId, "discussion-created", { discussion: serializeDiscussion(discussion, userId) });
379
380
  await notifyMentionedUsers(input.classId, userId, input.body, `/class/${input.classId}/discussions/${discussion.id}`);
381
+ // Auto-index discussion for RAG search
382
+ enqueueEmbedding(input.classId, 'DISCUSSION', discussion.id);
380
383
  return { discussion: serializeDiscussion(discussion, userId) };
381
384
  }
382
385
  export async function updateDiscussion(userId, input) {
@@ -399,6 +402,8 @@ export async function updateDiscussion(userId, input) {
399
402
  include: discussionInclude,
400
403
  });
401
404
  triggerDiscussionEvent(updated.classId, "discussion-updated", { discussion: serializeDiscussion(updated, userId) });
405
+ // Re-index discussion for RAG search after update
406
+ enqueueEmbedding(updated.classId, 'DISCUSSION', updated.id);
402
407
  return { discussion: serializeDiscussion(updated, userId) };
403
408
  }
404
409
  export async function deleteDiscussion(userId, discussionId) {
@@ -448,6 +453,8 @@ export async function replyToDiscussion(userId, input) {
448
453
  notifyMentionedUsers(discussion.classId, userId, input.body, link),
449
454
  ]);
450
455
  triggerDiscussionEvent(discussion.classId, "reply-created", { discussionId: discussion.id, reply: serializeReply(reply, userId) });
456
+ // Re-index discussion for RAG search (includes new reply)
457
+ enqueueEmbedding(discussion.classId, 'DISCUSSION', discussion.id);
451
458
  return { reply: serializeReply(reply, userId) };
452
459
  }
453
460
  export async function updateDiscussionReply(userId, input) {
@@ -594,32 +601,32 @@ export async function toggleDiscussionReaction(userId, input) {
594
601
  }
595
602
  export async function listDiscussionTags(userId, classId) {
596
603
  await getDiscussionClassAccess(classId, userId);
597
- return prisma.discussionTag.findMany({ where: { classId }, orderBy: { name: "asc" } });
604
+ return prisma.classTag.findMany({ where: { classId }, orderBy: { name: "asc" } });
598
605
  }
599
606
  export async function createDiscussionTag(userId, input) {
600
607
  const isTeacher = await prisma.class.findFirst({ where: { id: input.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });
601
608
  if (!isTeacher?.discussionsEnabled)
602
609
  throw new TRPCError({ code: "FORBIDDEN", message: "Only teachers can manage discussion tags" });
603
- return prisma.discussionTag.create({ data: { classId: input.classId, name: input.name.trim(), color: input.color } });
610
+ return prisma.classTag.create({ data: { classId: input.classId, name: input.name.trim(), color: input.color } });
604
611
  }
605
612
  export async function updateDiscussionTag(userId, input) {
606
- const tag = await prisma.discussionTag.findUnique({ where: { id: input.tagId }, select: { classId: true } });
613
+ const tag = await prisma.classTag.findUnique({ where: { id: input.tagId }, select: { classId: true } });
607
614
  if (!tag)
608
615
  throw new TRPCError({ code: "NOT_FOUND", message: "Tag not found" });
609
616
  const isTeacher = await prisma.class.findFirst({ where: { id: tag.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });
610
617
  if (!isTeacher?.discussionsEnabled)
611
618
  throw new TRPCError({ code: "FORBIDDEN", message: "Only teachers can manage discussion tags" });
612
- return prisma.discussionTag.update({ where: { id: input.tagId }, data: { name: input.name?.trim(), color: input.color } });
619
+ return prisma.classTag.update({ where: { id: input.tagId }, data: { name: input.name?.trim(), color: input.color } });
613
620
  }
614
621
  export async function deleteDiscussionTag(userId, tagId) {
615
- const tag = await prisma.discussionTag.findUnique({ where: { id: tagId }, select: { classId: true } });
622
+ const tag = await prisma.classTag.findUnique({ where: { id: tagId }, select: { classId: true } });
616
623
  if (!tag)
617
624
  throw new TRPCError({ code: "NOT_FOUND", message: "Tag not found" });
618
625
  const isTeacher = await prisma.class.findFirst({ where: { id: tag.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });
619
626
  if (!isTeacher?.discussionsEnabled)
620
627
  throw new TRPCError({ code: "FORBIDDEN", message: "Only teachers can manage discussion tags" });
621
- await prisma.discussionTag.delete({ where: { id: tagId } });
628
+ await prisma.classTag.delete({ where: { id: tagId } });
622
629
  return { success: true };
623
630
  }
624
631
  //# sourceMappingURL=discussion.js.map
625
- //# debugId=b10e68f8-0106-57a7-be41-a32938701565
632
+ //# debugId=9ce66b69-3963-5ac9-91a6-6aa8b6d86a75
@@ -1 +1 @@
1
- {"version":3,"file":"discussion.js","sources":["services/discussion.ts"],"sourceRoot":"/","sourcesContent":["import type { DiscussionType, Prisma, ReactionType } from \"@prisma/client\";\nimport { TRPCError } from \"@trpc/server\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { discussionChannel, pusher } from \"../lib/pusher.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { classMemberOrSchoolAdminWhere, classTeacherOrSchoolAdminWhere } from \"../models/access.js\";\nimport { sendNotification } from \"./notification.js\";\n\nconst authorSelect = {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n} as const;\n\nconst attachmentSelect = {\n id: true,\n name: true,\n type: true,\n size: true,\n path: true,\n uploadedAt: true,\n uploadStatus: true,\n thumbnailId: true,\n thumbnail: { select: { id: true, path: true } },\n} as const;\n\nconst reactionCounts = {\n THUMBSUP: 0,\n CELEBRATE: 0,\n CARE: 0,\n HEART: 0,\n IDEA: 0,\n HAPPY: 0,\n} satisfies Record<ReactionType, number>;\n\nconst discussionInclude = {\n author: { select: authorSelect },\n attachments: { select: attachmentSelect },\n tags: { select: { id: true, name: true, color: true } },\n reactions: { select: { type: true, userId: true } },\n _count: { select: { replies: { where: { deletedAt: null } } } },\n} as const;\n\nconst replyInclude = {\n author: { select: authorSelect },\n attachments: { select: attachmentSelect },\n reactions: { select: { type: true, userId: true } },\n} as const;\n\nconst unclaimedAttachmentWhere = {\n assignmentId: null,\n submissionId: null,\n annotationId: null,\n classDraftId: null,\n folderId: null,\n messageId: null,\n announcementId: null,\n discussionId: null,\n discussionReplyId: null,\n} satisfies Prisma.FileWhereInput;\n\ntype DiscussionWithInclude = Prisma.DiscussionGetPayload<{ include: typeof discussionInclude }>;\ntype ReplyWithInclude = Prisma.DiscussionReplyGetPayload<{ include: typeof replyInclude }>;\n\nexport type DiscussionReplyTree = ReturnType<typeof serializeReply> & {\n children: DiscussionReplyTree[];\n};\n\nfunction summarizeReactions(reactions: { type: ReactionType; userId: string }[], userId: string) {\n const counts = { ...reactionCounts };\n for (const reaction of reactions) {\n counts[reaction.type] += 1;\n }\n return {\n counts,\n userReaction: reactions.find((reaction) => reaction.userId === userId)?.type ?? null,\n total: reactions.length,\n };\n}\n\nfunction serializeDiscussion(discussion: DiscussionWithInclude, userId: string, unreadCount = 0) {\n return {\n id: discussion.id,\n classId: discussion.classId,\n authorId: discussion.authorId,\n title: discussion.title,\n body: discussion.body,\n type: discussion.type,\n isPinned: discussion.isPinned,\n isLocked: discussion.isLocked,\n allowReplies: discussion.allowReplies,\n createdAt: discussion.createdAt,\n updatedAt: discussion.updatedAt,\n lastActivityAt: discussion.lastActivityAt,\n author: discussion.author,\n attachments: discussion.attachments,\n tags: discussion.tags,\n replyCount: discussion._count.replies,\n hasAcceptedAnswer: false,\n reactions: summarizeReactions(discussion.reactions, userId),\n unreadCount,\n };\n}\n\nfunction serializeReply(reply: ReplyWithInclude, userId: string) {\n return {\n id: reply.id,\n discussionId: reply.discussionId,\n authorId: reply.authorId,\n parentId: reply.parentId,\n body: reply.deletedAt ? \"[deleted]\" : reply.body,\n deletedAt: reply.deletedAt,\n isAcceptedAnswer: reply.isAcceptedAnswer,\n createdAt: reply.createdAt,\n modifiedAt: reply.modifiedAt,\n author: reply.author,\n attachments: reply.deletedAt ? [] : reply.attachments,\n reactions: summarizeReactions(reply.reactions, userId),\n };\n}\n\nexport function buildReplyTree(replies: ReplyWithInclude[], userId: string): DiscussionReplyTree[] {\n const byId = new Map<string, DiscussionReplyTree>();\n const roots: DiscussionReplyTree[] = [];\n\n for (const reply of replies) {\n byId.set(reply.id, { ...serializeReply(reply, userId), children: [] });\n }\n\n for (const reply of replies) {\n const node = byId.get(reply.id)!;\n if (reply.parentId && byId.has(reply.parentId)) {\n byId.get(reply.parentId)!.children.push(node);\n } else {\n roots.push(node);\n }\n }\n\n return roots;\n}\n\nfunction isWithinAuthorEditWindow(createdAt: Date) {\n return Date.now() - createdAt.getTime() <= 24 * 60 * 60 * 1000;\n}\n\nexport async function getDiscussionClassAccess(classId: string, userId: string) {\n const classData = await prisma.class.findFirst({\n where: { id: classId, ...classMemberOrSchoolAdminWhere(userId) },\n select: {\n id: true,\n name: true,\n discussionsEnabled: true,\n studentsCanCreateDiscussions: true,\n studentsCanReply: true,\n students: { where: { id: userId }, select: { id: true } },\n teachers: { where: { id: userId }, select: { id: true } },\n school: {\n select: {\n memberships: {\n where: { userId, role: \"ADMIN\", status: \"ACTIVE\" },\n select: { userId: true },\n },\n },\n },\n },\n });\n\n if (!classData) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Not a member in this class\" });\n }\n if (!classData.discussionsEnabled) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Discussions are disabled for this class\" });\n }\n\n const isTeacher = classData.teachers.length > 0 || Boolean(classData.school?.memberships.length);\n const isStudent = classData.students.length > 0;\n\n return { ...classData, isTeacher, isStudent };\n}\n\nasync function getDiscussionForUser(discussionId: string, userId: string) {\n const discussion = await prisma.discussion.findUnique({\n where: { id: discussionId },\n include: {\n class: {\n select: {\n id: true,\n discussionsEnabled: true,\n studentsCanReply: true,\n teachers: { where: { id: userId }, select: { id: true } },\n students: { where: { id: userId }, select: { id: true } },\n school: {\n select: {\n memberships: {\n where: { userId, role: \"ADMIN\", status: \"ACTIVE\" },\n select: { userId: true },\n },\n },\n },\n },\n },\n },\n });\n\n if (!discussion) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Discussion not found\" });\n }\n\n const isTeacher = discussion.class.teachers.length > 0 || Boolean(discussion.class.school?.memberships.length);\n const isStudent = discussion.class.students.length > 0;\n if (!isTeacher && !isStudent) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Not a member in this class\" });\n }\n if (!discussion.class.discussionsEnabled) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Discussions are disabled for this class\" });\n }\n\n return { discussion, isTeacher, isStudent };\n}\n\nasync function claimDiscussionAttachments(\n tx: Prisma.TransactionClient,\n userId: string,\n discussionId: string,\n attachmentIds: string[] = []\n) {\n const uniqueIds = [...new Set(attachmentIds)];\n if (!uniqueIds.length) return;\n const { count } = await tx.file.updateMany({\n where: { id: { in: uniqueIds }, userId, uploadStatus: \"COMPLETED\", ...unclaimedAttachmentWhere },\n data: { discussionId },\n });\n if (count !== uniqueIds.length) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"Some attachments are missing, unfinished, or unavailable\" });\n }\n}\n\nasync function claimReplyAttachments(\n tx: Prisma.TransactionClient,\n userId: string,\n replyId: string,\n attachmentIds: string[] = []\n) {\n const uniqueIds = [...new Set(attachmentIds)];\n if (!uniqueIds.length) return;\n const { count } = await tx.file.updateMany({\n where: { id: { in: uniqueIds }, userId, uploadStatus: \"COMPLETED\", ...unclaimedAttachmentWhere },\n data: { discussionReplyId: replyId },\n });\n if (count !== uniqueIds.length) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"Some attachments are missing, unfinished, or unavailable\" });\n }\n}\n\nfunction triggerDiscussionEvent(classId: string, event: string, payload: unknown) {\n pusher.trigger(discussionChannel(classId), event, payload).catch((error) => {\n logger.error(\"Failed to trigger discussion pusher event\", { event, classId, error });\n });\n}\n\nasync function notify(receiverId: string | null | undefined, senderId: string, title: string, content: string) {\n if (!receiverId || receiverId === senderId) return;\n await sendNotification({ receiverId, title, content }).catch((error) => {\n logger.error(\"Failed to send discussion notification\", { receiverId, error });\n });\n}\n\nasync function notifyMentionedUsers(classId: string, senderId: string, body: string, link: string) {\n const usernames = [...new Set(Array.from(body.matchAll(/(^|\\s)@([a-zA-Z0-9_.-]{2,32})/g)).map((match) => match[2]))];\n if (!usernames.length) return;\n const members = await prisma.user.findMany({\n where: {\n username: { in: usernames },\n OR: [\n { teacherIn: { some: { id: classId } } },\n { studentIn: { some: { id: classId } } },\n { schoolMemberships: { some: { status: \"ACTIVE\", school: { classes: { some: { id: classId } } } } } },\n ],\n },\n select: { id: true },\n });\n await Promise.all(members.map((member) => notify(member.id, senderId, \"You were mentioned in a discussion\", link)));\n}\n\nasync function unreadCountsForDiscussions(userId: string, discussionIds: string[]) {\n if (!discussionIds.length) return new Map<string, number>();\n const reads = await prisma.discussionRead.findMany({\n where: { userId, discussionId: { in: discussionIds } },\n select: { discussionId: true, lastReadAt: true },\n });\n const readMap = new Map(reads.map((read) => [read.discussionId, read.lastReadAt]));\n const neverRead = discussionIds.filter((discussionId) => !readMap.has(discussionId));\n const readPredicates = Array.from(readMap.entries()).map(([discussionId, lastReadAt]) => ({\n discussionId,\n createdAt: { gt: lastReadAt },\n }));\n const counts = new Map<string, number>();\n\n const [neverReadCounts, readCounts] = await Promise.all([\n neverRead.length\n ? prisma.discussionReply.groupBy({\n by: [\"discussionId\"],\n where: { discussionId: { in: neverRead }, deletedAt: null, authorId: { not: userId } },\n _count: true,\n })\n : Promise.resolve([]),\n readPredicates.length\n ? prisma.discussionReply.groupBy({\n by: [\"discussionId\"],\n where: { deletedAt: null, authorId: { not: userId }, OR: readPredicates },\n _count: true,\n })\n : Promise.resolve([]),\n ]);\n\n for (const item of [...neverReadCounts, ...readCounts]) {\n counts.set(item.discussionId, item._count);\n }\n return counts;\n}\n\nexport async function listDiscussions(userId: string, input: {\n classId: string;\n tagId?: string;\n type?: DiscussionType;\n search?: string;\n sort: \"recent\" | \"activity\" | \"top\";\n cursor?: string;\n limit: number;\n}) {\n await getDiscussionClassAccess(input.classId, userId);\n const where: Prisma.DiscussionWhereInput = {\n classId: input.classId,\n ...(input.tagId ? { tags: { some: { id: input.tagId } } } : {}),\n ...(input.type ? { type: input.type } : {}),\n ...(input.search?.trim()\n ? {\n OR: [\n { title: { contains: input.search.trim(), mode: \"insensitive\" } },\n { body: { contains: input.search.trim(), mode: \"insensitive\" } },\n ],\n }\n : {}),\n };\n const orderBy: Prisma.DiscussionOrderByWithRelationInput[] =\n input.sort === \"recent\"\n ? [{ isPinned: \"desc\" }, { createdAt: \"desc\" }]\n : input.sort === \"top\"\n ? [{ isPinned: \"desc\" }, { replies: { _count: \"desc\" } }, { lastActivityAt: \"desc\" }]\n : [{ isPinned: \"desc\" }, { lastActivityAt: \"desc\" }];\n\n const items = await prisma.discussion.findMany({\n where,\n include: discussionInclude,\n orderBy,\n cursor: input.cursor ? { id: input.cursor } : undefined,\n skip: input.cursor ? 1 : 0,\n take: input.limit + 1,\n });\n const next = items.length > input.limit ? items.pop() : undefined;\n const unreadMap = await unreadCountsForDiscussions(userId, items.map((item) => item.id));\n const accepted = await prisma.discussionReply.groupBy({\n by: [\"discussionId\"],\n where: { discussionId: { in: items.map((item) => item.id) }, isAcceptedAnswer: true, deletedAt: null },\n });\n const acceptedIds = new Set(accepted.map((item) => item.discussionId));\n\n return {\n items: items.map((item) => ({\n ...serializeDiscussion(item, userId, unreadMap.get(item.id) ?? 0),\n hasAcceptedAnswer: acceptedIds.has(item.id),\n })),\n nextCursor: next?.id,\n };\n}\n\nexport async function getDiscussion(userId: string, discussionId: string) {\n const { discussion: accessDiscussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n const [discussion, replies, myReaction] = await Promise.all([\n prisma.discussion.findUniqueOrThrow({ where: { id: discussionId }, include: discussionInclude }),\n prisma.discussionReply.findMany({ where: { discussionId }, include: replyInclude, orderBy: { createdAt: \"asc\" } }),\n prisma.reaction.findUnique({ where: { userId_discussionId: { userId, discussionId } }, select: { type: true } }),\n prisma.discussionRead.upsert({\n where: { userId_discussionId: { userId, discussionId } },\n update: { lastReadAt: new Date() },\n create: { userId, discussionId },\n }),\n ]);\n const canAuthorEdit = accessDiscussion.authorId === userId && isWithinAuthorEditWindow(accessDiscussion.createdAt);\n const canReply = isTeacher || (accessDiscussion.class.studentsCanReply && !accessDiscussion.isLocked && accessDiscussion.allowReplies);\n return {\n discussion: serializeDiscussion(discussion, userId),\n replies: buildReplyTree(replies, userId),\n myReaction: myReaction?.type ?? null,\n canEdit: isTeacher || canAuthorEdit,\n canPin: isTeacher,\n canLock: isTeacher,\n canDelete: isTeacher || accessDiscussion.authorId === userId,\n canReply,\n };\n}\n\nexport async function createDiscussion(userId: string, input: {\n classId: string;\n title: string;\n body: string;\n type: DiscussionType;\n tagIds?: string[];\n attachmentIds?: string[];\n}) {\n const classData = await getDiscussionClassAccess(input.classId, userId);\n if (!classData.isTeacher && !classData.studentsCanCreateDiscussions) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Students cannot create discussions in this class\" });\n }\n if (input.type === \"ANNOUNCEMENT\" && !classData.isTeacher) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can create announcement discussions\" });\n }\n\n const discussion = await prisma.$transaction(async (tx) => {\n const created = await tx.discussion.create({\n data: {\n classId: input.classId,\n authorId: userId,\n title: input.title.trim(),\n body: input.body.trim(),\n type: input.type,\n allowReplies: input.type !== \"ANNOUNCEMENT\",\n tags: input.tagIds?.length ? { connect: input.tagIds.map((id) => ({ id })) } : undefined,\n },\n });\n await claimDiscussionAttachments(tx, userId, created.id, input.attachmentIds);\n return tx.discussion.findUniqueOrThrow({ where: { id: created.id }, include: discussionInclude });\n });\n\n triggerDiscussionEvent(input.classId, \"discussion-created\", { discussion: serializeDiscussion(discussion, userId) });\n await notifyMentionedUsers(input.classId, userId, input.body, `/class/${input.classId}/discussions/${discussion.id}`);\n return { discussion: serializeDiscussion(discussion, userId) };\n}\n\nexport async function updateDiscussion(userId: string, input: {\n discussionId: string;\n title?: string;\n body?: string;\n type?: DiscussionType;\n tagIds?: string[];\n allowReplies?: boolean;\n}) {\n const { discussion, isTeacher } = await getDiscussionForUser(input.discussionId, userId);\n if (!isTeacher && !(discussion.authorId === userId && isWithinAuthorEditWindow(discussion.createdAt))) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot edit this discussion\" });\n }\n if (input.type === \"ANNOUNCEMENT\" && !isTeacher) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can create announcement discussions\" });\n }\n const updated = await prisma.discussion.update({\n where: { id: input.discussionId },\n data: {\n ...(input.title !== undefined ? { title: input.title.trim() } : {}),\n ...(input.body !== undefined ? { body: input.body.trim() } : {}),\n ...(input.type !== undefined ? { type: input.type } : {}),\n ...(input.allowReplies !== undefined ? { allowReplies: input.allowReplies } : {}),\n ...(input.tagIds ? { tags: { set: input.tagIds.map((id) => ({ id })) } } : {}),\n },\n include: discussionInclude,\n });\n triggerDiscussionEvent(updated.classId, \"discussion-updated\", { discussion: serializeDiscussion(updated, userId) });\n return { discussion: serializeDiscussion(updated, userId) };\n}\n\nexport async function deleteDiscussion(userId: string, discussionId: string) {\n const { discussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n if (!isTeacher && discussion.authorId !== userId) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot delete this discussion\" });\n }\n await prisma.discussion.delete({ where: { id: discussionId } });\n triggerDiscussionEvent(discussion.classId, \"discussion-deleted\", { discussionId });\n return { success: true };\n}\n\nexport async function replyToDiscussion(userId: string, input: {\n discussionId: string;\n parentReplyId?: string;\n body: string;\n attachmentIds?: string[];\n}) {\n const { discussion, isTeacher } = await getDiscussionForUser(input.discussionId, userId);\n const canReply = isTeacher || (discussion.class.studentsCanReply && !discussion.isLocked && discussion.allowReplies);\n if (!canReply) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot reply to this discussion\" });\n }\n let parent: { id: string; authorId: string } | null = null;\n if (input.parentReplyId) {\n parent = await prisma.discussionReply.findFirst({\n where: { id: input.parentReplyId, discussionId: input.discussionId },\n select: { id: true, authorId: true },\n });\n if (!parent) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Parent reply not found\" });\n }\n const reply = await prisma.$transaction(async (tx) => {\n const created = await tx.discussionReply.create({\n data: {\n discussionId: input.discussionId,\n authorId: userId,\n parentId: input.parentReplyId,\n body: input.body.trim(),\n },\n });\n await claimReplyAttachments(tx, userId, created.id, input.attachmentIds);\n await tx.discussion.update({\n where: { id: input.discussionId },\n data: { lastActivityAt: new Date() },\n });\n return tx.discussionReply.findUniqueOrThrow({ where: { id: created.id }, include: replyInclude });\n });\n const link = `/class/${discussion.classId}/discussions/${discussion.id}#${reply.id}`;\n await Promise.all([\n notify(discussion.authorId, userId, \"New reply to your discussion\", link),\n notify(parent?.authorId, userId, \"New reply in a discussion thread\", link),\n notifyMentionedUsers(discussion.classId, userId, input.body, link),\n ]);\n triggerDiscussionEvent(discussion.classId, \"reply-created\", { discussionId: discussion.id, reply: serializeReply(reply, userId) });\n return { reply: serializeReply(reply, userId) };\n}\n\nexport async function updateDiscussionReply(userId: string, input: { replyId: string; body: string; attachmentIds?: string[] }) {\n const existing = await prisma.discussionReply.findUnique({ where: { id: input.replyId }, include: { discussion: true } });\n if (!existing) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n const { isTeacher } = await getDiscussionForUser(existing.discussionId, userId);\n if (!isTeacher && !(existing.authorId === userId && isWithinAuthorEditWindow(existing.createdAt))) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot edit this reply\" });\n }\n const reply = await prisma.$transaction(async (tx) => {\n await tx.file.updateMany({ where: { discussionReplyId: input.replyId }, data: { discussionReplyId: null } });\n await claimReplyAttachments(tx, userId, input.replyId, input.attachmentIds);\n return tx.discussionReply.update({\n where: { id: input.replyId },\n data: { body: input.body.trim(), deletedAt: null },\n include: replyInclude,\n });\n });\n triggerDiscussionEvent(existing.discussion.classId, \"reply-updated\", { discussionId: existing.discussionId, reply: serializeReply(reply, userId) });\n return { reply: serializeReply(reply, userId) };\n}\n\nexport async function deleteDiscussionReply(userId: string, replyId: string) {\n const existing = await prisma.discussionReply.findUnique({ where: { id: replyId }, include: { discussion: true } });\n if (!existing) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n const { isTeacher } = await getDiscussionForUser(existing.discussionId, userId);\n if (!isTeacher && existing.authorId !== userId) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot delete this reply\" });\n }\n const reply = await prisma.discussionReply.update({\n where: { id: replyId },\n data: { body: \"[deleted]\", deletedAt: new Date(), isAcceptedAnswer: false },\n include: replyInclude,\n });\n triggerDiscussionEvent(existing.discussion.classId, \"reply-deleted\", { discussionId: existing.discussionId, reply: serializeReply(reply, userId) });\n return { reply: serializeReply(reply, userId) };\n}\n\nexport async function pinDiscussion(userId: string, discussionId: string, isPinned: boolean) {\n const { discussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n if (!isTeacher) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can pin discussions\" });\n const updated = await prisma.discussion.update({ where: { id: discussionId }, data: { isPinned }, include: discussionInclude });\n await notify(discussion.authorId, userId, isPinned ? \"Your discussion was pinned\" : \"Your discussion was unpinned\", `/class/${discussion.classId}/discussions/${discussionId}`);\n triggerDiscussionEvent(discussion.classId, \"discussion-updated\", { discussion: serializeDiscussion(updated, userId) });\n return { discussion: serializeDiscussion(updated, userId) };\n}\n\nexport async function lockDiscussion(userId: string, discussionId: string, isLocked: boolean) {\n const { discussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n if (!isTeacher) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can lock discussions\" });\n const updated = await prisma.discussion.update({ where: { id: discussionId }, data: { isLocked }, include: discussionInclude });\n triggerDiscussionEvent(discussion.classId, \"discussion-updated\", { discussion: serializeDiscussion(updated, userId) });\n return { discussion: serializeDiscussion(updated, userId) };\n}\n\nexport async function markAcceptedAnswer(userId: string, replyId: string, accepted: boolean) {\n const reply = await prisma.discussionReply.findUnique({ where: { id: replyId }, include: { discussion: true } });\n if (!reply) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n const { isTeacher } = await getDiscussionForUser(reply.discussionId, userId);\n if (reply.discussion.type !== \"QUESTION\") {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"Only question discussions can have accepted answers\" });\n }\n if (!isTeacher && reply.discussion.authorId !== userId) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only the discussion author or a teacher can mark an accepted answer\" });\n }\n const updated = await prisma.$transaction(async (tx) => {\n if (accepted) {\n await tx.discussionReply.updateMany({ where: { discussionId: reply.discussionId, isAcceptedAnswer: true }, data: { isAcceptedAnswer: false } });\n }\n return tx.discussionReply.update({ where: { id: replyId }, data: { isAcceptedAnswer: accepted }, include: replyInclude });\n });\n await notify(reply.authorId, userId, accepted ? \"Your answer was accepted\" : \"Your answer was unmarked\", `/class/${reply.discussion.classId}/discussions/${reply.discussionId}#${replyId}`);\n triggerDiscussionEvent(reply.discussion.classId, \"reply-updated\", { discussionId: reply.discussionId, reply: serializeReply(updated, userId) });\n return { reply: serializeReply(updated, userId) };\n}\n\nexport async function markDiscussionRead(userId: string, discussionId: string) {\n await getDiscussionForUser(discussionId, userId);\n return prisma.discussionRead.upsert({\n where: { userId_discussionId: { userId, discussionId } },\n update: { lastReadAt: new Date() },\n create: { userId, discussionId },\n });\n}\n\nexport async function getUnreadCounts(userId: string, classIds: string[]) {\n const allowedClasses = await prisma.class.findMany({\n where: { id: { in: classIds }, discussionsEnabled: true, ...classMemberOrSchoolAdminWhere(userId) },\n select: { id: true },\n });\n const result: Record<string, { total: number; perDiscussion: { discussionId: string; count: number }[] }> = {};\n for (const cls of allowedClasses) {\n const discussions = await prisma.discussion.findMany({\n where: { classId: cls.id },\n select: { id: true },\n });\n const countMap = await unreadCountsForDiscussions(userId, discussions.map((discussion) => discussion.id));\n const perDiscussion = Array.from(countMap.entries())\n .map(([discussionId, count]) => ({ discussionId, count }))\n .filter((item) => item.count > 0);\n result[cls.id] = {\n total: perDiscussion.reduce((sum, item) => sum + item.count, 0),\n perDiscussion,\n };\n }\n return result;\n}\n\nexport async function toggleDiscussionReaction(userId: string, input: { discussionId?: string; discussionReplyId?: string; type: ReactionType }) {\n if (!input.discussionId && !input.discussionReplyId) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"A discussion or reply is required\" });\n }\n if (input.discussionId && input.discussionReplyId) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"React to either a discussion or a reply\" });\n }\n const target = input.discussionId\n ? await getDiscussionForUser(input.discussionId, userId).then(({ discussion }) => ({ classId: discussion.classId, discussionId: discussion.id }))\n : await prisma.discussionReply.findUnique({ where: { id: input.discussionReplyId }, include: { discussion: true } }).then(async (reply) => {\n if (!reply) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n await getDiscussionForUser(reply.discussionId, userId);\n return { classId: reply.discussion.classId, discussionId: reply.discussionId };\n });\n const where = input.discussionId\n ? { userId_discussionId: { userId, discussionId: input.discussionId } }\n : { userId_discussionReplyId: { userId, discussionReplyId: input.discussionReplyId! } };\n const existing = await prisma.reaction.findUnique({ where });\n if (existing?.type === input.type) {\n await prisma.reaction.delete({ where: { id: existing.id } });\n triggerDiscussionEvent(target.classId, \"reaction-removed\", { discussionId: target.discussionId, discussionReplyId: input.discussionReplyId, userId });\n return { reaction: null };\n }\n const reaction = input.discussionId\n ? await prisma.reaction.upsert({\n where: { userId_discussionId: { userId, discussionId: input.discussionId } },\n update: { type: input.type },\n create: { userId, discussionId: input.discussionId, type: input.type },\n })\n : await prisma.reaction.upsert({\n where: { userId_discussionReplyId: { userId, discussionReplyId: input.discussionReplyId! } },\n update: { type: input.type },\n create: { userId, discussionReplyId: input.discussionReplyId!, type: input.type },\n });\n triggerDiscussionEvent(target.classId, \"reaction-added\", { discussionId: target.discussionId, discussionReplyId: input.discussionReplyId, reaction });\n return { reaction };\n}\n\nexport async function listDiscussionTags(userId: string, classId: string) {\n await getDiscussionClassAccess(classId, userId);\n return prisma.discussionTag.findMany({ where: { classId }, orderBy: { name: \"asc\" } });\n}\n\nexport async function createDiscussionTag(userId: string, input: { classId: string; name: string; color: string }) {\n const isTeacher = await prisma.class.findFirst({ where: { id: input.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });\n if (!isTeacher?.discussionsEnabled) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can manage discussion tags\" });\n return prisma.discussionTag.create({ data: { classId: input.classId, name: input.name.trim(), color: input.color } });\n}\n\nexport async function updateDiscussionTag(userId: string, input: { tagId: string; name?: string; color?: string }) {\n const tag = await prisma.discussionTag.findUnique({ where: { id: input.tagId }, select: { classId: true } });\n if (!tag) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Tag not found\" });\n const isTeacher = await prisma.class.findFirst({ where: { id: tag.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });\n if (!isTeacher?.discussionsEnabled) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can manage discussion tags\" });\n return prisma.discussionTag.update({ where: { id: input.tagId }, data: { name: input.name?.trim(), color: input.color } });\n}\n\nexport async function deleteDiscussionTag(userId: string, tagId: string) {\n const tag = await prisma.discussionTag.findUnique({ where: { id: tagId }, select: { classId: true } });\n if (!tag) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Tag not found\" });\n const isTeacher = await prisma.class.findFirst({ where: { id: tag.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });\n if (!isTeacher?.discussionsEnabled) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can manage discussion tags\" });\n await prisma.discussionTag.delete({ where: { id: tagId } });\n return { success: true };\n}\n"],"names":[],"mappings":"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","debug_id":"b10e68f8-0106-57a7-be41-a32938701565"}
1
+ {"version":3,"file":"discussion.js","sources":["services/discussion.ts"],"sourceRoot":"/","sourcesContent":["import type { DiscussionType, Prisma, ReactionType } from \"@prisma/client\";\nimport type { AppTransactionClient } from \"../lib/prisma.js\";\nimport { TRPCError } from \"@trpc/server\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { discussionChannel, pusher } from \"../lib/pusher.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { classMemberOrSchoolAdminWhere, classTeacherOrSchoolAdminWhere } from \"../models/access.js\";\nimport { sendNotification } from \"./notification.js\";\nimport { enqueueEmbedding } from \"./embedding.js\";\n\nconst authorSelect = {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n} as const;\n\nconst attachmentSelect = {\n id: true,\n name: true,\n type: true,\n size: true,\n path: true,\n uploadedAt: true,\n uploadStatus: true,\n thumbnailId: true,\n thumbnail: { select: { id: true, path: true } },\n} as const;\n\nconst reactionCounts = {\n THUMBSUP: 0,\n CELEBRATE: 0,\n CARE: 0,\n HEART: 0,\n IDEA: 0,\n HAPPY: 0,\n} satisfies Record<ReactionType, number>;\n\nconst discussionInclude = {\n author: { select: authorSelect },\n attachments: { select: attachmentSelect },\n tags: { select: { id: true, name: true, color: true } },\n reactions: { select: { type: true, userId: true } },\n _count: { select: { replies: { where: { deletedAt: null } } } },\n} as const;\n\nconst replyInclude = {\n author: { select: authorSelect },\n attachments: { select: attachmentSelect },\n reactions: { select: { type: true, userId: true } },\n} as const;\n\nconst unclaimedAttachmentWhere = {\n assignmentId: null,\n submissionId: null,\n annotationId: null,\n classDraftId: null,\n folderId: null,\n messageId: null,\n announcementId: null,\n discussionId: null,\n discussionReplyId: null,\n} satisfies Prisma.FileWhereInput;\n\ntype DiscussionWithInclude = Prisma.DiscussionGetPayload<{ include: typeof discussionInclude }>;\ntype ReplyWithInclude = Prisma.DiscussionReplyGetPayload<{ include: typeof replyInclude }>;\n\nexport type DiscussionReplyTree = ReturnType<typeof serializeReply> & {\n children: DiscussionReplyTree[];\n};\n\nfunction summarizeReactions(reactions: { type: ReactionType; userId: string }[], userId: string) {\n const counts = { ...reactionCounts };\n for (const reaction of reactions) {\n counts[reaction.type] += 1;\n }\n return {\n counts,\n userReaction: reactions.find((reaction) => reaction.userId === userId)?.type ?? null,\n total: reactions.length,\n };\n}\n\nfunction serializeDiscussion(discussion: DiscussionWithInclude, userId: string, unreadCount = 0) {\n return {\n id: discussion.id,\n classId: discussion.classId,\n authorId: discussion.authorId,\n title: discussion.title,\n body: discussion.body,\n type: discussion.type,\n isPinned: discussion.isPinned,\n isLocked: discussion.isLocked,\n allowReplies: discussion.allowReplies,\n createdAt: discussion.createdAt,\n updatedAt: discussion.updatedAt,\n lastActivityAt: discussion.lastActivityAt,\n author: discussion.author,\n attachments: discussion.attachments,\n tags: discussion.tags,\n replyCount: discussion._count.replies,\n hasAcceptedAnswer: false,\n reactions: summarizeReactions(discussion.reactions, userId),\n unreadCount,\n };\n}\n\nfunction serializeReply(reply: ReplyWithInclude, userId: string) {\n return {\n id: reply.id,\n discussionId: reply.discussionId,\n authorId: reply.authorId,\n parentId: reply.parentId,\n body: reply.deletedAt ? \"[deleted]\" : reply.body,\n deletedAt: reply.deletedAt,\n isAcceptedAnswer: reply.isAcceptedAnswer,\n createdAt: reply.createdAt,\n modifiedAt: reply.modifiedAt,\n author: reply.author,\n attachments: reply.deletedAt ? [] : reply.attachments,\n reactions: summarizeReactions(reply.reactions, userId),\n };\n}\n\nexport function buildReplyTree(replies: ReplyWithInclude[], userId: string): DiscussionReplyTree[] {\n const byId = new Map<string, DiscussionReplyTree>();\n const roots: DiscussionReplyTree[] = [];\n\n for (const reply of replies) {\n byId.set(reply.id, { ...serializeReply(reply, userId), children: [] });\n }\n\n for (const reply of replies) {\n const node = byId.get(reply.id)!;\n if (reply.parentId && byId.has(reply.parentId)) {\n byId.get(reply.parentId)!.children.push(node);\n } else {\n roots.push(node);\n }\n }\n\n return roots;\n}\n\nfunction isWithinAuthorEditWindow(createdAt: Date) {\n return Date.now() - createdAt.getTime() <= 24 * 60 * 60 * 1000;\n}\n\nexport async function getDiscussionClassAccess(classId: string, userId: string) {\n const classData = await prisma.class.findFirst({\n where: { id: classId, ...classMemberOrSchoolAdminWhere(userId) },\n select: {\n id: true,\n name: true,\n discussionsEnabled: true,\n studentsCanCreateDiscussions: true,\n studentsCanReply: true,\n students: { where: { id: userId }, select: { id: true } },\n teachers: { where: { id: userId }, select: { id: true } },\n school: {\n select: {\n memberships: {\n where: { userId, role: \"ADMIN\", status: \"ACTIVE\" },\n select: { userId: true },\n },\n },\n },\n },\n });\n\n if (!classData) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Not a member in this class\" });\n }\n if (!classData.discussionsEnabled) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Discussions are disabled for this class\" });\n }\n\n const isTeacher = classData.teachers.length > 0 || Boolean(classData.school?.memberships.length);\n const isStudent = classData.students.length > 0;\n\n return { ...classData, isTeacher, isStudent };\n}\n\nasync function getDiscussionForUser(discussionId: string, userId: string) {\n const discussion = await prisma.discussion.findUnique({\n where: { id: discussionId },\n include: {\n class: {\n select: {\n id: true,\n discussionsEnabled: true,\n studentsCanReply: true,\n teachers: { where: { id: userId }, select: { id: true } },\n students: { where: { id: userId }, select: { id: true } },\n school: {\n select: {\n memberships: {\n where: { userId, role: \"ADMIN\", status: \"ACTIVE\" },\n select: { userId: true },\n },\n },\n },\n },\n },\n },\n });\n\n if (!discussion) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Discussion not found\" });\n }\n\n const isTeacher = discussion.class.teachers.length > 0 || Boolean(discussion.class.school?.memberships.length);\n const isStudent = discussion.class.students.length > 0;\n if (!isTeacher && !isStudent) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Not a member in this class\" });\n }\n if (!discussion.class.discussionsEnabled) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Discussions are disabled for this class\" });\n }\n\n return { discussion, isTeacher, isStudent };\n}\n\nasync function claimDiscussionAttachments(\n tx: AppTransactionClient,\n userId: string,\n discussionId: string,\n attachmentIds: string[] = []\n) {\n const uniqueIds = [...new Set(attachmentIds)];\n if (!uniqueIds.length) return;\n const { count } = await tx.file.updateMany({\n where: { id: { in: uniqueIds }, userId, uploadStatus: \"COMPLETED\", ...unclaimedAttachmentWhere },\n data: { discussionId },\n });\n if (count !== uniqueIds.length) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"Some attachments are missing, unfinished, or unavailable\" });\n }\n}\n\nasync function claimReplyAttachments(\n tx: AppTransactionClient,\n userId: string,\n replyId: string,\n attachmentIds: string[] = []\n) {\n const uniqueIds = [...new Set(attachmentIds)];\n if (!uniqueIds.length) return;\n const { count } = await tx.file.updateMany({\n where: { id: { in: uniqueIds }, userId, uploadStatus: \"COMPLETED\", ...unclaimedAttachmentWhere },\n data: { discussionReplyId: replyId },\n });\n if (count !== uniqueIds.length) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"Some attachments are missing, unfinished, or unavailable\" });\n }\n}\n\nfunction triggerDiscussionEvent(classId: string, event: string, payload: unknown) {\n pusher.trigger(discussionChannel(classId), event, payload).catch((error) => {\n logger.error(\"Failed to trigger discussion pusher event\", { event, classId, error });\n });\n}\n\nasync function notify(receiverId: string | null | undefined, senderId: string, title: string, content: string) {\n if (!receiverId || receiverId === senderId) return;\n await sendNotification({ receiverId, title, content }).catch((error) => {\n logger.error(\"Failed to send discussion notification\", { receiverId, error });\n });\n}\n\nasync function notifyMentionedUsers(classId: string, senderId: string, body: string, link: string) {\n const usernames = [...new Set(Array.from(body.matchAll(/(^|\\s)@([a-zA-Z0-9_.-]{2,32})/g)).map((match) => match[2]))];\n if (!usernames.length) return;\n const members = await prisma.user.findMany({\n where: {\n username: { in: usernames },\n OR: [\n { teacherIn: { some: { id: classId } } },\n { studentIn: { some: { id: classId } } },\n { schoolMemberships: { some: { status: \"ACTIVE\", school: { classes: { some: { id: classId } } } } } },\n ],\n },\n select: { id: true },\n });\n await Promise.all(members.map((member) => notify(member.id, senderId, \"You were mentioned in a discussion\", link)));\n}\n\nasync function unreadCountsForDiscussions(userId: string, discussionIds: string[]) {\n if (!discussionIds.length) return new Map<string, number>();\n const reads = await prisma.discussionRead.findMany({\n where: { userId, discussionId: { in: discussionIds } },\n select: { discussionId: true, lastReadAt: true },\n });\n const readMap = new Map(reads.map((read) => [read.discussionId, read.lastReadAt]));\n const neverRead = discussionIds.filter((discussionId) => !readMap.has(discussionId));\n const readPredicates = Array.from(readMap.entries()).map(([discussionId, lastReadAt]) => ({\n discussionId,\n createdAt: { gt: lastReadAt },\n }));\n const counts = new Map<string, number>();\n\n const [neverReadCounts, readCounts] = await Promise.all([\n neverRead.length\n ? prisma.discussionReply.groupBy({\n by: [\"discussionId\"],\n where: { discussionId: { in: neverRead }, deletedAt: null, authorId: { not: userId } },\n _count: true,\n })\n : Promise.resolve([]),\n readPredicates.length\n ? prisma.discussionReply.groupBy({\n by: [\"discussionId\"],\n where: { deletedAt: null, authorId: { not: userId }, OR: readPredicates },\n _count: true,\n })\n : Promise.resolve([]),\n ]);\n\n for (const item of [...neverReadCounts, ...readCounts]) {\n counts.set(item.discussionId, item._count);\n }\n return counts;\n}\n\nexport async function listDiscussions(userId: string, input: {\n classId: string;\n tagId?: string;\n type?: DiscussionType;\n search?: string;\n sort: \"recent\" | \"activity\" | \"top\";\n cursor?: string;\n limit: number;\n}) {\n await getDiscussionClassAccess(input.classId, userId);\n const where: Prisma.DiscussionWhereInput = {\n classId: input.classId,\n ...(input.tagId ? { tags: { some: { id: input.tagId } } } : {}),\n ...(input.type ? { type: input.type } : {}),\n ...(input.search?.trim()\n ? {\n OR: [\n { title: { contains: input.search.trim(), mode: \"insensitive\" } },\n { body: { contains: input.search.trim(), mode: \"insensitive\" } },\n ],\n }\n : {}),\n };\n const orderBy: Prisma.DiscussionOrderByWithRelationInput[] =\n input.sort === \"recent\"\n ? [{ isPinned: \"desc\" }, { createdAt: \"desc\" }]\n : input.sort === \"top\"\n ? [{ isPinned: \"desc\" }, { replies: { _count: \"desc\" } }, { lastActivityAt: \"desc\" }]\n : [{ isPinned: \"desc\" }, { lastActivityAt: \"desc\" }];\n\n const items = await prisma.discussion.findMany({\n where,\n include: discussionInclude,\n orderBy,\n cursor: input.cursor ? { id: input.cursor } : undefined,\n skip: input.cursor ? 1 : 0,\n take: input.limit + 1,\n });\n const next = items.length > input.limit ? items.pop() : undefined;\n const unreadMap = await unreadCountsForDiscussions(userId, items.map((item) => item.id));\n const accepted = await prisma.discussionReply.groupBy({\n by: [\"discussionId\"],\n where: { discussionId: { in: items.map((item) => item.id) }, isAcceptedAnswer: true, deletedAt: null },\n });\n const acceptedIds = new Set(accepted.map((item) => item.discussionId));\n\n return {\n items: items.map((item) => ({\n ...serializeDiscussion(item, userId, unreadMap.get(item.id) ?? 0),\n hasAcceptedAnswer: acceptedIds.has(item.id),\n })),\n nextCursor: next?.id,\n };\n}\n\nexport async function getDiscussion(userId: string, discussionId: string) {\n const { discussion: accessDiscussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n const [discussion, replies, myReaction] = await Promise.all([\n prisma.discussion.findUniqueOrThrow({ where: { id: discussionId }, include: discussionInclude }),\n prisma.discussionReply.findMany({ where: { discussionId }, include: replyInclude, orderBy: { createdAt: \"asc\" } }),\n prisma.reaction.findUnique({ where: { userId_discussionId: { userId, discussionId } }, select: { type: true } }),\n prisma.discussionRead.upsert({\n where: { userId_discussionId: { userId, discussionId } },\n update: { lastReadAt: new Date() },\n create: { userId, discussionId },\n }),\n ]);\n const canAuthorEdit = accessDiscussion.authorId === userId && isWithinAuthorEditWindow(accessDiscussion.createdAt);\n const canReply = isTeacher || (accessDiscussion.class.studentsCanReply && !accessDiscussion.isLocked && accessDiscussion.allowReplies);\n return {\n discussion: serializeDiscussion(discussion, userId),\n replies: buildReplyTree(replies, userId),\n myReaction: myReaction?.type ?? null,\n canEdit: isTeacher || canAuthorEdit,\n canPin: isTeacher,\n canLock: isTeacher,\n canDelete: isTeacher || accessDiscussion.authorId === userId,\n canReply,\n };\n}\n\nexport async function createDiscussion(userId: string, input: {\n classId: string;\n title: string;\n body: string;\n type: DiscussionType;\n tagIds?: string[];\n attachmentIds?: string[];\n}) {\n const classData = await getDiscussionClassAccess(input.classId, userId);\n if (!classData.isTeacher && !classData.studentsCanCreateDiscussions) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Students cannot create discussions in this class\" });\n }\n if (input.type === \"ANNOUNCEMENT\" && !classData.isTeacher) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can create announcement discussions\" });\n }\n\n const discussion = await prisma.$transaction(async (tx) => {\n const created = await tx.discussion.create({\n data: {\n classId: input.classId,\n authorId: userId,\n title: input.title.trim(),\n body: input.body.trim(),\n type: input.type,\n allowReplies: input.type !== \"ANNOUNCEMENT\",\n tags: input.tagIds?.length ? { connect: input.tagIds.map((id) => ({ id })) } : undefined,\n },\n });\n await claimDiscussionAttachments(tx, userId, created.id, input.attachmentIds);\n return tx.discussion.findUniqueOrThrow({ where: { id: created.id }, include: discussionInclude });\n });\n\n triggerDiscussionEvent(input.classId, \"discussion-created\", { discussion: serializeDiscussion(discussion, userId) });\n await notifyMentionedUsers(input.classId, userId, input.body, `/class/${input.classId}/discussions/${discussion.id}`);\n\n // Auto-index discussion for RAG search\n enqueueEmbedding(input.classId, 'DISCUSSION', discussion.id);\n\n return { discussion: serializeDiscussion(discussion, userId) };\n}\n\nexport async function updateDiscussion(userId: string, input: {\n discussionId: string;\n title?: string;\n body?: string;\n type?: DiscussionType;\n tagIds?: string[];\n allowReplies?: boolean;\n}) {\n const { discussion, isTeacher } = await getDiscussionForUser(input.discussionId, userId);\n if (!isTeacher && !(discussion.authorId === userId && isWithinAuthorEditWindow(discussion.createdAt))) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot edit this discussion\" });\n }\n if (input.type === \"ANNOUNCEMENT\" && !isTeacher) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can create announcement discussions\" });\n }\n const updated = await prisma.discussion.update({\n where: { id: input.discussionId },\n data: {\n ...(input.title !== undefined ? { title: input.title.trim() } : {}),\n ...(input.body !== undefined ? { body: input.body.trim() } : {}),\n ...(input.type !== undefined ? { type: input.type } : {}),\n ...(input.allowReplies !== undefined ? { allowReplies: input.allowReplies } : {}),\n ...(input.tagIds ? { tags: { set: input.tagIds.map((id) => ({ id })) } } : {}),\n },\n include: discussionInclude,\n });\n triggerDiscussionEvent(updated.classId, \"discussion-updated\", { discussion: serializeDiscussion(updated, userId) });\n\n // Re-index discussion for RAG search after update\n enqueueEmbedding(updated.classId, 'DISCUSSION', updated.id);\n\n return { discussion: serializeDiscussion(updated, userId) };\n}\n\nexport async function deleteDiscussion(userId: string, discussionId: string) {\n const { discussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n if (!isTeacher && discussion.authorId !== userId) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot delete this discussion\" });\n }\n await prisma.discussion.delete({ where: { id: discussionId } });\n triggerDiscussionEvent(discussion.classId, \"discussion-deleted\", { discussionId });\n return { success: true };\n}\n\nexport async function replyToDiscussion(userId: string, input: {\n discussionId: string;\n parentReplyId?: string;\n body: string;\n attachmentIds?: string[];\n}) {\n const { discussion, isTeacher } = await getDiscussionForUser(input.discussionId, userId);\n const canReply = isTeacher || (discussion.class.studentsCanReply && !discussion.isLocked && discussion.allowReplies);\n if (!canReply) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot reply to this discussion\" });\n }\n let parent: { id: string; authorId: string } | null = null;\n if (input.parentReplyId) {\n parent = await prisma.discussionReply.findFirst({\n where: { id: input.parentReplyId, discussionId: input.discussionId },\n select: { id: true, authorId: true },\n });\n if (!parent) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Parent reply not found\" });\n }\n const reply = await prisma.$transaction(async (tx) => {\n const created = await tx.discussionReply.create({\n data: {\n discussionId: input.discussionId,\n authorId: userId,\n parentId: input.parentReplyId,\n body: input.body.trim(),\n },\n });\n await claimReplyAttachments(tx, userId, created.id, input.attachmentIds);\n await tx.discussion.update({\n where: { id: input.discussionId },\n data: { lastActivityAt: new Date() },\n });\n return tx.discussionReply.findUniqueOrThrow({ where: { id: created.id }, include: replyInclude });\n });\n const link = `/class/${discussion.classId}/discussions/${discussion.id}#${reply.id}`;\n await Promise.all([\n notify(discussion.authorId, userId, \"New reply to your discussion\", link),\n notify(parent?.authorId, userId, \"New reply in a discussion thread\", link),\n notifyMentionedUsers(discussion.classId, userId, input.body, link),\n ]);\n triggerDiscussionEvent(discussion.classId, \"reply-created\", { discussionId: discussion.id, reply: serializeReply(reply, userId) });\n\n // Re-index discussion for RAG search (includes new reply)\n enqueueEmbedding(discussion.classId, 'DISCUSSION', discussion.id);\n\n return { reply: serializeReply(reply, userId) };\n}\n\nexport async function updateDiscussionReply(userId: string, input: { replyId: string; body: string; attachmentIds?: string[] }) {\n const existing = await prisma.discussionReply.findUnique({ where: { id: input.replyId }, include: { discussion: true } });\n if (!existing) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n const { isTeacher } = await getDiscussionForUser(existing.discussionId, userId);\n if (!isTeacher && !(existing.authorId === userId && isWithinAuthorEditWindow(existing.createdAt))) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot edit this reply\" });\n }\n const reply = await prisma.$transaction(async (tx) => {\n await tx.file.updateMany({ where: { discussionReplyId: input.replyId }, data: { discussionReplyId: null } });\n await claimReplyAttachments(tx, userId, input.replyId, input.attachmentIds);\n return tx.discussionReply.update({\n where: { id: input.replyId },\n data: { body: input.body.trim(), deletedAt: null },\n include: replyInclude,\n });\n });\n triggerDiscussionEvent(existing.discussion.classId, \"reply-updated\", { discussionId: existing.discussionId, reply: serializeReply(reply, userId) });\n return { reply: serializeReply(reply, userId) };\n}\n\nexport async function deleteDiscussionReply(userId: string, replyId: string) {\n const existing = await prisma.discussionReply.findUnique({ where: { id: replyId }, include: { discussion: true } });\n if (!existing) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n const { isTeacher } = await getDiscussionForUser(existing.discussionId, userId);\n if (!isTeacher && existing.authorId !== userId) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot delete this reply\" });\n }\n const reply = await prisma.discussionReply.update({\n where: { id: replyId },\n data: { body: \"[deleted]\", deletedAt: new Date(), isAcceptedAnswer: false },\n include: replyInclude,\n });\n triggerDiscussionEvent(existing.discussion.classId, \"reply-deleted\", { discussionId: existing.discussionId, reply: serializeReply(reply, userId) });\n return { reply: serializeReply(reply, userId) };\n}\n\nexport async function pinDiscussion(userId: string, discussionId: string, isPinned: boolean) {\n const { discussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n if (!isTeacher) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can pin discussions\" });\n const updated = await prisma.discussion.update({ where: { id: discussionId }, data: { isPinned }, include: discussionInclude });\n await notify(discussion.authorId, userId, isPinned ? \"Your discussion was pinned\" : \"Your discussion was unpinned\", `/class/${discussion.classId}/discussions/${discussionId}`);\n triggerDiscussionEvent(discussion.classId, \"discussion-updated\", { discussion: serializeDiscussion(updated, userId) });\n return { discussion: serializeDiscussion(updated, userId) };\n}\n\nexport async function lockDiscussion(userId: string, discussionId: string, isLocked: boolean) {\n const { discussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n if (!isTeacher) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can lock discussions\" });\n const updated = await prisma.discussion.update({ where: { id: discussionId }, data: { isLocked }, include: discussionInclude });\n triggerDiscussionEvent(discussion.classId, \"discussion-updated\", { discussion: serializeDiscussion(updated, userId) });\n return { discussion: serializeDiscussion(updated, userId) };\n}\n\nexport async function markAcceptedAnswer(userId: string, replyId: string, accepted: boolean) {\n const reply = await prisma.discussionReply.findUnique({ where: { id: replyId }, include: { discussion: true } });\n if (!reply) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n const { isTeacher } = await getDiscussionForUser(reply.discussionId, userId);\n if (reply.discussion.type !== \"QUESTION\") {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"Only question discussions can have accepted answers\" });\n }\n if (!isTeacher && reply.discussion.authorId !== userId) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only the discussion author or a teacher can mark an accepted answer\" });\n }\n const updated = await prisma.$transaction(async (tx) => {\n if (accepted) {\n await tx.discussionReply.updateMany({ where: { discussionId: reply.discussionId, isAcceptedAnswer: true }, data: { isAcceptedAnswer: false } });\n }\n return tx.discussionReply.update({ where: { id: replyId }, data: { isAcceptedAnswer: accepted }, include: replyInclude });\n });\n await notify(reply.authorId, userId, accepted ? \"Your answer was accepted\" : \"Your answer was unmarked\", `/class/${reply.discussion.classId}/discussions/${reply.discussionId}#${replyId}`);\n triggerDiscussionEvent(reply.discussion.classId, \"reply-updated\", { discussionId: reply.discussionId, reply: serializeReply(updated, userId) });\n return { reply: serializeReply(updated, userId) };\n}\n\nexport async function markDiscussionRead(userId: string, discussionId: string) {\n await getDiscussionForUser(discussionId, userId);\n return prisma.discussionRead.upsert({\n where: { userId_discussionId: { userId, discussionId } },\n update: { lastReadAt: new Date() },\n create: { userId, discussionId },\n });\n}\n\nexport async function getUnreadCounts(userId: string, classIds: string[]) {\n const allowedClasses = await prisma.class.findMany({\n where: { id: { in: classIds }, discussionsEnabled: true, ...classMemberOrSchoolAdminWhere(userId) },\n select: { id: true },\n });\n const result: Record<string, { total: number; perDiscussion: { discussionId: string; count: number }[] }> = {};\n for (const cls of allowedClasses) {\n const discussions = await prisma.discussion.findMany({\n where: { classId: cls.id },\n select: { id: true },\n });\n const countMap = await unreadCountsForDiscussions(userId, discussions.map((discussion) => discussion.id));\n const perDiscussion = Array.from(countMap.entries())\n .map(([discussionId, count]) => ({ discussionId, count }))\n .filter((item) => item.count > 0);\n result[cls.id] = {\n total: perDiscussion.reduce((sum, item) => sum + item.count, 0),\n perDiscussion,\n };\n }\n return result;\n}\n\nexport async function toggleDiscussionReaction(userId: string, input: { discussionId?: string; discussionReplyId?: string; type: ReactionType }) {\n if (!input.discussionId && !input.discussionReplyId) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"A discussion or reply is required\" });\n }\n if (input.discussionId && input.discussionReplyId) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"React to either a discussion or a reply\" });\n }\n const target = input.discussionId\n ? await getDiscussionForUser(input.discussionId, userId).then(({ discussion }) => ({ classId: discussion.classId, discussionId: discussion.id }))\n : await prisma.discussionReply.findUnique({ where: { id: input.discussionReplyId }, include: { discussion: true } }).then(async (reply) => {\n if (!reply) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n await getDiscussionForUser(reply.discussionId, userId);\n return { classId: reply.discussion.classId, discussionId: reply.discussionId };\n });\n const where = input.discussionId\n ? { userId_discussionId: { userId, discussionId: input.discussionId } }\n : { userId_discussionReplyId: { userId, discussionReplyId: input.discussionReplyId! } };\n const existing = await prisma.reaction.findUnique({ where });\n if (existing?.type === input.type) {\n await prisma.reaction.delete({ where: { id: existing.id } });\n triggerDiscussionEvent(target.classId, \"reaction-removed\", { discussionId: target.discussionId, discussionReplyId: input.discussionReplyId, userId });\n return { reaction: null };\n }\n const reaction = input.discussionId\n ? await prisma.reaction.upsert({\n where: { userId_discussionId: { userId, discussionId: input.discussionId } },\n update: { type: input.type },\n create: { userId, discussionId: input.discussionId, type: input.type },\n })\n : await prisma.reaction.upsert({\n where: { userId_discussionReplyId: { userId, discussionReplyId: input.discussionReplyId! } },\n update: { type: input.type },\n create: { userId, discussionReplyId: input.discussionReplyId!, type: input.type },\n });\n triggerDiscussionEvent(target.classId, \"reaction-added\", { discussionId: target.discussionId, discussionReplyId: input.discussionReplyId, reaction });\n return { reaction };\n}\n\nexport async function listDiscussionTags(userId: string, classId: string) {\n await getDiscussionClassAccess(classId, userId);\n return prisma.classTag.findMany({ where: { classId }, orderBy: { name: \"asc\" } });\n}\n\nexport async function createDiscussionTag(userId: string, input: { classId: string; name: string; color: string }) {\n const isTeacher = await prisma.class.findFirst({ where: { id: input.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });\n if (!isTeacher?.discussionsEnabled) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can manage discussion tags\" });\n return prisma.classTag.create({ data: { classId: input.classId, name: input.name.trim(), color: input.color } });\n}\n\nexport async function updateDiscussionTag(userId: string, input: { tagId: string; name?: string; color?: string }) {\n const tag = await prisma.classTag.findUnique({ where: { id: input.tagId }, select: { classId: true } });\n if (!tag) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Tag not found\" });\n const isTeacher = await prisma.class.findFirst({ where: { id: tag.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });\n if (!isTeacher?.discussionsEnabled) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can manage discussion tags\" });\n return prisma.classTag.update({ where: { id: input.tagId }, data: { name: input.name?.trim(), color: input.color } });\n}\n\nexport async function deleteDiscussionTag(userId: string, tagId: string) {\n const tag = await prisma.classTag.findUnique({ where: { id: tagId }, select: { classId: true } });\n if (!tag) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Tag not found\" });\n const isTeacher = await prisma.class.findFirst({ where: { id: tag.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });\n if (!isTeacher?.discussionsEnabled) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can manage discussion tags\" });\n await prisma.classTag.delete({ where: { id: tagId } });\n return { success: true };\n}\n"],"names":[],"mappings":"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","debug_id":"9ce66b69-3963-5ac9-91a6-6aa8b6d86a75"}
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ declare const discussionSummarySchema: z.ZodObject<{
3
+ summary: z.ZodString;
4
+ keyQuestions: z.ZodArray<z.ZodString, "many">;
5
+ unresolvedIssues: z.ZodArray<z.ZodString, "many">;
6
+ participantCount: z.ZodNumber;
7
+ }, "strip", z.ZodTypeAny, {
8
+ summary: string;
9
+ keyQuestions: string[];
10
+ unresolvedIssues: string[];
11
+ participantCount: number;
12
+ }, {
13
+ summary: string;
14
+ keyQuestions: string[];
15
+ unresolvedIssues: string[];
16
+ participantCount: number;
17
+ }>;
18
+ export type DiscussionSummary = z.infer<typeof discussionSummarySchema>;
19
+ export declare function getDiscussionSummary(userId: string, discussionId: string): Promise<DiscussionSummary>;
20
+ export {};
21
+ //# sourceMappingURL=discussionSummary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discussionSummary.d.ts","sourceRoot":"/","sources":["services/discussionSummary.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,QAAA,MAAM,uBAAuB;;;;;;;;;;;;;;;EAe3B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAmFxE,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,iBAAiB,CAAC,CA+G5B"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * AI-powered discussion summary service with in-memory + Redis caching.
3
+ */
4
+
5
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="123ae967-1b03-513e-8fd2-867781eb48f0")}catch(e){}}();
6
+ import { prisma } from "../lib/prisma.js";
7
+ import { getRedis } from "../lib/redis.js";
8
+ import { inference } from "../utils/inference.js";
9
+ import { logger } from "../utils/logger.js";
10
+ import { TRPCError } from "@trpc/server";
11
+ import { z } from "zod";
12
+ import { classMemberOrSchoolAdminWhere } from "../models/access.js";
13
+ const discussionSummarySchema = z.object({
14
+ summary: z
15
+ .string()
16
+ .describe("A concise 2-4 sentence TL;DR of the entire discussion thread."),
17
+ keyQuestions: z
18
+ .array(z.string())
19
+ .describe("Up to 5 important student questions raised in the thread."),
20
+ unresolvedIssues: z
21
+ .array(z.string())
22
+ .describe("Up to 3 questions or topics that remain unanswered or unresolved."),
23
+ participantCount: z
24
+ .number()
25
+ .describe("Number of unique participants in the thread."),
26
+ });
27
+ const REDIS_PREFIX = "discussionSummary:";
28
+ const REDIS_TTL_SECONDS = 60 * 30; // 30 min
29
+ const memoryCache = new Map();
30
+ const MEMORY_TTL_MS = 10 * 60 * 1000; // 10 min
31
+ function memoryCacheKey(discussionId) {
32
+ return discussionId;
33
+ }
34
+ function getMemoryCacheHit(discussionId, currentReplyCount) {
35
+ const entry = memoryCache.get(memoryCacheKey(discussionId));
36
+ if (!entry)
37
+ return undefined;
38
+ if (Date.now() - entry.cachedAt > MEMORY_TTL_MS) {
39
+ memoryCache.delete(memoryCacheKey(discussionId));
40
+ return undefined;
41
+ }
42
+ if (entry.replyCount !== currentReplyCount) {
43
+ memoryCache.delete(memoryCacheKey(discussionId));
44
+ return undefined;
45
+ }
46
+ return entry.value;
47
+ }
48
+ function setMemoryCache(discussionId, value, replyCount) {
49
+ memoryCache.set(memoryCacheKey(discussionId), {
50
+ value,
51
+ replyCount,
52
+ cachedAt: Date.now(),
53
+ });
54
+ }
55
+ async function getRedisCacheHit(discussionId, currentReplyCount) {
56
+ const redis = getRedis();
57
+ if (!redis)
58
+ return undefined;
59
+ try {
60
+ const raw = await redis.get(`${REDIS_PREFIX}${discussionId}`);
61
+ if (!raw)
62
+ return undefined;
63
+ const parsed = JSON.parse(raw);
64
+ if (parsed.replyCount !== currentReplyCount)
65
+ return undefined;
66
+ return parsed.value;
67
+ }
68
+ catch {
69
+ return undefined;
70
+ }
71
+ }
72
+ async function setRedisCache(discussionId, value, replyCount) {
73
+ const redis = getRedis();
74
+ if (!redis)
75
+ return;
76
+ try {
77
+ await redis.set(`${REDIS_PREFIX}${discussionId}`, JSON.stringify({ value, replyCount }), "EX", REDIS_TTL_SECONDS);
78
+ }
79
+ catch (err) {
80
+ logger.error("Failed to cache discussion summary in Redis", { err });
81
+ }
82
+ }
83
+ export async function getDiscussionSummary(userId, discussionId) {
84
+ const discussion = await prisma.discussion.findUnique({
85
+ where: { id: discussionId },
86
+ select: {
87
+ id: true,
88
+ classId: true,
89
+ title: true,
90
+ body: true,
91
+ type: true,
92
+ replies: {
93
+ where: { deletedAt: null },
94
+ select: {
95
+ body: true,
96
+ author: {
97
+ select: {
98
+ username: true,
99
+ profile: { select: { displayName: true } },
100
+ },
101
+ },
102
+ createdAt: true,
103
+ },
104
+ orderBy: { createdAt: "asc" },
105
+ },
106
+ author: {
107
+ select: {
108
+ username: true,
109
+ profile: { select: { displayName: true } },
110
+ },
111
+ },
112
+ },
113
+ });
114
+ if (!discussion) {
115
+ throw new TRPCError({
116
+ code: "NOT_FOUND",
117
+ message: "Discussion not found",
118
+ });
119
+ }
120
+ // Verify user is a member of the class
121
+ const classMembership = await prisma.class.findFirst({
122
+ where: { id: discussion.classId, ...classMemberOrSchoolAdminWhere(userId) },
123
+ select: { id: true },
124
+ });
125
+ if (!classMembership) {
126
+ throw new TRPCError({
127
+ code: "UNAUTHORIZED",
128
+ message: "You are not a member of this class",
129
+ });
130
+ }
131
+ const replyCount = discussion.replies.length;
132
+ // Check memory cache
133
+ const memoryCached = getMemoryCacheHit(discussionId, replyCount);
134
+ if (memoryCached)
135
+ return memoryCached;
136
+ // Check Redis cache
137
+ const redisCached = await getRedisCacheHit(discussionId, replyCount);
138
+ if (redisCached) {
139
+ setMemoryCache(discussionId, redisCached, replyCount);
140
+ return redisCached;
141
+ }
142
+ // Build context for inference
143
+ const authorName = discussion.author.profile?.displayName ?? discussion.author.username;
144
+ const threadText = [
145
+ `Title: ${discussion.title}`,
146
+ `Type: ${discussion.type}`,
147
+ `Author: ${authorName}`,
148
+ `Original post:\n${discussion.body}`,
149
+ "",
150
+ ...discussion.replies.map((reply, i) => {
151
+ const name = reply.author.profile?.displayName ?? reply.author.username;
152
+ return `Reply ${i + 1} by ${name}:\n${reply.body}`;
153
+ }),
154
+ ].join("\n\n");
155
+ const messages = [
156
+ {
157
+ role: "system",
158
+ content: "You are a helpful assistant summarizing a class discussion thread for a teacher. Be concise, specific, and grounded in the actual content. Do not fabricate information.",
159
+ },
160
+ {
161
+ role: "user",
162
+ content: threadText,
163
+ },
164
+ {
165
+ role: "user",
166
+ content: "Generate a structured summary of this discussion thread. Include a TL;DR, key student questions, and any unresolved issues.",
167
+ },
168
+ ];
169
+ const result = await inference(messages, discussionSummarySchema, {
170
+ reason: "discussion_summary",
171
+ metadata: { discussionId, classId: discussion.classId },
172
+ });
173
+ // Cache result
174
+ setMemoryCache(discussionId, result, replyCount);
175
+ await setRedisCache(discussionId, result, replyCount);
176
+ return result;
177
+ }
178
+ //# sourceMappingURL=discussionSummary.js.map
179
+ //# debugId=123ae967-1b03-513e-8fd2-867781eb48f0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discussionSummary.js","sources":["services/discussionSummary.ts"],"sourceRoot":"/","sourcesContent":["/**\n * AI-powered discussion summary service with in-memory + Redis caching.\n */\nimport { prisma } from \"../lib/prisma.js\";\nimport { getRedis } from \"../lib/redis.js\";\nimport { inference } from \"../utils/inference.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { TRPCError } from \"@trpc/server\";\nimport { z } from \"zod\";\nimport { classMemberOrSchoolAdminWhere } from \"../models/access.js\";\n\nconst discussionSummarySchema = z.object({\n summary: z\n .string()\n .describe(\"A concise 2-4 sentence TL;DR of the entire discussion thread.\"),\n keyQuestions: z\n .array(z.string())\n .describe(\"Up to 5 important student questions raised in the thread.\"),\n unresolvedIssues: z\n .array(z.string())\n .describe(\n \"Up to 3 questions or topics that remain unanswered or unresolved.\",\n ),\n participantCount: z\n .number()\n .describe(\"Number of unique participants in the thread.\"),\n});\n\nexport type DiscussionSummary = z.infer<typeof discussionSummarySchema>;\n\nconst REDIS_PREFIX = \"discussionSummary:\";\nconst REDIS_TTL_SECONDS = 60 * 30; // 30 min\n\nconst memoryCache = new Map<\n string,\n { value: DiscussionSummary; replyCount: number; cachedAt: number }\n>();\nconst MEMORY_TTL_MS = 10 * 60 * 1000; // 10 min\n\nfunction memoryCacheKey(discussionId: string) {\n return discussionId;\n}\n\nfunction getMemoryCacheHit(\n discussionId: string,\n currentReplyCount: number,\n): DiscussionSummary | undefined {\n const entry = memoryCache.get(memoryCacheKey(discussionId));\n if (!entry) return undefined;\n if (Date.now() - entry.cachedAt > MEMORY_TTL_MS) {\n memoryCache.delete(memoryCacheKey(discussionId));\n return undefined;\n }\n if (entry.replyCount !== currentReplyCount) {\n memoryCache.delete(memoryCacheKey(discussionId));\n return undefined;\n }\n return entry.value;\n}\n\nfunction setMemoryCache(\n discussionId: string,\n value: DiscussionSummary,\n replyCount: number,\n) {\n memoryCache.set(memoryCacheKey(discussionId), {\n value,\n replyCount,\n cachedAt: Date.now(),\n });\n}\n\nasync function getRedisCacheHit(\n discussionId: string,\n currentReplyCount: number,\n): Promise<DiscussionSummary | undefined> {\n const redis = getRedis();\n if (!redis) return undefined;\n try {\n const raw = await redis.get(`${REDIS_PREFIX}${discussionId}`);\n if (!raw) return undefined;\n const parsed = JSON.parse(raw) as {\n value: DiscussionSummary;\n replyCount: number;\n };\n if (parsed.replyCount !== currentReplyCount) return undefined;\n return parsed.value;\n } catch {\n return undefined;\n }\n}\n\nasync function setRedisCache(\n discussionId: string,\n value: DiscussionSummary,\n replyCount: number,\n) {\n const redis = getRedis();\n if (!redis) return;\n try {\n await redis.set(\n `${REDIS_PREFIX}${discussionId}`,\n JSON.stringify({ value, replyCount }),\n \"EX\",\n REDIS_TTL_SECONDS,\n );\n } catch (err) {\n logger.error(\"Failed to cache discussion summary in Redis\", { err });\n }\n}\n\nexport async function getDiscussionSummary(\n userId: string,\n discussionId: string,\n): Promise<DiscussionSummary> {\n const discussion = await prisma.discussion.findUnique({\n where: { id: discussionId },\n select: {\n id: true,\n classId: true,\n title: true,\n body: true,\n type: true,\n replies: {\n where: { deletedAt: null },\n select: {\n body: true,\n author: {\n select: {\n username: true,\n profile: { select: { displayName: true } },\n },\n },\n createdAt: true,\n },\n orderBy: { createdAt: \"asc\" },\n },\n author: {\n select: {\n username: true,\n profile: { select: { displayName: true } },\n },\n },\n },\n });\n\n if (!discussion) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Discussion not found\",\n });\n }\n\n // Verify user is a member of the class\n const classMembership = await prisma.class.findFirst({\n where: { id: discussion.classId, ...classMemberOrSchoolAdminWhere(userId) },\n select: { id: true },\n });\n if (!classMembership) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You are not a member of this class\",\n });\n }\n\n const replyCount = discussion.replies.length;\n\n // Check memory cache\n const memoryCached = getMemoryCacheHit(discussionId, replyCount);\n if (memoryCached) return memoryCached;\n\n // Check Redis cache\n const redisCached = await getRedisCacheHit(discussionId, replyCount);\n if (redisCached) {\n setMemoryCache(discussionId, redisCached, replyCount);\n return redisCached;\n }\n\n // Build context for inference\n const authorName =\n discussion.author.profile?.displayName ?? discussion.author.username;\n const threadText = [\n `Title: ${discussion.title}`,\n `Type: ${discussion.type}`,\n `Author: ${authorName}`,\n `Original post:\\n${discussion.body}`,\n \"\",\n ...discussion.replies.map((reply, i) => {\n const name =\n reply.author.profile?.displayName ?? reply.author.username;\n return `Reply ${i + 1} by ${name}:\\n${reply.body}`;\n }),\n ].join(\"\\n\\n\");\n\n const messages = [\n {\n role: \"system\" as const,\n content:\n \"You are a helpful assistant summarizing a class discussion thread for a teacher. Be concise, specific, and grounded in the actual content. Do not fabricate information.\",\n },\n {\n role: \"user\" as const,\n content: threadText,\n },\n {\n role: \"user\" as const,\n content:\n \"Generate a structured summary of this discussion thread. Include a TL;DR, key student questions, and any unresolved issues.\",\n },\n ];\n\n const result = await inference<DiscussionSummary>(\n messages,\n discussionSummarySchema,\n {\n reason: \"discussion_summary\",\n metadata: { discussionId, classId: discussion.classId },\n },\n );\n\n // Cache result\n setMemoryCache(discussionId, result, replyCount);\n await setRedisCache(discussionId, result, replyCount);\n\n return result;\n}\n"],"names":[],"mappings":"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","debug_id":"123ae967-1b03-513e-8fd2-867781eb48f0"}