@studious-lms/server 1.4.1 → 1.4.3

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 (248) hide show
  1. package/.coderabbit.yaml +4 -1
  2. package/.env.example +6 -0
  3. package/.env.test.example +2 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +101 -76
  6. package/dist/index.js.map +1 -1
  7. package/dist/lib/config/cors.d.ts +16 -0
  8. package/dist/lib/config/cors.d.ts.map +1 -0
  9. package/dist/lib/config/cors.js +75 -0
  10. package/dist/lib/config/cors.js.map +1 -0
  11. package/dist/lib/config/env.d.ts +14 -0
  12. package/dist/lib/config/env.d.ts.map +1 -1
  13. package/dist/lib/config/env.js +9 -2
  14. package/dist/lib/config/env.js.map +1 -1
  15. package/dist/lib/fileUpload.d.ts +10 -2
  16. package/dist/lib/fileUpload.d.ts.map +1 -1
  17. package/dist/lib/fileUpload.js +38 -6
  18. package/dist/lib/fileUpload.js.map +1 -1
  19. package/dist/lib/prisma.d.ts +14 -2
  20. package/dist/lib/prisma.d.ts.map +1 -1
  21. package/dist/lib/prisma.js +27 -8
  22. package/dist/lib/prisma.js.map +1 -1
  23. package/dist/middleware/auth.d.ts.map +1 -1
  24. package/dist/middleware/auth.js +18 -5
  25. package/dist/middleware/auth.js.map +1 -1
  26. package/dist/middleware/security.d.ts.map +1 -1
  27. package/dist/middleware/security.js +3 -3
  28. package/dist/middleware/security.js.map +1 -1
  29. package/dist/models/agenda.d.ts +16 -16
  30. package/dist/models/announcement.d.ts +59 -23
  31. package/dist/models/announcement.d.ts.map +1 -1
  32. package/dist/models/assignment.d.ts +363 -276
  33. package/dist/models/assignment.d.ts.map +1 -1
  34. package/dist/models/attendance.d.ts +63 -21
  35. package/dist/models/attendance.d.ts.map +1 -1
  36. package/dist/models/auth.d.ts +115 -26
  37. package/dist/models/auth.d.ts.map +1 -1
  38. package/dist/models/auth.js +53 -30
  39. package/dist/models/auth.js.map +1 -1
  40. package/dist/models/class.d.ts +115 -65
  41. package/dist/models/class.d.ts.map +1 -1
  42. package/dist/models/class.js +16 -4
  43. package/dist/models/class.js.map +1 -1
  44. package/dist/models/comment.d.ts +52 -16
  45. package/dist/models/comment.d.ts.map +1 -1
  46. package/dist/models/conversation.d.ts +46 -16
  47. package/dist/models/conversation.d.ts.map +1 -1
  48. package/dist/models/event.d.ts +107 -53
  49. package/dist/models/event.d.ts.map +1 -1
  50. package/dist/models/file.d.ts +213 -165
  51. package/dist/models/file.d.ts.map +1 -1
  52. package/dist/models/folder.d.ts +161 -77
  53. package/dist/models/folder.d.ts.map +1 -1
  54. package/dist/models/labChat.d.ts +73 -31
  55. package/dist/models/labChat.d.ts.map +1 -1
  56. package/dist/models/marketing.d.ts +25 -7
  57. package/dist/models/marketing.d.ts.map +1 -1
  58. package/dist/models/message.d.ts +31 -13
  59. package/dist/models/message.d.ts.map +1 -1
  60. package/dist/models/newtonChat.d.ts +34 -10
  61. package/dist/models/newtonChat.d.ts.map +1 -1
  62. package/dist/models/notification.d.ts +29 -10
  63. package/dist/models/notification.d.ts.map +1 -1
  64. package/dist/models/notification.js +13 -9
  65. package/dist/models/notification.js.map +1 -1
  66. package/dist/models/section.d.ts +71 -23
  67. package/dist/models/section.d.ts.map +1 -1
  68. package/dist/models/user.d.ts +27 -9
  69. package/dist/models/user.d.ts.map +1 -1
  70. package/dist/models/worksheet.d.ts +606 -106
  71. package/dist/models/worksheet.d.ts.map +1 -1
  72. package/dist/models/worksheet.js +168 -2
  73. package/dist/models/worksheet.js.map +1 -1
  74. package/dist/pipelines/aiLabChat.d.ts +22 -2
  75. package/dist/pipelines/aiLabChat.d.ts.map +1 -1
  76. package/dist/pipelines/aiLabChat.js +133 -95
  77. package/dist/pipelines/aiLabChat.js.map +1 -1
  78. package/dist/pipelines/aiLabChatContract.d.ts +25 -25
  79. package/dist/pipelines/aiNewtonChat.d.ts.map +1 -1
  80. package/dist/pipelines/aiNewtonChat.js +25 -14
  81. package/dist/pipelines/aiNewtonChat.js.map +1 -1
  82. package/dist/pipelines/gradeWorksheet.d.ts +8 -8
  83. package/dist/pipelines/gradeWorksheet.d.ts.map +1 -1
  84. package/dist/pipelines/gradeWorksheet.js +12 -5
  85. package/dist/pipelines/gradeWorksheet.js.map +1 -1
  86. package/dist/pipelines/labChatPrompt.d.ts +27 -0
  87. package/dist/pipelines/labChatPrompt.d.ts.map +1 -1
  88. package/dist/pipelines/labChatPrompt.js +143 -69
  89. package/dist/pipelines/labChatPrompt.js.map +1 -1
  90. package/dist/routers/_app.d.ts +1579 -1257
  91. package/dist/routers/_app.d.ts.map +1 -1
  92. package/dist/routers/agenda.d.ts +16 -16
  93. package/dist/routers/announcement.d.ts +19 -19
  94. package/dist/routers/assignment.d.ts +307 -291
  95. package/dist/routers/assignment.d.ts.map +1 -1
  96. package/dist/routers/assignment.js +3 -2
  97. package/dist/routers/assignment.js.map +1 -1
  98. package/dist/routers/attendance.d.ts +7 -7
  99. package/dist/routers/auth.d.ts +1 -1
  100. package/dist/routers/class.d.ts +79 -72
  101. package/dist/routers/class.d.ts.map +1 -1
  102. package/dist/routers/class.js +3 -3
  103. package/dist/routers/class.js.map +1 -1
  104. package/dist/routers/comment.d.ts +6 -6
  105. package/dist/routers/conversation.d.ts +11 -11
  106. package/dist/routers/event.d.ts +35 -35
  107. package/dist/routers/file.d.ts +12 -12
  108. package/dist/routers/folder.d.ts +54 -54
  109. package/dist/routers/labChat.d.ts +18 -12
  110. package/dist/routers/labChat.d.ts.map +1 -1
  111. package/dist/routers/labChat.js +5 -3
  112. package/dist/routers/labChat.js.map +1 -1
  113. package/dist/routers/marketing.d.ts +2 -2
  114. package/dist/routers/message.d.ts +33 -2
  115. package/dist/routers/message.d.ts.map +1 -1
  116. package/dist/routers/message.js +27 -4
  117. package/dist/routers/message.js.map +1 -1
  118. package/dist/routers/newtonChat.d.ts +7 -1
  119. package/dist/routers/newtonChat.d.ts.map +1 -1
  120. package/dist/routers/newtonChat.js +5 -4
  121. package/dist/routers/newtonChat.js.map +1 -1
  122. package/dist/routers/notifications.d.ts +13 -6
  123. package/dist/routers/notifications.d.ts.map +1 -1
  124. package/dist/routers/notifications.js +4 -4
  125. package/dist/routers/notifications.js.map +1 -1
  126. package/dist/routers/section.d.ts +7 -7
  127. package/dist/routers/studentProgress.d.ts +86 -0
  128. package/dist/routers/studentProgress.d.ts.map +1 -1
  129. package/dist/routers/studentProgress.js +14 -4
  130. package/dist/routers/studentProgress.js.map +1 -1
  131. package/dist/routers/user.d.ts +1 -1
  132. package/dist/routers/worksheet.d.ts +64 -62
  133. package/dist/routers/worksheet.d.ts.map +1 -1
  134. package/dist/routers/worksheet.js +18 -16
  135. package/dist/routers/worksheet.js.map +1 -1
  136. package/dist/seedDatabase.d.ts +1 -1
  137. package/dist/services/agenda.d.ts +16 -16
  138. package/dist/services/announcement.d.ts +8 -8
  139. package/dist/services/assignment.d.ts +299 -283
  140. package/dist/services/assignment.d.ts.map +1 -1
  141. package/dist/services/assignment.js +24 -5
  142. package/dist/services/assignment.js.map +1 -1
  143. package/dist/services/attendance.d.ts +7 -7
  144. package/dist/services/auth.d.ts +2 -2
  145. package/dist/services/auth.d.ts.map +1 -1
  146. package/dist/services/auth.js +19 -12
  147. package/dist/services/auth.js.map +1 -1
  148. package/dist/services/class.d.ts +74 -68
  149. package/dist/services/class.d.ts.map +1 -1
  150. package/dist/services/class.js +6 -3
  151. package/dist/services/class.js.map +1 -1
  152. package/dist/services/comment.d.ts +6 -6
  153. package/dist/services/conversation.d.ts +11 -11
  154. package/dist/services/event.d.ts +31 -31
  155. package/dist/services/file.d.ts +12 -12
  156. package/dist/services/file.d.ts.map +1 -1
  157. package/dist/services/file.js +7 -2
  158. package/dist/services/file.js.map +1 -1
  159. package/dist/services/folder.d.ts +52 -52
  160. package/dist/services/labChat.d.ts +18 -12
  161. package/dist/services/labChat.d.ts.map +1 -1
  162. package/dist/services/labChat.js +30 -18
  163. package/dist/services/labChat.js.map +1 -1
  164. package/dist/services/marketing.d.ts +2 -2
  165. package/dist/services/message.d.ts +30 -0
  166. package/dist/services/message.d.ts.map +1 -1
  167. package/dist/services/message.js +97 -21
  168. package/dist/services/message.js.map +1 -1
  169. package/dist/services/newtonChat.d.ts +6 -1
  170. package/dist/services/newtonChat.d.ts.map +1 -1
  171. package/dist/services/newtonChat.js +36 -18
  172. package/dist/services/newtonChat.js.map +1 -1
  173. package/dist/services/notification.d.ts +16 -9
  174. package/dist/services/notification.d.ts.map +1 -1
  175. package/dist/services/notification.js +24 -9
  176. package/dist/services/notification.js.map +1 -1
  177. package/dist/services/section.d.ts +6 -6
  178. package/dist/services/studentProgress.d.ts +75 -0
  179. package/dist/services/studentProgress.d.ts.map +1 -1
  180. package/dist/services/studentProgress.js +300 -107
  181. package/dist/services/studentProgress.js.map +1 -1
  182. package/dist/services/worksheet.d.ts +64 -64
  183. package/dist/services/worksheet.d.ts.map +1 -1
  184. package/dist/services/worksheet.js +138 -54
  185. package/dist/services/worksheet.js.map +1 -1
  186. package/dist/trpc.d.ts.map +1 -1
  187. package/dist/trpc.js +11 -17
  188. package/dist/trpc.js.map +1 -1
  189. package/dist/utils/inference.d.ts +9 -12
  190. package/dist/utils/inference.d.ts.map +1 -1
  191. package/dist/utils/inference.js +135 -95
  192. package/dist/utils/inference.js.map +1 -1
  193. package/package.json +1 -1
  194. package/prisma/migrations/20260410124000_add_submission_recommendation_state/migration.sql +14 -0
  195. package/prisma/migrations/20260415103500_add_session_type/migration.sql +33 -0
  196. package/prisma/migrations/20260415133000_add_ai_usage_logs/migration.sql +19 -0
  197. package/prisma/schema.prisma +41 -1
  198. package/scripts/test-pre-push.ts +6 -2
  199. package/src/index.ts +119 -79
  200. package/src/lib/config/cors.ts +96 -0
  201. package/src/lib/config/env.ts +12 -1
  202. package/src/lib/fileUpload.ts +55 -5
  203. package/src/lib/prisma.ts +25 -6
  204. package/src/middleware/auth.ts +19 -4
  205. package/src/middleware/security.ts +1 -1
  206. package/src/models/auth.ts +59 -29
  207. package/src/models/class.ts +15 -4
  208. package/src/models/notification.ts +13 -7
  209. package/src/models/worksheet.ts +202 -0
  210. package/src/pipelines/aiLabChat.ts +183 -104
  211. package/src/pipelines/aiNewtonChat.ts +24 -14
  212. package/src/pipelines/gradeWorksheet.ts +10 -2
  213. package/src/pipelines/labChatPrompt.ts +196 -68
  214. package/src/routers/assignment.ts +1 -0
  215. package/src/routers/class.ts +2 -2
  216. package/src/routers/labChat.ts +3 -1
  217. package/src/routers/message.ts +38 -1
  218. package/src/routers/newtonChat.ts +4 -2
  219. package/src/routers/notifications.ts +2 -2
  220. package/src/routers/studentProgress.ts +25 -1
  221. package/src/routers/worksheet.ts +31 -19
  222. package/src/services/assignment.ts +30 -2
  223. package/src/services/auth.ts +26 -12
  224. package/src/services/class.ts +4 -1
  225. package/src/services/file.ts +6 -0
  226. package/src/services/labChat.ts +42 -18
  227. package/src/services/message.ts +163 -18
  228. package/src/services/newtonChat.ts +49 -18
  229. package/src/services/notification.ts +27 -8
  230. package/src/services/studentProgress.ts +425 -121
  231. package/src/services/worksheet.ts +191 -51
  232. package/src/trpc.ts +12 -18
  233. package/src/utils/inference.ts +205 -112
  234. package/tests/globalSetup.ts +13 -4
  235. package/tests/lib/cors.test.ts +103 -0
  236. package/tests/pipelines/aiLabChat.test.ts +64 -84
  237. package/tests/routers/auth.test.ts +120 -17
  238. package/tests/routers/class.test.ts +7 -1
  239. package/tests/routers/message.test.ts +236 -9
  240. package/tests/routers/newtonChat.test.ts +81 -0
  241. package/tests/routers/notification.test.ts +12 -0
  242. package/tests/routers/studentProgress.test.ts +2 -31
  243. package/tests/routers/worksheet.test.ts +194 -0
  244. package/tests/setup.ts +22 -5
  245. package/tests/utils/aiLabChatPrompt.test.ts +114 -6
  246. package/tests/utils/inference.test.ts +218 -0
  247. package/tests/utils/studentProgress.test.ts +361 -0
  248. package/vitest.unit.config.ts +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"class.js","sources":["services/class.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Class service – CRUD for classes, members, grades, mark schemes, grading boundaries,\n * syllabus, lab drafts, and invite codes.\n */\nimport { TRPCError } from \"@trpc/server\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { generateInviteCode } from \"../utils/generateInviteCode.js\";\nimport {\n findTeacherClasses,\n findStudentClasses,\n isTeacherInClass,\n findClassWithAssignments,\n findSectionsByClassId,\n findUserById,\n findSessionByClassCode,\n findSessionByClassId,\n findSubmissionsForGrades,\n findEventsByClassId,\n findMarkSchemesByClassId,\n findGradingBoundariesByClassId,\n findClassSyllabus,\n findLabDraftsByClass,\n findAssignmentsWithFiles,\n findFullExportableClass,\n createClassByImport,\n} from \"../models/class.js\";\nimport { Class, Folder } from \"@prisma/client\";\n\n/** Get all classes where user is teacher or student, with assignments and members. */\nexport async function getAllClasses(userId: string) {\n const [teacherClasses, studentClasses] = await Promise.all([\n findTeacherClasses(userId),\n findStudentClasses(userId),\n ]);\n\n return {\n teacherInClass: teacherClasses.map((cls) => ({\n id: cls.id,\n name: cls.name,\n section: cls.section,\n subject: cls.subject,\n dueToday: cls.assignments,\n assignments: cls.assignments,\n members: [...cls.students, ...cls.teachers],\n color: cls.color,\n })),\n studentInClass: studentClasses.map((cls) => ({\n id: cls.id,\n name: cls.name,\n section: cls.section,\n subject: cls.subject,\n dueToday: cls.assignments,\n assignments: cls.assignments,\n members: [...cls.students, ...cls.teachers],\n color: cls.color,\n })),\n };\n}\n\n/** Get single class with assignments, sections, and submission status. */\nexport async function getClass(userId: string, classId: string) {\n const isTeacher = await isTeacherInClass(classId, userId ?? \"\");\n\n const classData = await findClassWithAssignments(classId, {\n isTeacher: !!isTeacher,\n userId: userId ?? undefined,\n });\n\n if (!classData) {\n throw new Error(\"Class not found\");\n }\n\n const formattedClassData = {\n ...classData,\n assignments: classData.assignments.map((assignment) => ({\n ...assignment,\n late: assignment.dueDate < new Date(),\n submitted: assignment.submissions.find(\n (s) => s.studentId === userId\n )?.submitted,\n returned: assignment.submissions.find(\n (s) => s.studentId === userId\n )?.returned,\n })),\n };\n\n const sections = await findSectionsByClassId(classId);\n\n return {\n class: {\n ...formattedClassData,\n sections,\n },\n };\n}\n\nexport async function updateClass(\n classId: string,\n data: { name?: string; section?: string; subject?: string }\n) {\n const updatedClass = await prisma.class.update({\n where: { id: classId },\n data,\n select: {\n id: true,\n name: true,\n section: true,\n subject: true,\n },\n });\n return { updatedClass };\n}\n\nexport async function createClass(\n userId: string,\n input: {\n students?: string[];\n teachers?: string[];\n name: string;\n section: string;\n subject: string;\n color?: string;\n }\n) {\n const { students, teachers, name, section, subject, color } = input;\n\n if (teachers && teachers.length > 0 && students && students.length > 0) {\n return prisma.class.create({\n data: {\n name,\n section,\n subject,\n color,\n teachers: { connect: teachers.map((id) => ({ id })) },\n students: { connect: students.map((id) => ({ id })) },\n },\n include: { teachers: true, students: true },\n });\n }\n\n return prisma.class.create({\n data: {\n name,\n section,\n subject,\n color,\n teachers: { connect: { id: userId } },\n },\n });\n}\n\nexport async function deleteClass(classId: string) {\n const classToDelete = await prisma.class.findFirst({\n where: { id: classId },\n });\n\n if (!classToDelete) {\n throw new Error(\"Class not found or you don't have permission to delete it\");\n }\n\n await prisma.class.delete({\n where: { id: classId },\n });\n\n return { deletedClass: { id: classId } };\n}\n\nexport async function addStudent(classId: string, studentId: string) {\n const student = await findUserById(studentId);\n if (!student) {\n throw new Error(\"Student not found\");\n }\n\n const updatedClass = await prisma.class.update({\n where: { id: classId },\n data: {\n students: { connect: { id: studentId } },\n },\n select: {\n id: true,\n name: true,\n section: true,\n subject: true,\n },\n });\n\n return { updatedClass, newStudent: student };\n}\n\nexport async function changeRole(\n classId: string,\n userId: string,\n type: \"teacher\" | \"student\"\n) {\n const user = await findUserById(userId);\n if (!user) {\n throw new Error(\"User not found\");\n }\n\n const updatedClass = await prisma.class.update({\n where: { id: classId },\n data: {\n [type === \"teacher\" ? \"teachers\" : \"students\"]: {\n connect: { id: userId },\n },\n [type === \"teacher\" ? \"students\" : \"teachers\"]: {\n disconnect: { id: userId },\n },\n },\n });\n\n return {\n updatedClass,\n user: { ...user, type },\n };\n}\n\nexport async function removeMember(classId: string, userId: string) {\n const updatedClass = await prisma.class.update({\n where: { id: classId },\n data: {\n teachers: { disconnect: { id: userId } },\n students: { disconnect: { id: userId } },\n },\n });\n return { updatedClass, removedUserId: userId };\n}\n\nexport async function leaveClass(userId: string, classId: string) {\n const classData = await prisma.class.findFirst({\n where: {\n id: classId,\n students: { some: { id: userId } },\n },\n });\n\n if (!classData) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Class not found or you are not a student in this class\",\n });\n }\n\n await prisma.class.update({\n where: { id: classId },\n data: {\n students: { disconnect: { id: userId } },\n },\n });\n\n return { success: true, leftClassId: classId };\n}\n\nexport async function joinClass(userId: string, classCode: string) {\n const session = await findSessionByClassCode(classCode);\n\n if (!session || !session.classId) {\n throw new Error(\"Class not found\");\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n throw new Error(\"Session expired\");\n }\n\n const updatedClass = await prisma.class.update({\n where: { id: session.classId },\n data: {\n students: { connect: { id: userId } },\n },\n select: {\n id: true,\n name: true,\n section: true,\n subject: true,\n },\n });\n\n return { joinedClass: updatedClass };\n}\n\nexport async function getInviteCode(classId: string) {\n const session = await findSessionByClassId(classId);\n\n if ((session?.expiresAt && session.expiresAt < new Date()) || !session) {\n const newSession = await prisma.session.create({\n data: {\n id: generateInviteCode(),\n classId,\n expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),\n },\n });\n return { code: newSession.id };\n }\n\n return { code: session?.id };\n}\n\nexport async function createInviteCode(classId: string) {\n await prisma.session.deleteMany({\n where: { classId },\n });\n\n const session = await prisma.session.create({\n data: {\n id: generateInviteCode(),\n classId,\n expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),\n },\n });\n\n return { code: session.id };\n}\n\nexport async function getGrades(\n userId: string,\n classId: string,\n targetUserId: string\n) {\n const isTeacher = await isTeacherInClass(classId, userId);\n if (userId !== targetUserId && !isTeacher) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You can only view your own grades\",\n });\n }\n\n const grades = await findSubmissionsForGrades(targetUserId, classId);\n return { grades };\n}\n\nexport async function updateGrade(\n assignmentId: string,\n submissionId: string,\n gradeReceived: number | null\n) {\n const updatedSubmission = await prisma.submission.update({\n where: { id: submissionId, assignmentId },\n data: { gradeReceived },\n include: {\n assignment: {\n select: {\n id: true,\n title: true,\n maxGrade: true,\n weight: true,\n },\n },\n },\n });\n return updatedSubmission;\n}\n\nexport async function getEvents(classId: string) {\n return findEventsByClassId(classId);\n}\n\nexport async function listMarkSchemes(classId: string) {\n return findMarkSchemesByClassId(classId);\n}\n\nexport async function createMarkScheme(classId: string, structure: string) {\n const validatedStructure = structure.replace(/\\\\n/g, \"\\n\");\n return prisma.markScheme.create({\n data: {\n class: { connect: { id: classId } },\n structured: validatedStructure,\n },\n });\n}\n\nexport async function updateMarkScheme(\n markSchemeId: string,\n classId: string,\n structure: string\n) {\n const validatedStructure = structure.replace(/\\\\n/g, \"\\n\");\n return prisma.markScheme.update({\n where: { id: markSchemeId },\n data: {\n class: { connect: { id: classId } },\n structured: validatedStructure,\n },\n });\n}\n\nexport async function deleteMarkScheme(markSchemeId: string) {\n return prisma.markScheme.delete({\n where: { id: markSchemeId },\n });\n}\n\nexport async function listGradingBoundaries(classId: string) {\n return findGradingBoundariesByClassId(classId);\n}\n\nexport async function createGradingBoundary(classId: string, structure: string) {\n const validatedStructure = structure.replace(/\\\\n/g, \"\\n\");\n return prisma.gradingBoundary.create({\n data: {\n class: { connect: { id: classId } },\n structured: validatedStructure,\n },\n });\n}\n\nexport async function updateGradingBoundary(\n gradingBoundaryId: string,\n classId: string,\n structure: string\n) {\n const validatedStructure = structure.replace(/\\\\n/g, \"\\n\");\n return prisma.gradingBoundary.update({\n where: { id: gradingBoundaryId },\n data: {\n class: { connect: { id: classId } },\n structured: validatedStructure,\n },\n });\n}\n\nexport async function deleteGradingBoundary(gradingBoundaryId: string) {\n return prisma.gradingBoundary.delete({\n where: { id: gradingBoundaryId },\n });\n}\n\nexport async function getSyllabus(classId: string) {\n const classData = await findClassSyllabus(classId);\n const markSchemes = await findMarkSchemesByClassId(classId);\n const gradingBoundaries = await findGradingBoundariesByClassId(classId);\n return {\n syllabus: classData?.syllabus,\n gradingBoundaries,\n markSchemes,\n };\n}\n\nexport async function updateSyllabus(classId: string, contents: string) {\n if (!contents) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Missing key contents\",\n });\n }\n return prisma.class.update({\n where: { id: classId },\n data: { syllabus: contents },\n });\n}\n\nexport async function listLabDrafts(classId: string, teacherId: string) {\n return findLabDraftsByClass(classId, teacherId);\n}\n\nexport async function createLabDraft(\n classId: string,\n teacherId: string,\n input: {\n title: string;\n type: string;\n instructions: string;\n dueDate?: Date;\n maxGrade?: number;\n weight?: number;\n graded?: boolean;\n sectionId?: string;\n markSchemeId?: string;\n gradingBoundaryId?: string;\n }\n) {\n return prisma.assignment.create({\n data: {\n classId,\n teacherId,\n inProgress: true,\n graded: input.graded ?? false,\n maxGrade: input.maxGrade ?? 0,\n weight: input.weight ?? 1,\n dueDate:\n input.dueDate ||\n new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),\n title: input.title,\n instructions: input.instructions,\n type: input.type as any,\n ...(input.sectionId && { sectionId: input.sectionId }),\n ...(input.markSchemeId && { markSchemeId: input.markSchemeId }),\n ...(input.gradingBoundaryId && {\n gradingBoundaryId: input.gradingBoundaryId,\n }),\n },\n });\n}\n\nexport async function updateLabDraft(\n classId: string,\n teacherId: string,\n draftId: string,\n input: Record<string, unknown>\n) {\n const updateData: Record<string, unknown> = {\n modifiedAt: new Date(),\n };\n if (input.title !== undefined) updateData.title = input.title;\n if (input.instructions !== undefined)\n updateData.instructions = input.instructions;\n if (input.dueDate !== undefined) updateData.dueDate = input.dueDate;\n if (input.maxGrade !== undefined) updateData.maxGrade = input.maxGrade;\n if (input.weight !== undefined) updateData.weight = input.weight;\n if (input.graded !== undefined) updateData.graded = input.graded;\n if (input.sectionId !== undefined) updateData.sectionId = input.sectionId;\n if (input.markSchemeId !== undefined)\n updateData.markSchemeId = input.markSchemeId;\n if (input.gradingBoundaryId !== undefined)\n updateData.gradingBoundaryId = input.gradingBoundaryId;\n\n return prisma.assignment.update({\n where: {\n id: draftId,\n classId,\n teacherId,\n inProgress: true,\n },\n data: updateData as any,\n });\n}\n\nexport async function deleteLabDraft(\n classId: string,\n teacherId: string,\n draftId: string\n) {\n return prisma.assignment.delete({\n where: {\n id: draftId,\n classId,\n teacherId,\n inProgress: true,\n },\n });\n}\n\nexport async function publishLabDraft(\n classId: string,\n teacherId: string,\n draftId: string,\n input: {\n dueDate?: Date;\n maxGrade?: number;\n weight?: number;\n graded?: boolean;\n }\n) {\n const labDraft = await prisma.assignment.findUnique({\n where: {\n id: draftId,\n classId,\n teacherId,\n inProgress: true,\n },\n });\n\n if (!labDraft) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Lab draft not found\",\n });\n }\n\n return prisma.assignment.update({\n where: { id: draftId },\n data: {\n inProgress: false,\n dueDate: input.dueDate || labDraft.dueDate,\n maxGrade: input.maxGrade || labDraft.maxGrade || 100,\n weight: input.weight || labDraft.weight || 1,\n graded: input.graded !== undefined ? input.graded : true,\n modifiedAt: new Date(),\n },\n });\n}\n\nexport async function getFiles(classId: string) {\n const assignments = await findAssignmentsWithFiles(classId);\n return assignments.map((assignment) => ({\n id: assignment.id,\n title: assignment.title,\n teacher: assignment.teacher,\n teacherAttachments: assignment.attachments,\n students: assignment.submissions.map((submission) => ({\n id: submission.student.id,\n username: submission.student.username,\n attachments: submission.attachments,\n annotations: submission.annotations,\n })),\n }));\n}\n\nexport async function exportClass(classId: string, userId: string) {\n const classExport = await findFullExportableClass(classId);\n if (!classExport) {\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"Failed to export class\",\n });\n }\n\n return classExport;\n}\n\nexport async function importClass(classId: string, userId: string, year: number, classData: Class & { classFiles: Folder | null }) {\n try {\n const newClassId = await createClassByImport(classId, userId, year, classData);\n if (!newClassId) {\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"Failed to import class\",\n });\n }\n return newClassId;\n } catch (err) {\n if (err instanceof TRPCError) throw err;\n const message = err instanceof Error ? err.message : \"Unknown error\";\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: `Failed to import class: ${message}`,\n cause: err,\n });\n }\n}"],"names":[],"mappings":"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","debug_id":"f6a97cb7-783f-56a4-ae40-1d145ee5c1ee"}
