@studious-lms/server 1.4.5 → 1.4.7

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 (167) hide show
  1. package/dist/lib/config/cors.d.ts.map +1 -1
  2. package/dist/lib/config/cors.js +8 -3
  3. package/dist/lib/config/cors.js.map +1 -1
  4. package/dist/models/access.d.ts +112 -0
  5. package/dist/models/access.d.ts.map +1 -0
  6. package/dist/models/access.js +49 -0
  7. package/dist/models/access.js.map +1 -0
  8. package/dist/models/announcement.d.ts +17 -2
  9. package/dist/models/announcement.d.ts.map +1 -1
  10. package/dist/models/announcement.js +21 -4
  11. package/dist/models/announcement.js.map +1 -1
  12. package/dist/models/assignment.d.ts +37 -37
  13. package/dist/models/assignment.d.ts.map +1 -1
  14. package/dist/models/assignment.js +15 -15
  15. package/dist/models/assignment.js.map +1 -1
  16. package/dist/models/attendance.d.ts +1 -1
  17. package/dist/models/attendance.d.ts.map +1 -1
  18. package/dist/models/attendance.js +6 -5
  19. package/dist/models/attendance.js.map +1 -1
  20. package/dist/models/auth.d.ts +5 -5
  21. package/dist/models/auth.d.ts.map +1 -1
  22. package/dist/models/auth.js +7 -11
  23. package/dist/models/auth.js.map +1 -1
  24. package/dist/models/class.d.ts +26 -26
  25. package/dist/models/class.d.ts.map +1 -1
  26. package/dist/models/class.js +7 -11
  27. package/dist/models/class.js.map +1 -1
  28. package/dist/models/comment.d.ts +233 -6
  29. package/dist/models/comment.d.ts.map +1 -1
  30. package/dist/models/comment.js +133 -3
  31. package/dist/models/comment.js.map +1 -1
  32. package/dist/models/conversation.d.ts +7 -7
  33. package/dist/models/event.d.ts +52 -3
  34. package/dist/models/event.d.ts.map +1 -1
  35. package/dist/models/event.js +56 -6
  36. package/dist/models/event.js.map +1 -1
  37. package/dist/models/file.d.ts +178 -103
  38. package/dist/models/file.d.ts.map +1 -1
  39. package/dist/models/file.js +54 -14
  40. package/dist/models/file.js.map +1 -1
  41. package/dist/models/folder.d.ts +22 -22
  42. package/dist/models/folder.d.ts.map +1 -1
  43. package/dist/models/folder.js +5 -4
  44. package/dist/models/folder.js.map +1 -1
  45. package/dist/models/labChat.d.ts +20 -20
  46. package/dist/models/labChat.d.ts.map +1 -1
  47. package/dist/models/labChat.js +8 -10
  48. package/dist/models/labChat.js.map +1 -1
  49. package/dist/models/marketing.d.ts +1 -1
  50. package/dist/models/message.d.ts +6 -6
  51. package/dist/models/newtonChat.d.ts +5 -5
  52. package/dist/models/school.d.ts +361 -0
  53. package/dist/models/school.d.ts.map +1 -0
  54. package/dist/models/school.js +314 -0
  55. package/dist/models/school.js.map +1 -0
  56. package/dist/models/section.d.ts +1 -1
  57. package/dist/models/section.d.ts.map +1 -1
  58. package/dist/models/section.js +5 -4
  59. package/dist/models/section.js.map +1 -1
  60. package/dist/models/user.d.ts +4 -4
  61. package/dist/models/worksheet.d.ts +67 -65
  62. package/dist/models/worksheet.d.ts.map +1 -1
  63. package/dist/models/worksheet.js +6 -14
  64. package/dist/models/worksheet.js.map +1 -1
  65. package/dist/pipelines/aiLabChat.d.ts.map +1 -1
  66. package/dist/pipelines/aiLabChat.js +4 -3
  67. package/dist/pipelines/aiLabChat.js.map +1 -1
  68. package/dist/pipelines/gradeWorksheet.d.ts +2 -2
  69. package/dist/pipelines/pdfToWorksheet.d.ts +1 -1
  70. package/dist/routers/_app.d.ts +2462 -1104
  71. package/dist/routers/_app.d.ts.map +1 -1
  72. package/dist/routers/_app.js +4 -2
  73. package/dist/routers/_app.js.map +1 -1
  74. package/dist/routers/announcement.d.ts +13 -5
  75. package/dist/routers/announcement.d.ts.map +1 -1
  76. package/dist/routers/announcement.js +25 -5
  77. package/dist/routers/announcement.js.map +1 -1
  78. package/dist/routers/assignment.d.ts +266 -36
  79. package/dist/routers/assignment.d.ts.map +1 -1
  80. package/dist/routers/assignment.js +221 -3
  81. package/dist/routers/assignment.js.map +1 -1
  82. package/dist/routers/class.d.ts +21 -20
  83. package/dist/routers/class.d.ts.map +1 -1
  84. package/dist/routers/class.js +3 -2
  85. package/dist/routers/class.js.map +1 -1
  86. package/dist/routers/comment.d.ts +40 -3
  87. package/dist/routers/comment.d.ts.map +1 -1
  88. package/dist/routers/comment.js +14 -5
  89. package/dist/routers/comment.js.map +1 -1
  90. package/dist/routers/conversation.d.ts +6 -6
  91. package/dist/routers/event.d.ts +21 -2
  92. package/dist/routers/event.d.ts.map +1 -1
  93. package/dist/routers/file.d.ts +2 -2
  94. package/dist/routers/folder.d.ts +24 -24
  95. package/dist/routers/labChat.d.ts +7 -7
  96. package/dist/routers/school.d.ts +384 -0
  97. package/dist/routers/school.d.ts.map +1 -0
  98. package/dist/routers/school.js +79 -0
  99. package/dist/routers/school.js.map +1 -0
  100. package/dist/routers/search.d.ts +1 -1
  101. package/dist/routers/worksheet.d.ts +23 -21
  102. package/dist/routers/worksheet.d.ts.map +1 -1
  103. package/dist/services/announcement.d.ts.map +1 -1
  104. package/dist/services/announcement.js +10 -6
  105. package/dist/services/announcement.js.map +1 -1
  106. package/dist/services/assignment.d.ts +36 -36
  107. package/dist/services/class.d.ts +20 -19
  108. package/dist/services/class.d.ts.map +1 -1
  109. package/dist/services/class.js +22 -3
  110. package/dist/services/class.js.map +1 -1
  111. package/dist/services/comment.d.ts +31 -5
  112. package/dist/services/comment.d.ts.map +1 -1
  113. package/dist/services/comment.js +102 -19
  114. package/dist/services/comment.js.map +1 -1
  115. package/dist/services/conversation.d.ts +6 -6
  116. package/dist/services/event.d.ts +21 -2
  117. package/dist/services/event.d.ts.map +1 -1
  118. package/dist/services/event.js +11 -7
  119. package/dist/services/event.js.map +1 -1
  120. package/dist/services/file.d.ts +2 -2
  121. package/dist/services/file.d.ts.map +1 -1
  122. package/dist/services/file.js +17 -8
  123. package/dist/services/file.js.map +1 -1
  124. package/dist/services/folder.d.ts +24 -24
  125. package/dist/services/labChat.d.ts +7 -7
  126. package/dist/services/school.d.ts +299 -0
  127. package/dist/services/school.d.ts.map +1 -0
  128. package/dist/services/school.js +225 -0
  129. package/dist/services/school.js.map +1 -0
  130. package/dist/services/worksheet.d.ts +23 -21
  131. package/dist/services/worksheet.d.ts.map +1 -1
  132. package/package.json +1 -1
  133. package/prisma/migrations/20260502230500_assignment_submission_comments/migration.sql +60 -0
  134. package/prisma/migrations/20260504071500_school_memberships/migration.sql +81 -0
  135. package/prisma/schema.prisma +75 -2
  136. package/src/lib/config/cors.ts +8 -1
  137. package/src/models/access.ts +48 -0
  138. package/src/models/announcement.ts +19 -2
  139. package/src/models/assignment.ts +17 -13
  140. package/src/models/attendance.ts +4 -3
  141. package/src/models/auth.ts +8 -9
  142. package/src/models/class.ts +8 -9
  143. package/src/models/comment.ts +137 -1
  144. package/src/models/event.ts +54 -4
  145. package/src/models/file.ts +53 -12
  146. package/src/models/folder.ts +3 -2
  147. package/src/models/labChat.ts +9 -8
  148. package/src/models/school.ts +361 -0
  149. package/src/models/section.ts +3 -2
  150. package/src/models/worksheet.ts +7 -12
  151. package/src/pipelines/aiLabChat.ts +2 -1
  152. package/src/routers/_app.ts +2 -0
  153. package/src/routers/announcement.ts +30 -4
  154. package/src/routers/assignment.ts +243 -2
  155. package/src/routers/class.ts +1 -0
  156. package/src/routers/comment.ts +19 -2
  157. package/src/routers/school.ts +122 -0
  158. package/src/services/announcement.ts +12 -4
  159. package/src/services/class.ts +25 -2
  160. package/src/services/comment.ts +122 -18
  161. package/src/services/event.ts +23 -6
  162. package/src/services/file.ts +20 -6
  163. package/src/services/school.ts +308 -0
  164. package/tests/lib/cors.test.ts +13 -1
  165. package/tests/routers/assignment.test.ts +68 -2
  166. package/tests/routers/comment.test.ts +42 -1
  167. package/vercel.json +8 -0
