@studious-lms/server 1.2.52 → 1.3.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 (480) 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 +36 -94
  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 +439 -0
  53. package/dist/models/class.d.ts.map +1 -0
  54. package/dist/models/class.js +546 -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 +21 -0
  109. package/dist/pipelines/aiLabChat.d.ts.map +1 -0
  110. package/dist/pipelines/aiLabChat.js +460 -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 +1399 -1271
  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 +140 -68
  143. package/dist/routers/class.d.ts.map +1 -1
  144. package/dist/routers/class.js +82 -1051
  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 +11 -10
  167. package/dist/routers/labChat.d.ts.map +1 -1
  168. package/dist/routers/labChat.js +19 -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 +2 -2
  175. package/dist/routers/message.d.ts.map +1 -1
  176. package/dist/routers/message.js +27 -522
  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 +51 -38
  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/aiNewtonChat.d.ts.map +1 -1
  200. package/dist/server/pipelines/aiNewtonChat.js +8 -3
  201. package/dist/server/pipelines/aiNewtonChat.js.map +1 -1
  202. package/dist/server/pipelines/gradeWorksheet.d.ts +6 -6
  203. package/dist/server/pipelines/gradeWorksheet.d.ts.map +1 -1
  204. package/dist/server/pipelines/gradeWorksheet.js +12 -5
  205. package/dist/server/pipelines/gradeWorksheet.js.map +1 -1
  206. package/dist/services/agenda.d.ts +100 -0
  207. package/dist/services/agenda.d.ts.map +1 -0
  208. package/dist/services/agenda.js +21 -0
  209. package/dist/services/agenda.js.map +1 -0
  210. package/dist/services/announcement.d.ts +135 -0
  211. package/dist/services/announcement.d.ts.map +1 -0
  212. package/dist/services/announcement.js +223 -0
  213. package/dist/services/announcement.js.map +1 -0
  214. package/dist/services/assignment.d.ts +1462 -0
  215. package/dist/services/assignment.d.ts.map +1 -0
  216. package/dist/services/assignment.js +898 -0
  217. package/dist/services/assignment.js.map +1 -0
  218. package/dist/services/attendance.d.ts +93 -0
  219. package/dist/services/attendance.d.ts.map +1 -0
  220. package/dist/services/attendance.js +61 -0
  221. package/dist/services/attendance.js.map +1 -0
  222. package/dist/services/auth.d.ts +68 -0
  223. package/dist/services/auth.d.ts.map +1 -0
  224. package/dist/services/auth.js +218 -0
  225. package/dist/services/auth.js.map +1 -0
  226. package/dist/services/class.d.ts +621 -0
  227. package/dist/services/class.d.ts.map +1 -0
  228. package/dist/services/class.js +474 -0
  229. package/dist/services/class.js.map +1 -0
  230. package/dist/services/comment.d.ts +100 -0
  231. package/dist/services/comment.d.ts.map +1 -0
  232. package/dist/services/comment.js +83 -0
  233. package/dist/services/comment.js.map +1 -0
  234. package/dist/services/conversation.d.ts +159 -0
  235. package/dist/services/conversation.d.ts.map +1 -0
  236. package/dist/services/conversation.js +138 -0
  237. package/dist/services/conversation.js.map +1 -0
  238. package/dist/services/event.d.ts +216 -0
  239. package/dist/services/event.d.ts.map +1 -0
  240. package/dist/services/event.js +168 -0
  241. package/dist/services/event.js.map +1 -0
  242. package/dist/services/file.d.ts +74 -0
  243. package/dist/services/file.d.ts.map +1 -0
  244. package/dist/services/file.js +133 -0
  245. package/dist/services/file.js.map +1 -0
  246. package/dist/services/folder.d.ts +239 -0
  247. package/dist/services/folder.d.ts.map +1 -0
  248. package/dist/services/folder.js +248 -0
  249. package/dist/services/folder.js.map +1 -0
  250. package/dist/services/labChat.d.ts +165 -0
  251. package/dist/services/labChat.d.ts.map +1 -0
  252. package/dist/services/labChat.js +289 -0
  253. package/dist/services/labChat.js.map +1 -0
  254. package/dist/services/marketing.d.ts +50 -0
  255. package/dist/services/marketing.d.ts.map +1 -0
  256. package/dist/services/marketing.js +32 -0
  257. package/dist/services/marketing.js.map +1 -0
  258. package/dist/services/message.d.ts +95 -0
  259. package/dist/services/message.d.ts.map +1 -0
  260. package/dist/services/message.js +350 -0
  261. package/dist/services/message.js.map +1 -0
  262. package/dist/services/newtonChat.d.ts +22 -0
  263. package/dist/services/newtonChat.d.ts.map +1 -0
  264. package/dist/services/newtonChat.js +174 -0
  265. package/dist/services/newtonChat.js.map +1 -0
  266. package/dist/services/notification.d.ts +65 -0
  267. package/dist/services/notification.d.ts.map +1 -0
  268. package/dist/services/notification.js +33 -0
  269. package/dist/services/notification.js.map +1 -0
  270. package/dist/services/section.d.ts +53 -0
  271. package/dist/services/section.d.ts.map +1 -0
  272. package/dist/services/section.js +199 -0
  273. package/dist/services/section.js.map +1 -0
  274. package/dist/services/user.d.ts +48 -0
  275. package/dist/services/user.d.ts.map +1 -0
  276. package/dist/services/user.js +141 -0
  277. package/dist/services/user.js.map +1 -0
  278. package/dist/services/worksheet.d.ts +239 -0
  279. package/dist/services/worksheet.d.ts.map +1 -0
  280. package/dist/services/worksheet.js +235 -0
  281. package/dist/services/worksheet.js.map +1 -0
  282. package/dist/utils/aiUser.d.ts +1 -3
  283. package/dist/utils/aiUser.d.ts.map +1 -1
  284. package/dist/utils/aiUser.js +6 -5
  285. package/dist/utils/aiUser.js.map +1 -1
  286. package/dist/utils/email.d.ts +3 -0
  287. package/dist/utils/email.d.ts.map +1 -1
  288. package/dist/utils/email.js +7 -4
  289. package/dist/utils/email.js.map +1 -1
  290. package/dist/utils/generateInviteCode.d.ts +1 -2
  291. package/dist/utils/generateInviteCode.d.ts.map +1 -1
  292. package/dist/utils/generateInviteCode.js +3 -4
  293. package/dist/utils/generateInviteCode.js.map +1 -1
  294. package/dist/utils/inference.d.ts +3 -0
  295. package/dist/utils/inference.d.ts.map +1 -1
  296. package/dist/utils/inference.js +7 -4
  297. package/dist/utils/inference.js.map +1 -1
  298. package/dist/utils/logger.d.ts +3 -0
  299. package/dist/utils/logger.d.ts.map +1 -1
  300. package/dist/utils/logger.js +5 -2
  301. package/dist/utils/logger.js.map +1 -1
  302. package/dist/utils/prismaErrorHandler.d.ts.map +1 -1
  303. package/dist/utils/prismaErrorHandler.js +5 -2
  304. package/dist/utils/prismaErrorHandler.js.map +1 -1
  305. package/dist/utils/prismaWrapper.d.ts +1 -0
  306. package/dist/utils/prismaWrapper.d.ts.map +1 -1
  307. package/dist/utils/prismaWrapper.js +6 -2
  308. package/dist/utils/prismaWrapper.js.map +1 -1
  309. package/docker-compose.yml +5 -0
  310. package/package.json +4 -3
  311. package/src/index.ts +119 -12
  312. package/src/lib/config/env.ts +6 -0
  313. package/src/lib/fileUpload.ts +0 -1
  314. package/src/lib/googleCloudStorage.ts +17 -0
  315. package/src/lib/pusher.ts +5 -1
  316. package/src/lib/redis.ts +56 -0
  317. package/src/lib/thumbnailGenerator.ts +170 -168
  318. package/src/middleware/auth.ts +83 -136
  319. package/src/models/agenda.ts +46 -0
  320. package/src/models/announcement.ts +134 -0
  321. package/src/models/assignment.ts +322 -0
  322. package/src/models/attendance.ts +208 -0
  323. package/src/models/auth.ts +247 -0
  324. package/src/models/class.ts +598 -0
  325. package/src/models/comment.ts +152 -0
  326. package/src/models/conversation.ts +200 -0
  327. package/src/models/event.ts +177 -0
  328. package/src/models/file.ts +129 -0
  329. package/src/models/folder.ts +225 -0
  330. package/src/models/labChat.ts +213 -0
  331. package/src/models/marketing.ts +45 -0
  332. package/src/models/message.ts +153 -0
  333. package/src/models/newtonChat.ts +70 -0
  334. package/src/models/notification.ts +54 -0
  335. package/src/models/section.ts +98 -0
  336. package/src/models/user.ts +47 -0
  337. package/src/models/worksheet.ts +294 -0
  338. package/src/{server/pipelines → pipelines}/aiLabChat.ts +11 -7
  339. package/src/{server/pipelines → pipelines}/aiNewtonChat.ts +15 -6
  340. package/src/{server/pipelines → pipelines}/gradeWorksheet.ts +25 -14
  341. package/src/routers/agenda.ts +3 -66
  342. package/src/routers/announcement.ts +54 -495
  343. package/src/routers/assignment.ts +126 -2018
  344. package/src/routers/attendance.ts +15 -276
  345. package/src/routers/auth.ts +79 -442
  346. package/src/routers/class.ts +263 -1186
  347. package/src/routers/comment.ts +61 -288
  348. package/src/routers/conversation.ts +51 -360
  349. package/src/routers/event.ts +50 -481
  350. package/src/routers/file.ts +45 -368
  351. package/src/routers/folder.ts +107 -836
  352. package/src/routers/labChat.ts +29 -605
  353. package/src/routers/marketing.ts +35 -77
  354. package/src/routers/message.ts +45 -571
  355. package/src/routers/newtonChat.ts +17 -278
  356. package/src/routers/notifications.ts +32 -82
  357. package/src/routers/section.ts +46 -330
  358. package/src/routers/user.ts +49 -227
  359. package/src/routers/worksheet.ts +215 -503
  360. package/src/services/agenda.ts +21 -0
  361. package/src/services/announcement.ts +290 -0
  362. package/src/services/assignment.ts +1198 -0
  363. package/src/services/attendance.ts +85 -0
  364. package/src/services/auth.ts +277 -0
  365. package/src/services/class.ts +622 -0
  366. package/src/services/comment.ts +106 -0
  367. package/src/services/conversation.ts +213 -0
  368. package/src/services/event.ts +231 -0
  369. package/src/services/file.ts +167 -0
  370. package/src/services/folder.ts +316 -0
  371. package/src/services/labChat.ts +352 -0
  372. package/src/services/marketing.ts +57 -0
  373. package/src/services/message.ts +461 -0
  374. package/src/services/newtonChat.ts +222 -0
  375. package/src/services/notification.ts +50 -0
  376. package/src/services/section.ts +283 -0
  377. package/src/services/user.ts +172 -0
  378. package/src/services/worksheet.ts +358 -0
  379. package/src/utils/aiUser.ts +4 -3
  380. package/src/utils/email.ts +5 -3
  381. package/src/utils/generateInviteCode.ts +1 -3
  382. package/src/utils/inference.ts +5 -2
  383. package/src/utils/logger.ts +3 -1
  384. package/src/utils/prismaErrorHandler.ts +3 -0
  385. package/src/utils/prismaWrapper.ts +4 -0
  386. package/tests/globalSetup.ts +62 -0
  387. package/tests/helpers.ts +22 -0
  388. package/tests/middleware/security.test.ts +42 -0
  389. package/tests/routers/agenda.test.ts +138 -0
  390. package/tests/routers/announcement.test.ts +490 -0
  391. package/tests/routers/assignment.test.ts +837 -0
  392. package/tests/{attendance.test.ts → routers/attendance.test.ts} +6 -14
  393. package/tests/routers/auth.test.ts +171 -0
  394. package/tests/{class.test.ts → routers/class.test.ts} +131 -85
  395. package/tests/routers/comment.test.ts +126 -0
  396. package/tests/routers/conversation.test.ts +145 -0
  397. package/tests/{event.test.ts → routers/event.test.ts} +93 -32
  398. package/tests/routers/folder.test.ts +178 -0
  399. package/tests/routers/labChat.test.ts +115 -0
  400. package/tests/routers/marketing.test.ts +59 -0
  401. package/tests/routers/message.test.ts +123 -0
  402. package/tests/routers/notification.test.ts +69 -0
  403. package/tests/{section.test.ts → routers/section.test.ts} +5 -13
  404. package/tests/server/rateLimit.test.ts +73 -0
  405. package/tests/setup.ts +18 -92
  406. package/tests/user.test.ts +9 -31
  407. package/tests/utils/aiUser.test.ts +22 -0
  408. package/tests/utils/generateInviteCode.test.ts +24 -0
  409. package/tests/utils/logger.test.ts +74 -0
  410. package/tests/utils/prismaErrorHandler.test.ts +101 -0
  411. package/tests/utils/prismaWrapper.test.ts +82 -0
  412. package/tests/worksheet.test.ts +181 -0
  413. package/vitest.config.ts +6 -3
  414. package/vitest.unit.config.ts +21 -0
  415. package/TODO.md +0 -2
  416. package/coverage/base.css +0 -224
  417. package/coverage/block-navigation.js +0 -87
  418. package/coverage/clover.xml +0 -12110
  419. package/coverage/coverage-final.json +0 -44
  420. package/coverage/favicon.png +0 -0
  421. package/coverage/index.html +0 -221
  422. package/coverage/prettify.css +0 -1
  423. package/coverage/prettify.js +0 -2
  424. package/coverage/server/index.html +0 -116
  425. package/coverage/server/src/exportType.ts.html +0 -109
  426. package/coverage/server/src/index.html +0 -161
  427. package/coverage/server/src/index.ts.html +0 -1702
  428. package/coverage/server/src/instrument.ts.html +0 -130
  429. package/coverage/server/src/lib/config/env.ts.html +0 -448
  430. package/coverage/server/src/lib/config/index.html +0 -116
  431. package/coverage/server/src/lib/fileUpload.ts.html +0 -1138
  432. package/coverage/server/src/lib/googleCloudStorage.ts.html +0 -334
  433. package/coverage/server/src/lib/index.html +0 -206
  434. package/coverage/server/src/lib/jsonConversion.ts.html +0 -2323
  435. package/coverage/server/src/lib/jsonStyles.ts.html +0 -193
  436. package/coverage/server/src/lib/notificationHandler.ts.html +0 -193
  437. package/coverage/server/src/lib/pusher.ts.html +0 -121
  438. package/coverage/server/src/lib/thumbnailGenerator.ts.html +0 -592
  439. package/coverage/server/src/middleware/auth.ts.html +0 -646
  440. package/coverage/server/src/middleware/index.html +0 -146
  441. package/coverage/server/src/middleware/logging.ts.html +0 -244
  442. package/coverage/server/src/middleware/security.ts.html +0 -271
  443. package/coverage/server/src/routers/_app.ts.html +0 -232
  444. package/coverage/server/src/routers/agenda.ts.html +0 -319
  445. package/coverage/server/src/routers/announcement.ts.html +0 -3481
  446. package/coverage/server/src/routers/assignment.ts.html +0 -7633
  447. package/coverage/server/src/routers/attendance.ts.html +0 -1030
  448. package/coverage/server/src/routers/auth.ts.html +0 -1081
  449. package/coverage/server/src/routers/class.ts.html +0 -3535
  450. package/coverage/server/src/routers/comment.ts.html +0 -991
  451. package/coverage/server/src/routers/conversation.ts.html +0 -982
  452. package/coverage/server/src/routers/event.ts.html +0 -1609
  453. package/coverage/server/src/routers/file.ts.html +0 -1144
  454. package/coverage/server/src/routers/folder.ts.html +0 -2797
  455. package/coverage/server/src/routers/index.html +0 -386
  456. package/coverage/server/src/routers/labChat.ts.html +0 -3073
  457. package/coverage/server/src/routers/marketing.ts.html +0 -340
  458. package/coverage/server/src/routers/message.ts.html +0 -1912
  459. package/coverage/server/src/routers/notifications.ts.html +0 -364
  460. package/coverage/server/src/routers/section.ts.html +0 -1120
  461. package/coverage/server/src/routers/user.ts.html +0 -862
  462. package/coverage/server/src/routers/worksheet.ts.html +0 -1729
  463. package/coverage/server/src/trpc.ts.html +0 -397
  464. package/coverage/server/src/types/index.html +0 -116
  465. package/coverage/server/src/types/trpc.ts.html +0 -127
  466. package/coverage/server/src/utils/aiUser.ts.html +0 -280
  467. package/coverage/server/src/utils/email.ts.html +0 -121
  468. package/coverage/server/src/utils/generateInviteCode.ts.html +0 -106
  469. package/coverage/server/src/utils/index.html +0 -206
  470. package/coverage/server/src/utils/inference.ts.html +0 -709
  471. package/coverage/server/src/utils/logger.ts.html +0 -664
  472. package/coverage/server/src/utils/prismaErrorHandler.ts.html +0 -907
  473. package/coverage/server/src/utils/prismaWrapper.ts.html +0 -355
  474. package/coverage/server/vitest.config.ts.html +0 -196
  475. package/coverage/sort-arrow-sprite.png +0 -0
  476. package/coverage/sorter.js +0 -210
  477. package/src/lib/notificationHandler.ts +0 -36
  478. package/tests/announcement.test.ts +0 -164
  479. package/tests/assignment.test.ts +0 -296
  480. package/tests/auth.test.ts +0 -48
