@studious-lms/server 1.6.0 → 1.8.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 (212) hide show
  1. package/dist/models/access.d.ts +21 -66
  2. package/dist/models/access.d.ts.map +1 -1
  3. package/dist/models/access.js +10 -26
  4. package/dist/models/access.js.map +1 -1
  5. package/dist/models/agenda.d.ts +2 -0
  6. package/dist/models/agenda.d.ts.map +1 -1
  7. package/dist/models/announcement.d.ts +2 -1
  8. package/dist/models/announcement.d.ts.map +1 -1
  9. package/dist/models/announcement.js +2 -3
  10. package/dist/models/announcement.js.map +1 -1
  11. package/dist/models/assignment.d.ts +7 -0
  12. package/dist/models/assignment.d.ts.map +1 -1
  13. package/dist/models/auth.d.ts +2 -4
  14. package/dist/models/auth.d.ts.map +1 -1
  15. package/dist/models/auth.js +2 -3
  16. package/dist/models/auth.js.map +1 -1
  17. package/dist/models/class.d.ts +32 -4
  18. package/dist/models/class.d.ts.map +1 -1
  19. package/dist/models/class.js +15 -2
  20. package/dist/models/class.js.map +1 -1
  21. package/dist/models/cloudStorage.d.ts +140 -0
  22. package/dist/models/cloudStorage.d.ts.map +1 -0
  23. package/dist/models/cloudStorage.js +175 -0
  24. package/dist/models/cloudStorage.js.map +1 -0
  25. package/dist/models/comment.d.ts +0 -24
  26. package/dist/models/comment.d.ts.map +1 -1
  27. package/dist/models/comment.js +2 -6
  28. package/dist/models/comment.js.map +1 -1
  29. package/dist/models/conversation.d.ts +38 -22
  30. package/dist/models/conversation.d.ts.map +1 -1
  31. package/dist/models/conversation.js +50 -2
  32. package/dist/models/conversation.js.map +1 -1
  33. package/dist/models/department.d.ts +154 -0
  34. package/dist/models/department.d.ts.map +1 -0
  35. package/dist/models/department.js +135 -0
  36. package/dist/models/department.js.map +1 -0
  37. package/dist/models/event.d.ts +7 -1
  38. package/dist/models/event.d.ts.map +1 -1
  39. package/dist/models/event.js +2 -5
  40. package/dist/models/event.js.map +1 -1
  41. package/dist/models/file.d.ts +25 -10
  42. package/dist/models/file.d.ts.map +1 -1
  43. package/dist/models/file.js +2 -5
  44. package/dist/models/file.js.map +1 -1
  45. package/dist/models/folder.d.ts +47 -0
  46. package/dist/models/folder.d.ts.map +1 -1
  47. package/dist/models/labChat.d.ts +5 -3
  48. package/dist/models/labChat.d.ts.map +1 -1
  49. package/dist/models/message.d.ts +46 -12
  50. package/dist/models/message.d.ts.map +1 -1
  51. package/dist/models/message.js +19 -10
  52. package/dist/models/message.js.map +1 -1
  53. package/dist/models/newtonChat.d.ts +2 -1
  54. package/dist/models/newtonChat.d.ts.map +1 -1
  55. package/dist/models/school.d.ts +45 -12
  56. package/dist/models/school.d.ts.map +1 -1
  57. package/dist/models/school.js +19 -2
  58. package/dist/models/school.js.map +1 -1
  59. package/dist/models/section.d.ts +1 -0
  60. package/dist/models/section.d.ts.map +1 -1
  61. package/dist/models/tag.d.ts +117 -0
  62. package/dist/models/tag.d.ts.map +1 -0
  63. package/dist/models/tag.js +113 -0
  64. package/dist/models/tag.js.map +1 -0
  65. package/dist/models/worksheet.d.ts +3 -0
  66. package/dist/models/worksheet.d.ts.map +1 -1
  67. package/dist/pipelines/aiLabChatContract.d.ts +8 -8
  68. package/dist/routers/_app.d.ts +3556 -2298
  69. package/dist/routers/_app.d.ts.map +1 -1
  70. package/dist/routers/_app.js +6 -2
  71. package/dist/routers/_app.js.map +1 -1
  72. package/dist/routers/agenda.d.ts +2 -0
  73. package/dist/routers/agenda.d.ts.map +1 -1
  74. package/dist/routers/announcement.d.ts.map +1 -1
  75. package/dist/routers/announcement.js +3 -5
  76. package/dist/routers/announcement.js.map +1 -1
  77. package/dist/routers/assignment.d.ts +18 -9
  78. package/dist/routers/assignment.d.ts.map +1 -1
  79. package/dist/routers/assignment.js +2 -3
  80. package/dist/routers/assignment.js.map +1 -1
  81. package/dist/routers/class.d.ts +87 -14
  82. package/dist/routers/class.d.ts.map +1 -1
  83. package/dist/routers/class.js +5 -2
  84. package/dist/routers/class.js.map +1 -1
  85. package/dist/routers/conversation.d.ts +20 -5
  86. package/dist/routers/conversation.d.ts.map +1 -1
  87. package/dist/routers/conversation.js +6 -3
  88. package/dist/routers/conversation.js.map +1 -1
  89. package/dist/routers/department.d.ts +293 -0
  90. package/dist/routers/department.d.ts.map +1 -0
  91. package/dist/routers/department.js +93 -0
  92. package/dist/routers/department.js.map +1 -0
  93. package/dist/routers/event.d.ts +2 -1
  94. package/dist/routers/event.d.ts.map +1 -1
  95. package/dist/routers/file.d.ts +8 -6
  96. package/dist/routers/file.d.ts.map +1 -1
  97. package/dist/routers/file.js +26 -17
  98. package/dist/routers/file.js.map +1 -1
  99. package/dist/routers/folder.d.ts +139 -186
  100. package/dist/routers/folder.d.ts.map +1 -1
  101. package/dist/routers/folder.js +82 -90
  102. package/dist/routers/folder.js.map +1 -1
  103. package/dist/routers/labChat.d.ts +11 -2
  104. package/dist/routers/labChat.d.ts.map +1 -1
  105. package/dist/routers/message.d.ts +20 -2
  106. package/dist/routers/message.d.ts.map +1 -1
  107. package/dist/routers/newtonChat.d.ts +9 -0
  108. package/dist/routers/newtonChat.d.ts.map +1 -1
  109. package/dist/routers/school.d.ts +160 -17
  110. package/dist/routers/school.d.ts.map +1 -1
  111. package/dist/routers/school.js +46 -3
  112. package/dist/routers/school.js.map +1 -1
  113. package/dist/routers/tag.d.ts +119 -0
  114. package/dist/routers/tag.d.ts.map +1 -0
  115. package/dist/routers/tag.js +52 -0
  116. package/dist/routers/tag.js.map +1 -0
  117. package/dist/routers/worksheet.d.ts +1 -0
  118. package/dist/routers/worksheet.d.ts.map +1 -1
  119. package/dist/seedDatabase.d.ts +0 -1
  120. package/dist/seedDatabase.d.ts.map +1 -1
  121. package/dist/services/agenda.d.ts +2 -0
  122. package/dist/services/agenda.d.ts.map +1 -1
  123. package/dist/services/assignment.d.ts +18 -9
  124. package/dist/services/assignment.d.ts.map +1 -1
  125. package/dist/services/assignment.js +4 -4
  126. package/dist/services/assignment.js.map +1 -1
  127. package/dist/services/class.d.ts +87 -14
  128. package/dist/services/class.d.ts.map +1 -1
  129. package/dist/services/class.js +91 -4
  130. package/dist/services/class.js.map +1 -1
  131. package/dist/services/conversation.d.ts +21 -5
  132. package/dist/services/conversation.d.ts.map +1 -1
  133. package/dist/services/conversation.js +22 -3
  134. package/dist/services/conversation.js.map +1 -1
  135. package/dist/services/department.d.ts +200 -0
  136. package/dist/services/department.d.ts.map +1 -0
  137. package/dist/services/department.js +368 -0
  138. package/dist/services/department.js.map +1 -0
  139. package/dist/services/event.d.ts +2 -1
  140. package/dist/services/event.d.ts.map +1 -1
  141. package/dist/services/file.d.ts +85 -0
  142. package/dist/services/file.d.ts.map +1 -1
  143. package/dist/services/file.js +92 -2
  144. package/dist/services/file.js.map +1 -1
  145. package/dist/services/folder.d.ts +125 -149
  146. package/dist/services/folder.d.ts.map +1 -1
  147. package/dist/services/folder.js +258 -199
  148. package/dist/services/folder.js.map +1 -1
  149. package/dist/services/labChat.d.ts +11 -2
  150. package/dist/services/labChat.d.ts.map +1 -1
  151. package/dist/services/labChat.js +8 -7
  152. package/dist/services/labChat.js.map +1 -1
  153. package/dist/services/message.d.ts +20 -2
  154. package/dist/services/message.d.ts.map +1 -1
  155. package/dist/services/message.js +7 -23
  156. package/dist/services/message.js.map +1 -1
  157. package/dist/services/newtonChat.d.ts +9 -0
  158. package/dist/services/newtonChat.d.ts.map +1 -1
  159. package/dist/services/newtonChat.js +7 -6
  160. package/dist/services/newtonChat.js.map +1 -1
  161. package/dist/services/school.d.ts +142 -15
  162. package/dist/services/school.d.ts.map +1 -1
  163. package/dist/services/school.js +308 -54
  164. package/dist/services/school.js.map +1 -1
  165. package/dist/services/tag.d.ts +71 -0
  166. package/dist/services/tag.d.ts.map +1 -0
  167. package/dist/services/tag.js +178 -0
  168. package/dist/services/tag.js.map +1 -0
  169. package/dist/services/worksheet.d.ts +1 -0
  170. package/dist/services/worksheet.d.ts.map +1 -1
  171. package/dist/utils/aiUser.d.ts.map +1 -1
  172. package/dist/utils/aiUser.js +2 -3
  173. package/dist/utils/aiUser.js.map +1 -1
  174. package/package.json +1 -1
  175. package/prisma/migrations/20260509220000_institution_overhaul/migration.sql +184 -0
  176. package/prisma/schema.prisma +119 -35
  177. package/src/models/access.ts +8 -24
  178. package/src/models/announcement.ts +0 -1
  179. package/src/models/auth.ts +0 -1
  180. package/src/models/class.ts +13 -0
  181. package/src/models/cloudStorage.ts +194 -0
  182. package/src/models/comment.ts +0 -4
  183. package/src/models/conversation.ts +54 -0
  184. package/src/models/department.ts +159 -0
  185. package/src/models/event.ts +0 -3
  186. package/src/models/file.ts +0 -3
  187. package/src/models/message.ts +19 -5
  188. package/src/models/school.ts +26 -0
  189. package/src/models/tag.ts +140 -0
  190. package/src/routers/_app.ts +4 -0
  191. package/src/routers/announcement.ts +1 -3
  192. package/src/routers/assignment.ts +0 -1
  193. package/src/routers/class.ts +3 -0
  194. package/src/routers/conversation.ts +7 -0
  195. package/src/routers/department.ts +174 -0
  196. package/src/routers/file.ts +29 -26
  197. package/src/routers/folder.ts +100 -121
  198. package/src/routers/school.ts +83 -0
  199. package/src/routers/tag.ts +78 -0
  200. package/src/services/assignment.ts +2 -3
  201. package/src/services/class.ts +108 -3
  202. package/src/services/conversation.ts +30 -0
  203. package/src/services/department.ts +478 -0
  204. package/src/services/file.ts +100 -0
  205. package/src/services/folder.ts +313 -240
  206. package/src/services/labChat.ts +7 -6
  207. package/src/services/message.ts +5 -21
  208. package/src/services/newtonChat.ts +5 -5
  209. package/src/services/school.ts +369 -57
  210. package/src/services/tag.ts +229 -0
  211. package/src/utils/aiUser.ts +0 -1
  212. package/tests/integration/routers/conversation.test.ts +121 -2