1
+ {"version":3,"file":"class.js","sources":["services/class.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Class service – CRUD for classes, members, grades, mark schemes, grading boundaries,\n * syllabus, lab drafts, and invite codes.\n */\nimport { SessionType } from \"@prisma/client\";\nimport { TRPCError } from \"@trpc/server\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { generateInviteCode } from \"../utils/generateInviteCode.js\";\nimport {\n findTeacherClasses,\n findStudentClasses,\n isTeacherInClass,\n findClassWithAssignments,\n findSectionsByClassId,\n findUserById,\n findSessionByClassCode,\n findSessionByClassId,\n findSubmissionsForGrades,\n findEventsByClassId,\n findMarkSchemesByClassId,\n findGradingBoundariesByClassId,\n findClassSyllabus,\n findLabDraftsByClass,\n findAssignmentsWithFiles,\n findFullExportableClass,\n createClassByImport,\n} from \"../models/class.js\";\nimport { Class, Folder } from \"@prisma/client\";\n\n/** Get all classes where user is teacher or student, with assignments and members. */\nexport async function getAllClasses(userId: string) {\n const [teacherClasses, studentClasses] = await Promise.all([\n findTeacherClasses(userId),\n findStudentClasses(userId),\n ]);\n\n return {\n teacherInClass: teacherClasses.map((cls) => ({\n id: cls.id,\n name: cls.name,\n section: cls.section,\n subject: cls.subject,\n dueToday: cls.assignments,\n assignments: cls.assignments,\n members: [...cls.students, ...cls.teachers],\n color: cls.color,\n })),\n studentInClass: studentClasses.map((cls) => ({\n id: cls.id,\n name: cls.name,\n section: cls.section,\n subject: cls.subject,\n dueToday: cls.assignments,\n assignments: cls.assignments,\n members: [...cls.students, ...cls.teachers],\n color: cls.color,\n })),\n };\n}\n\n/** Get single class with assignments, sections, and submission status. */\nexport async function getClass(userId: string, classId: string) {\n const isTeacher = await isTeacherInClass(classId, userId ?? \"\");\n\n const classData = await findClassWithAssignments(classId, {\n isTeacher: !!isTeacher,\n userId: userId ?? undefined,\n });\n\n if (!classData) {\n throw new Error(\"Class not found\");\n }\n\n const formattedClassData = {\n ...classData,\n assignments: classData.assignments.map((assignment) => ({\n ...assignment,\n late: assignment.dueDate < new Date(),\n submitted: assignment.submissions.find(\n (s) => s.studentId === userId\n )?.submitted,\n returned: assignment.submissions.find(\n (s) => s.studentId === userId\n )?.returned,\n })),\n };\n\n const sections = await findSectionsByClassId(classId);\n\n return {\n class: {\n ...formattedClassData,\n sections,\n },\n };\n}\n\nexport async function updateClass(\n classId: string,\n data: { name?: string; section?: string; subject?: string }\n) {\n const updatedClass = await prisma.class.update({\n where: { id: classId },\n data,\n select: {\n id: true,\n name: true,\n section: true,\n subject: true,\n },\n });\n return { updatedClass };\n}\n\nexport async function createClass(\n userId: string,\n input: {\n students?: string[];\n teachers?: string[];\n name: string;\n section: string;\n subject: string;\n color?: string;\n }\n) {\n const { students, teachers, name, section, subject, color } = input;\n\n if (teachers && teachers.length > 0 && students && students.length > 0) {\n return prisma.class.create({\n data: {\n name,\n section,\n subject,\n color,\n teachers: { connect: teachers.map((id) => ({ id })) },\n students: { connect: students.map((id) => ({ id })) },\n },\n include: { teachers: true, students: true },\n });\n }\n\n return prisma.class.create({\n data: {\n name,\n section,\n subject,\n color,\n teachers: { connect: { id: userId } },\n },\n });\n}\n\nexport async function deleteClass(classId: string) {\n const classToDelete = await prisma.class.findFirst({\n where: { id: classId },\n });\n\n if (!classToDelete) {\n throw new Error(\"Class not found or you don't have permission to delete it\");\n }\n\n await prisma.class.delete({\n where: { id: classId },\n });\n\n return { deletedClass: { id: classId } };\n}\n\nexport async function addStudent(classId: string, studentId: string) {\n const student = await findUserById(studentId);\n if (!student) {\n throw new Error(\"Student not found\");\n }\n\n const updatedClass = await prisma.class.update({\n where: { id: classId },\n data: {\n students: { connect: { id: studentId } },\n },\n select: {\n id: true,\n name: true,\n section: true,\n subject: true,\n },\n });\n\n return { updatedClass, newStudent: student };\n}\n\nexport async function changeRole(\n classId: string,\n userId: string,\n type: \"teacher\" | \"student\"\n) {\n const user = await findUserById(userId);\n if (!user) {\n throw new Error(\"User not found\");\n }\n\n const updatedClass = await prisma.class.update({\n where: { id: classId },\n data: {\n [type === \"teacher\" ? \"teachers\" : \"students\"]: {\n connect: { id: userId },\n },\n [type === \"teacher\" ? \"students\" : \"teachers\"]: {\n disconnect: { id: userId },\n },\n },\n });\n\n return {\n updatedClass,\n user: { ...user, type },\n };\n}\n\nexport async function removeMember(classId: string, userId: string) {\n const updatedClass = await prisma.class.update({\n where: { id: classId },\n data: {\n teachers: { disconnect: { id: userId } },\n students: { disconnect: { id: userId } },\n },\n });\n return { updatedClass, removedUserId: userId };\n}\n\nexport async function leaveClass(userId: string, classId: string) {\n const classData = await prisma.class.findFirst({\n where: {\n id: classId,\n students: { some: { id: userId } },\n },\n });\n\n if (!classData) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Class not found or you are not a student in this class\",\n });\n }\n\n await prisma.class.update({\n where: { id: classId },\n data: {\n students: { disconnect: { id: userId } },\n },\n });\n\n return { success: true, leftClassId: classId };\n}\n\nexport async function joinClass(userId: string, classCode: string) {\n const session = await findSessionByClassCode(classCode);\n\n if (!session || !session.classId) {\n throw new Error(\"Class not found\");\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n throw new Error(\"Session expired\");\n }\n\n const updatedClass = await prisma.class.update({\n where: { id: session.classId },\n data: {\n students: { connect: { id: userId } },\n },\n select: {\n id: true,\n name: true,\n section: true,\n subject: true,\n },\n });\n\n return { joinedClass: updatedClass };\n}\n\nexport async function getInviteCode(classId: string) {\n const session = await findSessionByClassId(classId);\n\n if ((session?.expiresAt && session.expiresAt < new Date()) || !session) {\n const newSession = await prisma.session.create({\n data: {\n id: generateInviteCode(),\n classId,\n type: SessionType.CLASS_INVITE,\n expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),\n },\n });\n return { code: newSession.id };\n }\n\n return { code: session?.id };\n}\n\nexport async function createInviteCode(classId: string) {\n await prisma.session.deleteMany({\n where: { classId, type: SessionType.CLASS_INVITE },\n });\n\n const session = await prisma.session.create({\n data: {\n id: generateInviteCode(),\n classId,\n type: SessionType.CLASS_INVITE,\n expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),\n },\n });\n\n return { code: session.id };\n}\n\nexport async function getGrades(\n userId: string,\n classId: string,\n targetUserId: string\n) {\n const isTeacher = await isTeacherInClass(classId, userId);\n if (userId !== targetUserId && !isTeacher) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You can only view your own grades\",\n });\n }\n\n const grades = await findSubmissionsForGrades(targetUserId, classId);\n return { grades };\n}\n\nexport async function updateGrade(\n assignmentId: string,\n submissionId: string,\n gradeReceived: number | null\n) {\n const updatedSubmission = await prisma.submission.update({\n where: { id: submissionId, assignmentId },\n data: { gradeReceived },\n include: {\n assignment: {\n select: {\n id: true,\n title: true,\n maxGrade: true,\n weight: true,\n },\n },\n },\n });\n return updatedSubmission;\n}\n\nexport async function getEvents(classId: string) {\n return findEventsByClassId(classId);\n}\n\nexport async function listMarkSchemes(classId: string) {\n return findMarkSchemesByClassId(classId);\n}\n\nexport async function createMarkScheme(classId: string, structure: string) {\n const validatedStructure = structure.replace(/\\\\n/g, \"\\n\");\n return prisma.markScheme.create({\n data: {\n class: { connect: { id: classId } },\n structured: validatedStructure,\n },\n });\n}\n\nexport async function updateMarkScheme(\n markSchemeId: string,\n classId: string,\n structure: string\n) {\n const validatedStructure = structure.replace(/\\\\n/g, \"\\n\");\n return prisma.markScheme.update({\n where: { id: markSchemeId },\n data: {\n class: { connect: { id: classId } },\n structured: validatedStructure,\n },\n });\n}\n\nexport async function deleteMarkScheme(markSchemeId: string) {\n return prisma.markScheme.delete({\n where: { id: markSchemeId },\n });\n}\n\nexport async function listGradingBoundaries(classId: string) {\n return findGradingBoundariesByClassId(classId);\n}\n\nexport async function createGradingBoundary(classId: string, structure: string) {\n const validatedStructure = structure.replace(/\\\\n/g, \"\\n\");\n return prisma.gradingBoundary.create({\n data: {\n class: { connect: { id: classId } },\n structured: validatedStructure,\n },\n });\n}\n\nexport async function updateGradingBoundary(\n gradingBoundaryId: string,\n classId: string,\n structure: string\n) {\n const validatedStructure = structure.replace(/\\\\n/g, \"\\n\");\n return prisma.gradingBoundary.update({\n where: { id: gradingBoundaryId },\n data: {\n class: { connect: { id: classId } },\n structured: validatedStructure,\n },\n });\n}\n\nexport async function deleteGradingBoundary(gradingBoundaryId: string) {\n return prisma.gradingBoundary.delete({\n where: { id: gradingBoundaryId },\n });\n}\n\nexport async function getSyllabus(classId: string) {\n const classData = await findClassSyllabus(classId);\n const markSchemes = await findMarkSchemesByClassId(classId);\n const gradingBoundaries = await findGradingBoundariesByClassId(classId);\n return {\n syllabus: classData?.syllabus,\n gradingBoundaries,\n markSchemes,\n };\n}\n\nexport async function updateSyllabus(classId: string, contents: string) {\n if (!contents) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Missing key contents\",\n });\n }\n return prisma.class.update({\n where: { id: classId },\n data: { syllabus: contents },\n });\n}\n\nexport async function listLabDrafts(classId: string, teacherId: string) {\n return findLabDraftsByClass(classId, teacherId);\n}\n\nexport async function createLabDraft(\n classId: string,\n teacherId: string,\n input: {\n title: string;\n type: string;\n instructions: string;\n dueDate?: Date;\n maxGrade?: number;\n weight?: number;\n graded?: boolean;\n sectionId?: string;\n markSchemeId?: string;\n gradingBoundaryId?: string;\n }\n) {\n return prisma.assignment.create({\n data: {\n classId,\n teacherId,\n inProgress: true,\n graded: input.graded ?? false,\n maxGrade: input.maxGrade ?? 0,\n weight: input.weight ?? 1,\n dueDate:\n input.dueDate ||\n new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),\n title: input.title,\n instructions: input.instructions,\n type: input.type as any,\n ...(input.sectionId && { sectionId: input.sectionId }),\n ...(input.markSchemeId && { markSchemeId: input.markSchemeId }),\n ...(input.gradingBoundaryId && {\n gradingBoundaryId: input.gradingBoundaryId,\n }),\n },\n });\n}\n\nexport async function updateLabDraft(\n classId: string,\n teacherId: string,\n draftId: string,\n input: Record<string, unknown>\n) {\n const updateData: Record<string, unknown> = {\n modifiedAt: new Date(),\n };\n if (input.title !== undefined) updateData.title = input.title;\n if (input.instructions !== undefined)\n updateData.instructions = input.instructions;\n if (input.dueDate !== undefined) updateData.dueDate = input.dueDate;\n if (input.maxGrade !== undefined) updateData.maxGrade = input.maxGrade;\n if (input.weight !== undefined) updateData.weight = input.weight;\n if (input.graded !== undefined) updateData.graded = input.graded;\n if (input.sectionId !== undefined) updateData.sectionId = input.sectionId;\n if (input.markSchemeId !== undefined)\n updateData.markSchemeId = input.markSchemeId;\n if (input.gradingBoundaryId !== undefined)\n updateData.gradingBoundaryId = input.gradingBoundaryId;\n\n return prisma.assignment.update({\n where: {\n id: draftId,\n classId,\n teacherId,\n inProgress: true,\n },\n data: updateData as any,\n });\n}\n\nexport async function deleteLabDraft(\n classId: string,\n teacherId: string,\n draftId: string\n) {\n return prisma.assignment.delete({\n where: {\n id: draftId,\n classId,\n teacherId,\n inProgress: true,\n },\n });\n}\n\nexport async function publishLabDraft(\n classId: string,\n teacherId: string,\n draftId: string,\n input: {\n dueDate?: Date;\n maxGrade?: number;\n weight?: number;\n graded?: boolean;\n }\n) {\n const labDraft = await prisma.assignment.findUnique({\n where: {\n id: draftId,\n classId,\n teacherId,\n inProgress: true,\n },\n });\n\n if (!labDraft) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Lab draft not found\",\n });\n }\n\n return prisma.assignment.update({\n where: { id: draftId },\n data: {\n inProgress: false,\n dueDate: input.dueDate || labDraft.dueDate,\n maxGrade: input.maxGrade || labDraft.maxGrade || 100,\n weight: input.weight || labDraft.weight || 1,\n graded: input.graded !== undefined ? input.graded : true,\n modifiedAt: new Date(),\n },\n });\n}\n\nexport async function getFiles(classId: string) {\n const assignments = await findAssignmentsWithFiles(classId);\n return assignments.map((assignment) => ({\n id: assignment.id,\n title: assignment.title,\n teacher: assignment.teacher,\n teacherAttachments: assignment.attachments,\n students: assignment.submissions.map((submission) => ({\n id: submission.student.id,\n username: submission.student.username,\n attachments: submission.attachments,\n annotations: submission.annotations,\n })),\n }));\n}\n\nexport async function exportClass(classId: string, userId: string) {\n const classExport = await findFullExportableClass(classId);\n if (!classExport) {\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"Failed to export class\",\n });\n }\n\n return classExport;\n}\n\nexport async function importClass(classId: string, userId: string, year: number, classData: Class & { classFiles: Folder | null }) {\n try {\n const newClassId = await createClassByImport(classId, userId, year, classData);\n if (!newClassId) {\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"Failed to import class\",\n });\n }\n return newClassId;\n } catch (err) {\n if (err instanceof TRPCError) throw err;\n const message = err instanceof Error ? err.message : \"Unknown error\";\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: `Failed to import class: ${message}`,\n cause: err,\n });\n }\n}"],"names":[],"mappings":"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","debug_id":"b0980742-2fbe-5c12-897f-ba5bf6ed98c4"}
@@ -14,8 +14,8 @@ export declare function getComment(id: string): Promise<{
14
14
  };