@@ -1 +1 @@
1
- {"version":3,"file":"file.js","sources":["models/file.ts"],"sourceRoot":"/","sourcesContent":["/**\n * File model – file lookup by ID, folder, assignment, submission. Permission checks.\n */\nimport { prisma } from \"../lib/prisma.js\";\n\n/** @returns File with assignment, submission, annotations, folder, announcement for permission checks. */\nexport function findFileById(fileId: string) {\n return prisma.file.findUnique({\n where: { id: fileId },\n include: {\n assignment: {\n include: {\n class: {\n include: {\n students: true,\n teachers: true,\n },\n },\n },\n },\n submission: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true,\n },\n },\n },\n },\n },\n },\n annotations: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true,\n },\n },\n },\n },\n },\n },\n folder: {\n include: {\n class: {\n include: {\n students: true,\n teachers: true,\n },\n },\n },\n },\n announcement: {\n include: {\n class: {\n include: {\n students: true,\n teachers: true,\n },\n },\n },\n },\n },\n });\n}\n\n/** @returns File with folder and class. */\nexport function findFileWithFolder(fileId: string) {\n return prisma.file.findUnique({\n where: { id: fileId },\n include: {\n folder: { include: { class: true } },\n },\n });\n}\n\n/** @returns File with folder and thumbnail. */\nexport function findFileWithFolderAndThumbnail(fileId: string) {\n return prisma.file.findUnique({\n where: { id: fileId },\n include: {\n folder: { include: { class: true } },\n thumbnail: true,\n },\n });\n}\n\n/** @returns Folder by ID with class. */\nexport function findFolderById(folderId: string) {\n return prisma.folder.findUnique({\n where: { id: folderId },\n include: { class: true },\n });\n}\n\n/** Move file to a folder. */\nexport function updateFileFolder(fileId: string, folderId: string) {\n return prisma.file.update({\n where: { id: fileId },\n data: { folderId },\n include: {\n user: { select: { id: true, username: true } },\n },\n });\n}\n\n/** Rename a file. */\nexport function updateFileName(fileId: string, name: string) {\n return prisma.file.update({\n where: { id: fileId },\n data: { name },\n include: {\n user: { select: { id: true, username: true } },\n },\n });\n}\n\n/** Delete a file record. */\nexport function deleteFileById(fileId: string) {\n return prisma.file.delete({\n where: { id: fileId },\n });\n}\n"],"names":[],"mappings":"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","debug_id":"7aee984e-13ae-5392-b286-7ab68953ac8c"}
1
+ {"version":3,"file":"file.js","sources":["models/file.ts"],"sourceRoot":"/","sourcesContent":["/**\n * File model – file lookup by ID, folder, assignment, submission. Permission checks.\n */\nimport { prisma } from \"../lib/prisma.js\";\n\nconst classFileAccessInclude = {\n students: true,\n teachers: true,\n school: {\n include: {\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 File with assignment, submission, annotations, folder, announcement for permission checks. */\nexport function findFileById(fileId: string) {\n return prisma.file.findUnique({\n where: { id: fileId },\n include: {\n assignment: {\n include: {\n class: {\n include: classFileAccessInclude,\n },\n },\n },\n submission: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true,\n school: {\n include: {\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 },\n },\n },\n },\n },\n },\n annotations: {\n include: {\n student: true,\n assignment: {\n include: {\n class: {\n include: {\n teachers: true,\n school: {\n include: {\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 },\n },\n },\n },\n },\n },\n folder: {\n include: {\n class: {\n include: classFileAccessInclude,\n },\n },\n },\n announcement: {\n include: {\n class: {\n include: classFileAccessInclude,\n },\n },\n },\n },\n });\n}\n\n/** @returns File with folder and class. */\nexport function findFileWithFolder(fileId: string) {\n return prisma.file.findUnique({\n where: { id: fileId },\n include: {\n folder: { include: { class: true } },\n },\n });\n}\n\n/** @returns File with folder and thumbnail. */\nexport function findFileWithFolderAndThumbnail(fileId: string) {\n return prisma.file.findUnique({\n where: { id: fileId },\n include: {\n folder: { include: { class: true } },\n thumbnail: true,\n },\n });\n}\n\n/** @returns Folder by ID with class. */\nexport function findFolderById(folderId: string) {\n return prisma.folder.findUnique({\n where: { id: folderId },\n include: { class: true },\n });\n}\n\n/** Move file to a folder. */\nexport function updateFileFolder(fileId: string, folderId: string) {\n return prisma.file.update({\n where: { id: fileId },\n data: { folderId },\n include: {\n user: { select: { id: true, username: true } },\n },\n });\n}\n\n/** Rename a file. */\nexport function updateFileName(fileId: string, name: string) {\n return prisma.file.update({\n where: { id: fileId },\n data: { name },\n include: {\n user: { select: { id: true, username: true } },\n },\n });\n}\n\n/** Delete a file record. */\nexport function deleteFileById(fileId: string) {\n return prisma.file.delete({\n where: { id: fileId },\n });\n}\n"],"names":[],"mappings":"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","debug_id":"5fff69ed-bff2-579c-a03e-467530b4ea27"}
@@ -1,4 +1,4 @@
1
- /** @returns Class if user is a teacher. */
1
+ /** @returns Class if user is a teacher or school admin. */
2
2
  export declare function findClassWithTeacher(classId: string, teacherId: string): import(".prisma/client").Prisma.Prisma__ClassClient<{
3
3
  name: string;
4
4
  id: string;
@@ -85,21 +85,21 @@ export declare function createFolder(data: {
85
85
  type: string;
86
86
  name: string;
87
87
  id: string;
88
- size: number | null;
89
- uploadedAt: Date | null;
90
88
  user: {
91
89
  id: string;
92
90
  username: string;
93
91
  } | null;
92
+ size: number | null;
93
+ uploadedAt: Date | null;
94
94
  }[];
95
95
  childFolders: {
96
96
  name: string;
97
97
  id: string;
98
+ color: string | null;
98
99
  _count: {
99
100
  files: number;
100
101
  childFolders: number;
101
102
  };
102
- color: string | null;
103
103
  }[];
104
104
  } & {
105
105
  name: string;
@@ -120,21 +120,21 @@ export declare function findFolderWithContents(folderId: string): import(".prism
120
120
  type: string;
121
121
  name: string;
122
122
  id: string;
123
- size: number | null;
124
- uploadedAt: Date | null;
125
123
  user: {
126
124
  id: string;
127
125
  username: string;
128
126
  } | null;
127
+ size: number | null;
128
+ uploadedAt: Date | null;
129
129
  }[];
130
130
  childFolders: {
131
131
  name: string;
132
132
  id: string;
133
+ color: string | null;
133
134
  _count: {
134
135
  files: number;
135
136
  childFolders: number;
136
137
  };
137
- color: string | null;
138
138
  }[];
139
139
  parentFolder: {
140
140
  name: string;
@@ -159,21 +159,21 @@ export declare function findChildFolders(parentFolderId: string): import(".prism
159
159
  type: string;
160
160
  name: string;
161
161
  id: string;
162
- size: number | null;
163
- uploadedAt: Date | null;
164
162
  user: {
165
163
  id: string;
166
164
  username: string;
167
165
  } | null;
166
+ size: number | null;
167
+ uploadedAt: Date | null;
168
168
  }[];
169
169
  childFolders: {
170
170
  name: string;
171
171
  id: string;
172
+ color: string | null;
172
173
  _count: {
173
174
  files: number;
174
175
  childFolders: number;
175
176
  };
176
- color: string | null;
177
177
  }[];
178
178
  } & {
179
179
  name: string;
@@ -188,24 +188,24 @@ export declare function findRootFolderWithContents(classId: string): import(".pr
188
188
  type: string;
189
189
  name: string;
190
190
  id: string;
191
- size: number | null;
192
- uploadedAt: Date | null;
193
191
  user: {
194
192
  id: string;
195
193
  username: string;
196
194
  } | null;
195
+ size: number | null;
196
+ uploadedAt: Date | null;
197
197
  }[];
198
198
  childFolders: {
199
199
  name: string;
200
200
  id: string;
201
- files: {
202
- id: string;
203
- }[];
201
+ color: string | null;
204
202
  _count: {
205
203
  files: number;
206
204
  childFolders: number;
207
205
  };
208
- color: string | null;
206
+ files: {
207
+ id: string;
208
+ }[];
209
209
  childFolders: {
210
210
  id: string;
211
211
  }[];
@@ -281,21 +281,21 @@ export declare function updateFolderParent(folderId: string, parentFolderId: str
281
281
  type: string;
282
282
  name: string;
283
283
  id: string;
284
- size: number | null;
285
- uploadedAt: Date | null;
286
284
  user: {
287
285
  id: string;
288
286
  username: string;
289
287
  } | null;
288
+ size: number | null;
289
+ uploadedAt: Date | null;
290
290
  }[];
291
291
  childFolders: {
292
292
  name: string;
293
293
  id: string;
294
+ color: string | null;
294
295
  _count: {
295
296
  files: number;
296
297
  childFolders: number;
297
298
  };
298
- color: string | null;
299
299
  }[];
300
300
  } & {
301
301
  name: string;
@@ -319,21 +319,21 @@ export declare function updateFolder(folderId: string, data: {
319
319
  type: string;
320
320
  name: string;
321
321
  id: string;
322
- size: number | null;
323
- uploadedAt: Date | null;
324
322
  user: {
325
323
  id: string;
326
324
  username: string;
327
325
  } | null;
326
+ size: number | null;
327
+ uploadedAt: Date | null;
328
328
  }[];
329
329
  childFolders: {
330
330
  name: string;
331
331
  id: string;
332
+ color: string | null;
332
333
  _count: {
333
334
  files: number;
334
335
  childFolders: number;
335
336
  };
336
- color: string | null;
337
337
  }[];
338
338
  } & {
339
339
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"folder.d.ts","sourceRoot":"/","sources":["models/folder.ts"],"names":[],"mappings":"AAqBA,2CAA2C;AAC3C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;GAOtE;AAED,6BAA6B;AAC7B,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;GAI9C;AAED,kCAAkC;AAClC,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;GAKvD;AAED,wCAAwC;AACxC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;GAOtD;AAED,6CAA6C;AAC7C,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM;;;;;;GAW3D;AAED,uBAAuB;AACvB,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqBA;AAcD,oDAAoD;AACpD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAKtD;AAED,qCAAqC;AACrC,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;MAetD;AAED,sDAAsD;AACtD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBzD;AAED,+CAA+C;AAC/C,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;GAOpE;AAED,+CAA+C;AAC/C,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;GAOvD;AAED,uBAAuB;AACvB,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;GAIhD;AAED,iCAAiC;AACjC,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAS1E;AAED,oCAAoC;AACpC,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUxC;AAED,0CAA0C;AAC1C,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;GAIpD;AAED,6BAA6B;AAC7B,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;GAIjD"}
1
+ {"version":3,"file":"folder.d.ts","sourceRoot":"/","sources":["models/folder.ts"],"names":[],"mappings":"AAsBA,2DAA2D;AAC3D,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;GAOtE;AAED,6BAA6B;AAC7B,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;GAI9C;AAED,kCAAkC;AAClC,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;GAKvD;AAED,wCAAwC;AACxC,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;GAOtD;AAED,6CAA6C;AAC7C,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM;;;;;;GAW3D;AAED,uBAAuB;AACvB,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqBA;AAcD,oDAAoD;AACpD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAKtD;AAED,qCAAqC;AACrC,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;MAetD;AAED,sDAAsD;AACtD,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBzD;AAED,+CAA+C;AAC/C,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;GAOpE;AAED,+CAA+C;AAC/C,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;GAOvD;AAED,uBAAuB;AACvB,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;GAIhD;AAED,iCAAiC;AACjC,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAS1E;AAED,oCAAoC;AACpC,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUxC;AAED,0CAA0C;AAC1C,wBAAgB,0BAA0B,CAAC,EAAE,EAAE,MAAM;;;;;;;;;;;;GAIpD;AAED,6BAA6B;AAC7B,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;;;;;GAIjD"}
@@ -2,8 +2,9 @@
2
2
  * Folder model – class folders, hierarchy, contents. Teacher permission checks.
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]="f914d30a-5901-54ec-9a00-fba86348df0a")}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]="09a4aeb2-aef9-585f-9480-2197a905014d")}catch(e){}}();
6
6
  import { prisma } from "../lib/prisma.js";