@@ -2,7 +2,7 @@
2
2
  * Comment model – comments, replies, and reactions.
3
3
  */
4
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]="4e10262a-c8cd-5388-9b97-3cf8d34902b6")}catch(e){}}();
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]="8dbc1c18-53a6-535e-8af0-25c781796a36")}catch(e){}}();
6
6
  import { prisma } from "../lib/prisma.js";
7
7
  export const commentSelect = {
8
8
  id: true,
@@ -51,10 +51,6 @@ const commentClassAuthSelect = {
51
51
  students: { select: { id: true } },
52
52
  school: {
53
53
  select: {
54
- users: {
55
- where: { role: "ADMIN" },
56
- select: { id: true },
57
- },
58
54
  memberships: {
59
55
  where: {
60
56
  role: "ADMIN",
@@ -265,4 +261,4 @@ export function getReactionCountsByCommentId(commentId) {
265
261
  });
266
262
  }
267
263
  //# sourceMappingURL=comment.js.map
268
- //# debugId=4e10262a-c8cd-5388-9b97-3cf8d34902b6
264
+ //# debugId=8dbc1c18-53a6-535e-8af0-25c781796a36
@@ -1 +1 @@
1
- {"version":3,"file":"comment.js","sources":["models/comment.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Comment model – comments, replies, and reactions.\n */\nimport { prisma } from \"../lib/prisma.js\";\nimport type { ReactionType } from \"@prisma/client\";\n\nexport const commentSelect = {\n id: true,\n content: true,\n announcementId: true,\n assignmentId: true,\n submissionId: true,\n parentCommentId: true,\n createdAt: true,\n modifiedAt: true,\n author: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n },\n },\n reactions: {\n select: {\n type: true,\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n },\n },\n },\n },\n} as const;\n\nconst commentClassAuthSelect = {\n id: true,\n teachers: { select: { id: true } },\n students: { select: { id: true } },\n school: {\n select: {\n users: {\n where: { role: \"ADMIN\" as const },\n select: { id: true },\n },\n memberships: {\n where: {\n role: \"ADMIN\" as const,\n status: \"ACTIVE\" as const,\n },\n select: { userId: true },\n },\n },\n },\n} as const;\n\n/** @returns Comment by ID with author and reactions. */\nexport function findCommentById(id: string) {\n return prisma.comment.findUnique({\n where: { id },\n select: commentSelect,\n });\n}\n\n/** @returns Replies to a comment. */\nexport function findRepliesByCommentId(commentId: string) {\n return prisma.comment.findMany({\n where: { parentCommentId: commentId },\n include: {\n author: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n },\n },\n },\n });\n}\n\n/** Create a comment (reply). */\nexport function createComment(data: {\n parentCommentId: string;\n content: string;\n authorId: string;\n announcementId?: string | null;\n assignmentId?: string | null;\n submissionId?: string | null;\n studentQuestionProgressId?: string | null;\n}) {\n return prisma.comment.create({\n data,\n });\n}\n\n/** @returns User's reaction on a comment. */\nexport function findReactionByUserAndComment(userId: string, commentId: string) {\n return prisma.reaction.findUnique({\n where: {\n userId_commentId: { userId, commentId },\n },\n });\n}\n\n/** Add or update reaction on a comment. */\nexport function upsertReaction(data: {\n userId: string;\n commentId: string;\n type: string;\n}) {\n return prisma.reaction.upsert({\n where: {\n userId_commentId: {\n userId: data.userId,\n commentId: data.commentId,\n },\n },\n update: { type: data.type as ReactionType },\n create: { ...data, type: data.type as ReactionType },\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n },\n },\n },\n });\n}\n\n/** Delete a reaction. */\nexport function deleteReactionById(id: string) {\n return prisma.reaction.delete({\n where: { id },\n });\n}\n\n/** @returns Comment with announcement classId. */\nexport function findCommentWithAnnouncement(commentId: string) {\n return prisma.comment.findUnique({\n where: { id: commentId },\n include: {\n announcement: { select: { classId: true } },\n },\n });\n}\n\n/** @returns Comment with the owning class context for authorization. */\nexport function findCommentWithContext(commentId: string) {\n return prisma.comment.findUnique({\n where: { id: commentId },\n include: {\n announcement: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n submission: {\n select: {\n studentId: true,\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n },\n },\n studentQuestionProgress: {\n select: {\n studentId: true,\n studentWorksheetResponse: {\n select: {\n submission: {\n select: {\n studentId: true,\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n },\n },\n },\n },\n },\n },\n parentComment: {\n include: {\n announcement: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n submission: {\n select: {\n studentId: true,\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n },\n },\n studentQuestionProgress: {\n select: {\n studentId: true,\n studentWorksheetResponse: {\n select: {\n submission: {\n select: {\n studentId: true,\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n });\n}\n\n/** @returns Reaction counts by type for a comment. */\nexport function getReactionCountsByCommentId(commentId: string) {\n return prisma.reaction.groupBy({\n by: [\"type\"],\n where: { commentId },\n _count: { type: true },\n });\n}\n"],"names":[],"mappings":"AAAA;;GAEG;;;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG1C,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,EAAE,EAAE,IAAI;IACR,OAAO,EAAE,IAAI;IACb,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,IAAI;IAClB,eAAe,EAAE,IAAI;IACrB,SAAS,EAAE,IAAI;IACf,UAAU,EAAE,IAAI;IAChB,MAAM,EAAE;QACN,MAAM,EAAE;YACN,EAAE,EAAE,IAAI;YACR,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE;gBACP,MAAM,EAAE;oBACN,WAAW,EAAE,IAAI;oBACjB,cAAc,EAAE,IAAI;oBACpB,uBAAuB,EAAE,IAAI;iBAC9B;aACF;SACF;KACF;IACD,SAAS,EAAE;QACT,MAAM,EAAE;YACN,IAAI,EAAE,IAAI;YACV,IAAI,EAAE;gBACJ,MAAM,EAAE;oBACN,EAAE,EAAE,IAAI;oBACR,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE;wBACP,MAAM,EAAE;4BACN,WAAW,EAAE,IAAI;4BACjB,cAAc,EAAE,IAAI;4BACpB,uBAAuB,EAAE,IAAI;yBAC9B;qBACF;iBACF;aACF;SACF;KACF;CACO,CAAC;AAEX,MAAM,sBAAsB,GAAG;IAC7B,EAAE,EAAE,IAAI;IACR,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;IAClC,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;IAClC,MAAM,EAAE;QACN,MAAM,EAAE;YACN,KAAK,EAAE;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,OAAgB,EAAE;gBACjC,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE;aACrB;YACD,WAAW,EAAE;gBACX,KAAK,EAAE;oBACL,IAAI,EAAE,OAAgB;oBACtB,MAAM,EAAE,QAAiB;iBAC1B;gBACD,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;aACzB;SACF;KACF;CACO,CAAC;AAEX,wDAAwD;AACxD,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;QAC/B,KAAK,EAAE,EAAE,EAAE,EAAE;QACb,MAAM,EAAE,aAAa;KACtB,CAAC,CAAC;AACL,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC7B,KAAK,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE;QACrC,OAAO,EAAE;YACP,MAAM,EAAE;gBACN,MAAM,EAAE;oBACN,EAAE,EAAE,IAAI;oBACR,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE;wBACP,MAAM,EAAE;4BACN,WAAW,EAAE,IAAI;4BACjB,cAAc,EAAE,IAAI;4BACpB,uBAAuB,EAAE,IAAI;yBAC9B;qBACF;iBACF;aACF;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,aAAa,CAAC,IAQ7B;IACC,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;QAC3B,IAAI;KACL,CAAC,CAAC;AACL,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,4BAA4B,CAAC,MAAc,EAAE,SAAiB;IAC5E,OAAO,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;QAChC,KAAK,EAAE;YACL,gBAAgB,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;SACxC;KACF,CAAC,CAAC;AACL,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,cAAc,CAAC,IAI9B;IACC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC5B,KAAK,EAAE;YACL,gBAAgB,EAAE;gBAChB,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,SAAS,EAAE,IAAI,CAAC,SAAS;aAC1B;SACF;QACD,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAoB,EAAE;QAC3C,MAAM,EAAE,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAoB,EAAE;QACpD,OAAO,EAAE;YACP,IAAI,EAAE;gBACJ,MAAM,EAAE;oBACN,EAAE,EAAE,IAAI;oBACR,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE;wBACP,MAAM,EAAE;4BACN,WAAW,EAAE,IAAI;4BACjB,cAAc,EAAE,IAAI;4BACpB,uBAAuB,EAAE,IAAI;yBAC9B;qBACF;iBACF;aACF;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,yBAAyB;AACzB,MAAM,UAAU,kBAAkB,CAAC,EAAU;IAC3C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAC5B,KAAK,EAAE,EAAE,EAAE,EAAE;KACd,CAAC,CAAC;AACL,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,2BAA2B,CAAC,SAAiB;IAC3D,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;QAC/B,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;QACxB,OAAO,EAAE;YACP,YAAY,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;SAC5C;KACF,CAAC,CAAC;AACL,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,sBAAsB,CAAC,SAAiB;IACtD,OAAO,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC;QAC/B,KAAK,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;QACxB,OAAO,EAAE;YACP,YAAY,EAAE;gBACZ,MAAM,EAAE;oBACN,KAAK,EAAE;wBACL,MAAM,EAAE,sBAAsB;qBAC/B;iBACF;aACF;YACD,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,KAAK,EAAE;wBACL,MAAM,EAAE,sBAAsB;qBAC/B;iBACF;aACF;YACD,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,SAAS,EAAE,IAAI;oBACf,UAAU,EAAE;wBACV,MAAM,EAAE;4BACN,KAAK,EAAE;gCACL,MAAM,EAAE,sBAAsB;6BAC/B;yBACF;qBACF;iBACF;aACF;YACD,uBAAuB,EAAE;gBACvB,MAAM,EAAE;oBACN,SAAS,EAAE,IAAI;oBACf,wBAAwB,EAAE;wBACxB,MAAM,EAAE;4BACN,UAAU,EAAE;gCACV,MAAM,EAAE;oCACN,SAAS,EAAE,IAAI;oCACf,UAAU,EAAE;wCACV,MAAM,EAAE;4CACN,KAAK,EAAE;gDACL,MAAM,EAAE,sBAAsB;6CAC/B;yCACF;qCACF;iCACF;6BACF;yBACF;qBACF;iBACF;aACF;YACD,aAAa,EAAE;gBACb,OAAO,EAAE;oBACP,YAAY,EAAE;wBACZ,MAAM,EAAE;4BACN,KAAK,EAAE;gCACL,MAAM,EAAE,sBAAsB;6BAC/B;yBACF;qBACF;oBACD,UAAU,EAAE;wBACV,MAAM,EAAE;4BACN,KAAK,EAAE;gCACL,MAAM,EAAE,sBAAsB;6BAC/B;yBACF;qBACF;oBACD,UAAU,EAAE;wBACV,MAAM,EAAE;4BACN,SAAS,EAAE,IAAI;4BACf,UAAU,EAAE;gCACV,MAAM,EAAE;oCACN,KAAK,EAAE;wCACL,MAAM,EAAE,sBAAsB;qCAC/B;iCACF;6BACF;yBACF;qBACF;oBACD,uBAAuB,EAAE;wBACvB,MAAM,EAAE;4BACN,SAAS,EAAE,IAAI;4BACf,wBAAwB,EAAE;gCACxB,MAAM,EAAE;oCACN,UAAU,EAAE;wCACV,MAAM,EAAE;4CACN,SAAS,EAAE,IAAI;4CACf,UAAU,EAAE;gDACV,MAAM,EAAE;oDACN,KAAK,EAAE;wDACL,MAAM,EAAE,sBAAsB;qDAC/B;iDACF;6CACF;yCACF;qCACF;iCACF;6BACF;yBACF;qBACF;iBACF;aACF;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,4BAA4B,CAAC,SAAiB;IAC5D,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QAC7B,EAAE,EAAE,CAAC,MAAM,CAAC;QACZ,KAAK,EAAE,EAAE,SAAS,EAAE;QACpB,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;KACvB,CAAC,CAAC;AACL,CAAC","debug_id":"4e10262a-c8cd-5388-9b97-3cf8d34902b6"}
1
+ {"version":3,"file":"comment.js","sources":["models/comment.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Comment model – comments, replies, and reactions.\n */\nimport { prisma } from \"../lib/prisma.js\";\nimport type { ReactionType } from \"@prisma/client\";\n\nexport const commentSelect = {\n id: true,\n content: true,\n announcementId: true,\n assignmentId: true,\n submissionId: true,\n parentCommentId: true,\n createdAt: true,\n modifiedAt: true,\n author: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n },\n },\n reactions: {\n select: {\n type: true,\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n },\n },\n },\n },\n} as const;\n\nconst commentClassAuthSelect = {\n id: true,\n teachers: { select: { id: true } },\n students: { select: { id: true } },\n school: {\n select: {\n memberships: {\n where: {\n role: \"ADMIN\" as const,\n status: \"ACTIVE\" as const,\n },\n select: { userId: true },\n },\n },\n },\n} as const;\n\n/** @returns Comment by ID with author and reactions. */\nexport function findCommentById(id: string) {\n return prisma.comment.findUnique({\n where: { id },\n select: commentSelect,\n });\n}\n\n/** @returns Replies to a comment. */\nexport function findRepliesByCommentId(commentId: string) {\n return prisma.comment.findMany({\n where: { parentCommentId: commentId },\n include: {\n author: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n },\n },\n },\n });\n}\n\n/** Create a comment (reply). */\nexport function createComment(data: {\n parentCommentId: string;\n content: string;\n authorId: string;\n announcementId?: string | null;\n assignmentId?: string | null;\n submissionId?: string | null;\n studentQuestionProgressId?: string | null;\n}) {\n return prisma.comment.create({\n data,\n });\n}\n\n/** @returns User's reaction on a comment. */\nexport function findReactionByUserAndComment(userId: string, commentId: string) {\n return prisma.reaction.findUnique({\n where: {\n userId_commentId: { userId, commentId },\n },\n });\n}\n\n/** Add or update reaction on a comment. */\nexport function upsertReaction(data: {\n userId: string;\n commentId: string;\n type: string;\n}) {\n return prisma.reaction.upsert({\n where: {\n userId_commentId: {\n userId: data.userId,\n commentId: data.commentId,\n },\n },\n update: { type: data.type as ReactionType },\n create: { ...data, type: data.type as ReactionType },\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n },\n },\n },\n });\n}\n\n/** Delete a reaction. */\nexport function deleteReactionById(id: string) {\n return prisma.reaction.delete({\n where: { id },\n });\n}\n\n/** @returns Comment with announcement classId. */\nexport function findCommentWithAnnouncement(commentId: string) {\n return prisma.comment.findUnique({\n where: { id: commentId },\n include: {\n announcement: { select: { classId: true } },\n },\n });\n}\n\n/** @returns Comment with the owning class context for authorization. */\nexport function findCommentWithContext(commentId: string) {\n return prisma.comment.findUnique({\n where: { id: commentId },\n include: {\n announcement: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n submission: {\n select: {\n studentId: true,\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n },\n },\n studentQuestionProgress: {\n select: {\n studentId: true,\n studentWorksheetResponse: {\n select: {\n submission: {\n select: {\n studentId: true,\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n },\n },\n },\n },\n },\n },\n parentComment: {\n include: {\n announcement: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n submission: {\n select: {\n studentId: true,\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n },\n },\n studentQuestionProgress: {\n select: {\n studentId: true,\n studentWorksheetResponse: {\n select: {\n submission: {\n select: {\n studentId: true,\n assignment: {\n select: {\n class: {\n select: commentClassAuthSelect,\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n });\n}\n\n/** @returns Reaction counts by type for a comment. */\nexport function getReactionCountsByCommentId(commentId: string) {\n return prisma.reaction.groupBy({\n by: [\"type\"],\n where: { commentId },\n _count: { type: true },\n });\n}\n"],"names":[],"mappings":"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","debug_id":"8dbc1c18-53a6-535e-8af0-25c781796a36"}
@@ -4,42 +4,42 @@ export declare function findConversationsByUserId(userId: string): import(".pris
4
4
  id: string;
5
5
  title: string;
6
6
  } | null;
7
- messages: ({
8
- sender: {
7
+ members: ({
8
+ user: {
9
9
  id: string;
10
10
  username: string;
11
11
  profile: {
12
12
  displayName: string | null;
13
+ profilePicture: string | null;
13
14
  } | null;
14
15
  };
15
16
  } & {
16
- status: import(".prisma/client").$Enums.JobStatus | null;
17
- meta: import("@prisma/client/runtime/library.js").JsonValue | null;
18
17
  id: string;
19
- createdAt: Date;
18
+ userId: string;
19
+ role: import(".prisma/client").$Enums.ConversationRole;
20
20
  conversationId: string;
21
- content: string;
22
- senderId: string;
23
- runJobId: string | null;
21
+ joinedAt: Date;
22
+ hiddenAt: Date | null;
23
+ lastViewedAt: Date | null;
24
+ lastViewedMentionAt: Date | null;
24
25
  })[];
25
- members: ({
26
- user: {
26
+ messages: ({
27
+ sender: {
27
28
  id: string;
28
29
  username: string;
29
30
  profile: {
30
31
  displayName: string | null;
31
- profilePicture: string | null;
32
32
  } | null;
33
33
  };
34
34
  } & {
35
+ status: import(".prisma/client").$Enums.JobStatus | null;
36
+ meta: import("@prisma/client/runtime/library.js").JsonValue | null;
35
37
  id: string;
36
- role: import(".prisma/client").$Enums.ConversationRole;
37
- userId: string;
38
+ createdAt: Date;
38
39
  conversationId: string;
39
- joinedAt: Date;
40
- hiddenAt: Date | null;
41
- lastViewedAt: Date | null;
42
- lastViewedMentionAt: Date | null;
40
+ content: string;
41
+ senderId: string;
42
+ runJobId: string | null;
43
43
  })[];
44
44
  } & {
45
45
  type: import(".prisma/client").$Enums.ConversationType;
@@ -64,6 +64,22 @@ export declare function findUserByUsername(username: string): import(".prisma/cl
64
64
  };
65
65
  };
66
66
  }>;
67
+ /**
68
+ * Search users who share at least one active school membership with the
69
+ * requester and match the query by username or profile display name.
70
+ *
71
+ * The requester is always excluded so the result set can be used directly as
72
+ * conversation member suggestions.
73
+ */
74
+ export declare function searchInstitutionConversationMembers(userId: string, query: string, limit: number): Promise<{
75
+ id: string;
76
+ username: string;
77
+ profile: {
78
+ displayName: string | null;
79
+ profilePicture: string | null;
80
+ profilePictureThumbnail: string | null;
81
+ } | null;
82
+ }[]>;
67
83
  /** @returns User's DM conversations. */
68
84
  export declare function findDmConversationsByUserId(userId: string): import(".prisma/client").Prisma.PrismaPromise<({
69
85
  members: {
@@ -102,8 +118,8 @@ export declare function createConversation(data: {
102
118
  };
103
119
  } & {
104
120
  id: string;
105
- role: import(".prisma/client").$Enums.ConversationRole;
106
121
  userId: string;
122
+ role: import(".prisma/client").$Enums.ConversationRole;
107
123
  conversationId: string;
108
124
  joinedAt: Date;
109
125
  hiddenAt: Date | null;
@@ -137,8 +153,8 @@ export declare function findConversationByIdAndMember(conversationId: string, us
137
153
  };
138
154
  } & {
139
155
  id: string;
140
- role: import(".prisma/client").$Enums.ConversationRole;
141
156
  userId: string;
157
+ role: import(".prisma/client").$Enums.ConversationRole;
142
158
  conversationId: string;
143
159
  joinedAt: Date;
144
160
  hiddenAt: Date | null;
@@ -166,8 +182,8 @@ export declare function createConversationMember(data: {
166
182
  role: string;
167
183
  }): import(".prisma/client").Prisma.Prisma__ConversationMemberClient<{
168
184
  id: string;
169
- role: import(".prisma/client").$Enums.ConversationRole;
170
185
  userId: string;
186
+ role: import(".prisma/client").$Enums.ConversationRole;
171
187
  conversationId: string;
172
188
  joinedAt: Date;
173
189
  hiddenAt: Date | null;
@@ -183,8 +199,8 @@ export declare function createConversationMember(data: {
183
199
  /** Hide a conversation for a single member until new activity occurs. */
184
200
  export declare function hideConversationMember(userId: string, conversationId: string): import(".prisma/client").Prisma.Prisma__ConversationMemberClient<{
185
201
  id: string;
186
- role: import(".prisma/client").$Enums.ConversationRole;
187
202
  userId: string;
203
+ role: import(".prisma/client").$Enums.ConversationRole;
188
204
  conversationId: string;
189
205
  joinedAt: Date;
190
206
  hiddenAt: Date | null;
@@ -200,8 +216,8 @@ export declare function hideConversationMember(userId: string, conversationId: s
200
216
  /** Remove a member from a conversation. */
201
217
  export declare function deleteConversationMember(userId: string, conversationId: string): import(".prisma/client").Prisma.Prisma__ConversationMemberClient<{
202
218
  id: string;
203
- role: import(".prisma/client").$Enums.ConversationRole;
204
219
  userId: string;
220
+ role: import(".prisma/client").$Enums.ConversationRole;
205
221
  conversationId: string;
206
222
  joinedAt: Date;
207
223
  hiddenAt: Date | null;
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.d.ts","sourceRoot":"/","sources":["models/conversation.ts"],"names":[],"mappings":"AAmCA,mEAAmE;AACnE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAQvD;AAED,sDAAsD;AACtD,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,IAAI,yDASb;AAED,sDAAsD;AACtD,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,IAAI,yDAYb;AAED,qDAAqD;AACrD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;GAKlD;AAED,wCAAwC;AACxC,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;MAUzD;AAED,0CAA0C;AAC1C,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE;;;KAW9D;AAED,sDAAsD;AACtD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BA;AAED,iDAAiD;AACjD,wBAAgB,6BAA6B,CAC3C,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuBf;AAED,sCAAsC;AACtC,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;;;;;;;;;;;;;;;GAQA;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;GAS5E;AAED,2CAA2C;AAC3C,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;GAM9E"}
1
+ {"version":3,"file":"conversation.d.ts","sourceRoot":"/","sources":["models/conversation.ts"],"names":[],"mappings":"AAmCA,mEAAmE;AACnE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAQvD;AAED,sDAAsD;AACtD,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,IAAI,yDASb;AAED,sDAAsD;AACtD,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,IAAI,yDAYb;AAED,qDAAqD;AACrD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;GAKlD;AAED;;;;;;GAMG;AACH,wBAAsB,oCAAoC,CACxD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM;;;;;;;;KA0Cd;AAED,wCAAwC;AACxC,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;MAUzD;AAED,0CAA0C;AAC1C,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE;;;KAW9D;AAED,sDAAsD;AACtD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BA;AAED,iDAAiD;AACjD,wBAAgB,6BAA6B,CAC3C,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuBf;AAED,sCAAsC;AACtC,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;;;;;;;;;;;;;;;GAQA;AAED,yEAAyE;AACzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;GAS5E;AAED,2CAA2C;AAC3C,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;GAM9E"}
@@ -2,7 +2,7 @@
2
2
  * Conversation model – DM/group conversations, members, unread counts.
3
3
  */
4
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]="7ea2e02b-0f12-5407-9926-5fab4c199704")}catch(e){}}();
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]="14c80725-5a2b-5e37-aa01-49cb94535659")}catch(e){}}();
6
6
  import { prisma } from "../lib/prisma.js";
7
7
  const conversationListInclude = {
8
8
  labChat: { select: { id: true, title: true } },
@@ -73,6 +73,54 @@ export function findUserByUsername(username) {
73
73
  select: { id: true, username: true },
74
74
  });
75
75
  }
76
+ /**
77
+ * Search users who share at least one active school membership with the
78
+ * requester and match the query by username or profile display name.
79
+ *
80
+ * The requester is always excluded so the result set can be used directly as
81
+ * conversation member suggestions.
82
+ */
83
+ export async function searchInstitutionConversationMembers(userId, query, limit) {
84
+ const memberships = await prisma.schoolMembership.findMany({
85
+ where: { userId, status: "ACTIVE" },
86
+ select: { schoolId: true },
87
+ });
88
+ const schoolIds = memberships.map((membership) => membership.schoolId);
89
+ if (schoolIds.length === 0)
90
+ return [];
91
+ return prisma.user.findMany({
92
+ where: {
93
+ id: { not: userId },
94
+ schoolMemberships: {
95
+ some: {
96
+ schoolId: { in: schoolIds },
97
+ status: "ACTIVE",
98
+ },
99
+ },
100
+ OR: [
101
+ { username: { contains: query, mode: "insensitive" } },
102
+ {
103
+ profile: {
104
+ is: { displayName: { contains: query, mode: "insensitive" } },
105
+ },
106
+ },
107
+ ],
108
+ },
109
+ select: {
110
+ id: true,
111
+ username: true,
112
+ profile: {
113
+ select: {
114
+ displayName: true,
115
+ profilePicture: true,
116
+ profilePictureThumbnail: true,
117
+ },
118
+ },
119
+ },
120
+ orderBy: { username: "asc" },
121
+ take: limit,
122
+ });
123
+ }
76
124
  /** @returns User's DM conversations. */
77
125
  export function findDmConversationsByUserId(userId) {
78
126
  return prisma.conversation.findMany({
@@ -183,4 +231,4 @@ export function deleteConversationMember(userId, conversationId) {
183
231
  });
184
232
  }
185
233
  //# sourceMappingURL=conversation.js.map
186
- //# debugId=7ea2e02b-0f12-5407-9926-5fab4c199704
234
+ //# debugId=14c80725-5a2b-5e37-aa01-49cb94535659
@@ -1 +1 @@
1
- {"version":3,"file":"conversation.js","sources":["models/conversation.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Conversation model – DM/group conversations, members, unread counts.\n */\nimport { prisma } from \"../lib/prisma.js\";\n\nconst conversationListInclude = {\n labChat: { select: { id: true, title: true } },\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: { displayName: true, profilePicture: true },\n },\n },\n },\n },\n },\n messages: {\n orderBy: { createdAt: \"desc\" as const },\n take: 1,\n include: {\n sender: {\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n },\n },\n },\n },\n};\n\n/** @returns User's conversations with members and last message. */\nexport function findConversationsByUserId(userId: string) {\n return prisma.conversation.findMany({\n where: {\n members: { some: { userId } },\n },\n include: conversationListInclude,\n orderBy: { updatedAt: \"desc\" },\n });\n}\n\n/** Count unread messages in conversation for user. */\nexport function countUnreadMessages(\n conversationId: string,\n userId: string,\n after?: Date\n) {\n return prisma.message.count({\n where: {\n conversationId,\n senderId: { not: userId },\n ...(after && { createdAt: { gt: after } }),\n },\n });\n}\n\n/** Count unread mentions for user in conversation. */\nexport function countUnreadMentions(\n conversationId: string,\n userId: string,\n after?: Date\n) {\n return prisma.mention.count({\n where: {\n userId,\n message: {\n conversationId,\n senderId: { not: userId },\n ...(after && { createdAt: { gt: after } }),\n },\n },\n });\n}\n\n/** @returns User by username (id, username only). */\nexport function findUserByUsername(username: string) {\n return prisma.user.findFirst({\n where: { username },\n select: { id: true, username: true },\n });\n}\n\n/** @returns User's DM conversations. */\nexport function findDmConversationsByUserId(userId: string) {\n return prisma.conversation.findMany({\n where: {\n type: \"DM\",\n members: { some: { userId } },\n },\n include: {\n members: { select: { userId: true } },\n },\n });\n}\n\n/** @returns Users by IDs or usernames. */\nexport function findUsersByIdsOrUsernames(identifiers: string[]) {\n if (identifiers.length === 0) return Promise.resolve([]);\n return prisma.user.findMany({\n where: {\n OR: [\n { id: { in: identifiers } },\n { username: { in: identifiers } },\n ],\n },\n select: { id: true, username: true },\n });\n}\n\n/** Create a DM or group conversation with members. */\nexport function createConversation(data: {\n type: \"DM\" | \"GROUP\";\n name?: string;\n members: { userId: string; role: string }[];\n}) {\n return prisma.conversation.create({\n data: {\n type: data.type,\n name: data.name,\n members: {\n create: data.members.map((m) => ({\n userId: m.userId,\n role: m.role as \"ADMIN\" | \"MEMBER\",\n })),\n },\n },\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: { displayName: true, profilePicture: true },\n },\n },\n },\n },\n },\n },\n });\n}\n\n/** @returns Conversation if user is a member. */\nexport function findConversationByIdAndMember(\n conversationId: string,\n userId: string\n) {\n return prisma.conversation.findFirst({\n where: {\n id: conversationId,\n members: { some: { userId } },\n },\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: { displayName: true, profilePicture: true },\n },\n },\n },\n },\n },\n },\n });\n}\n\n/** Add a member to a conversation. */\nexport function createConversationMember(data: {\n userId: string;\n conversationId: string;\n role: string;\n}) {\n return prisma.conversationMember.create({\n data: {\n userId: data.userId,\n conversationId: data.conversationId,\n role: data.role as \"ADMIN\" | \"MEMBER\",\n },\n });\n}\n\n/** Hide a conversation for a single member until new activity occurs. */\nexport function hideConversationMember(userId: string, conversationId: string) {\n return prisma.conversationMember.update({\n where: {\n userId_conversationId: { userId, conversationId },\n },\n data: {\n hiddenAt: new Date(),\n },\n });\n}\n\n/** Remove a member from a conversation. */\nexport function deleteConversationMember(userId: string, conversationId: string) {\n return prisma.conversationMember.delete({\n where: {\n userId_conversationId: { userId, conversationId },\n },\n });\n}\n"],"names":[],"mappings":"AAAA;;GAEG;;;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,uBAAuB,GAAG;IAC9B,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAC9C,OAAO,EAAE;QACP,OAAO,EAAE;YACP,IAAI,EAAE;gBACJ,MAAM,EAAE;oBACN,EAAE,EAAE,IAAI;oBACR,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE;wBACP,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE;qBACpD;iBACF;aACF;SACF;KACF;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,EAAE,SAAS,EAAE,MAAe,EAAE;QACvC,IAAI,EAAE,CAAC;QACP,OAAO,EAAE;YACP,MAAM,EAAE;gBACN,MAAM,EAAE;oBACN,EAAE,EAAE,IAAI;oBACR,QAAQ,EAAE,IAAI;oBACd,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;iBAC3C;aACF;SACF;KACF;CACF,CAAC;AAEF,mEAAmE;AACnE,MAAM,UAAU,yBAAyB,CAAC,MAAc;IACtD,OAAO,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;QAClC,KAAK,EAAE;YACL,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE;SAC9B;QACD,OAAO,EAAE,uBAAuB;QAChC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,mBAAmB,CACjC,cAAsB,EACtB,MAAc,EACd,KAAY;IAEZ,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QAC1B,KAAK,EAAE;YACL,cAAc;YACd,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;YACzB,GAAG,CAAC,KAAK,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;SAC3C;KACF,CAAC,CAAC;AACL,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,mBAAmB,CACjC,cAAsB,EACtB,MAAc,EACd,KAAY;IAEZ,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QAC1B,KAAK,EAAE;YACL,MAAM;YACN,OAAO,EAAE;gBACP,cAAc;gBACd,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;gBACzB,GAAG,CAAC,KAAK,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC;aAC3C;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3B,KAAK,EAAE,EAAE,QAAQ,EAAE;QACnB,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KACrC,CAAC,CAAC;AACL,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,2BAA2B,CAAC,MAAc;IACxD,OAAO,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;QAClC,KAAK,EAAE;YACL,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE;SAC9B;QACD,OAAO,EAAE;YACP,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;SACtC;KACF,CAAC,CAAC;AACL,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,yBAAyB,CAAC,WAAqB;IAC7D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACzD,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC1B,KAAK,EAAE;YACL,EAAE,EAAE;gBACF,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE;gBAC3B,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE;aAClC;SACF;QACD,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KACrC,CAAC,CAAC;AACL,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,kBAAkB,CAAC,IAIlC;IACC,OAAO,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;QAChC,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE;gBACP,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC/B,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,IAAI,EAAE,CAAC,CAAC,IAA0B;iBACnC,CAAC,CAAC;aACJ;SACF;QACD,OAAO,EAAE;YACP,OAAO,EAAE;gBACP,OAAO,EAAE;oBACP,IAAI,EAAE;wBACJ,MAAM,EAAE;4BACN,EAAE,EAAE,IAAI;4BACR,QAAQ,EAAE,IAAI;4BACd,OAAO,EAAE;gCACP,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE;6BACpD;yBACF;qBACF;iBACF;aACF;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,6BAA6B,CAC3C,cAAsB,EACtB,MAAc;IAEd,OAAO,MAAM,CAAC,YAAY,CAAC,SAAS,CAAC;QACnC,KAAK,EAAE;YACL,EAAE,EAAE,cAAc;YAClB,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE;SAC9B;QACD,OAAO,EAAE;YACP,OAAO,EAAE;gBACP,OAAO,EAAE;oBACP,IAAI,EAAE;wBACJ,MAAM,EAAE;4BACN,EAAE,EAAE,IAAI;4BACR,QAAQ,EAAE,IAAI;4BACd,OAAO,EAAE;gCACP,MAAM,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE;6BACpD;yBACF;qBACF;iBACF;aACF;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,wBAAwB,CAAC,IAIxC;IACC,OAAO,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC;QACtC,IAAI,EAAE;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,IAAI,EAAE,IAAI,CAAC,IAA0B;SACtC;KACF,CAAC,CAAC;AACL,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,sBAAsB,CAAC,MAAc,EAAE,cAAsB;IAC3E,OAAO,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC;QACtC,KAAK,EAAE;YACL,qBAAqB,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE;SAClD;QACD,IAAI,EAAE;YACJ,QAAQ,EAAE,IAAI,IAAI,EAAE;SACrB;KACF,CAAC,CAAC;AACL,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,wBAAwB,CAAC,MAAc,EAAE,cAAsB;IAC7E,OAAO,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC;QACtC,KAAK,EAAE;YACL,qBAAqB,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE;SAClD;KACF,CAAC,CAAC;AACL,CAAC","debug_id":"7ea2e02b-0f12-5407-9926-5fab4c199704"}
1
+ {"version":3,"file":"conversation.js","sources":["models/conversation.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Conversation model – DM/group conversations, members, unread counts.\n */\nimport { prisma } from \"../lib/prisma.js\";\n\nconst conversationListInclude = {\n labChat: { select: { id: true, title: true } },\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: { displayName: true, profilePicture: true },\n },\n },\n },\n },\n },\n messages: {\n orderBy: { createdAt: \"desc\" as const },\n take: 1,\n include: {\n sender: {\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n },\n },\n },\n },\n};\n\n/** @returns User's conversations with members and last message. */\nexport function findConversationsByUserId(userId: string) {\n return prisma.conversation.findMany({\n where: {\n members: { some: { userId } },\n },\n include: conversationListInclude,\n orderBy: { updatedAt: \"desc\" },\n });\n}\n\n/** Count unread messages in conversation for user. */\nexport function countUnreadMessages(\n conversationId: string,\n userId: string,\n after?: Date\n) {\n return prisma.message.count({\n where: {\n conversationId,\n senderId: { not: userId },\n ...(after && { createdAt: { gt: after } }),\n },\n });\n}\n\n/** Count unread mentions for user in conversation. */\nexport function countUnreadMentions(\n conversationId: string,\n userId: string,\n after?: Date\n) {\n return prisma.mention.count({\n where: {\n userId,\n message: {\n conversationId,\n senderId: { not: userId },\n ...(after && { createdAt: { gt: after } }),\n },\n },\n });\n}\n\n/** @returns User by username (id, username only). */\nexport function findUserByUsername(username: string) {\n return prisma.user.findFirst({\n where: { username },\n select: { id: true, username: true },\n });\n}\n\n/**\n * Search users who share at least one active school membership with the\n * requester and match the query by username or profile display name.\n *\n * The requester is always excluded so the result set can be used directly as\n * conversation member suggestions.\n */\nexport async function searchInstitutionConversationMembers(\n userId: string,\n query: string,\n limit: number\n) {\n const memberships = await prisma.schoolMembership.findMany({\n where: { userId, status: \"ACTIVE\" },\n select: { schoolId: true },\n });\n const schoolIds = memberships.map((membership) => membership.schoolId);\n\n if (schoolIds.length === 0) return [];\n\n return prisma.user.findMany({\n where: {\n id: { not: userId },\n schoolMemberships: {\n some: {\n schoolId: { in: schoolIds },\n status: \"ACTIVE\",\n },\n },\n OR: [\n { username: { contains: query, mode: \"insensitive\" } },\n {\n profile: {\n is: { displayName: { contains: query, mode: \"insensitive\" } },\n },\n },\n ],\n },\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n },\n orderBy: { username: \"asc\" },\n take: limit,\n });\n}\n\n/** @returns User's DM conversations. */\nexport function findDmConversationsByUserId(userId: string) {\n return prisma.conversation.findMany({\n where: {\n type: \"DM\",\n members: { some: { userId } },\n },\n include: {\n members: { select: { userId: true } },\n },\n });\n}\n\n/** @returns Users by IDs or usernames. */\nexport function findUsersByIdsOrUsernames(identifiers: string[]) {\n if (identifiers.length === 0) return Promise.resolve([]);\n return prisma.user.findMany({\n where: {\n OR: [\n { id: { in: identifiers } },\n { username: { in: identifiers } },\n ],\n },\n select: { id: true, username: true },\n });\n}\n\n/** Create a DM or group conversation with members. */\nexport function createConversation(data: {\n type: \"DM\" | \"GROUP\";\n name?: string;\n members: { userId: string; role: string }[];\n}) {\n return prisma.conversation.create({\n data: {\n type: data.type,\n name: data.name,\n members: {\n create: data.members.map((m) => ({\n userId: m.userId,\n role: m.role as \"ADMIN\" | \"MEMBER\",\n })),\n },\n },\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: { displayName: true, profilePicture: true },\n },\n },\n },\n },\n },\n },\n });\n}\n\n/** @returns Conversation if user is a member. */\nexport function findConversationByIdAndMember(\n conversationId: string,\n userId: string\n) {\n return prisma.conversation.findFirst({\n where: {\n id: conversationId,\n members: { some: { userId } },\n },\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: { displayName: true, profilePicture: true },\n },\n },\n },\n },\n },\n },\n });\n}\n\n/** Add a member to a conversation. */\nexport function createConversationMember(data: {\n userId: string;\n conversationId: string;\n role: string;\n}) {\n return prisma.conversationMember.create({\n data: {\n userId: data.userId,\n conversationId: data.conversationId,\n role: data.role as \"ADMIN\" | \"MEMBER\",\n },\n });\n}\n\n/** Hide a conversation for a single member until new activity occurs. */\nexport function hideConversationMember(userId: string, conversationId: string) {\n return prisma.conversationMember.update({\n where: {\n userId_conversationId: { userId, conversationId },\n },\n data: {\n hiddenAt: new Date(),\n },\n });\n}\n\n/** Remove a member from a conversation. */\nexport function deleteConversationMember(userId: string, conversationId: string) {\n return prisma.conversationMember.delete({\n where: {\n userId_conversationId: { userId, conversationId },\n },\n });\n}\n"],"names":[],"mappings":"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","debug_id":"14c80725-5a2b-5e37-aa01-49cb94535659"}
@@ -0,0 +1,154 @@
1
+ export declare function listDepartmentsForSchool(schoolId: string): import(".prisma/client").Prisma.PrismaPromise<{
2
+ name: string;
3
+ id: string;
4
+ description: string | null;
5
+ createdAt: Date;
6
+ updatedAt: Date;
7
+ schoolId: string;
8
+ color: string | null;
9
+ _count: {
10
+ tags: number;
11
+ classes: number;
12
+ members: number;
13
+ rubricTemplates: number;
14
+ boundaryTemplates: number;
15
+ };
16
+ }[]>;
17
+ export declare function listDepartmentsForUser(userId: string, schoolId: string): import(".prisma/client").Prisma.PrismaPromise<{
18
+ name: string;
19
+ id: string;
20
+ description: string | null;
21
+ createdAt: Date;
22
+ updatedAt: Date;
23
+ schoolId: string;
24
+ color: string | null;
25
+ }[]>;
26
+ export declare function getDepartment(departmentId: string): import(".prisma/client").Prisma.Prisma__DepartmentClient<{
27
+ name: string;
28
+ id: string;
29
+ description: string | null;
30
+ createdAt: Date;
31
+ updatedAt: Date;
32
+ schoolId: string;
33
+ color: string | null;
34
+ tags: {
35
+ name: string;
36
+ id: string;
37
+ color: string;
38
+ }[];
39
+ classes: {
40
+ name: string;
41
+ id: string;
42
+ subject: string;
43
+ color: string | null;
44
+ section: string;
45
+ }[];
46
+ members: {
47
+ id: string;
48
+ username: string;
49
+ email: string;
50
+ profile: {
51
+ displayName: string | null;
52
+ profilePicture: string | null;
53
+ profilePictureThumbnail: string | null;
54
+ } | null;
55
+ }[];
56
+ rubricTemplates: {
57
+ name: string | null;
58
+ id: string;
59
+ structured: string;
60
+ }[];
61
+ boundaryTemplates: {
62
+ name: string | null;
63
+ id: string;
64
+ structured: string;
65
+ }[];
66
+ } | null, null, import("@prisma/client/runtime/library.js").DefaultArgs, {
67
+ datasources: {
68
+ db: {
69
+ url: string;
70
+ };
71
+ };
72
+ }>;
73
+ export declare function createDepartment(data: {
74
+ schoolId: string;
75
+ name: string;
76
+ description?: string;
77
+ color?: string;
78
+ }): import(".prisma/client").Prisma.Prisma__DepartmentClient<{
79
+ name: string;
80
+ id: string;
81
+ description: string | null;
82
+ createdAt: Date;
83
+ updatedAt: Date;
84
+ schoolId: string;
85
+ color: string | null;
86
+ }, never, import("@prisma/client/runtime/library.js").DefaultArgs, {
87
+ datasources: {
88
+ db: {
89
+ url: string;
90
+ };
91
+ };
92
+ }>;
93
+ export declare function updateDepartment(departmentId: string, data: {
94
+ name?: string;
95
+ description?: string | null;
96
+ color?: string;
97
+ }): import(".prisma/client").Prisma.Prisma__DepartmentClient<{
98
+ name: string;
99
+ id: string;
100
+ description: string | null;
101
+ createdAt: Date;
102
+ updatedAt: Date;
103
+ schoolId: string;
104
+ color: string | null;
105
+ }, never, import("@prisma/client/runtime/library.js").DefaultArgs, {
106
+ datasources: {
107
+ db: {
108
+ url: string;
109
+ };
110
+ };
111
+ }>;
112
+ export declare function deleteDepartment(departmentId: string): import(".prisma/client").Prisma.Prisma__DepartmentClient<{
113
+ name: string;
114
+ id: string;
115
+ description: string | null;
116
+ createdAt: Date;
117
+ updatedAt: Date;
118
+ schoolId: string;
119
+ color: string | null;
120
+ }, never, import("@prisma/client/runtime/library.js").DefaultArgs, {
121
+ datasources: {
122
+ db: {
123
+ url: string;
124
+ };
125
+ };
126
+ }>;
127
+ export declare function addDepartmentMembers(departmentId: string, userIds: string[]): import(".prisma/client").Prisma.Prisma__DepartmentClient<{
128
+ id: string;
129
+ }, never, import("@prisma/client/runtime/library.js").DefaultArgs, {
130
+ datasources: {
131
+ db: {
132
+ url: string;
133
+ };
134
+ };
135
+ }>;
136
+ export declare function removeDepartmentMember(departmentId: string, userId: string): import(".prisma/client").Prisma.Prisma__DepartmentClient<{
137
+ id: string;
138
+ }, never, import("@prisma/client/runtime/library.js").DefaultArgs, {
139
+ datasources: {
140
+ db: {
141
+ url: string;
142
+ };
143
+ };
144
+ }>;
145
+ export declare function findDepartmentMembership(departmentId: string, userId: string): import(".prisma/client").Prisma.Prisma__DepartmentClient<{
146
+ id: string;
147
+ } | null, null, import("@prisma/client/runtime/library.js").DefaultArgs, {
148
+ datasources: {
149
+ db: {
150
+ url: string;
151
+ };
152
+ };
153
+ }>;
154
+ //# sourceMappingURL=department.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"department.d.ts","sourceRoot":"/","sources":["models/department.ts"],"names":[],"mappings":"AAgCA,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;KAiBxD;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;KAStE;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BjD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;;;;;;;;;;;;GAUA;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;GAOrE;AAED,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM;;;;;;;;;;;;;;GAIpD;AAED,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EAAE;;;;;;;;GASlB;AAED,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM;;;;;;;;GASf;AAED,wBAAgB,wBAAwB,CACtC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM;;;;;;;;GAMf"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Department model — department CRUD, members, and template artefacts.
3
+ *
4
+ * Departments scope rubric/boundary templates and tags inside an institution.
5
+ * They are an admin-managed taxonomy; teachers/students can be members of
6
+ * many departments.
7
+ */
8
+
9
+ !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]="5b5ee7e7-d0d6-5846-a279-d6c6dee02dd4")}catch(e){}}();
10
+ import { prisma } from "../lib/prisma.js";
11
+ const departmentSelect = {
12
+ id: true,
13
+ schoolId: true,
14
+ name: true,
15
+ description: true,
16
+ color: true,
17
+ createdAt: true,
18
+ updatedAt: true,
19
+ };
20
+ const memberSelect = {
21
+ id: true,
22
+ username: true,
23
+ email: true,
24
+ profile: {
25
+ select: {
26
+ displayName: true,
27
+ profilePicture: true,
28
+ profilePictureThumbnail: true,
29
+ },
30
+ },
31
+ };
32
+ export function listDepartmentsForSchool(schoolId) {
33
+ return prisma.department.findMany({
34
+ where: { schoolId },
35
+ orderBy: { name: "asc" },
36
+ select: {
37
+ ...departmentSelect,
38
+ _count: {
39
+ select: {
40
+ members: true,
41
+ classes: true,
42
+ tags: true,
43
+ rubricTemplates: true,
44
+ boundaryTemplates: true,
45
+ },
46
+ },
47
+ },
48
+ });
49
+ }
50
+ export function listDepartmentsForUser(userId, schoolId) {
51
+ return prisma.department.findMany({
52
+ where: {
53
+ schoolId,
54
+ members: { some: { id: userId } },
55
+ },
56
+ orderBy: { name: "asc" },
57
+ select: departmentSelect,
58
+ });
59
+ }
60
+ export function getDepartment(departmentId) {
61
+ return prisma.department.findUnique({
62
+ where: { id: departmentId },
63
+ select: {
64
+ ...departmentSelect,
65
+ members: { select: memberSelect },
66
+ tags: {
67
+ select: { id: true, name: true, color: true },
68
+ },
69
+ rubricTemplates: {
70
+ select: { id: true, name: true, structured: true },
71
+ },
72
+ boundaryTemplates: {
73
+ select: { id: true, name: true, structured: true },
74
+ },
75
+ classes: {
76
+ select: {
77
+ id: true,
78
+ name: true,
79
+ subject: true,
80
+ section: true,
81
+ color: true,
82
+ },
83
+ },
84
+ },
85
+ });
86
+ }
87
+ export function createDepartment(data) {
88
+ return prisma.department.create({
89
+ data: {
90
+ schoolId: data.schoolId,
91
+ name: data.name,
92
+ description: data.description,
93
+ color: data.color,
94
+ },
95
+ select: departmentSelect,
96
+ });
97
+ }
98
+ export function updateDepartment(departmentId, data) {
99
+ return prisma.department.update({
100
+ where: { id: departmentId },
101
+ data,
102
+ select: departmentSelect,
103
+ });
104
+ }
105
+ export function deleteDepartment(departmentId) {
106
+ return prisma.department.delete({
107
+ where: { id: departmentId },
108
+ });
109
+ }
110
+ export function addDepartmentMembers(departmentId, userIds) {
111
+ return prisma.department.update({
112
+ where: { id: departmentId },
113
+ data: {
114
+ members: { connect: userIds.map((id) => ({ id })) },
115
+ },
116
+ select: { id: true },
117
+ });
118
+ }
119
+ export function removeDepartmentMember(departmentId, userId) {
120
+ return prisma.department.update({
121
+ where: { id: departmentId },
122
+ data: {
123
+ members: { disconnect: { id: userId } },
124
+ },
125
+ select: { id: true },
126
+ });
127
+ }
128
+ export function findDepartmentMembership(departmentId, userId) {
129
+ return prisma.department.findFirst({
130
+ where: { id: departmentId, members: { some: { id: userId } } },
131
+ select: { id: true },
132
+ });
133
+ }
134
+ //# sourceMappingURL=department.js.map
135
+ //# debugId=5b5ee7e7-d0d6-5846-a279-d6c6dee02dd4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"department.js","sources":["models/department.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Department model — department CRUD, members, and template artefacts.\n *\n * Departments scope rubric/boundary templates and tags inside an institution.\n * They are an admin-managed taxonomy; teachers/students can be members of\n * many departments.\n */\nimport { prisma } from \"../lib/prisma.js\";\n\nconst departmentSelect = {\n id: true,\n schoolId: true,\n name: true,\n description: true,\n color: true,\n createdAt: true,\n updatedAt: true,\n} as const;\n\nconst memberSelect = {\n id: true,\n username: true,\n email: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n} as const;\n\nexport function listDepartmentsForSchool(schoolId: string) {\n return prisma.department.findMany({\n where: { schoolId },\n orderBy: { name: \"asc\" },\n select: {\n ...departmentSelect,\n _count: {\n select: {\n members: true,\n classes: true,\n tags: true,\n rubricTemplates: true,\n boundaryTemplates: true,\n },\n },\n },\n });\n}\n\nexport function listDepartmentsForUser(userId: string, schoolId: string) {\n return prisma.department.findMany({\n where: {\n schoolId,\n members: { some: { id: userId } },\n },\n orderBy: { name: \"asc\" },\n select: departmentSelect,\n });\n}\n\nexport function getDepartment(departmentId: string) {\n return prisma.department.findUnique({\n where: { id: departmentId },\n select: {\n ...departmentSelect,\n members: { select: memberSelect },\n tags: {\n select: { id: true, name: true, color: true },\n },\n rubricTemplates: {\n select: { id: true, name: true, structured: true },\n },\n boundaryTemplates: {\n select: { id: true, name: true, structured: true },\n },\n classes: {\n select: {\n id: true,\n name: true,\n subject: true,\n section: true,\n color: true,\n },\n },\n },\n });\n}\n\nexport function createDepartment(data: {\n schoolId: string;\n name: string;\n description?: string;\n color?: string;\n}) {\n return prisma.department.create({\n data: {\n schoolId: data.schoolId,\n name: data.name,\n description: data.description,\n color: data.color,\n },\n select: departmentSelect,\n });\n}\n\nexport function updateDepartment(\n departmentId: string,\n data: { name?: string; description?: string | null; color?: string }\n) {\n return prisma.department.update({\n where: { id: departmentId },\n data,\n select: departmentSelect,\n });\n}\n\nexport function deleteDepartment(departmentId: string) {\n return prisma.department.delete({\n where: { id: departmentId },\n });\n}\n\nexport function addDepartmentMembers(\n departmentId: string,\n userIds: string[]\n) {\n return prisma.department.update({\n where: { id: departmentId },\n data: {\n members: { connect: userIds.map((id) => ({ id })) },\n },\n select: { id: true },\n });\n}\n\nexport function removeDepartmentMember(\n departmentId: string,\n userId: string\n) {\n return prisma.department.update({\n where: { id: departmentId },\n data: {\n members: { disconnect: { id: userId } },\n },\n select: { id: true },\n });\n}\n\nexport function findDepartmentMembership(\n departmentId: string,\n userId: string\n) {\n return prisma.department.findFirst({\n where: { id: departmentId, members: { some: { id: userId } } },\n select: { id: true },\n });\n}\n"],"names":[],"mappings":"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","debug_id":"5b5ee7e7-d0d6-5846-a279-d6c6dee02dd4"}