@studious-lms/server 1.2.53 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (479) hide show
  1. package/.coderabbit.yaml +9 -0
  2. package/.env.example +9 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +102 -8
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/config/env.d.ts +21 -0
  7. package/dist/lib/config/env.d.ts.map +1 -1
  8. package/dist/lib/config/env.js +8 -2
  9. package/dist/lib/config/env.js.map +1 -1
  10. package/dist/lib/fileUpload.d.ts.map +1 -1
  11. package/dist/lib/fileUpload.js +2 -2
  12. package/dist/lib/fileUpload.js.map +1 -1
  13. package/dist/lib/googleCloudStorage.d.ts +6 -0
  14. package/dist/lib/googleCloudStorage.d.ts.map +1 -1
  15. package/dist/lib/googleCloudStorage.js +19 -2
  16. package/dist/lib/googleCloudStorage.js.map +1 -1
  17. package/dist/lib/pusher.d.ts +4 -1
  18. package/dist/lib/pusher.d.ts.map +1 -1
  19. package/dist/lib/pusher.js +6 -3
  20. package/dist/lib/pusher.js.map +1 -1
  21. package/dist/lib/redis.d.ts +5 -0
  22. package/dist/lib/redis.d.ts.map +1 -0
  23. package/dist/lib/redis.js +53 -0
  24. package/dist/lib/redis.js.map +1 -0
  25. package/dist/lib/thumbnailGenerator.d.ts +0 -21
  26. package/dist/lib/thumbnailGenerator.d.ts.map +1 -1
  27. package/dist/lib/thumbnailGenerator.js +157 -160
  28. package/dist/lib/thumbnailGenerator.js.map +1 -1
  29. package/dist/middleware/auth.d.ts.map +1 -1
  30. package/dist/middleware/auth.js +33 -95
  31. package/dist/middleware/auth.js.map +1 -1
  32. package/dist/models/agenda.d.ts +97 -0
  33. package/dist/models/agenda.d.ts.map +1 -0
  34. package/dist/models/agenda.js +40 -0
  35. package/dist/models/agenda.js.map +1 -0
  36. package/dist/models/announcement.d.ts +223 -0
  37. package/dist/models/announcement.d.ts.map +1 -0
  38. package/dist/models/announcement.js +120 -0
  39. package/dist/models/announcement.js.map +1 -0
  40. package/dist/models/assignment.d.ts +1292 -0
  41. package/dist/models/assignment.d.ts.map +1 -0
  42. package/dist/models/assignment.js +309 -0
  43. package/dist/models/assignment.js.map +1 -0
  44. package/dist/models/attendance.d.ts +180 -0
  45. package/dist/models/attendance.d.ts.map +1 -0
  46. package/dist/models/attendance.js +188 -0
  47. package/dist/models/attendance.js.map +1 -0
  48. package/dist/models/auth.d.ts +153 -0
  49. package/dist/models/auth.d.ts.map +1 -0
  50. package/dist/models/auth.js +217 -0
  51. package/dist/models/auth.js.map +1 -0
  52. package/dist/models/class.d.ts +461 -0
  53. package/dist/models/class.d.ts.map +1 -0
  54. package/dist/models/class.js +645 -0
  55. package/dist/models/class.js.map +1 -0
  56. package/dist/models/comment.d.ts +171 -0
  57. package/dist/models/comment.d.ts.map +1 -0
  58. package/dist/models/comment.js +138 -0
  59. package/dist/models/comment.js.map +1 -0
  60. package/dist/models/conversation.d.ts +164 -0
  61. package/dist/models/conversation.d.ts.map +1 -0
  62. package/dist/models/conversation.js +175 -0
  63. package/dist/models/conversation.js.map +1 -0
  64. package/dist/models/event.d.ts +295 -0
  65. package/dist/models/event.d.ts.map +1 -0
  66. package/dist/models/event.js +145 -0
  67. package/dist/models/event.js.map +1 -0
  68. package/dist/models/file.d.ts +536 -0
  69. package/dist/models/file.d.ts.map +1 -0
  70. package/dist/models/file.js +126 -0
  71. package/dist/models/file.js.map +1 -0
  72. package/dist/models/folder.d.ts +295 -0
  73. package/dist/models/folder.d.ts.map +1 -0
  74. package/dist/models/folder.js +202 -0
  75. package/dist/models/folder.js.map +1 -0
  76. package/dist/models/labChat.d.ts +243 -0
  77. package/dist/models/labChat.d.ts.map +1 -0
  78. package/dist/models/labChat.js +204 -0
  79. package/dist/models/labChat.js.map +1 -0
  80. package/dist/models/marketing.d.ts +72 -0
  81. package/dist/models/marketing.d.ts.map +1 -0
  82. package/dist/models/marketing.js +26 -0
  83. package/dist/models/marketing.js.map +1 -0
  84. package/dist/models/message.d.ts +100 -0
  85. package/dist/models/message.d.ts.map +1 -0
  86. package/dist/models/message.js +131 -0
  87. package/dist/models/message.js.map +1 -0
  88. package/dist/models/newtonChat.d.ts +72 -0
  89. package/dist/models/newtonChat.d.ts.map +1 -0
  90. package/dist/models/newtonChat.js +61 -0
  91. package/dist/models/newtonChat.js.map +1 -0
  92. package/dist/models/notification.d.ts +65 -0
  93. package/dist/models/notification.d.ts.map +1 -0
  94. package/dist/models/notification.js +46 -0
  95. package/dist/models/notification.js.map +1 -0
  96. package/dist/models/section.d.ts +102 -0
  97. package/dist/models/section.d.ts.map +1 -0
  98. package/dist/models/section.js +83 -0
  99. package/dist/models/section.js.map +1 -0
  100. package/dist/models/user.d.ts +39 -0
  101. package/dist/models/user.d.ts.map +1 -0
  102. package/dist/models/user.js +38 -0
  103. package/dist/models/user.js.map +1 -0
  104. package/dist/models/worksheet.d.ts +460 -0
  105. package/dist/models/worksheet.d.ts.map +1 -0
  106. package/dist/models/worksheet.js +200 -0
  107. package/dist/models/worksheet.js.map +1 -0
  108. package/dist/pipelines/aiLabChat.d.ts +76 -0
  109. package/dist/pipelines/aiLabChat.d.ts.map +1 -0
  110. package/dist/pipelines/aiLabChat.js +599 -0
  111. package/dist/pipelines/aiLabChat.js.map +1 -0
  112. package/dist/pipelines/aiNewtonChat.d.ts +30 -0
  113. package/dist/pipelines/aiNewtonChat.d.ts.map +1 -0
  114. package/dist/pipelines/aiNewtonChat.js +289 -0
  115. package/dist/pipelines/aiNewtonChat.js.map +1 -0
  116. package/dist/pipelines/gradeWorksheet.d.ts +30 -0
  117. package/dist/pipelines/gradeWorksheet.d.ts.map +1 -0
  118. package/dist/pipelines/gradeWorksheet.js +252 -0
  119. package/dist/pipelines/gradeWorksheet.js.map +1 -0
  120. package/dist/routers/_app.d.ts +1523 -1315
  121. package/dist/routers/_app.d.ts.map +1 -1
  122. package/dist/routers/agenda.d.ts +22 -22
  123. package/dist/routers/agenda.d.ts.map +1 -1
  124. package/dist/routers/agenda.js +4 -65
  125. package/dist/routers/agenda.js.map +1 -1
  126. package/dist/routers/announcement.d.ts +16 -16
  127. package/dist/routers/announcement.d.ts.map +1 -1
  128. package/dist/routers/announcement.js +37 -446
  129. package/dist/routers/announcement.js.map +1 -1
  130. package/dist/routers/assignment.d.ts +300 -378
  131. package/dist/routers/assignment.d.ts.map +1 -1
  132. package/dist/routers/assignment.js +78 -1868
  133. package/dist/routers/assignment.js.map +1 -1
  134. package/dist/routers/attendance.d.ts +19 -9
  135. package/dist/routers/attendance.d.ts.map +1 -1
  136. package/dist/routers/attendance.js +7 -264
  137. package/dist/routers/attendance.js.map +1 -1
  138. package/dist/routers/auth.d.ts +2 -2
  139. package/dist/routers/auth.d.ts.map +1 -1
  140. package/dist/routers/auth.js +29 -354
  141. package/dist/routers/auth.js.map +1 -1
  142. package/dist/routers/class.d.ts +160 -68
  143. package/dist/routers/class.d.ts.map +1 -1
  144. package/dist/routers/class.js +82 -1052
  145. package/dist/routers/class.js.map +1 -1
  146. package/dist/routers/comment.d.ts +6 -42
  147. package/dist/routers/comment.d.ts.map +1 -1
  148. package/dist/routers/comment.js +24 -244
  149. package/dist/routers/comment.js.map +1 -1
  150. package/dist/routers/conversation.d.ts +45 -7
  151. package/dist/routers/conversation.d.ts.map +1 -1
  152. package/dist/routers/conversation.js +19 -327
  153. package/dist/routers/conversation.js.map +1 -1
  154. package/dist/routers/event.d.ts +36 -36
  155. package/dist/routers/event.d.ts.map +1 -1
  156. package/dist/routers/event.js +13 -433
  157. package/dist/routers/event.js.map +1 -1
  158. package/dist/routers/file.d.ts +2 -2
  159. package/dist/routers/file.d.ts.map +1 -1
  160. package/dist/routers/file.js +9 -323
  161. package/dist/routers/file.js.map +1 -1
  162. package/dist/routers/folder.d.ts +21 -14
  163. package/dist/routers/folder.d.ts.map +1 -1
  164. package/dist/routers/folder.js +34 -745
  165. package/dist/routers/folder.js.map +1 -1
  166. package/dist/routers/labChat.d.ts +21 -11
  167. package/dist/routers/labChat.d.ts.map +1 -1
  168. package/dist/routers/labChat.js +22 -570
  169. package/dist/routers/labChat.js.map +1 -1
  170. package/dist/routers/marketing.d.ts +1 -1
  171. package/dist/routers/marketing.d.ts.map +1 -1
  172. package/dist/routers/marketing.js +7 -56
  173. package/dist/routers/marketing.js.map +1 -1
  174. package/dist/routers/message.d.ts +13 -2
  175. package/dist/routers/message.d.ts.map +1 -1
  176. package/dist/routers/message.js +32 -520
  177. package/dist/routers/message.js.map +1 -1
  178. package/dist/routers/newtonChat.d.ts +1 -1
  179. package/dist/routers/newtonChat.d.ts.map +1 -1
  180. package/dist/routers/newtonChat.js +7 -246
  181. package/dist/routers/newtonChat.js.map +1 -1
  182. package/dist/routers/notifications.d.ts +4 -4
  183. package/dist/routers/notifications.d.ts.map +1 -1
  184. package/dist/routers/notifications.js +18 -83
  185. package/dist/routers/notifications.js.map +1 -1
  186. package/dist/routers/section.d.ts +4 -4
  187. package/dist/routers/section.d.ts.map +1 -1
  188. package/dist/routers/section.js +14 -286
  189. package/dist/routers/section.js.map +1 -1
  190. package/dist/routers/user.d.ts +1 -1
  191. package/dist/routers/user.d.ts.map +1 -1
  192. package/dist/routers/user.js +32 -207
  193. package/dist/routers/user.js.map +1 -1
  194. package/dist/routers/worksheet.d.ts +68 -55
  195. package/dist/routers/worksheet.d.ts.map +1 -1
  196. package/dist/routers/worksheet.js +79 -394
  197. package/dist/routers/worksheet.js.map +1 -1
  198. package/dist/seedDatabase.d.ts +1 -1
  199. package/dist/server/pipelines/gradeWorksheet.d.ts +6 -6
  200. package/dist/server/pipelines/gradeWorksheet.d.ts.map +1 -1
  201. package/dist/server/pipelines/gradeWorksheet.js +12 -5
  202. package/dist/server/pipelines/gradeWorksheet.js.map +1 -1
  203. package/dist/services/agenda.d.ts +100 -0
  204. package/dist/services/agenda.d.ts.map +1 -0
  205. package/dist/services/agenda.js +21 -0
  206. package/dist/services/agenda.js.map +1 -0
  207. package/dist/services/announcement.d.ts +135 -0
  208. package/dist/services/announcement.d.ts.map +1 -0
  209. package/dist/services/announcement.js +223 -0
  210. package/dist/services/announcement.js.map +1 -0
  211. package/dist/services/assignment.d.ts +1462 -0
  212. package/dist/services/assignment.d.ts.map +1 -0
  213. package/dist/services/assignment.js +898 -0
  214. package/dist/services/assignment.js.map +1 -0
  215. package/dist/services/attendance.d.ts +93 -0
  216. package/dist/services/attendance.d.ts.map +1 -0
  217. package/dist/services/attendance.js +61 -0
  218. package/dist/services/attendance.js.map +1 -0
  219. package/dist/services/auth.d.ts +68 -0
  220. package/dist/services/auth.d.ts.map +1 -0
  221. package/dist/services/auth.js +218 -0
  222. package/dist/services/auth.js.map +1 -0
  223. package/dist/services/class.d.ts +643 -0
  224. package/dist/services/class.d.ts.map +1 -0
  225. package/dist/services/class.js +486 -0
  226. package/dist/services/class.js.map +1 -0
  227. package/dist/services/comment.d.ts +100 -0
  228. package/dist/services/comment.d.ts.map +1 -0
  229. package/dist/services/comment.js +83 -0
  230. package/dist/services/comment.js.map +1 -0
  231. package/dist/services/conversation.d.ts +159 -0
  232. package/dist/services/conversation.d.ts.map +1 -0
  233. package/dist/services/conversation.js +138 -0
  234. package/dist/services/conversation.js.map +1 -0
  235. package/dist/services/event.d.ts +216 -0
  236. package/dist/services/event.d.ts.map +1 -0
  237. package/dist/services/event.js +168 -0
  238. package/dist/services/event.js.map +1 -0
  239. package/dist/services/file.d.ts +74 -0
  240. package/dist/services/file.d.ts.map +1 -0
  241. package/dist/services/file.js +133 -0
  242. package/dist/services/file.js.map +1 -0
  243. package/dist/services/folder.d.ts +239 -0
  244. package/dist/services/folder.d.ts.map +1 -0
  245. package/dist/services/folder.js +248 -0
  246. package/dist/services/folder.js.map +1 -0
  247. package/dist/services/labChat.d.ts +169 -0
  248. package/dist/services/labChat.d.ts.map +1 -0
  249. package/dist/services/labChat.js +381 -0
  250. package/dist/services/labChat.js.map +1 -0
  251. package/dist/services/marketing.d.ts +50 -0
  252. package/dist/services/marketing.d.ts.map +1 -0
  253. package/dist/services/marketing.js +32 -0
  254. package/dist/services/marketing.js.map +1 -0
  255. package/dist/services/message.d.ts +103 -0
  256. package/dist/services/message.d.ts.map +1 -0
  257. package/dist/services/message.js +422 -0
  258. package/dist/services/message.js.map +1 -0
  259. package/dist/services/newtonChat.d.ts +22 -0
  260. package/dist/services/newtonChat.d.ts.map +1 -0
  261. package/dist/services/newtonChat.js +174 -0
  262. package/dist/services/newtonChat.js.map +1 -0
  263. package/dist/services/notification.d.ts +65 -0
  264. package/dist/services/notification.d.ts.map +1 -0
  265. package/dist/services/notification.js +33 -0
  266. package/dist/services/notification.js.map +1 -0
  267. package/dist/services/section.d.ts +53 -0
  268. package/dist/services/section.d.ts.map +1 -0
  269. package/dist/services/section.js +199 -0
  270. package/dist/services/section.js.map +1 -0
  271. package/dist/services/user.d.ts +48 -0
  272. package/dist/services/user.d.ts.map +1 -0
  273. package/dist/services/user.js +141 -0
  274. package/dist/services/user.js.map +1 -0
  275. package/dist/services/worksheet.d.ts +239 -0
  276. package/dist/services/worksheet.d.ts.map +1 -0
  277. package/dist/services/worksheet.js +235 -0
  278. package/dist/services/worksheet.js.map +1 -0
  279. package/dist/utils/aiUser.d.ts +1 -3
  280. package/dist/utils/aiUser.d.ts.map +1 -1
  281. package/dist/utils/aiUser.js +6 -5
  282. package/dist/utils/aiUser.js.map +1 -1
  283. package/dist/utils/email.d.ts +3 -0
  284. package/dist/utils/email.d.ts.map +1 -1
  285. package/dist/utils/email.js +7 -4
  286. package/dist/utils/email.js.map +1 -1
  287. package/dist/utils/generateInviteCode.d.ts +1 -2
  288. package/dist/utils/generateInviteCode.d.ts.map +1 -1
  289. package/dist/utils/generateInviteCode.js +3 -4
  290. package/dist/utils/generateInviteCode.js.map +1 -1
  291. package/dist/utils/inference.d.ts +3 -0
  292. package/dist/utils/inference.d.ts.map +1 -1
  293. package/dist/utils/inference.js +7 -4
  294. package/dist/utils/inference.js.map +1 -1
  295. package/dist/utils/logger.d.ts +3 -0
  296. package/dist/utils/logger.d.ts.map +1 -1
  297. package/dist/utils/logger.js +5 -2
  298. package/dist/utils/logger.js.map +1 -1
  299. package/dist/utils/prismaErrorHandler.d.ts.map +1 -1
  300. package/dist/utils/prismaErrorHandler.js +5 -2
  301. package/dist/utils/prismaErrorHandler.js.map +1 -1
  302. package/dist/utils/prismaWrapper.d.ts +1 -0
  303. package/dist/utils/prismaWrapper.d.ts.map +1 -1
  304. package/dist/utils/prismaWrapper.js +6 -2
  305. package/dist/utils/prismaWrapper.js.map +1 -1
  306. package/docker-compose.yml +5 -0
  307. package/package.json +4 -3
  308. package/prisma/schema.prisma +1 -1
  309. package/src/index.ts +119 -12
  310. package/src/lib/config/env.ts +6 -0
  311. package/src/lib/fileUpload.ts +0 -1
  312. package/src/lib/googleCloudStorage.ts +17 -0
  313. package/src/lib/pusher.ts +5 -1
  314. package/src/lib/redis.ts +56 -0
  315. package/src/lib/thumbnailGenerator.ts +170 -168
  316. package/src/middleware/auth.ts +80 -137
  317. package/src/models/agenda.ts +46 -0
  318. package/src/models/announcement.ts +134 -0
  319. package/src/models/assignment.ts +322 -0
  320. package/src/models/attendance.ts +208 -0
  321. package/src/models/auth.ts +247 -0
  322. package/src/models/class.ts +703 -0
  323. package/src/models/comment.ts +152 -0
  324. package/src/models/conversation.ts +200 -0
  325. package/src/models/event.ts +177 -0
  326. package/src/models/file.ts +129 -0
  327. package/src/models/folder.ts +225 -0
  328. package/src/models/labChat.ts +213 -0
  329. package/src/models/marketing.ts +45 -0
  330. package/src/models/message.ts +153 -0
  331. package/src/models/newtonChat.ts +70 -0
  332. package/src/models/notification.ts +54 -0
  333. package/src/models/section.ts +98 -0
  334. package/src/models/user.ts +47 -0
  335. package/src/models/worksheet.ts +294 -0
  336. package/src/pipelines/aiLabChat.ts +684 -0
  337. package/src/{server/pipelines → pipelines}/aiNewtonChat.ts +9 -5
  338. package/src/{server/pipelines → pipelines}/gradeWorksheet.ts +25 -14
  339. package/src/routers/agenda.ts +3 -66
  340. package/src/routers/announcement.ts +54 -495
  341. package/src/routers/assignment.ts +126 -2018
  342. package/src/routers/attendance.ts +15 -276
  343. package/src/routers/auth.ts +79 -442
  344. package/src/routers/class.ts +263 -1187
  345. package/src/routers/comment.ts +61 -288
  346. package/src/routers/conversation.ts +51 -360
  347. package/src/routers/event.ts +50 -481
  348. package/src/routers/file.ts +45 -368
  349. package/src/routers/folder.ts +107 -836
  350. package/src/routers/labChat.ts +35 -604
  351. package/src/routers/marketing.ts +35 -77
  352. package/src/routers/message.ts +54 -567
  353. package/src/routers/newtonChat.ts +17 -278
  354. package/src/routers/notifications.ts +32 -82
  355. package/src/routers/section.ts +46 -330
  356. package/src/routers/user.ts +49 -227
  357. package/src/routers/worksheet.ts +215 -503
  358. package/src/services/agenda.ts +21 -0
  359. package/src/services/announcement.ts +290 -0
  360. package/src/services/assignment.ts +1198 -0
  361. package/src/services/attendance.ts +85 -0
  362. package/src/services/auth.ts +277 -0
  363. package/src/services/class.ts +629 -0
  364. package/src/services/comment.ts +106 -0
  365. package/src/services/conversation.ts +213 -0
  366. package/src/services/event.ts +231 -0
  367. package/src/services/file.ts +167 -0
  368. package/src/services/folder.ts +316 -0
  369. package/src/services/labChat.ts +458 -0
  370. package/src/services/marketing.ts +57 -0
  371. package/src/services/message.ts +554 -0
  372. package/src/services/newtonChat.ts +222 -0
  373. package/src/services/notification.ts +50 -0
  374. package/src/services/section.ts +283 -0
  375. package/src/services/user.ts +172 -0
  376. package/src/services/worksheet.ts +358 -0
  377. package/src/utils/aiUser.ts +4 -3
  378. package/src/utils/email.ts +5 -3
  379. package/src/utils/generateInviteCode.ts +1 -3
  380. package/src/utils/inference.ts +5 -2
  381. package/src/utils/logger.ts +3 -1
  382. package/src/utils/prismaErrorHandler.ts +3 -0
  383. package/src/utils/prismaWrapper.ts +4 -0
  384. package/tests/globalSetup.ts +62 -0
  385. package/tests/helpers.ts +22 -0
  386. package/tests/middleware/security.test.ts +42 -0
  387. package/tests/routers/agenda.test.ts +138 -0
  388. package/tests/routers/announcement.test.ts +490 -0
  389. package/tests/routers/assignment.test.ts +837 -0
  390. package/tests/{attendance.test.ts → routers/attendance.test.ts} +6 -14
  391. package/tests/routers/auth.test.ts +171 -0
  392. package/tests/{class.test.ts → routers/class.test.ts} +131 -85
  393. package/tests/routers/comment.test.ts +126 -0
  394. package/tests/routers/conversation.test.ts +145 -0
  395. package/tests/{event.test.ts → routers/event.test.ts} +93 -32
  396. package/tests/routers/folder.test.ts +178 -0
  397. package/tests/routers/labChat.test.ts +115 -0
  398. package/tests/routers/marketing.test.ts +59 -0
  399. package/tests/routers/message.test.ts +123 -0
  400. package/tests/routers/notification.test.ts +69 -0
  401. package/tests/{section.test.ts → routers/section.test.ts} +5 -13
  402. package/tests/server/rateLimit.test.ts +73 -0
  403. package/tests/setup.ts +18 -92
  404. package/tests/user.test.ts +9 -31
  405. package/tests/utils/aiUser.test.ts +22 -0
  406. package/tests/utils/generateInviteCode.test.ts +24 -0
  407. package/tests/utils/logger.test.ts +74 -0
  408. package/tests/utils/prismaErrorHandler.test.ts +101 -0
  409. package/tests/utils/prismaWrapper.test.ts +82 -0
  410. package/tests/worksheet.test.ts +181 -0
  411. package/vitest.config.ts +6 -3
  412. package/vitest.unit.config.ts +21 -0
  413. package/TODO.md +0 -2
  414. package/coverage/base.css +0 -224
  415. package/coverage/block-navigation.js +0 -87
  416. package/coverage/clover.xml +0 -12110
  417. package/coverage/coverage-final.json +0 -44
  418. package/coverage/favicon.png +0 -0
  419. package/coverage/index.html +0 -221
  420. package/coverage/prettify.css +0 -1
  421. package/coverage/prettify.js +0 -2
  422. package/coverage/server/index.html +0 -116
  423. package/coverage/server/src/exportType.ts.html +0 -109
  424. package/coverage/server/src/index.html +0 -161
  425. package/coverage/server/src/index.ts.html +0 -1702
  426. package/coverage/server/src/instrument.ts.html +0 -130
  427. package/coverage/server/src/lib/config/env.ts.html +0 -448
  428. package/coverage/server/src/lib/config/index.html +0 -116
  429. package/coverage/server/src/lib/fileUpload.ts.html +0 -1138
  430. package/coverage/server/src/lib/googleCloudStorage.ts.html +0 -334
  431. package/coverage/server/src/lib/index.html +0 -206
  432. package/coverage/server/src/lib/jsonConversion.ts.html +0 -2323
  433. package/coverage/server/src/lib/jsonStyles.ts.html +0 -193
  434. package/coverage/server/src/lib/notificationHandler.ts.html +0 -193
  435. package/coverage/server/src/lib/pusher.ts.html +0 -121
  436. package/coverage/server/src/lib/thumbnailGenerator.ts.html +0 -592
  437. package/coverage/server/src/middleware/auth.ts.html +0 -646
  438. package/coverage/server/src/middleware/index.html +0 -146
  439. package/coverage/server/src/middleware/logging.ts.html +0 -244
  440. package/coverage/server/src/middleware/security.ts.html +0 -271
  441. package/coverage/server/src/routers/_app.ts.html +0 -232
  442. package/coverage/server/src/routers/agenda.ts.html +0 -319
  443. package/coverage/server/src/routers/announcement.ts.html +0 -3481
  444. package/coverage/server/src/routers/assignment.ts.html +0 -7633
  445. package/coverage/server/src/routers/attendance.ts.html +0 -1030
  446. package/coverage/server/src/routers/auth.ts.html +0 -1081
  447. package/coverage/server/src/routers/class.ts.html +0 -3535
  448. package/coverage/server/src/routers/comment.ts.html +0 -991
  449. package/coverage/server/src/routers/conversation.ts.html +0 -982
  450. package/coverage/server/src/routers/event.ts.html +0 -1609
  451. package/coverage/server/src/routers/file.ts.html +0 -1144
  452. package/coverage/server/src/routers/folder.ts.html +0 -2797
  453. package/coverage/server/src/routers/index.html +0 -386
  454. package/coverage/server/src/routers/labChat.ts.html +0 -3073
  455. package/coverage/server/src/routers/marketing.ts.html +0 -340
  456. package/coverage/server/src/routers/message.ts.html +0 -1912
  457. package/coverage/server/src/routers/notifications.ts.html +0 -364
  458. package/coverage/server/src/routers/section.ts.html +0 -1120
  459. package/coverage/server/src/routers/user.ts.html +0 -862
  460. package/coverage/server/src/routers/worksheet.ts.html +0 -1729
  461. package/coverage/server/src/trpc.ts.html +0 -397
  462. package/coverage/server/src/types/index.html +0 -116
  463. package/coverage/server/src/types/trpc.ts.html +0 -127
  464. package/coverage/server/src/utils/aiUser.ts.html +0 -280
  465. package/coverage/server/src/utils/email.ts.html +0 -121
  466. package/coverage/server/src/utils/generateInviteCode.ts.html +0 -106
  467. package/coverage/server/src/utils/index.html +0 -206
  468. package/coverage/server/src/utils/inference.ts.html +0 -709
  469. package/coverage/server/src/utils/logger.ts.html +0 -664
  470. package/coverage/server/src/utils/prismaErrorHandler.ts.html +0 -907
  471. package/coverage/server/src/utils/prismaWrapper.ts.html +0 -355
  472. package/coverage/server/vitest.config.ts.html +0 -196
  473. package/coverage/sort-arrow-sprite.png +0 -0
  474. package/coverage/sorter.js +0 -210
  475. package/src/lib/notificationHandler.ts +0 -36
  476. package/src/server/pipelines/aiLabChat.ts +0 -507
  477. package/tests/announcement.test.ts +0 -164
  478. package/tests/assignment.test.ts +0 -296
  479. package/tests/auth.test.ts +0 -48