15
15
  }[];
16
16
  createdAt: Date;
17
- content: string;
18
17
  modifiedAt: Date | null;
18
+ content: string;
19
19
  author: {
20
20
  id: string;
21
21
  username: string;
@@ -40,10 +40,10 @@ export declare function getReplies(commentId: string): Promise<({
40
40
  } & {
41
41
  status: import(".prisma/client").$Enums.GenerationStatus | null;
42
42
  id: string;
43
+ announcementId: string | null;
43
44
  createdAt: Date;
44
- content: string;
45
45
  modifiedAt: Date | null;
46
- announcementId: string | null;
46
+ content: string;
47
47
  authorId: string;
48
48
  parentCommentId: string | null;
49
49
  studentQuestionProgressId: string | null;
@@ -52,10 +52,10 @@ export declare function getReplies(commentId: string): Promise<({
52
52
  export declare function replyToComment(userId: string, parentCommentId: string, content: string): Promise<{
53
53
  status: import(".prisma/client").$Enums.GenerationStatus | null;
54
54
  id: string;
55
+ announcementId: string | null;
55
56
  createdAt: Date;
56
- content: string;
57
57
  modifiedAt: Date | null;
58
- announcementId: string | null;
58
+ content: string;
59
59
  authorId: string;
60
60
  parentCommentId: string | null;
61
61
  studentQuestionProgressId: string | null;
@@ -76,8 +76,8 @@ export declare function addReaction(userId: string, commentId: string, type: str
76
76
  type: import(".prisma/client").$Enums.ReactionType;
77
77
  id: string;
78
78
  userId: string;
79
- createdAt: Date;
80
79
  announcementId: string | null;
80
+ createdAt: Date;
81
81
  commentId: string | null;
82
82
  };
83
83
  }>;
@@ -20,9 +20,9 @@ export declare function listConversations(userId: string): Promise<{
20
20
  };
21
21
  } & {
22
22
  id: string;
23
- role: import(".prisma/client").$Enums.ConversationRole;
24
23
  userId: string;
25
24
  conversationId: string;
25
+ role: import(".prisma/client").$Enums.ConversationRole;
26
26
  joinedAt: Date;
27
27
  lastViewedAt: Date | null;
28
28
  lastViewedMentionAt: Date | null;
@@ -37,11 +37,11 @@ export declare function listConversations(userId: string): Promise<{
37
37
  };
38
38
  } & {
39
39
  status: import(".prisma/client").$Enums.GenerationStatus | null;
40
+ meta: import("@prisma/client/runtime/library.js").JsonValue | null;
40
41
  id: string;
42
+ conversationId: string;
41
43
  createdAt: Date;
42
- meta: import("@prisma/client/runtime/library.js").JsonValue | null;
43
44
  content: string;
44
- conversationId: string;
45
45
  senderId: string;
46
46
  };
47
47
  unreadCount: number;
@@ -60,19 +60,19 @@ export declare function createConversationRecord(userId: string, type: "DM" | "G
60
60
  };
61
61
  } & {
62
62
  id: string;
63
- role: import(".prisma/client").$Enums.ConversationRole;
64
63
  userId: string;
65
64
  conversationId: string;
65
+ role: import(".prisma/client").$Enums.ConversationRole;
66
66
  joinedAt: Date;
67
67
  lastViewedAt: Date | null;
68
68
  lastViewedMentionAt: Date | null;
69
69
  })[];
70
70
  } & {
71
71
  type: import(".prisma/client").$Enums.ConversationType;
72
+ name: string | null;
72
73
  id: string;
73
74
  createdAt: Date;
74
75
  updatedAt: Date;
75
- name: string | null;
76
76
  displayInChat: boolean;
77
77
  }>;
78
78
  export declare function getConversation(userId: string, conversationId: string): Promise<{
@@ -87,19 +87,19 @@ export declare function getConversation(userId: string, conversationId: string):
87
87
  };
88
88
  } & {
89
89
  id: string;
90
- role: import(".prisma/client").$Enums.ConversationRole;
91
90
  userId: string;
92
91
  conversationId: string;
92
+ role: import(".prisma/client").$Enums.ConversationRole;
93
93
  joinedAt: Date;
94
94
  lastViewedAt: Date | null;
95
95
  lastViewedMentionAt: Date | null;
96
96
  })[];