7
+ import { classTeacherOrSchoolAdminWhere } from "./access.js";
7
8
  const fileSelect = {
8
9
  id: true,
9
10
  name: true,
@@ -18,12 +19,12 @@ const childFolderSelect = {
18
19
  color: true,
19
20
  _count: { select: { files: true, childFolders: true } },
20
21
  };
21
- /** @returns Class if user is a teacher. */
22
+ /** @returns Class if user is a teacher or school admin. */
22
23
  export function findClassWithTeacher(classId, teacherId) {
23
24
  return prisma.class.findFirst({
24
25
  where: {
25
26
  id: classId,
26
- teachers: { some: { id: teacherId } },
27
+ ...classTeacherOrSchoolAdminWhere(teacherId),
27
28
  },
28
29
  });
29
30
  }
@@ -199,4 +200,4 @@ export function findFolderParents(folderId) {
199
200
  });
200
201
  }
201
202
  //# sourceMappingURL=folder.js.map
202
- //# debugId=f914d30a-5901-54ec-9a00-fba86348df0a
203
+ //# debugId=09a4aeb2-aef9-585f-9480-2197a905014d
@@ -1 +1 @@
1
- {"version":3,"file":"folder.js","sources":["models/folder.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Folder model – class folders, hierarchy, contents. Teacher permission checks.\n */\nimport { prisma } from \"../lib/prisma.js\";\n\nconst fileSelect = {\n id: true,\n name: true,\n type: true,\n size: true,\n uploadedAt: true,\n user: { select: { id: true, username: true } },\n};\n\nconst childFolderSelect = {\n id: true,\n name: true,\n color: true,\n _count: { select: { files: true, childFolders: true } },\n};\n\n/** @returns Class if user is a teacher. */\nexport function findClassWithTeacher(classId: string, teacherId: string) {\n return prisma.class.findFirst({\n where: {\n id: classId,\n teachers: { some: { id: teacherId } },\n },\n });\n}\n\n/** @returns Folder by ID. */\nexport function findFolderById(folderId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId },\n });\n}\n\n/** @returns Folder with class. */\nexport function findFolderByIdWithClass(folderId: string) {\n return prisma.folder.findUnique({\n where: { id: folderId },\n include: { class: true },\n });\n}\n\n/** @returns Root folder for a class. */\nexport function findRootFolderByClassId(classId: string) {\n return prisma.folder.findFirst({\n where: {\n classId,\n parentFolderId: null,\n },\n });\n}\n\n/** Get or create root folder for a class. */\nexport async function findOrCreateRootFolder(classId: string) {\n let parent = await findRootFolderByClassId(classId);\n if (!parent) {\n parent = await prisma.folder.create({\n data: {\n name: \"Class Files\",\n class: { connect: { id: classId } },\n },\n });\n }\n return parent;\n}\n\n/** Create a folder. */\nexport function createFolder(data: {\n name: string;\n parentFolderId?: string | null;\n classId?: string;\n color?: string;\n}) {\n return prisma.folder.create({\n data: {\n name: data.name,\n ...(data.parentFolderId && {\n parentFolder: { connect: { id: data.parentFolderId } },\n }),\n ...(data.classId && { class: { connect: { id: data.classId } } }),\n ...(data.color && { color: data.color }),\n },\n include: {\n files: {\n select: fileSelect,\n orderBy: { uploadedAt: \"desc\" as const },\n },\n childFolders: {\n select: childFolderSelect,\n orderBy: { name: \"asc\" as const },\n },\n },\n });\n}\n\nconst folderIncludeWithFiles = {\n files: {\n select: fileSelect,\n orderBy: { uploadedAt: \"desc\" as const },\n },\n childFolders: {\n select: childFolderSelect,\n orderBy: { name: \"asc\" as const },\n },\n parentFolder: { select: { id: true, name: true } },\n};\n\n/** @returns Folder with files and child folders. */\nexport function findFolderWithContents(folderId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId },\n include: folderIncludeWithFiles,\n });\n}\n\n/** @returns Direct child folders. */\nexport function findChildFolders(parentFolderId: string) {\n return prisma.folder.findMany({\n where: { parentFolderId },\n include: {\n files: {\n select: fileSelect,\n orderBy: { uploadedAt: \"desc\" as const },\n },\n childFolders: {\n select: childFolderSelect,\n orderBy: { name: \"asc\" as const },\n },\n },\n orderBy: { name: \"asc\" },\n });\n}\n\n/** @returns Root folder with contents for a class. */\nexport function findRootFolderWithContents(classId: string) {\n return prisma.folder.findFirst({\n where: { classId, parentFolderId: null },\n include: {\n files: {\n select: fileSelect,\n orderBy: { uploadedAt: \"desc\" as const },\n },\n childFolders: {\n select: {\n ...childFolderSelect,\n files: { select: { id: true } },\n childFolders: { select: { id: true } },\n },\n orderBy: { name: \"asc\" as const },\n },\n },\n });\n}\n\n/** @returns Folder with file/folder counts. */\nexport function findFolderWithCount(folderId: string, classId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId, classId },\n include: {\n _count: { select: { files: true, childFolders: true } },\n },\n });\n}\n\n/** @returns Folder with file/folder counts. */\nexport function findFolderByIdWithCount(folderId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId },\n include: {\n _count: { select: { files: true, childFolders: true } },\n },\n });\n}\n\n/** Delete a folder. */\nexport function deleteFolderById(folderId: string) {\n return prisma.folder.delete({\n where: { id: folderId },\n });\n}\n\n/** Move folder to new parent. */\nexport function updateFolderParent(folderId: string, parentFolderId: string) {\n return prisma.folder.update({\n where: { id: folderId },\n data: { parentFolderId },\n include: {\n files: { select: fileSelect },\n childFolders: { select: childFolderSelect },\n },\n });\n}\n\n/** Update folder name and color. */\nexport function updateFolder(\n folderId: string,\n data: { name?: string; color?: string }\n) {\n return prisma.folder.update({\n where: { id: folderId },\n data,\n include: {\n files: { select: fileSelect },\n childFolders: { select: childFolderSelect },\n },\n });\n}\n\n/** @returns Folder for path traversal. */\nexport function findFolderByIdForTraversal(id: string) {\n return prisma.folder.findUnique({\n where: { id },\n });\n}\n\n/** @returns Folder by ID. */\nexport function findFolderParents(folderId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId },\n });\n}\n"],"names":[],"mappings":"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","debug_id":"f914d30a-5901-54ec-9a00-fba86348df0a"}
1
+ {"version":3,"file":"folder.js","sources":["models/folder.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Folder model – class folders, hierarchy, contents. Teacher permission checks.\n */\nimport { prisma } from \"../lib/prisma.js\";\nimport { classTeacherOrSchoolAdminWhere } from \"./access.js\";\n\nconst fileSelect = {\n id: true,\n name: true,\n type: true,\n size: true,\n uploadedAt: true,\n user: { select: { id: true, username: true } },\n};\n\nconst childFolderSelect = {\n id: true,\n name: true,\n color: true,\n _count: { select: { files: true, childFolders: true } },\n};\n\n/** @returns Class if user is a teacher or school admin. */\nexport function findClassWithTeacher(classId: string, teacherId: string) {\n return prisma.class.findFirst({\n where: {\n id: classId,\n ...classTeacherOrSchoolAdminWhere(teacherId),\n },\n });\n}\n\n/** @returns Folder by ID. */\nexport function findFolderById(folderId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId },\n });\n}\n\n/** @returns Folder with class. */\nexport function findFolderByIdWithClass(folderId: string) {\n return prisma.folder.findUnique({\n where: { id: folderId },\n include: { class: true },\n });\n}\n\n/** @returns Root folder for a class. */\nexport function findRootFolderByClassId(classId: string) {\n return prisma.folder.findFirst({\n where: {\n classId,\n parentFolderId: null,\n },\n });\n}\n\n/** Get or create root folder for a class. */\nexport async function findOrCreateRootFolder(classId: string) {\n let parent = await findRootFolderByClassId(classId);\n if (!parent) {\n parent = await prisma.folder.create({\n data: {\n name: \"Class Files\",\n class: { connect: { id: classId } },\n },\n });\n }\n return parent;\n}\n\n/** Create a folder. */\nexport function createFolder(data: {\n name: string;\n parentFolderId?: string | null;\n classId?: string;\n color?: string;\n}) {\n return prisma.folder.create({\n data: {\n name: data.name,\n ...(data.parentFolderId && {\n parentFolder: { connect: { id: data.parentFolderId } },\n }),\n ...(data.classId && { class: { connect: { id: data.classId } } }),\n ...(data.color && { color: data.color }),\n },\n include: {\n files: {\n select: fileSelect,\n orderBy: { uploadedAt: \"desc\" as const },\n },\n childFolders: {\n select: childFolderSelect,\n orderBy: { name: \"asc\" as const },\n },\n },\n });\n}\n\nconst folderIncludeWithFiles = {\n files: {\n select: fileSelect,\n orderBy: { uploadedAt: \"desc\" as const },\n },\n childFolders: {\n select: childFolderSelect,\n orderBy: { name: \"asc\" as const },\n },\n parentFolder: { select: { id: true, name: true } },\n};\n\n/** @returns Folder with files and child folders. */\nexport function findFolderWithContents(folderId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId },\n include: folderIncludeWithFiles,\n });\n}\n\n/** @returns Direct child folders. */\nexport function findChildFolders(parentFolderId: string) {\n return prisma.folder.findMany({\n where: { parentFolderId },\n include: {\n files: {\n select: fileSelect,\n orderBy: { uploadedAt: \"desc\" as const },\n },\n childFolders: {\n select: childFolderSelect,\n orderBy: { name: \"asc\" as const },\n },\n },\n orderBy: { name: \"asc\" },\n });\n}\n\n/** @returns Root folder with contents for a class. */\nexport function findRootFolderWithContents(classId: string) {\n return prisma.folder.findFirst({\n where: { classId, parentFolderId: null },\n include: {\n files: {\n select: fileSelect,\n orderBy: { uploadedAt: \"desc\" as const },\n },\n childFolders: {\n select: {\n ...childFolderSelect,\n files: { select: { id: true } },\n childFolders: { select: { id: true } },\n },\n orderBy: { name: \"asc\" as const },\n },\n },\n });\n}\n\n/** @returns Folder with file/folder counts. */\nexport function findFolderWithCount(folderId: string, classId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId, classId },\n include: {\n _count: { select: { files: true, childFolders: true } },\n },\n });\n}\n\n/** @returns Folder with file/folder counts. */\nexport function findFolderByIdWithCount(folderId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId },\n include: {\n _count: { select: { files: true, childFolders: true } },\n },\n });\n}\n\n/** Delete a folder. */\nexport function deleteFolderById(folderId: string) {\n return prisma.folder.delete({\n where: { id: folderId },\n });\n}\n\n/** Move folder to new parent. */\nexport function updateFolderParent(folderId: string, parentFolderId: string) {\n return prisma.folder.update({\n where: { id: folderId },\n data: { parentFolderId },\n include: {\n files: { select: fileSelect },\n childFolders: { select: childFolderSelect },\n },\n });\n}\n\n/** Update folder name and color. */\nexport function updateFolder(\n folderId: string,\n data: { name?: string; color?: string }\n) {\n return prisma.folder.update({\n where: { id: folderId },\n data,\n include: {\n files: { select: fileSelect },\n childFolders: { select: childFolderSelect },\n },\n });\n}\n\n/** @returns Folder for path traversal. */\nexport function findFolderByIdForTraversal(id: string) {\n return prisma.folder.findUnique({\n where: { id },\n });\n}\n\n/** @returns Folder by ID. */\nexport function findFolderParents(folderId: string) {\n return prisma.folder.findFirst({\n where: { id: folderId },\n });\n}\n"],"names":[],"mappings":"AAAA;;GAEG;;;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,8BAA8B,EAAE,MAAM,aAAa,CAAC;AAE7D,MAAM,UAAU,GAAG;IACjB,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,IAAI;IACV,UAAU,EAAE,IAAI;IAChB,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;CAC/C,CAAC;AAEF,MAAM,iBAAiB,GAAG;IACxB,EAAE,EAAE,IAAI;IACR,IAAI,EAAE,IAAI;IACV,KAAK,EAAE,IAAI;IACX,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE;CACxD,CAAC;AAEF,2DAA2D;AAC3D,MAAM,UAAU,oBAAoB,CAAC,OAAe,EAAE,SAAiB;IACrE,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;QAC5B,KAAK,EAAE;YACL,EAAE,EAAE,OAAO;YACX,GAAG,8BAA8B,CAAC,SAAS,CAAC;SAC7C;KACF,CAAC,CAAC;AACL,CAAC;AAED,6BAA6B;AAC7B,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QAC7B,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;KACxB,CAAC,CAAC;AACL,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;QAC9B,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACvB,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE;KACzB,CAAC,CAAC;AACL,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QAC7B,KAAK,EAAE;YACL,OAAO;YACP,cAAc,EAAE,IAAI;SACrB;KACF,CAAC,CAAC;AACL,CAAC;AAED,6CAA6C;AAC7C,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,OAAe;IAC1D,IAAI,MAAM,GAAG,MAAM,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;YAClC,IAAI,EAAE;gBACJ,IAAI,EAAE,aAAa;gBACnB,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE;aACpC;SACF,CAAC,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,YAAY,CAAC,IAK5B;IACC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAC1B,IAAI,EAAE;YACJ,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI;gBACzB,YAAY,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE;aACvD,CAAC;YACF,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC;YACjE,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;SACzC;QACD,OAAO,EAAE;YACP,KAAK,EAAE;gBACL,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,EAAE,UAAU,EAAE,MAAe,EAAE;aACzC;YACD,YAAY,EAAE;gBACZ,MAAM,EAAE,iBAAiB;gBACzB,OAAO,EAAE,EAAE,IAAI,EAAE,KAAc,EAAE;aAClC;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,sBAAsB,GAAG;IAC7B,KAAK,EAAE;QACL,MAAM,EAAE,UAAU;QAClB,OAAO,EAAE,EAAE,UAAU,EAAE,MAAe,EAAE;KACzC;IACD,YAAY,EAAE;QACZ,MAAM,EAAE,iBAAiB;QACzB,OAAO,EAAE,EAAE,IAAI,EAAE,KAAc,EAAE;KAClC;IACD,YAAY,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;CACnD,CAAC;AAEF,oDAAoD;AACpD,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QAC7B,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACvB,OAAO,EAAE,sBAAsB;KAChC,CAAC,CAAC;AACL,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,gBAAgB,CAAC,cAAsB;IACrD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC5B,KAAK,EAAE,EAAE,cAAc,EAAE;QACzB,OAAO,EAAE;YACP,KAAK,EAAE;gBACL,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,EAAE,UAAU,EAAE,MAAe,EAAE;aACzC;YACD,YAAY,EAAE;gBACZ,MAAM,EAAE,iBAAiB;gBACzB,OAAO,EAAE,EAAE,IAAI,EAAE,KAAc,EAAE;aAClC;SACF;QACD,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;KACzB,CAAC,CAAC;AACL,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,0BAA0B,CAAC,OAAe;IACxD,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QAC7B,KAAK,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE;QACxC,OAAO,EAAE;YACP,KAAK,EAAE;gBACL,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,EAAE,UAAU,EAAE,MAAe,EAAE;aACzC;YACD,YAAY,EAAE;gBACZ,MAAM,EAAE;oBACN,GAAG,iBAAiB;oBACpB,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;oBAC/B,YAAY,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;iBACvC;gBACD,OAAO,EAAE,EAAE,IAAI,EAAE,KAAc,EAAE;aAClC;SACF;KACF,CAAC,CAAC;AACL,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,mBAAmB,CAAC,QAAgB,EAAE,OAAe;IACnE,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QAC7B,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;QAChC,OAAO,EAAE;YACP,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE;SACxD;KACF,CAAC,CAAC;AACL,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,uBAAuB,CAAC,QAAgB;IACtD,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QAC7B,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACvB,OAAO,EAAE;YACP,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE;SACxD;KACF,CAAC,CAAC;AACL,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAC1B,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;KACxB,CAAC,CAAC;AACL,CAAC;AAED,iCAAiC;AACjC,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,cAAsB;IACzE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAC1B,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACvB,IAAI,EAAE,EAAE,cAAc,EAAE;QACxB,OAAO,EAAE;YACP,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;YAC7B,YAAY,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE;SAC5C;KACF,CAAC,CAAC;AACL,CAAC;AAED,oCAAoC;AACpC,MAAM,UAAU,YAAY,CAC1B,QAAgB,EAChB,IAAuC;IAEvC,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAC1B,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;QACvB,IAAI;QACJ,OAAO,EAAE;YACP,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;YAC7B,YAAY,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE;SAC5C;KACF,CAAC,CAAC;AACL,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,0BAA0B,CAAC,EAAU;IACnD,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;QAC9B,KAAK,EAAE,EAAE,EAAE,EAAE;KACd,CAAC,CAAC;AACL,CAAC;AAED,6BAA6B;AAC7B,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;QAC7B,KAAK,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;KACxB,CAAC,CAAC;AACL,CAAC","debug_id":"09a4aeb2-aef9-585f-9480-2197a905014d"}
@@ -1,6 +1,6 @@
1
1
  /** @returns Class with students and teachers for lab creation. */