@@ -36,6 +36,7 @@ const fullSchema = baseSchema.extend({
36
36
  BACKEND_URL: z.string().url().default('http://localhost:3001'),
37
37
  SENTRY_DSN: z.string().url().optional(),
38
38
  EMAIL_HOST: z.string().min(1, 'EMAIL_HOST is required'),
39
+ EMAIL_PORT: z.string().transform(Number).default('587'),
39
40
  EMAIL_USER: z.string().email('EMAIL_USER must be a valid email'),
40
41
  EMAIL_PASS: z.string().min(1, 'EMAIL_PASS is required'),
41
42
  EMAIL_DRY_RUN: z.string().optional().default('false'),
@@ -47,6 +48,8 @@ const fullSchema = baseSchema.extend({
47
48
  PUSHER_KEY: z.string().min(1, 'PUSHER_KEY is required'),
48
49
  PUSHER_SECRET: z.string().min(1, 'PUSHER_SECRET is required'),
49
50
  PUSHER_CLUSTER: z.string().min(1, 'PUSHER_CLUSTER is required'),
51
+ PUSHER_AUTH_COOKIE_NAME: z.string().optional(), // Cookie name for session token (default: 'token')
52
+ REDIS_URL: z.string().url().optional(), // Redis connection URL (e.g. redis://localhost:6379)
50
53
  INFERENCE_API_KEY: z.string().optional(),
51
54
  INFERENCE_API_BASE_URL: z.string().url().optional(),
52
55
  OPENAI_API_KEY: z.string().optional(),
@@ -59,6 +62,7 @@ const testSchema = baseSchema.extend({
59
62
  BACKEND_URL: z.string().url().optional().default('http://localhost:3001'),
60
63
  SENTRY_DSN: z.string().url().optional(),
61
64
  EMAIL_HOST: z.string().optional().default('smtp.test.com'),
65
+ EMAIL_PORT: z.string().transform(Number).default('587'),
62
66
  EMAIL_USER: z.string().email().optional().default('test@test.com'),
63
67
  EMAIL_PASS: z.string().optional().default('test'),
64
68
  EMAIL_DRY_RUN: z.string().optional().default('false'),
@@ -70,6 +74,8 @@ const testSchema = baseSchema.extend({
70
74
  PUSHER_KEY: z.string().optional().default('test-key'),
71
75
  PUSHER_SECRET: z.string().optional().default('test-secret'),
72
76
  PUSHER_CLUSTER: z.string().optional().default('us2'),
77
+ PUSHER_AUTH_COOKIE_NAME: z.string().optional(),
78
+ REDIS_URL: z.string().url().optional(),
73
79
  INFERENCE_API_KEY: z.string().optional(),
74
80
  OPENAI_API_KEY: z.string().optional(),
75
81
  INFERENCE_API_BASE_URL: z.string().url().optional(),
@@ -1,7 +1,6 @@
1
1
  import { TRPCError } from "@trpc/server";
2
2
  import { v4 as uuidv4 } from "uuid";
3
3
  import { getSignedUrl, objectExists } from "./googleCloudStorage.js";
4
- import { generateMediaThumbnail } from "./thumbnailGenerator.js";
5
4
  import { prisma } from "./prisma.js";
6
5
  import { logger } from "../utils/logger.js";
7
6
  import { env } from "./config/env.js";
@@ -81,4 +81,21 @@ export async function objectExists(bucketName: string, objectPath: string): Prom
81
81
  message: 'Failed to check object existence',
82
82
  });
83
83
  }
84
+ }
85
+
86
+ /**
87
+ * Copies a file within the same bucket to a new path
88
+ * @param sourcePath The GCS path of the source file
89
+ * @param destPath The GCS path for the destination
90
+ */
91
+ export async function copyFile(sourcePath: string, destPath: string): Promise<void> {
92
+ try {
93
+ await bucket.file(sourcePath).copy(destPath);
94
+ } catch (error) {
95
+ console.error('Error copying file in Google Cloud Storage:', error);
96
+ throw new TRPCError({
97
+ code: 'INTERNAL_SERVER_ERROR',
98
+ message: 'Failed to copy file in storage',
99
+ });
100
+ }
84
101
  }
package/src/lib/pusher.ts CHANGED
@@ -9,4 +9,8 @@ const pusher = new Pusher({
9
9
  useTLS: env.NODE_ENV !== 'development',
10
10
  });
11
11
 
12
- export { pusher };
12
+ const chatChannel = (conversationId: string) => `private-conversation-${conversationId}`;
13
+ const worksheetChannel = (worksheetResponseId: string) => `private-worksheet-${worksheetResponseId}`;
14
+ const teacherChannel = (classId: string) => `private-teacher-${classId}`;
15
+
16
+ export { pusher, chatChannel, worksheetChannel, teacherChannel };
@@ -0,0 +1,56 @@
1
+ import Redis from 'ioredis';
2
+ import { env } from './config/env.js';
3
+ import { logger } from '../utils/logger.js';
4
+
5
+ let redis: Redis | null = null;
6
+
7
+ export function getRedis(): Redis | null {
8
+ return redis;
9
+ }
10
+
11
+ export async function connectRedis(): Promise<Redis | null> {
12
+ const url = env.REDIS_URL;
13
+ if (!url) {
14
+ logger.info('Redis not configured (REDIS_URL not set), skipping');
15
+ return null;
16
+ }
17
+
18
+ if (redis) {
19
+ return redis;
20
+ }
21
+
22
+ redis = new Redis(url, {
23
+ maxRetriesPerRequest: 3,
24
+ retryStrategy(times) {
25
+ if (times > 3) return null;
26
+ return Math.min(times * 200, 2000);
27
+ },
28
+ });
29
+
30
+ redis.on('error', (err) => {
31
+ logger.error('Redis connection error', { error: err.message });
32
+ });
33
+
34
+ redis.on('connect', () => {
35
+ logger.info('Redis connected');
36
+ });
37
+
38
+ try {
39
+ await redis.ping();
40
+ logger.info('Redis ready');
41
+ return redis;
42
+ } catch (error) {
43
+ logger.error('Redis ping failed', { error });
44
+ redis.disconnect();
45
+ redis = null;
46
+ return null;
47
+ }
48
+ }
49
+
50
+ export async function disconnectRedis(): Promise<void> {
51
+ if (redis) {
52
+ await redis.quit();
53
+ redis = null;
54
+ logger.info('Redis disconnected');
55
+ }
56
+ }
@@ -1,170 +1,172 @@
1
- import sharp from 'sharp';
2
- import { prisma } from './prisma.js';
3
- import { deleteFile, getSignedUrl } from './googleCloudStorage.js';
4
-
5
- // Thumbnail size configuration
6
- const THUMBNAIL_WIDTH = 200;
7
- const THUMBNAIL_HEIGHT = 200;
8
-
9
- // File type configurations
10
- const SUPPORTED_IMAGE_TYPES = [
11
- 'image/jpeg',
12
- 'image/png',
13
- 'image/gif',
14
- 'image/webp',
15
- 'image/tiff',
16
- 'image/bmp',
17
- 'image/avif'
18
- ];
19
-
20
- const DOCUMENT_TYPES = [
21
- 'application/pdf',
22
- 'application/msword',
23
- 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // .docx
24
- 'application/vnd.ms-excel',
25
- 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
26
- 'application/vnd.ms-powerpoint',
27
- 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // .pptx
28
- 'text/plain',
29
- 'text/csv',
30
- 'application/json',
31
- 'text/html',
32
- 'text/javascript',
33
- 'text/css'
34
- ];
35
-
36
- const VIDEO_TYPES = [
37
- 'video/mp4',
38
- 'video/webm',
39
- 'video/ogg',
40
- 'video/quicktime'
41
- ];
42
-
43
- const AUDIO_TYPES = [
44
- 'audio/mpeg',
45
- 'audio/ogg',
46
- 'audio/wav',
47
- 'audio/webm'
48
- ];
49
-
50
- /**
51
- * Generates a thumbnail for an image or PDF file
52
- * @param fileBuffer The file buffer
53
- * @param fileType The MIME type of the file
54
- * @returns Thumbnail buffer
55
- */
56
- export async function generateMediaThumbnail(fileBuffer: Buffer, fileType: string): Promise<Buffer> {
57
- if (fileType === 'application/pdf') {
58
- // For PDFs, we need to use a different approach
59
- try {
60
- return await sharp(fileBuffer, {
61
- density: 300, // Higher density for better quality
62
- page: 0 // First page only
63
- })
64
- .resize(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, {
65
- fit: 'inside',
66
- withoutEnlargement: true,
67
- })
68
- .jpeg({ quality: 80 })
69
- .toBuffer();
70
- } catch (error) {
71
- console.warn('Failed to generate PDF thumbnail:', error);
72
- return generateGenericThumbnail(fileType);
73
- }
74
- }
1
+ // @deprecated: this is not used anymore
2
+
3
+ // import sharp from 'sharp';
4
+ // import { prisma } from './prisma.js';
5
+ // import { deleteFile, getSignedUrl } from './googleCloudStorage.js';
6
+
7
+ // // Thumbnail size configuration
8
+ // const THUMBNAIL_WIDTH = 200;
9
+ // const THUMBNAIL_HEIGHT = 200;
10
+
11
+ // // File type configurations
12
+ // const SUPPORTED_IMAGE_TYPES = [
13
+ // 'image/jpeg',
14
+ // 'image/png',
15
+ // 'image/gif',
16
+ // 'image/webp',
17
+ // 'image/tiff',
18
+ // 'image/bmp',
19
+ // 'image/avif'
20
+ // ];
21
+
22
+ // const DOCUMENT_TYPES = [
23
+ // 'application/pdf',
24
+ // 'application/msword',
25
+ // 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // .docx
26
+ // 'application/vnd.ms-excel',
27
+ // 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
28
+ // 'application/vnd.ms-powerpoint',
29
+ // 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // .pptx
30
+ // 'text/plain',
31
+ // 'text/csv',
32
+ // 'application/json',
33
+ // 'text/html',
34
+ // 'text/javascript',
35
+ // 'text/css'
36
+ // ];
37
+
38
+ // const VIDEO_TYPES = [
39
+ // 'video/mp4',
40
+ // 'video/webm',
41
+ // 'video/ogg',
42
+ // 'video/quicktime'
43
+ // ];
44
+
45
+ // const AUDIO_TYPES = [
46
+ // 'audio/mpeg',
47
+ // 'audio/ogg',
48
+ // 'audio/wav',
49
+ // 'audio/webm'
50
+ // ];
51
+
52
+ // /**
53
+ // * Generates a thumbnail for an image or PDF file
54
+ // * @param fileBuffer The file buffer
55
+ // * @param fileType The MIME type of the file
56
+ // * @returns Thumbnail buffer
57
+ // */
58
+ // export async function generateMediaThumbnail(fileBuffer: Buffer, fileType: string): Promise<Buffer> {
59
+ // if (fileType === 'application/pdf') {
60
+ // // For PDFs, we need to use a different approach
61
+ // try {
62
+ // return await sharp(fileBuffer, {
63
+ // density: 300, // Higher density for better quality
64
+ // page: 0 // First page only
65
+ // })
66
+ // .resize(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, {
67
+ // fit: 'inside',
68
+ // withoutEnlargement: true,
69
+ // })
70
+ // .jpeg({ quality: 80 })
71
+ // .toBuffer();
72
+ // } catch (error) {
73
+ // console.warn('Failed to generate PDF thumbnail:', error);
74
+ // return generateGenericThumbnail(fileType);
75
+ // }
76
+ // }
75
77
 
76
- // For regular images
77
- return sharp(fileBuffer)
78
- .resize(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, {
79
- fit: 'inside',
80
- withoutEnlargement: true,
81
- })
82
- .jpeg({ quality: 80 })
83
- .toBuffer();
84
- }
85
-
86
- /**
87
- * Generates a generic icon-based thumbnail for a file type
88
- * @param fileType The MIME type of the file
89
- * @returns Thumbnail buffer
90
- */
91
- async function generateGenericThumbnail(fileType: string): Promise<Buffer> {
92
- // Create a blank canvas with a colored background based on file type
93
- const canvas = sharp({
94
- create: {
95
- width: THUMBNAIL_WIDTH,
96
- height: THUMBNAIL_HEIGHT,
97
- channels: 4,
98
- background: { r: 245, g: 245, b: 245, alpha: 1 }
99
- }
100
- });
101
-
102
- // Add a colored overlay based on file type
103
- let color = { r: 200, g: 200, b: 200, alpha: 0.5 }; // Default gray
104
-
105
- if (DOCUMENT_TYPES.includes(fileType)) {
106
- color = { r: 52, g: 152, b: 219, alpha: 0.5 }; // Blue for documents
107
- } else if (VIDEO_TYPES.includes(fileType)) {
108
- color = { r: 231, g: 76, b: 60, alpha: 0.5 }; // Red for videos
109
- } else if (AUDIO_TYPES.includes(fileType)) {
110
- color = { r: 46, g: 204, b: 113, alpha: 0.5 }; // Green for audio
111
- }
112
-
113
- return canvas
114
- .composite([{
115
- input: Buffer.from([color.r, color.g, color.b, Math.floor(color.alpha * 255)]),
116
- raw: {
117
- width: 1,
118
- height: 1,
119
- channels: 4
120
- },
121
- tile: true,
122
- blend: 'overlay'
123
- }])
124
- .jpeg({ quality: 80 })
125
- .toBuffer();
126
- }
127
-
128
- /**
129
- * Generates a thumbnail for a file
130
- * @param fileName The name of the file in Google Cloud Storage
131
- * @param fileType The MIME type of the file
132
- * @returns The thumbnail buffer or null if thumbnail generation is not supported
133
- */
134
- export async function generateThumbnail(fileName: string, fileType: string): Promise<Buffer | null> {
135
- try {
136
- const signedUrl = await getSignedUrl(fileName);
137
- const response = await fetch(signedUrl);
78
+ // // For regular images
79
+ // return sharp(fileBuffer)
80
+ // .resize(THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, {
81
+ // fit: 'inside',
82
+ // withoutEnlargement: true,
83
+ // })
84
+ // .jpeg({ quality: 80 })
85
+ // .toBuffer();
86
+ // }
87
+
88
+ // /**
89
+ // * Generates a generic icon-based thumbnail for a file type
90
+ // * @param fileType The MIME type of the file
91
+ // * @returns Thumbnail buffer
92
+ // */
93
+ // async function generateGenericThumbnail(fileType: string): Promise<Buffer> {
94
+ // // Create a blank canvas with a colored background based on file type
95
+ // const canvas = sharp({
96
+ // create: {
97
+ // width: THUMBNAIL_WIDTH,
98
+ // height: THUMBNAIL_HEIGHT,
99
+ // channels: 4,
100
+ // background: { r: 245, g: 245, b: 245, alpha: 1 }
101
+ // }
102
+ // });
103
+
104
+ // // Add a colored overlay based on file type
105
+ // let color = { r: 200, g: 200, b: 200, alpha: 0.5 }; // Default gray
106
+
107
+ // if (DOCUMENT_TYPES.includes(fileType)) {
108
+ // color = { r: 52, g: 152, b: 219, alpha: 0.5 }; // Blue for documents
109
+ // } else if (VIDEO_TYPES.includes(fileType)) {
110
+ // color = { r: 231, g: 76, b: 60, alpha: 0.5 }; // Red for videos
111
+ // } else if (AUDIO_TYPES.includes(fileType)) {
112
+ // color = { r: 46, g: 204, b: 113, alpha: 0.5 }; // Green for audio
113
+ // }
114
+
115
+ // return canvas
116
+ // .composite([{
117
+ // input: Buffer.from([color.r, color.g, color.b, Math.floor(color.alpha * 255)]),
118
+ // raw: {
119
+ // width: 1,
120
+ // height: 1,
121
+ // channels: 4
122
+ // },
123
+ // tile: true,
124
+ // blend: 'overlay'
125
+ // }])
126
+ // .jpeg({ quality: 80 })
127
+ // .toBuffer();
128
+ // }
129
+
130
+ // /**
131
+ // * Generates a thumbnail for a file
132
+ // * @param fileName The name of the file in Google Cloud Storage
133
+ // * @param fileType The MIME type of the file
134
+ // * @returns The thumbnail buffer or null if thumbnail generation is not supported
135
+ // */
136
+ // export async function generateThumbnail(fileName: string, fileType: string): Promise<Buffer | null> {
137
+ // try {
138
+ // const signedUrl = await getSignedUrl(fileName);
139
+ // const response = await fetch(signedUrl);
138
140
 
139
- if (!response.ok) {
140
- throw new Error(`Failed to download file from storage: ${response.status} ${response.statusText}`);
141
- }
142
-
143
- const fileBuffer = await response.arrayBuffer();
144
-
145
- if (SUPPORTED_IMAGE_TYPES.includes(fileType) || fileType === 'application/pdf') {
146
- try {
147
- const thumbnail = await generateMediaThumbnail(Buffer.from(fileBuffer), fileType);
148
- return thumbnail;
149
- } catch (error) {
150
- return generateGenericThumbnail(fileType);
151
- }
152
- } else if ([...DOCUMENT_TYPES, ...VIDEO_TYPES, ...AUDIO_TYPES].includes(fileType)) {
153
- return generateGenericThumbnail(fileType);
154
- }
155
-
156
- return null; // Unsupported file type
157
- } catch (error) {
158
- return null;
159
- }
160
- }
161
-
162
- /**
163
- * Stores a thumbnail in Google Cloud Storage and creates a File entry
164
- * @param thumbnailBuffer The thumbnail buffer to store
165
- * @param originalFileName The original file name
166
- * @param userId The user ID who owns the file
167
- * @returns The ID of the created thumbnail File
168
- */
169
- // DEPRECATED: This function is no longer used - thumbnails are generated during direct uploads
170
- // Thumbnail generation is now handled in the direct upload flow
141
+ // if (!response.ok) {
142
+ // throw new Error(`Failed to download file from storage: ${response.status} ${response.statusText}`);
143
+ // }
144
+
145
+ // const fileBuffer = await response.arrayBuffer();
146
+
147
+ // if (SUPPORTED_IMAGE_TYPES.includes(fileType) || fileType === 'application/pdf') {
148
+ // try {
149
+ // const thumbnail = await generateMediaThumbnail(Buffer.from(fileBuffer), fileType);
150
+ // return thumbnail;
151
+ // } catch (error) {
152
+ // return generateGenericThumbnail(fileType);
153
+ // }
154
+ // } else if ([...DOCUMENT_TYPES, ...VIDEO_TYPES, ...AUDIO_TYPES].includes(fileType)) {
155
+ // return generateGenericThumbnail(fileType);
156
+ // }
157
+
158
+ // return null; // Unsupported file type
159
+ // } catch (error) {
160
+ // return null;
161
+ // }
162
+ // }
163
+
164
+ // /**
165
+ // * Stores a thumbnail in Google Cloud Storage and creates a File entry
166
+ // * @param thumbnailBuffer The thumbnail buffer to store
167
+ // * @param originalFileName The original file name
168
+ // * @param userId The user ID who owns the file
169
+ // * @returns The ID of the created thumbnail File
170
+ // */
171
+ // // DEPRECATED: This function is no longer used - thumbnails are generated during direct uploads
172
+ // // Thumbnail generation is now handled in the direct upload flow