97
97
  } & {
98
98
  type: import(".prisma/client").$Enums.ConversationType;
99
+ name: string | null;
99
100
  id: string;
100
101
  createdAt: Date;
101
102
  updatedAt: Date;
102
- name: string | null;
103
103
  displayInChat: boolean;
104
104
  }>;
105
105
  export declare function addMemberToConversation(userId: string, conversationId: string, memberUsername: string): Promise<{
@@ -114,19 +114,19 @@ export declare function addMemberToConversation(userId: string, conversationId:
114
114
  };
115
115
  } & {
116
116
  id: string;
117
- role: import(".prisma/client").$Enums.ConversationRole;
118
117
  userId: string;
119
118
  conversationId: string;
119
+ role: import(".prisma/client").$Enums.ConversationRole;
120
120
  joinedAt: Date;
121
121
  lastViewedAt: Date | null;
122
122
  lastViewedMentionAt: Date | null;
123
123
  })[];
124
124
  } & {
125
125
  type: import(".prisma/client").$Enums.ConversationType;
126
+ name: string | null;
126
127
  id: string;
127
128
  createdAt: Date;
128
129
  updatedAt: Date;
129
- name: string | null;
130
130
  displayInChat: boolean;
131
131
  }>;
132
132
  export declare function removeMemberFromConversation(userId: string, conversationId: string, memberId: string): Promise<{
@@ -141,19 +141,19 @@ export declare function removeMemberFromConversation(userId: string, conversatio
141
141
  };
142
142
  } & {
143
143
  id: string;
144
- role: import(".prisma/client").$Enums.ConversationRole;
145
144
  userId: string;
146
145
  conversationId: string;
146
+ role: import(".prisma/client").$Enums.ConversationRole;
147
147
  joinedAt: Date;
148
148
  lastViewedAt: Date | null;
149
149
  lastViewedMentionAt: Date | null;
150
150
  })[];