2
2
  export declare function findClassWithTeachersForLab(classId: string, teacherId: string): import(".prisma/client").Prisma.Prisma__ClassClient<({
3
- students: {
3
+ teachers: {
4
4
  id: string;
5
5
  username: string;
6
6
  profile: {
@@ -8,7 +8,7 @@ export declare function findClassWithTeachersForLab(classId: string, teacherId:
8
8
  profilePicture: string | null;
9
9
  } | null;
10
10
  }[];
11
- teachers: {
11
+ students: {
12
12
  id: string;
13
13
  username: string;
14
14
  profile: {
@@ -51,9 +51,9 @@ export declare function findLabChatByMember(labChatId: string, userId: string):
51
51
  };
52
52
  } & {
53
53
  id: string;
54
+ role: import(".prisma/client").$Enums.ConversationRole;
54
55
  userId: string;
55
56
  conversationId: string;
56
- role: import(".prisma/client").$Enums.ConversationRole;
57
57
  joinedAt: Date;
58
58
  hiddenAt: Date | null;
59
59
  lastViewedAt: Date | null;
@@ -78,11 +78,11 @@ export declare function findLabChatByMember(labChatId: string, userId: string):
78
78
  } & {
79
79
  context: string;
80
80
  id: string;
81
- conversationId: string;
82
81
  createdAt: Date;
82
+ updatedAt: Date;
83
+ conversationId: string;
83
84
  classId: string;
84
85
  title: string;
85
- updatedAt: Date;
86
86
  createdById: string;
87
87
  }) | null, null, import("@prisma/client/runtime/library.js").DefaultArgs, {
88
88
  datasources: {
@@ -91,7 +91,7 @@ export declare function findLabChatByMember(labChatId: string, userId: string):
91
91
  };
92
92
  };
93
93
  }>;
94
- /** @returns Lab chat if user is class teacher. */
94
+ /** @returns Lab chat if user is class teacher or school admin. */
95
95
  export declare function findLabChatByTeacher(labChatId: string, userId: string): import(".prisma/client").Prisma.Prisma__LabChatClient<({
96
96
  conversation: {
97
97
  id: string;
@@ -99,11 +99,11 @@ export declare function findLabChatByTeacher(labChatId: string, userId: string):
99
99
  } & {
100
100
  context: string;
101
101
  id: string;
102
- conversationId: string;
103
102
  createdAt: Date;
103
+ updatedAt: Date;
104
+ conversationId: string;
104
105
  classId: string;
105
106
  title: string;
106
- updatedAt: Date;
107
107
  createdById: string;
108
108
  }) | null, null, import("@prisma/client/runtime/library.js").DefaultArgs, {
109
109
  datasources: {
@@ -132,9 +132,9 @@ export declare function findLabChatById(labChatId: string): import(".prisma/clie
132
132
  };
133
133
  } & {
134
134
  id: string;
135
+ role: import(".prisma/client").$Enums.ConversationRole;
135
136
  userId: string;
136
137
  conversationId: string;
137
- role: import(".prisma/client").$Enums.ConversationRole;
138
138
  joinedAt: Date;
139
139
  hiddenAt: Date | null;
140
140
  lastViewedAt: Date | null;
@@ -159,11 +159,11 @@ export declare function findLabChatById(labChatId: string): import(".prisma/clie
159
159
  } & {
160
160
  context: string;
161
161
  id: string;
162
- conversationId: string;
163
162
  createdAt: Date;
163
+ updatedAt: Date;
164
+ conversationId: string;
164
165
  classId: string;
165
166
  title: string;
166
- updatedAt: Date;
167
167
  createdById: string;
168
168
  }) | null, null, import("@prisma/client/runtime/library.js").DefaultArgs, {
169
169
  datasources: {
@@ -172,7 +172,7 @@ export declare function findLabChatById(labChatId: string): import(".prisma/clie
172
172
  };
173
173
  };
174
174
  }>;
175
- /** @returns Class if user is student or teacher. */
175
+ /** @returns Class if user is student, teacher, or school admin. */
176
176
  export declare function findClassMembership(classId: string, userId: string): import(".prisma/client").Prisma.Prisma__ClassClient<{
177
177
  name: string;
178
178
  id: string;
@@ -206,8 +206,8 @@ export declare function findLabChatsByClass(classId: string): import(".prisma/cl
206
206
  status: import(".prisma/client").$Enums.GenerationStatus | null;
207
207
  meta: import("@prisma/client/runtime/library.js").JsonValue | null;
208
208
  id: string;
209
- conversationId: string;
210
209
  createdAt: Date;
210
+ conversationId: string;
211
211
  content: string;
212
212
  senderId: string;
213
213
  })[];
@@ -229,11 +229,11 @@ export declare function findLabChatsByClass(classId: string): import(".prisma/cl
229
229
  } & {
230
230
  context: string;
231
231
  id: string;
232
- conversationId: string;
233
232
  createdAt: Date;
233
+ updatedAt: Date;
234
+ conversationId: string;
234
235
  classId: string;
235
236
  title: string;
236
- updatedAt: Date;
237
237
  createdById: string;
238
238
  })[]>;
239
239
  /** @returns Lab chat if user can post (member or teacher). */
@@ -244,11 +244,11 @@ export declare function findLabChatForPost(labChatId: string, userId: string): i
244
244
  } & {
245
245
  context: string;
246
246
  id: string;
247
- conversationId: string;
248
247
  createdAt: Date;
248
+ updatedAt: Date;
249
+ conversationId: string;
249
250
  classId: string;
250
251
  title: string;
251
- updatedAt: Date;
252
252
  createdById: string;
253
253
  }) | null, null, import("@prisma/client/runtime/library.js").DefaultArgs, {
254
254
  datasources: {
@@ -261,11 +261,11 @@ export declare function findLabChatForPost(labChatId: string, userId: string): i
261
261
  export declare function findLabChatForDelete(labChatId: string, userId: string): import(".prisma/client").Prisma.Prisma__LabChatClient<{
262
262
  context: string;
263
263
  id: string;
264
- conversationId: string;
265
264
  createdAt: Date;
265
+ updatedAt: Date;
266
+ conversationId: string;
266
267
  classId: string;
267
268
  title: string;
268
- updatedAt: Date;
269
269
  createdById: string;
270
270
  } | null, null, import("@prisma/client/runtime/library.js").DefaultArgs, {
271
271
  datasources: {
@@ -277,9 +277,9 @@ export declare function findLabChatForDelete(labChatId: string, userId: string):
277
277
  /** @returns Conversation members for mentioned user IDs. */
278
278
  export declare function findMentionedMemberships(conversationId: string, userIds: string[]): import(".prisma/client").Prisma.PrismaPromise<{
279
279
  id: string;
280
+ role: import(".prisma/client").$Enums.ConversationRole;
280
281
  userId: string;
281
282
  conversationId: string;
282
- role: import(".prisma/client").$Enums.ConversationRole;
283
283
  joinedAt: Date;
284
284
  hiddenAt: Date | null;
285
285
  lastViewedAt: Date | null;
@@ -1 +1 @@
1
- {"version":3,"file":"labChat.d.ts","sourceRoot":"/","sources":["models/labChat.ts"],"names":[],"mappings":"AAgDA,kEAAkE;AAClE,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiC7E;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpE;AAED,kDAAkD;AAClD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;GAYrE;AAED,+BAA+B;AAC/B,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAKhD;AAED,oDAAoD;AACpD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;GAUlE;AAED,sCAAsC;AACtC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAwClD;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;GAYnE;AAED,sDAAsD;AACtD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;GAOrE;AAED,4DAA4D;AAC5D,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EAAE;;;;;;;;;KAQlB"}
1
+ {"version":3,"file":"labChat.d.ts","sourceRoot":"/","sources":["models/labChat.ts"],"names":[],"mappings":"AAoDA,kEAAkE;AAClE,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiC7E;AAED,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAUpE;AAED,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;GAYrE;AAED,+BAA+B;AAC/B,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAKhD;AAED,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;GAOlE;AAED,sCAAsC;AACtC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAwClD;AAED,8DAA8D;AAC9D,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;GAYnE;AAED,sDAAsD;AACtD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;GAOrE;AAED,4DAA4D;AAC5D,wBAAgB,wBAAwB,CACtC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,MAAM,EAAE;;;;;;;;;KAQlB"}
@@ -2,8 +2,9 @@
2
2
  * Lab chat model – AI lab conversations, members, posts. Teacher/student access.
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]="682f7005-c4c4-57cf-a5b6-e52ba1abe288")}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]="f519e035-445f-5c41-80c4-de7dd81d94e2")}catch(e){}}();
6
6
  import { prisma } from "../lib/prisma.js";