@@ -1,302 +1,13 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4de0a549-5566-5b60-aa1d-acdb528cce7a")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d26131b5-0358-5872-893b-73bd753de228")}catch(e){}}();
3
3
  import { z } from "zod";
4
- import { createTRPCRouter, protectedProcedure, protectedTeacherProcedure, protectedClassMemberProcedure } from "../trpc.js";
5
- import { prisma } from "../lib/prisma.js";
6
- import { TRPCError } from "@trpc/server";
7
- import { generateInviteCode } from "../utils/generateInviteCode.js";
4
+ import { createTRPCRouter, protectedProcedure, protectedTeacherProcedure, protectedClassMemberProcedure, } from "../trpc.js";
5
+ import { getAllClasses, getClass, updateClass, createClass, deleteClass, addStudent, changeRole, removeMember, leaveClass, joinClass, getInviteCode, createInviteCode, getGrades, updateGrade, getEvents, listMarkSchemes, createMarkScheme, updateMarkScheme, deleteMarkScheme, listGradingBoundaries, createGradingBoundary, updateGradingBoundary, deleteGradingBoundary, getSyllabus, updateSyllabus, listLabDrafts, createLabDraft, updateLabDraft, deleteLabDraft, publishLabDraft, getFiles, exportClass, importClass, } from "../services/class.js";
8
6
  export const classRouter = createTRPCRouter({
9
- getAll: protectedProcedure
10
- .query(async ({ ctx }) => {
11
- const [teacherClasses, studentClasses] = await Promise.all([
12
- prisma.class.findMany({
13
- where: {
14
- teachers: {
15
- some: {
16
- id: ctx.user?.id,
17
- },
18
- },
19
- },
20
- include: {
21
- assignments: {
22
- where: {
23
- dueDate: {
24
- lte: new Date(new Date().setHours(23, 59, 59, 999)),
25
- },
26
- template: false,
27
- },
28
- select: {
29
- id: true,
30
- title: true,
31
- type: true,
32
- dueDate: true,
33
- },
34
- },
35
- students: {
36
- select: {
37
- id: true,
38
- username: true,
39
- profile: {
40
- select: {
41
- displayName: true,
42
- profilePicture: true,
43
- profilePictureThumbnail: true,
44
- },
45
- },
46
- },
47
- },
48
- teachers: {
49
- select: {
50
- id: true,
51
- username: true,
52
- profile: {
53
- select: {
54
- displayName: true,
55
- profilePicture: true,
56
- profilePictureThumbnail: true,
57
- },
58
- },
59
- },
60
- },
61
- },
62
- }),
63
- prisma.class.findMany({
64
- where: {
65
- students: {
66
- some: {
67
- id: ctx.user?.id,
68
- },
69
- },
70
- },
71
- include: {
72
- assignments: {
73
- where: {
74
- dueDate: {
75
- lte: new Date(new Date().setHours(23, 59, 59, 999)),
76
- },
77
- template: false,
78
- },
79
- select: {
80
- id: true,
81
- title: true,
82
- type: true,
83
- dueDate: true,
84
- },
85
- },
86
- students: {
87
- select: {
88
- id: true,
89
- username: true,
90
- profile: {
91
- select: {
92
- displayName: true,
93
- profilePicture: true,
94
- profilePictureThumbnail: true,
95
- },
96
- },
97
- },
98
- },
99
- teachers: {
100
- select: {
101
- id: true,
102
- username: true,
103
- profile: {
104
- select: {
105
- displayName: true,
106
- profilePicture: true,
107
- profilePictureThumbnail: true,
108
- },
109
- },
110
- },
111
- },
112
- },
113
- }),
114
- ]);
115
- return {
116
- teacherInClass: teacherClasses.map(cls => ({
117
- id: cls.id,
118
- name: cls.name,
119
- section: cls.section,
120
- subject: cls.subject,
121
- dueToday: cls.assignments,
122
- assignments: cls.assignments,
123
- members: [...cls.students, ...cls.teachers],
124
- color: cls.color,
125
- })),
126
- studentInClass: studentClasses.map(cls => ({
127
- id: cls.id,
128
- name: cls.name,
129
- section: cls.section,
130
- subject: cls.subject,
131
- dueToday: cls.assignments,
132
- assignments: cls.assignments,
133
- members: [...cls.students, ...cls.teachers],
134
- color: cls.color,
135
- })),
136
- };
137
- }),
7
+ getAll: protectedProcedure.query(({ ctx }) => getAllClasses(ctx.user?.id ?? "")),
138
8
  get: protectedProcedure
139
- .input(z.object({
140
- classId: z.string(),
141
- }))
142
- .query(async ({ ctx, input }) => {
143
- const { classId } = input;
144
- const isTeacher = await prisma.class.findFirst({
145
- where: {
146
- id: classId,
147
- teachers: {
148
- some: { id: ctx.user?.id },
149
- },
150
- },
151
- });
152
- const classData = await prisma.class.findUnique({
153
- where: {
154
- id: classId,
155
- },
156
- include: {
157
- teachers: {
158
- select: {
159
- id: true,
160
- username: true,
161
- profile: {
162
- select: {
163
- displayName: true,
164
- profilePicture: true,
165
- profilePictureThumbnail: true,
166
- }
167
- }
168
- },
169
- },
170
- students: {
171
- select: {
172
- id: true,
173
- username: true,
174
- profile: {
175
- select: {
176
- displayName: true,
177
- profilePicture: true,
178
- profilePictureThumbnail: true,
179
- },
180
- },
181
- },
182
- },
183
- announcements: {
184
- orderBy: {
185
- createdAt: 'desc',
186
- },
187
- select: {
188
- id: true,
189
- remarks: true,
190
- createdAt: true,
191
- modifiedAt: true,
192
- teacher: {
193
- select: {
194
- id: true,
195
- username: true,
196
- profile: {
197
- select: {
198
- displayName: true,
199
- profilePicture: true,
200
- profilePictureThumbnail: true,
201
- },
202
- },
203
- },
204
- },
205
- },
206
- },
207
- assignments: {
208
- ...(!isTeacher && {
209
- where: { OR: [
210
- {
211
- assignedTo: {
212
- some: {
213
- id: ctx.user?.id,
214
- },
215
- },
216
- },
217
- {
218
- assignedTo: {
219
- none: {},
220
- },
221
- },
222
- ], }
223
- }),
224
- select: {
225
- type: true,
226
- id: true,
227
- title: true,
228
- dueDate: true,
229
- createdAt: true,
230
- weight: true,
231
- order: true,
232
- graded: true,
233
- maxGrade: true,
234
- instructions: true,
235
- inProgress: true,
236
- template: false,
237
- section: {
238
- select: {
239
- id: true,
240
- name: true,
241
- },
242
- },
243
- markScheme: {
244
- select: {
245
- id: true,
246
- structured: true,
247
- },
248
- },
249
- gradingBoundary: {
250
- select: {
251
- id: true,
252
- structured: true,
253
- },
254
- },
255
- submissions: {
256
- ...(!isTeacher && {
257
- where: {
258
- studentId: ctx.user?.id,
259
- },
260
- }),
261
- select: {
262
- studentId: true,
263
- id: true,
264
- submitted: true,
265
- gradeReceived: true,
266
- rubricState: true,
267
- teacherComments: true,
268
- returned: true,
269
- submittedAt: true,
270
- },
271
- },
272
- },
273
- },
274
- },
275
- });
276
- if (!classData) {
277
- throw new Error('Class not found');
278
- }
279
- const formattedClassData = {
280
- ...classData,
281
- assignments: classData.assignments.map(assignment => ({
282
- ...assignment,
283
- late: assignment.dueDate < new Date(),
284
- submitted: assignment.submissions.find(submission => submission.studentId === ctx.user?.id)?.submitted,
285
- returned: assignment.submissions.find(submission => submission.studentId === ctx.user?.id)?.returned,
286
- })),
287
- };
288
- const sections = await prisma.section.findMany({
289
- where: {
290
- classId: classId,
291
- },
292
- });
293
- return {
294
- class: {
295
- ...formattedClassData,
296
- sections,
297
- },
298
- };
299
- }),
9
+ .input(z.object({ classId: z.string() }))
10
+ .query(({ ctx, input }) => getClass(ctx.user?.id ?? "", input.classId)),
300
11
  update: protectedTeacherProcedure
301
12
  .input(z.object({
302
13
  classId: z.string(),
@@ -304,23 +15,9 @@ export const classRouter = createTRPCRouter({
304
15
  section: z.string().optional(),
305
16
  subject: z.string().optional(),
306
17
  }))
307
- .mutation(async ({ ctx, input }) => {
18
+ .mutation(({ input }) => {
308
19
  const { classId, ...updateData } = input;
309
- const updatedClass = await prisma.class.update({
310
- where: {
311
- id: classId,
312
- },
313
- data: updateData,
314
- select: {
315
- id: true,
316
- name: true,
317
- section: true,
318
- subject: true,
319
- }
320
- });
321
- return {
322
- updatedClass,
323
- };
20
+ return updateClass(classId, updateData);
324
21
  }),
325
22
  create: protectedProcedure
326
23
  .input(z.object({
@@ -331,355 +28,43 @@ export const classRouter = createTRPCRouter({
331
28
  subject: z.string(),
332
29
  color: z.string().optional(),
333
30
  }))
334
- .mutation(async ({ ctx, input }) => {
335
- const { students, teachers, name, section, subject, color } = input;
336
- if (teachers && teachers.length > 0 && students && students.length > 0) {
337
- const newClass = await prisma.class.create({
338
- data: {
339
- name,
340
- section,
341
- subject,
342
- color,
343
- teachers: {
344
- connect: teachers.map(teacher => ({ id: teacher })),
345
- },
346
- students: {
347
- connect: students.map(student => ({ id: student })),
348
- },
349
- },
350
- include: {
351
- teachers: true,
352
- students: true,
353
- },
354
- });
355
- return newClass;
356
- }
357
- const newClass = await prisma.class.create({
358
- data: {
359
- name,
360
- section,
361
- subject,
362
- color,
363
- teachers: {
364
- connect: {
365
- id: ctx.user?.id,
366
- },
367
- },
368
- },
369
- });
370
- return newClass;
371
- }),
31
+ .mutation(({ ctx, input }) => createClass(ctx.user?.id ?? "", input)),
372
32
  delete: protectedTeacherProcedure
373
- .input(z.object({
374
- classId: z.string(),
375
- id: z.string(),
376
- }))
377
- .mutation(async ({ ctx, input }) => {
378
- // Verify user is the teacher of this class
379
- const classToDelete = await prisma.class.findFirst({
380
- where: {
381
- id: input.id,
382
- },
383
- });
384
- if (!classToDelete) {
385
- throw new Error("Class not found or you don't have permission to delete it");
386
- }
387
- await prisma.class.delete({
388
- where: {
389
- id: input.id,
390
- },
391
- });
392
- return {
393
- deletedClass: {
394
- id: input.id,
395
- }
396
- };
397
- }),
33
+ .input(z.object({ classId: z.string(), id: z.string() }))
34
+ .mutation(({ input }) => deleteClass(input.id)),
398
35
  addStudent: protectedTeacherProcedure
399
- .input(z.object({
400
- classId: z.string(),
401
- studentId: z.string(),
402
- }))
403
- .mutation(async ({ ctx, input }) => {
404
- const { classId, studentId } = input;
405
- const student = await prisma.user.findUnique({
406
- where: {
407
- id: studentId,
408
- },
409
- });
410
- if (!student) {
411
- throw new Error("Student not found");
412
- }
413
- const updatedClass = await prisma.class.update({
414
- where: {
415
- id: classId,
416
- },
417
- data: {
418
- students: {
419
- connect: {
420
- id: studentId,
421
- },
422
- },
423
- },
424
- select: {
425
- id: true,
426
- name: true,
427
- section: true,
428
- subject: true,
429
- }
430
- });
431
- return {
432
- updatedClass,
433
- newStudent: student,
434
- };
435
- }),
36
+ .input(z.object({ classId: z.string(), studentId: z.string() }))
37
+ .mutation(({ input }) => addStudent(input.classId, input.studentId)),
436
38
  changeRole: protectedTeacherProcedure
437
39
  .input(z.object({
438
40
  classId: z.string(),
439
41
  userId: z.string(),
440
- type: z.enum(['teacher', 'student']),
42
+ type: z.enum(["teacher", "student"]),
441
43
  }))
442
- .mutation(async ({ ctx, input }) => {
443
- const { classId, userId, type } = input;
444
- const user = await prisma.user.findUnique({
445
- where: { id: userId },
446
- select: {
447
- id: true,
448
- username: true,
449
- },
450
- });
451
- if (!user) {
452
- throw new Error("User not found");
453
- }
454
- const updatedClass = await prisma.class.update({
455
- where: { id: classId },
456
- data: {
457
- [type === 'teacher' ? 'teachers' : 'students']: {
458
- connect: { id: userId },
459
- },
460
- [type === 'teacher' ? 'students' : 'teachers']: {
461
- disconnect: { id: userId },
462
- },
463
- },
464
- });
465
- return {
466
- updatedClass,
467
- user: {
468
- ...user,
469
- type,
470
- },
471
- };
472
- }),
44
+ .mutation(({ input }) => changeRole(input.classId, input.userId, input.type)),
473
45
  removeMember: protectedTeacherProcedure
474
- .input(z.object({
475
- classId: z.string(),
476
- userId: z.string(),
477
- }))
478
- .mutation(async ({ ctx, input }) => {
479
- const { classId, userId } = input;
480
- const updatedClass = await prisma.class.update({
481
- where: { id: classId },
482
- data: {
483
- teachers: {
484
- disconnect: { id: userId },
485
- },
486
- students: {
487
- disconnect: { id: userId },
488
- },
489
- },
490
- });
491
- return {
492
- updatedClass,
493
- removedUserId: userId,
494
- };
495
- }),
46
+ .input(z.object({ classId: z.string(), userId: z.string() }))
47
+ .mutation(({ input }) => removeMember(input.classId, input.userId)),
496
48
  leaveClass: protectedProcedure
497
- .input(z.object({
498
- classId: z.string(),
499
- }))
500
- .mutation(async ({ ctx, input }) => {
501
- const { classId } = input;
502
- const userId = ctx.user?.id;
503
- if (!userId) {
504
- throw new TRPCError({
505
- code: 'UNAUTHORIZED',
506
- message: 'User not authenticated',
507
- });
49
+ .input(z.object({ classId: z.string() }))
50
+ .mutation(({ ctx, input }) => {
51
+ if (!ctx.user?.id) {
52
+ throw new Error("User not authenticated");
508
53
  }
509
- const classData = await prisma.class.findFirst({
510
- where: {
511
- id: classId,
512
- students: {
513
- some: { id: userId },
514
- },
515
- },
516
- });
517
- if (!classData) {
518
- throw new TRPCError({
519
- code: 'NOT_FOUND',
520
- message: 'Class not found or you are not a student in this class',
521
- });
522
- }
523
- await prisma.class.update({
524
- where: { id: classId },
525
- data: {
526
- students: {
527
- disconnect: { id: userId },
528
- },
529
- },
530
- });
531
- return {
532
- success: true,
533
- leftClassId: classId,
534
- };
54
+ return leaveClass(ctx.user.id, input.classId);
535
55
  }),
536
56
  join: protectedProcedure
537
- .input(z.object({
538
- classCode: z.string(),
539
- }))
540
- .mutation(async ({ ctx, input }) => {
541
- const { classCode } = input;
542
- // Case-insensitive search for invite code
543
- const session = await prisma.session.findFirst({
544
- where: {
545
- id: {
546
- equals: classCode,
547
- mode: 'insensitive',
548
- },
549
- },
550
- });
551
- if (!session || !session.classId) {
552
- throw new Error("Class not found");
553
- }
554
- if (session.expiresAt && session.expiresAt < new Date()) {
555
- throw new Error("Session expired");
556
- }
557
- const updatedClass = await prisma.class.update({
558
- where: { id: session.classId },
559
- data: {
560
- students: {
561
- connect: { id: ctx.user?.id },
562
- },
563
- },
564
- select: {
565
- id: true,
566
- name: true,
567
- section: true,
568
- subject: true,
569
- },
570
- });
571
- return {
572
- joinedClass: updatedClass,
573
- };
574
- }),
57
+ .input(z.object({ classCode: z.string() }))
58
+ .mutation(({ ctx, input }) => joinClass(ctx.user?.id ?? "", input.classCode)),
575
59
  getInviteCode: protectedTeacherProcedure
576
- .input(z.object({
577
- classId: z.string(),
578
- }))
579
- .query(async ({ ctx, input }) => {
580
- const { classId } = input;
581
- const session = await prisma.session.findFirst({
582
- where: {
583
- classId,
584
- },
585
- });
586
- if ((session?.expiresAt && session.expiresAt < new Date()) || !session) {
587
- const newSession = await prisma.session.create({
588
- data: {
589
- id: generateInviteCode(),
590
- classId,
591
- expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours from now
592
- }
593
- });
594
- return {
595
- code: newSession.id,
596
- };
597
- }
598
- return {
599
- code: session?.id,
600
- };
601
- }),
60
+ .input(z.object({ classId: z.string() }))
61
+ .query(({ input }) => getInviteCode(input.classId)),
602
62
  createInviteCode: protectedTeacherProcedure
603
- .input(z.object({
604
- classId: z.string(),
605
- }))
606
- .mutation(async ({ ctx, input }) => {
607
- const { classId } = input;
608
- await prisma.session.deleteMany({
609
- where: {
610
- classId,
611
- },
612
- });
613
- // Create a new session for the invite code
614
- const session = await prisma.session.create({
615
- data: {
616
- id: generateInviteCode(),
617
- classId,
618
- expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours from now
619
- }
620
- });
621
- return {
622
- code: session.id,
623
- };
624
- }),
63
+ .input(z.object({ classId: z.string() }))
64
+ .mutation(({ input }) => createInviteCode(input.classId)),
625
65
  getGrades: protectedClassMemberProcedure
626
- .input(z.object({
627
- classId: z.string(),
628
- userId: z.string(),
629
- }))
630
- .query(async ({ ctx, input }) => {
631
- const { classId, userId } = input;
632
- const isTeacher = await prisma.class.findFirst({
633
- where: {
634
- id: classId,
635
- teachers: {
636
- some: { id: ctx.user?.id }
637
- }
638
- }
639
- });
640
- // If student, only allow viewing their own grades
641
- if (ctx.user?.id !== userId && !isTeacher) {
642
- throw new TRPCError({
643
- code: 'UNAUTHORIZED',
644
- message: 'You can only view your own grades',
645
- });
646
- }
647
- const grades = await prisma.submission.findMany({
648
- where: {
649
- studentId: userId,
650
- assignment: {
651
- classId: classId,
652
- graded: true
653
- }
654
- },
655
- include: {
656
- assignment: {
657
- select: {
658
- id: true,
659
- title: true,
660
- maxGrade: true,
661
- weight: true,
662
- markSchemeId: true,
663
- dueDate: true,
664
- markScheme: {
665
- select: {
666
- structured: true,
667
- }
668
- },
669
- gradingBoundaryId: true,
670
- gradingBoundary: {
671
- select: {
672
- structured: true,
673
- }
674
- },
675
- }
676
- },
677
- }
678
- });
679
- return {
680
- grades,
681
- };
682
- }),
66
+ .input(z.object({ classId: z.string(), userId: z.string() }))
67
+ .query(({ ctx, input }) => getGrades(ctx.user?.id ?? "", input.classId, input.userId)),
683
68
  updateGrade: protectedTeacherProcedure
684
69
  .input(z.object({
685
70
  classId: z.string(),
@@ -687,257 +72,66 @@ export const classRouter = createTRPCRouter({
687
72
  submissionId: z.string(),
688
73
  gradeReceived: z.number().nullable(),
689
74
  }))
690
- .mutation(async ({ ctx, input }) => {
691
- const { classId, assignmentId, submissionId, gradeReceived } = input;
692
- // Update the grade
693
- const updatedSubmission = await prisma.submission.update({
694
- where: {
695
- id: submissionId,
696
- assignmentId: assignmentId,
697
- },
698
- data: {
699
- gradeReceived,
700
- },
701
- include: {
702
- assignment: {
703
- select: {
704
- id: true,
705
- title: true,
706
- maxGrade: true,
707
- weight: true,
708
- }
709
- }
710
- }
711
- });
712
- return updatedSubmission;
713
- }),
75
+ .mutation(({ input }) => updateGrade(input.assignmentId, input.submissionId, input.gradeReceived)),
714
76
  getEvents: protectedTeacherProcedure
715
- .input(z.object({
716
- classId: z.string(),
717
- }))
718
- .query(async ({ ctx, input }) => {
719
- const { classId } = input;
720
- const events = await prisma.event.findMany({
721
- where: {
722
- class: {
723
- id: classId,
724
- }
725
- },
726
- select: {
727
- name: true,
728
- startTime: true,
729
- endTime: true,
730
- }
731
- });
732
- return events;
733
- }),
77
+ .input(z.object({ classId: z.string() }))
78
+ .query(({ input }) => getEvents(input.classId)),
734
79
  listMarkSchemes: protectedClassMemberProcedure
735
- .input(z.object({
736
- classId: z.string(),
737
- }))
738
- .query(async ({ ctx, input }) => {
739
- const { classId } = input;
740
- const markSchemes = await prisma.markScheme.findMany({
741
- where: {
742
- class: {
743
- id: classId,
744
- },
745
- },
746
- });
747
- return markSchemes;
748
- }),
80
+ .input(z.object({ classId: z.string() }))
81
+ .query(({ input }) => listMarkSchemes(input.classId)),
749
82
  createMarkScheme: protectedTeacherProcedure
750
- .input(z.object({
751
- classId: z.string(),
752
- structure: z.string(),
753
- }))
754
- .mutation(async ({ ctx, input }) => {
755
- const { classId, structure } = input;
756
- const validatedStructure = structure.replace(/\\n/g, '\n');
757
- const markScheme = await prisma.markScheme.create({
758
- data: {
759
- class: {
760
- connect: {
761
- id: classId,
762
- },
763
- },
764
- structured: validatedStructure,
765
- },
766
- });
767
- return markScheme;
768
- }),
83
+ .input(z.object({ classId: z.string(), structure: z.string() }))
84
+ .mutation(({ input }) => createMarkScheme(input.classId, input.structure)),
769
85
  updateMarkScheme: protectedTeacherProcedure
770
86
  .input(z.object({
771
87
  classId: z.string(),
772
88
  markSchemeId: z.string(),
773
89
  structure: z.string(),
774
90
  }))
775
- .mutation(async ({ ctx, input }) => {
776
- const { classId, markSchemeId, structure } = input;
777
- const validatedStructure = structure.replace(/\\n/g, '\n');
778
- const markScheme = await prisma.markScheme.update({
779
- where: { id: markSchemeId },
780
- data: {
781
- class: {
782
- connect: {
783
- id: classId,
784
- },
785
- },
786
- structured: validatedStructure,
787
- },
788
- });
789
- return markScheme;
790
- }),
91
+ .mutation(({ input }) => updateMarkScheme(input.markSchemeId, input.classId, input.structure)),
791
92
  deleteMarkScheme: protectedTeacherProcedure
792
- .input(z.object({
793
- classId: z.string(),
794
- markSchemeId: z.string(),
795
- }))
796
- .mutation(async ({ ctx, input }) => {
797
- const { classId, markSchemeId } = input;
798
- const markScheme = await prisma.markScheme.delete({
799
- where: { id: markSchemeId },
800
- });
801
- return markScheme;
802
- }),
93
+ .input(z.object({ classId: z.string(), markSchemeId: z.string() }))
94
+ .mutation(({ input }) => deleteMarkScheme(input.markSchemeId)),
803
95
  listGradingBoundaries: protectedClassMemberProcedure
804
- .input(z.object({
805
- classId: z.string(),
806
- }))
807
- .query(async ({ ctx, input }) => {
808
- const { classId } = input;
809
- const gradingBoundaries = await prisma.gradingBoundary.findMany({
810
- where: {
811
- class: {
812
- id: classId,
813
- },
814
- },
815
- });
816
- return gradingBoundaries;
817
- }),
96
+ .input(z.object({ classId: z.string() }))
97
+ .query(({ input }) => listGradingBoundaries(input.classId)),
818
98
  createGradingBoundary: protectedTeacherProcedure
819
- .input(z.object({
820
- classId: z.string(),
821
- structure: z.string(),
822
- }))
823
- .mutation(async ({ ctx, input }) => {
824
- const { classId, structure } = input;
825
- const validatedStructure = structure.replace(/\\n/g, '\n');
826
- const gradingBoundary = await prisma.gradingBoundary.create({
827
- data: {
828
- class: {
829
- connect: {
830
- id: classId,
831
- },
832
- },
833
- structured: validatedStructure,
834
- },
835
- });
836
- return gradingBoundary;
837
- }),
99
+ .input(z.object({ classId: z.string(), structure: z.string() }))
100
+ .mutation(({ input }) => createGradingBoundary(input.classId, input.structure)),
838
101
  updateGradingBoundary: protectedTeacherProcedure
839
102
  .input(z.object({
840
103
  classId: z.string(),
841
104
  gradingBoundaryId: z.string(),
842
105
  structure: z.string(),
843
106
  }))
844
- .mutation(async ({ ctx, input }) => {
845
- const { classId, gradingBoundaryId, structure } = input;
846
- const validatedStructure = structure.replace(/\\n/g, '\n');
847
- const gradingBoundary = await prisma.gradingBoundary.update({
848
- where: { id: gradingBoundaryId },
849
- data: {
850
- class: {
851
- connect: {
852
- id: classId,
853
- },
854
- },
855
- structured: validatedStructure,
856
- },
857
- });
858
- return gradingBoundary;
859
- }),
107
+ .mutation(({ input }) => updateGradingBoundary(input.gradingBoundaryId, input.classId, input.structure)),
860
108
  deleteGradingBoundary: protectedTeacherProcedure
861
- .input(z.object({
862
- classId: z.string(),
863
- gradingBoundaryId: z.string(),
864
- }))
865
- .mutation(async ({ ctx, input }) => {
866
- const { classId, gradingBoundaryId } = input;
867
- const gradingBoundary = await prisma.gradingBoundary.delete({
868
- where: { id: gradingBoundaryId },
869
- });
870
- return gradingBoundary;
871
- }),
109
+ .input(z.object({ classId: z.string(), gradingBoundaryId: z.string() }))
110
+ .mutation(({ input }) => deleteGradingBoundary(input.gradingBoundaryId)),
872
111
  getSyllabus: protectedClassMemberProcedure
873
- .input(z.object({
874
- classId: z.string(),
875
- }))
876
- .query(async ({ input }) => {
877
- const { classId } = input;
878
- const syllabus = (await prisma.class.findUnique({
879
- where: {
880
- id: classId,
881
- },
882
- }))?.syllabus;
883
- const markSchemes = await prisma.markScheme.findMany({
884
- where: {
885
- classId,
886
- }
887
- });
888
- const gradingBoundaries = await prisma.gradingBoundary.findMany({
889
- where: {
890
- classId,
891
- }
892
- });
893
- return { syllabus, gradingBoundaries, markSchemes };
894
- }),
112
+ .input(z.object({ classId: z.string() }))
113
+ .query(({ input }) => getSyllabus(input.classId)),
895
114
  updateSyllabus: protectedTeacherProcedure
896
- .input(z.object({
897
- classId: z.string(),
898
- contents: z.string(),
899
- }))
900
- .mutation(async ({ input }) => {
901
- const { contents, classId } = input;
902
- if (!contents)
903
- throw new TRPCError({
904
- code: 'BAD_REQUEST',
905
- message: "Missing key contents",
906
- });
907
- const updated = await prisma.class.update({
908
- where: {
909
- id: classId
910
- },
911
- data: {
912
- syllabus: contents,
913
- }
914
- });
915
- return updated;
916
- }),
917
- // Lab Management Endpoints (Assignment-based)
115
+ .input(z.object({ classId: z.string(), contents: z.string() }))
116
+ .mutation(({ input }) => updateSyllabus(input.classId, input.contents)),
918
117
  listLabDrafts: protectedTeacherProcedure
919
- .input(z.object({
920
- classId: z.string(),
921
- }))
922
- .query(async ({ ctx, input }) => {
923
- const { classId } = input;
924
- const labDrafts = await prisma.assignment.findMany({
925
- where: {
926
- classId: classId,
927
- teacherId: ctx.user?.id,
928
- inProgress: true,
929
- },
930
- orderBy: {
931
- modifiedAt: 'desc',
932
- },
933
- });
934
- return labDrafts;
935
- }),
118
+ .input(z.object({ classId: z.string() }))
119
+ .query(({ ctx, input }) => listLabDrafts(input.classId, ctx.user?.id ?? "")),
936
120
  createLabDraft: protectedTeacherProcedure
937
121
  .input(z.object({
938
122
  classId: z.string(),
939
123
  title: z.string(),
940
- type: z.enum(['LAB', 'HOMEWORK', 'QUIZ', 'TEST', 'PROJECT', 'ESSAY', 'DISCUSSION', 'PRESENTATION', 'OTHER']),
124
+ type: z.enum([
125
+ "LAB",
126
+ "HOMEWORK",
127
+ "QUIZ",
128
+ "TEST",
129
+ "PROJECT",
130
+ "ESSAY",
131
+ "DISCUSSION",
132
+ "PRESENTATION",
133
+ "OTHER",
134
+ ]),
941
135
  instructions: z.string(),
942
136
  dueDate: z.date().optional(),
943
137
  maxGrade: z.number().optional(),
@@ -947,26 +141,9 @@ export const classRouter = createTRPCRouter({
947
141
  markSchemeId: z.string().optional(),
948
142
  gradingBoundaryId: z.string().optional(),
949
143
  }))
950
- .mutation(async ({ ctx, input }) => {
144
+ .mutation(({ ctx, input }) => {
951
145
  const { classId, ...draftData } = input;
952
- const labDraft = await prisma.assignment.create({
953
- data: {
954
- classId: classId,
955
- teacherId: ctx.user?.id,
956
- inProgress: true,
957
- graded: draftData.graded ?? false,
958
- maxGrade: draftData.maxGrade ?? 0,
959
- weight: draftData.weight ?? 1,
960
- dueDate: draftData.dueDate || new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // Default 1 week from now
961
- title: draftData.title,
962
- instructions: draftData.instructions,
963
- type: draftData.type,
964
- ...(draftData.sectionId && { sectionId: draftData.sectionId }),
965
- ...(draftData.markSchemeId && { markSchemeId: draftData.markSchemeId }),
966
- ...(draftData.gradingBoundaryId && { gradingBoundaryId: draftData.gradingBoundaryId }),
967
- },
968
- });
969
- return labDraft;
146
+ return createLabDraft(classId, ctx.user?.id ?? "", draftData);
970
147
  }),
971
148
  updateLabDraft: protectedTeacherProcedure
972
149
  .input(z.object({
@@ -982,47 +159,13 @@ export const classRouter = createTRPCRouter({
982
159
  markSchemeId: z.string().optional(),
983
160
  gradingBoundaryId: z.string().optional(),
984
161
  }))
985
- .mutation(async ({ ctx, input }) => {
162
+ .mutation(({ ctx, input }) => {
986
163
  const { classId, draftId, ...updateData } = input;
987
- const labDraft = await prisma.assignment.update({
988
- where: {
989
- id: draftId,
990
- classId: classId,
991
- teacherId: ctx.user?.id,
992
- inProgress: true,
993
- },
994
- data: {
995
- ...(updateData.title && { title: updateData.title }),
996
- ...(updateData.instructions && { instructions: updateData.instructions }),
997
- ...(updateData.dueDate && { dueDate: updateData.dueDate }),
998
- ...(updateData.maxGrade !== undefined && { maxGrade: updateData.maxGrade }),
999
- ...(updateData.weight !== undefined && { weight: updateData.weight }),
1000
- ...(updateData.graded !== undefined && { graded: updateData.graded }),
1001
- ...(updateData.sectionId !== undefined && { sectionId: updateData.sectionId }),
1002
- ...(updateData.markSchemeId !== undefined && { markSchemeId: updateData.markSchemeId }),
1003
- ...(updateData.gradingBoundaryId !== undefined && { gradingBoundaryId: updateData.gradingBoundaryId }),
1004
- modifiedAt: new Date(),
1005
- },
1006
- });
1007
- return labDraft;
164
+ return updateLabDraft(classId, ctx.user?.id ?? "", draftId, updateData);
1008
165
  }),
1009
166
  deleteLabDraft: protectedTeacherProcedure
1010
- .input(z.object({
1011
- classId: z.string(),
1012
- draftId: z.string(),
1013
- }))
1014
- .mutation(async ({ ctx, input }) => {
1015
- const { classId, draftId } = input;
1016
- const labDraft = await prisma.assignment.delete({
1017
- where: {
1018
- id: draftId,
1019
- classId: classId,
1020
- teacherId: ctx.user?.id,
1021
- inProgress: true,
1022
- },
1023
- });
1024
- return labDraft;
1025
- }),
167
+ .input(z.object({ classId: z.string(), draftId: z.string() }))
168
+ .mutation(({ ctx, input }) => deleteLabDraft(input.classId, ctx.user?.id ?? "", input.draftId)),
1026
169
  publishLabDraft: protectedTeacherProcedure
1027
170
  .input(z.object({
1028
171
  classId: z.string(),
@@ -1032,136 +175,23 @@ export const classRouter = createTRPCRouter({
1032
175
  weight: z.number().optional(),
1033
176
  graded: z.boolean().optional(),
1034
177
  }))
1035
- .mutation(async ({ ctx, input }) => {
178
+ .mutation(({ ctx, input }) => {
1036
179
  const { classId, draftId, ...publishData } = input;
1037
- // Get the lab draft
1038
- const labDraft = await prisma.assignment.findUnique({
1039
- where: {
1040
- id: draftId,
1041
- classId: classId,
1042
- teacherId: ctx.user?.id,
1043
- inProgress: true,
1044
- },
1045
- });
1046
- if (!labDraft) {
1047
- throw new TRPCError({
1048
- code: 'NOT_FOUND',
1049
- message: 'Lab draft not found',
1050
- });
1051
- }
1052
- // Publish the draft by updating it to not be in progress
1053
- const publishedAssignment = await prisma.assignment.update({
1054
- where: { id: draftId },
1055
- data: {
1056
- inProgress: false,
1057
- dueDate: publishData.dueDate || labDraft.dueDate,
1058
- maxGrade: publishData.maxGrade || labDraft.maxGrade || 100,
1059
- weight: publishData.weight || labDraft.weight || 1,
1060
- graded: publishData.graded !== undefined ? publishData.graded : true,
1061
- modifiedAt: new Date(),
1062
- },
1063
- });
1064
- return publishedAssignment;
180
+ return publishLabDraft(classId, ctx.user?.id ?? "", draftId, publishData);
1065
181
  }),
1066
182
  getFiles: protectedClassMemberProcedure
183
+ .input(z.object({ classId: z.string() }))
184
+ .query(({ input }) => getFiles(input.classId)),
185
+ exportClass: protectedTeacherProcedure
186
+ .input(z.object({ classId: z.string() }))
187
+ .mutation(({ ctx, input }) => exportClass(input.classId, ctx.user?.id ?? "")),
188
+ importClass: protectedProcedure
1067
189
  .input(z.object({
1068
190
  classId: z.string(),
191
+ year: z.number(),
192
+ classData: z.any(),
1069
193
  }))
1070
- .query(async ({ ctx, input }) => {
1071
- const { classId } = input;
1072
- // Get all assignments with their files and submissions
1073
- const assignments = await prisma.assignment.findMany({
1074
- where: {
1075
- classId: classId,
1076
- },
1077
- include: {
1078
- attachments: {
1079
- select: {
1080
- id: true,
1081
- name: true,
1082
- type: true,
1083
- size: true,
1084
- path: true,
1085
- thumbnailId: true,
1086
- uploadedAt: true,
1087
- user: {
1088
- select: {
1089
- id: true,
1090
- username: true,
1091
- },
1092
- },
1093
- },
1094
- },
1095
- submissions: {
1096
- include: {
1097
- attachments: {
1098
- select: {
1099
- id: true,
1100
- name: true,
1101
- type: true,
1102
- size: true,
1103
- path: true,
1104
- thumbnailId: true,
1105
- uploadedAt: true,
1106
- user: {
1107
- select: {
1108
- id: true,
1109
- username: true,
1110
- },
1111
- },
1112
- },
1113
- },
1114
- annotations: {
1115
- select: {
1116
- id: true,
1117
- name: true,
1118
- type: true,
1119
- size: true,
1120
- path: true,
1121
- thumbnailId: true,
1122
- uploadedAt: true,
1123
- user: {
1124
- select: {
1125
- id: true,
1126
- username: true,
1127
- },
1128
- },
1129
- },
1130
- },
1131
- student: {
1132
- select: {
1133
- id: true,
1134
- username: true,
1135
- },
1136
- },
1137
- },
1138
- },
1139
- teacher: {
1140
- select: {
1141
- id: true,
1142
- username: true,
1143
- },
1144
- },
1145
- },
1146
- orderBy: {
1147
- createdAt: 'desc',
1148
- },
1149
- });
1150
- // Organize files by assignment structure
1151
- const organizedFiles = assignments.map(assignment => ({
1152
- id: assignment.id,
1153
- title: assignment.title,
1154
- teacher: assignment.teacher,
1155
- teacherAttachments: assignment.attachments,
1156
- students: assignment.submissions.map(submission => ({
1157
- id: submission.student.id,
1158
- username: submission.student.username,
1159
- attachments: submission.attachments,
1160
- annotations: submission.annotations,
1161
- })),
1162
- }));
1163
- return organizedFiles;
1164
- }),
194
+ .mutation(({ ctx, input }) => importClass(input.classId, ctx.user?.id ?? "", input.year, input.classData)),
1165
195
  });
1166
196
  //# sourceMappingURL=class.js.map
1167
- //# debugId=4de0a549-5566-5b60-aa1d-acdb528cce7a
197
+ //# debugId=d26131b5-0358-5872-893b-73bd753de228