151
151
  } & {
152
152
  type: import(".prisma/client").$Enums.ConversationType;
153
+ name: string | null;
153
154
  id: string;
154
155
  createdAt: Date;
155
156
  updatedAt: Date;
156
- name: string | null;
157
157
  displayInChat: boolean;
158
158
  }>;
159
159
  //# sourceMappingURL=conversation.d.ts.map
@@ -11,9 +11,9 @@ export declare function getEvent(userId: string, id: string): Promise<{
11
11
  schoolId: string | null;
12
12
  } | null;
13
13
  class: {
14
+ name: string;
14
15
  id: string;
15
16
  schoolId: string | null;
16
- name: string;
17
17
  subject: string;
18
18
  color: string | null;
19
19
  section: string;
@@ -23,14 +23,14 @@ export declare function getEvent(userId: string, id: string): Promise<{
23
23
  type: import(".prisma/client").$Enums.AssignmentType;
24
24
  id: string;
25
25
  section: {
26
- id: string;
27
26
  name: string;
27
+ id: string;
28
28
  } | null;
29
29
  title: string;
30
- dueDate: Date;
31
- maxGrade: number | null;
32
30
  instructions: string;
31
+ dueDate: Date;
33
32
  graded: boolean;
33
+ maxGrade: number | null;
34
34
  weight: number;
35
35
  teacher: {
36
36
  id: string;
@@ -38,19 +38,19 @@ export declare function getEvent(userId: string, id: string): Promise<{
38
38
  };
39
39
  attachments: {
40
40
  type: string;
41
- id: string;
42
41
  name: string;
42
+ id: string;
43
43
  }[];
44
44
  }[];
45
45
  } & {
46
+ name: string | null;
46
47
  id: string;
47
48
  userId: string | null;
48
- location: string | null;
49
- classId: string | null;
50
- name: string | null;
51
49
  color: string | null;
50
+ classId: string | null;
52
51
  startTime: Date;
53
52
  endTime: Date;
53
+ location: string | null;
54
54
  remarks: string | null;
55
55
  };
56
56
  }>;