7
+ import { classMemberOrSchoolAdminWhere, classTeacherOrSchoolAdminWhere, } from "./access.js";
7
8
  const labChatInclude = {
8
9
  conversation: {
9
10
  include: {
@@ -51,7 +52,7 @@ export function findClassWithTeachersForLab(classId, teacherId) {
51
52
  return prisma.class.findFirst({
52
53
  where: {
53
54
  id: classId,
54
- teachers: { some: { id: teacherId } },
55
+ ...classTeacherOrSchoolAdminWhere(teacherId),
55
56
  },
56
57
  include: {
57
58
  students: {
@@ -93,13 +94,13 @@ export function findLabChatByMember(labChatId, userId) {
93
94
  include: labChatInclude,
94
95
  });
95
96
  }
96
- /** @returns Lab chat if user is class teacher. */
97
+ /** @returns Lab chat if user is class teacher or school admin. */
97
98
  export function findLabChatByTeacher(labChatId, userId) {
98
99
  return prisma.labChat.findFirst({
99
100
  where: {
100
101
  id: labChatId,
101
102
  class: {
102
- teachers: { some: { id: userId } },
103
+ ...classTeacherOrSchoolAdminWhere(userId),
103
104
  },
104
105
  },
105
106
  include: {
@@ -114,15 +115,12 @@ export function findLabChatById(labChatId) {
114
115
  include: labChatInclude,
115
116
  });
116
117
  }
117
- /** @returns Class if user is student or teacher. */
118
+ /** @returns Class if user is student, teacher, or school admin. */
118
119
  export function findClassMembership(classId, userId) {
119
120
  return prisma.class.findFirst({
120
121
  where: {
121
122
  id: classId,
122
- OR: [
123
- { students: { some: { id: userId } } },
124
- { teachers: { some: { id: userId } } },
125
- ],
123
+ ...classMemberOrSchoolAdminWhere(userId),
126
124
  },
127
125
  });
128
126
  }
@@ -201,4 +199,4 @@ export function findMentionedMemberships(conversationId, userIds) {
201
199
  });
202
200
  }
203
201
  //# sourceMappingURL=labChat.js.map
204
- //# debugId=682f7005-c4c4-57cf-a5b6-e52ba1abe288
202
+ //# debugId=f519e035-445f-5c41-80c4-de7dd81d94e2
@@ -1 +1 @@
1
- {"version":3,"file":"labChat.js","sources":["models/labChat.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Lab chat model – AI lab conversations, members, posts. Teacher/student access.\n */\nimport { prisma } from \"../lib/prisma.js\";\n\nconst labChatInclude = {\n conversation: {\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n },\n },\n },\n createdBy: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n class: {\n select: {\n id: true,\n name: true,\n subject: true,\n section: true,\n },\n },\n};\n\n/** @returns Class with students and teachers for lab creation. */\nexport function findClassWithTeachersForLab(classId: string, teacherId: string) {\n return prisma.class.findFirst({\n where: {\n id: classId,\n teachers: { some: { id: teacherId } },\n },\n include: {\n students: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n teachers: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n });\n}\n\n/** @returns Lab chat if user is a conversation member. */\nexport function findLabChatByMember(labChatId: string, userId: string) {\n return prisma.labChat.findFirst({\n where: {\n id: labChatId,\n conversation: {\n members: { some: { userId } },\n },\n },\n include: labChatInclude,\n });\n}\n\n/** @returns Lab chat if user is class teacher. */\nexport function findLabChatByTeacher(labChatId: string, userId: string) {\n return prisma.labChat.findFirst({\n where: {\n id: labChatId,\n class: {\n teachers: { some: { id: userId } },\n },\n },\n include: {\n conversation: { select: { id: true } },\n },\n });\n}\n\n/** @returns Lab chat by ID. */\nexport function findLabChatById(labChatId: string) {\n return prisma.labChat.findFirst({\n where: { id: labChatId },\n include: labChatInclude,\n });\n}\n\n/** @returns Class if user is student or teacher. */\nexport function findClassMembership(classId: string, userId: string) {\n return prisma.class.findFirst({\n where: {\n id: classId,\n OR: [\n { students: { some: { id: userId } } },\n { teachers: { some: { id: userId } } },\n ],\n },\n });\n}\n\n/** @returns Lab chats for a class. */\nexport function findLabChatsByClass(classId: string) {\n return prisma.labChat.findMany({\n where: { classId },\n include: {\n createdBy: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n },\n },\n },\n },\n conversation: {\n include: {\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: {\n select: {\n displayName: true,\n },\n },\n },\n },\n },\n },\n _count: { select: { messages: true } },\n },\n },\n },\n orderBy: { createdAt: \"desc\" as const },\n });\n}\n\n/** @returns Lab chat if user can post (member or teacher). */\nexport function findLabChatForPost(labChatId: string, userId: string) {\n return prisma.labChat.findFirst({\n where: {\n id: labChatId,\n conversation: {\n members: { some: { userId } },\n },\n },\n include: {\n conversation: { select: { id: true } },\n },\n });\n}\n\n/** @returns Lab chat if user can delete (teacher). */\nexport function findLabChatForDelete(labChatId: string, userId: string) {\n return prisma.labChat.findFirst({\n where: {\n id: labChatId,\n createdById: userId,\n },\n });\n}\n\n/** @returns Conversation members for mentioned user IDs. */\nexport function findMentionedMemberships(\n conversationId: string,\n userIds: string[]\n) {\n return prisma.conversationMember.findMany({\n where: {\n conversationId,\n userId: { in: userIds },\n },\n });\n}\n"],"names":[],"mappings":"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","debug_id":"682f7005-c4c4-57cf-a5b6-e52ba1abe288"}
1
+ {"version":3,"file":"labChat.js","sources":["models/labChat.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Lab chat model – AI lab conversations, members, posts. Teacher/student access.\n */\nimport { prisma } from \"../lib/prisma.js\";\nimport {\n classMemberOrSchoolAdminWhere,\n classTeacherOrSchoolAdminWhere,\n} from \"./access.js\";\n\nconst labChatInclude = {\n conversation: {\n include: {\n members: {\n include: {\n user: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n },\n },\n },\n createdBy: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n class: {\n select: {\n id: true,\n name: true,\n subject: true,\n section: true,\n },\n },\n};\n\n/** @returns Class with students and teachers for lab creation. */\nexport function findClassWithTeachersForLab(classId: string, teacherId: string) {\n return prisma.class.findFirst({\n where: {\n id: classId,\n ...classTeacherOrSchoolAdminWhere(teacherId),\n },\n include: {\n students: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n teachers: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n },\n },\n },\n },\n },\n });\n}\n\n/** @returns Lab chat if user is a conversation member. */\nexport function findLabChatByMember(labChatId: string, userId: string) {\n return prisma.labChat.findFirst({\n where: {\n id: labChatId,\n conversation: {\n members: { some: { userId } },\n },\n },\n include: labChatInclude,\n });\n}\n\n/** @returns Lab chat if user is class teacher or school admin. */\nexport function findLabChatByTeacher(labChatId: string, userId: string) {\n return prisma.labChat.findFirst({\n where: {\n id: labChatId,\n class: {\n ...classTeacherOrSchoolAdminWhere(userId),\n },\n },\n include: {\n conversation: { select: { id: true } },\n },\n });\n}\n\n/** @returns Lab chat by ID. */\nexport function findLabChatById(labChatId: string) {\n return prisma.labChat.findFirst({\n where: { id: labChatId },\n include: labChatInclude,\n });\n}\n\n/** @returns Class if user is student, teacher, or school admin. */\nexport function findClassMembership(classId: string, userId: string) {\n return prisma.class.findFirst({\n where: {\n id: classId,\n ...classMemberOrSchoolAdminWhere(userId),\n },\n });\n}\n\n/** @returns Lab chats for a class. */\nexport function findLabChatsByClass(classId: string) {\n return prisma.labChat.findMany({\n where: { classId },\n include: {\n createdBy: {\n select: {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n },\n },\n },\n },\n conversation: {\n include: {\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: {\n select: {\n displayName: true,\n },\n },\n },\n },\n },\n },\n _count: { select: { messages: true } },\n },\n },\n },\n orderBy: { createdAt: \"desc\" as const },\n });\n}\n\n/** @returns Lab chat if user can post (member or teacher). */\nexport function findLabChatForPost(labChatId: string, userId: string) {\n return prisma.labChat.findFirst({\n where: {\n id: labChatId,\n conversation: {\n members: { some: { userId } },\n },\n },\n include: {\n conversation: { select: { id: true } },\n },\n });\n}\n\n/** @returns Lab chat if user can delete (teacher). */\nexport function findLabChatForDelete(labChatId: string, userId: string) {\n return prisma.labChat.findFirst({\n where: {\n id: labChatId,\n createdById: userId,\n },\n });\n}\n\n/** @returns Conversation members for mentioned user IDs. */\nexport function findMentionedMemberships(\n conversationId: string,\n userIds: string[]\n) {\n return prisma.conversationMember.findMany({\n where: {\n conversationId,\n userId: { in: userIds },\n },\n });\n}\n"],"names":[],"mappings":"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","debug_id":"f519e035-445f-5c41-80c4-de7dd81d94e2"}
@@ -77,8 +77,8 @@ export declare function createEarlyAccessRequest(data: {
77
77
  institutionSize: string;
78
78
  }): import(".prisma/client").Prisma.Prisma__EarlyAccessRequestClient<{
79
79
  id: string;
80
- email: string;
81
80
  createdAt: Date;
81
+ email: string;
82
82
  institutionSize: string;
83
83
  }, never, import("@prisma/client/runtime/library.js").DefaultArgs, {
84
84
  datasources: {
@@ -1,9 +1,9 @@
1
1
  /** @returns User's membership in a conversation. */
2
2
  export declare function findConversationMembership(conversationId: string, userId: string): import(".prisma/client").Prisma.Prisma__ConversationMemberClient<{
3
3
  id: string;
4
+ role: import(".prisma/client").$Enums.ConversationRole;
4
5
  userId: string;
5
6
  conversationId: string;
6
- role: import(".prisma/client").$Enums.ConversationRole;
7
7
  joinedAt: Date;
8
8
  hiddenAt: Date | null;
9
9
  lastViewedAt: Date | null;
@@ -30,9 +30,9 @@ export declare function findMessages(conversationId: string, options: {
30
30
  };
31
31
  } & {
32
32
  id: string;
33
+ createdAt: Date;
33
34
  userId: string;
34
35
  messageId: string;
35
- createdAt: Date;
36
36
  })[];
37
37
  attachments: {
38
38
  type: string;
@@ -51,17 +51,17 @@ export declare function findMessages(conversationId: string, options: {
51
51
  status: import(".prisma/client").$Enums.GenerationStatus | null;
52
52
  meta: import("@prisma/client/runtime/library.js").JsonValue | null;
53
53
  id: string;
54
- conversationId: string;
55
54
  createdAt: Date;
55
+ conversationId: string;
56
56
  content: string;
57
57
  senderId: string;
58
58
  })[]>;
59
59
  /** @returns Memberships for mentioned users. */
60
60
  export declare function findMentionedMemberships(conversationId: string, userIds: string[]): import(".prisma/client").Prisma.PrismaPromise<{
61
61
  id: string;
62
+ role: import(".prisma/client").$Enums.ConversationRole;
62
63
  userId: string;
63
64
  conversationId: string;
64
- role: import(".prisma/client").$Enums.ConversationRole;
65
65
  joinedAt: Date;
66
66
  hiddenAt: Date | null;
67
67
  lastViewedAt: Date | null;
@@ -81,8 +81,8 @@ export declare function findMessageById(messageId: string): import(".prisma/clie
81
81
  status: import(".prisma/client").$Enums.GenerationStatus | null;
82
82
  meta: import("@prisma/client/runtime/library.js").JsonValue | null;
83
83
  id: string;
84
- conversationId: string;
85
84
  createdAt: Date;
85
+ conversationId: string;
86
86
  content: string;
87
87
  senderId: string;
88
88
  }) | null, null, import("@prisma/client/runtime/library.js").DefaultArgs, {
@@ -102,8 +102,8 @@ export declare function findMessageByIdMinimal(messageId: string): import(".pris
102
102
  status: import(".prisma/client").$Enums.GenerationStatus | null;
103
103
  meta: import("@prisma/client/runtime/library.js").JsonValue | null;
104
104
  id: string;
105
- conversationId: string;
106
105
  createdAt: Date;
106
+ conversationId: string;
107
107
  content: string;
108
108
  senderId: string;
109
109
  }) | null, null, import("@prisma/client/runtime/library.js").DefaultArgs, {