@@ -65,18 +65,18 @@ export declare function createEventRecord(userId: string, input: {
65
65
  color?: string;
66
66
  }): Promise<{
67
67
  event: {
68
+ name: string | null;
68
69
  id: string;
69
70
  userId: string | null;
70
- location: string | null;
71
- classId: string | null;
72
71
  class: {
73
- id: string;
74
72
  name: string;
73
+ id: string;
75
74
  } | null;
76
- name: string | null;
77
75
  color: string | null;
76
+ classId: string | null;
78
77
  startTime: Date;
79
78
  endTime: Date;
79
+ location: string | null;
80
80
  remarks: string | null;
81
81
  };
82
82
  }>;
@@ -90,14 +90,14 @@ export declare function updateEventRecord(userId: string, id: string, data: {
90
90
  classId?: string;
91
91
  }): Promise<{
92
92
  event: {
93
+ name: string | null;
93
94
  id: string;
94
95
  userId: string | null;
95
- location: string | null;
96
- classId: string | null;
97
- name: string | null;
98
96
  color: string | null;
97
+ classId: string | null;
99
98
  startTime: Date;
100
99
  endTime: Date;
100
+ location: string | null;
101
101
  remarks: string | null;
102
102
  };
103
103
  }>;
@@ -107,8 +107,8 @@ export declare function deleteEventRecord(userId: string, id: string): Promise<{
107
107
  export declare function attachAssignment(userId: string, eventId: string, assignmentId: string): Promise<{
108
108
  assignment: {
109
109
  section: {
110
- id: string;
111
110
  name: string;
111
+ id: string;
112
112
  } | null;
113
113
  teacher: {
114
114
  id: string;
@@ -116,20 +116,18 @@ export declare function attachAssignment(userId: string, eventId: string, assign
116
116
  };
117
117
  attachments: {
118
118
  type: string;
119
- id: string;
120
119
  name: string;
120
+ id: string;
121
121
  }[];
122
122
  } & {
123
123
  type: import(".prisma/client").$Enums.AssignmentType;
124
124
  id: string;
125
125
  createdAt: Date | null;
126
+ modifiedAt: Date | null;
126
127
  classId: string;
127
128
  title: string;
128
- dueDate: Date;
129
- maxGrade: number | null;
130
- eventId: string | null;
131
129
  instructions: string;
132
- modifiedAt: Date | null;
130
+ dueDate: Date;
133
131
  teacherId: string;
134
132
  acceptFiles: boolean;
135
133
  acceptExtendedResponse: boolean;
@@ -138,9 +136,11 @@ export declare function attachAssignment(userId: string, eventId: string, assign
138
136
  aiPolicyLevel: number;
139
137
  sectionId: string | null;
140
138
  graded: boolean;
139
+ maxGrade: number | null;
141
140
  weight: number;
142
141
  inProgress: boolean;
143
142
  template: boolean;
143
+ eventId: string | null;
144
144
  markSchemeId: string | null;
145
145
  order: number | null;
146
146
  gradingBoundaryId: string | null;
@@ -149,8 +149,8 @@ export declare function attachAssignment(userId: string, eventId: string, assign
149
149
  export declare function detachAssignment(userId: string, eventId: string, assignmentId: string): Promise<{
150
150
  assignment: {
151
151
  section: {
152
- id: string;
153
152
  name: string;
153
+ id: string;
154
154
  } | null;
155
155
  teacher: {
156
156
  id: string;
@@ -158,20 +158,18 @@ export declare function detachAssignment(userId: string, eventId: string, assign
158
158
  };
159
159
  attachments: {
160
160
  type: string;
161
- id: string;
162
161
  name: string;
162
+ id: string;
163
163
  }[];
164
164
  } & {
165
165
  type: import(".prisma/client").$Enums.AssignmentType;
166
166
  id: string;
167
167
  createdAt: Date | null;
168
+ modifiedAt: Date | null;
168
169
  classId: string;
169
170
  title: string;
170
- dueDate: Date;
171
- maxGrade: number | null;
172
- eventId: string | null;
173
171
  instructions: string;
174
- modifiedAt: Date | null;
172
+ dueDate: Date;
175
173
  teacherId: string;
176
174
  acceptFiles: boolean;
177
175
  acceptExtendedResponse: boolean;
@@ -180,9 +178,11 @@ export declare function detachAssignment(userId: string, eventId: string, assign
180
178
  aiPolicyLevel: number;
181
179
  sectionId: string | null;
182
180
  graded: boolean;
181
+ maxGrade: number | null;
183
182
  weight: number;
184
183
  inProgress: boolean;
185
184
  template: boolean;
185
+ eventId: string | null;
186
186
  markSchemeId: string | null;
187
187
  order: number | null;
188
188
  gradingBoundaryId: string | null;
@@ -193,14 +193,14 @@ export declare function getAvailableAssignments(userId: string, eventId: string)
193
193
  type: import(".prisma/client").$Enums.AssignmentType;
194
194
  id: string;
195
195
  section: {
196
- id: string;
197
196
  name: string;
197
+ id: string;
198
198
  } | null;
199
199
  title: string;
200
- dueDate: Date;
201
- maxGrade: number | null;
202
200
  instructions: string;
201
+ dueDate: Date;
203
202
  graded: boolean;
203
+ maxGrade: number | null;
204
204
  weight: number;
205
205
  teacher: {
206
206
  id: string;
@@ -208,8 +208,8 @@ export declare function getAvailableAssignments(userId: string, eventId: string)
208
208
  };
209
209
  attachments: {
210
210
  type: string;
211
- id: string;
212
211
  name: string;
212
+ id: string;
213
213
  }[];
214
214
  }[];
215
215
  }>;
@@ -10,15 +10,11 @@ export declare function moveFile(fileId: string, targetFolderId: string): Promis
10
10
  } & {
11
11
  path: string;
12
12
  type: string;
13
- id: string;
14
- userId: string | null;
15
13
  name: string;
14
+ id: string;
16
15
  size: number | null;
16
+ userId: string | null;
17
17
  uploadedAt: Date | null;
18
- assignmentId: string | null;
19
- submissionId: string | null;
20
- thumbnailId: string | null;
21
- annotationId: string | null;
22
18
  uploadStatus: import(".prisma/client").$Enums.UploadStatus;
23
19
  uploadUrl: string | null;
24
20
  uploadExpiresAt: Date | null;
@@ -28,6 +24,10 @@ export declare function moveFile(fileId: string, targetFolderId: string): Promis
28
24
  uploadRetryCount: number;
29
25
  isOrphaned: boolean;
30
26
  cleanupAt: Date | null;
27
+ thumbnailId: string | null;
28
+ assignmentId: string | null;
29
+ submissionId: string | null;
30
+ annotationId: string | null;
31
31
  classDraftId: string | null;
32
32
  folderId: string | null;
33
33
  conversationId: string | null;
@@ -43,15 +43,11 @@ export declare function renameFile(fileId: string, newName: string): Promise<{
43
43
  } & {
44
44
  path: string;
45
45
  type: string;
46
- id: string;
47
- userId: string | null;
48
46
  name: string;
47
+ id: string;
49
48
  size: number | null;
49
+ userId: string | null;
50
50
  uploadedAt: Date | null;
51
- assignmentId: string | null;
52
- submissionId: string | null;
53
- thumbnailId: string | null;
54
- annotationId: string | null;
55
51
  uploadStatus: import(".prisma/client").$Enums.UploadStatus;
56
52
  uploadUrl: string | null;
57
53
  uploadExpiresAt: Date | null;
@@ -61,6 +57,10 @@ export declare function renameFile(fileId: string, newName: string): Promise<{
61
57
  uploadRetryCount: number;
62
58
  isOrphaned: boolean;
63
59
  cleanupAt: Date | null;
60
+ thumbnailId: string | null;
61
+ assignmentId: string | null;
62
+ submissionId: string | null;
63
+ annotationId: string | null;
64
64
  classDraftId: string | null;
65
65
  folderId: string | null;
66
66
  conversationId: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"file.d.ts","sourceRoot":"/","sources":["services/file.ts"],"names":[],"mappings":"AAiBA,0EAA0E;AAC1E,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;GAwEpE;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmBvB;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBhB;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;GA6BrE"}
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"/","sources":["services/file.ts"],"names":[],"mappings":"AAkBA,0EAA0E;AAC1E,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;GA6EpE;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmBvB;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBhB;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;GA6BrE"}
@@ -3,11 +3,12 @@
3
3
  * for assignment, submission, announcement, folder, and user-owned files.
4
4
  */
5
5
 
6
- !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]="df3e48dc-35bf-5218-b82c-a8934040efcf")}catch(e){}}();
6
+ !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]="c9a35639-e642-5ed5-b260-9bacbf8cb7e9")}catch(e){}}();
7
7
  import { TRPCError } from "@trpc/server";
8
8
  import { getSignedUrl, deleteFile } from "../lib/googleCloudStorage.js";
9
9
  import { logger } from "../utils/logger.js";
10
10
  import { findFileById, findFileWithFolder, findFileWithFolderAndThumbnail, findFolderById, updateFileFolder, updateFileName, deleteFileById, } from "../models/file.js";
11
+ import { findConversationMembership } from "../models/message.js";
11
12
  /** Generate a signed URL for file download. Validates user has access. */
12
13
  export async function getFileSignedUrl(userId, fileId) {
13
14
  const file = await findFileById(fileId);
@@ -45,6 +46,10 @@ export async function getFileSignedUrl(userId, fileId) {
45
46
  if (file.userId === userId) {
46
47
  hasAccess = true;
47
48
  }
49
+ if (file.conversationId) {
50
+ const membership = await findConversationMembership(file.conversationId, userId);
51
+ hasAccess = hasAccess || Boolean(membership);
52
+ }
48
53
  if (file.folder?.class) {
49
54
  const isTeacher = file.folder.class.teachers.some((t) => t.id === userId);
50
55
  const isStudent = file.folder.class.students.some((s) => s.id === userId);
@@ -130,4 +135,4 @@ export async function deleteFileRecord(fileId, classId) {
130
135
  return { success: true };
131
136
  }
132
137
  //# sourceMappingURL=file.js.map
133
- //# debugId=df3e48dc-35bf-5218-b82c-a8934040efcf
138
+ //# debugId=c9a35639-e642-5ed5-b260-9bacbf8cb7e9