@studious-lms/server 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/API_SPECIFICATION.md +1117 -0
  2. package/dist/exportType.js +1 -2
  3. package/dist/index.js +25 -30
  4. package/dist/lib/fileUpload.d.ts.map +1 -1
  5. package/dist/lib/fileUpload.js +31 -29
  6. package/dist/lib/googleCloudStorage.js +9 -14
  7. package/dist/lib/prisma.js +4 -7
  8. package/dist/lib/thumbnailGenerator.js +12 -20
  9. package/dist/middleware/auth.d.ts.map +1 -1
  10. package/dist/middleware/auth.js +17 -22
  11. package/dist/middleware/logging.js +5 -9
  12. package/dist/routers/_app.d.ts +3483 -1801
  13. package/dist/routers/_app.d.ts.map +1 -1
  14. package/dist/routers/_app.js +28 -27
  15. package/dist/routers/agenda.d.ts +13 -8
  16. package/dist/routers/agenda.d.ts.map +1 -1
  17. package/dist/routers/agenda.js +14 -17
  18. package/dist/routers/announcement.d.ts +4 -3
  19. package/dist/routers/announcement.d.ts.map +1 -1
  20. package/dist/routers/announcement.js +28 -31
  21. package/dist/routers/assignment.d.ts +282 -196
  22. package/dist/routers/assignment.d.ts.map +1 -1
  23. package/dist/routers/assignment.js +256 -202
  24. package/dist/routers/attendance.d.ts +5 -4
  25. package/dist/routers/attendance.d.ts.map +1 -1
  26. package/dist/routers/attendance.js +31 -34
  27. package/dist/routers/auth.d.ts +1 -0
  28. package/dist/routers/auth.d.ts.map +1 -1
  29. package/dist/routers/auth.js +80 -75
  30. package/dist/routers/class.d.ts +284 -14
  31. package/dist/routers/class.d.ts.map +1 -1
  32. package/dist/routers/class.js +435 -164
  33. package/dist/routers/event.d.ts +47 -38
  34. package/dist/routers/event.d.ts.map +1 -1
  35. package/dist/routers/event.js +76 -79
  36. package/dist/routers/file.d.ts +71 -1
  37. package/dist/routers/file.d.ts.map +1 -1
  38. package/dist/routers/file.js +267 -32
  39. package/dist/routers/folder.d.ts +296 -0
  40. package/dist/routers/folder.d.ts.map +1 -0
  41. package/dist/routers/folder.js +693 -0
  42. package/dist/routers/notifications.d.ts +103 -0
  43. package/dist/routers/notifications.d.ts.map +1 -0
  44. package/dist/routers/notifications.js +91 -0
  45. package/dist/routers/school.d.ts +208 -0
  46. package/dist/routers/school.d.ts.map +1 -0
  47. package/dist/routers/school.js +481 -0
  48. package/dist/routers/section.d.ts +1 -0
  49. package/dist/routers/section.d.ts.map +1 -1
  50. package/dist/routers/section.js +30 -33
  51. package/dist/routers/user.d.ts +2 -1
  52. package/dist/routers/user.d.ts.map +1 -1
  53. package/dist/routers/user.js +21 -24
  54. package/dist/seedDatabase.d.ts +22 -0
  55. package/dist/seedDatabase.d.ts.map +1 -0
  56. package/dist/seedDatabase.js +57 -0
  57. package/dist/socket/handlers.js +26 -30
  58. package/dist/trpc.d.ts +5 -0
  59. package/dist/trpc.d.ts.map +1 -1
  60. package/dist/trpc.js +35 -26
  61. package/dist/types/trpc.js +1 -2
  62. package/dist/utils/email.js +2 -8
  63. package/dist/utils/generateInviteCode.js +1 -5
  64. package/dist/utils/logger.d.ts.map +1 -1
  65. package/dist/utils/logger.js +13 -9
  66. package/dist/utils/prismaErrorHandler.d.ts +9 -0
  67. package/dist/utils/prismaErrorHandler.d.ts.map +1 -0
  68. package/dist/utils/prismaErrorHandler.js +234 -0
  69. package/dist/utils/prismaWrapper.d.ts +14 -0
  70. package/dist/utils/prismaWrapper.d.ts.map +1 -0
  71. package/dist/utils/prismaWrapper.js +64 -0
  72. package/package.json +11 -4
  73. package/prisma/migrations/20250807062924_init/migration.sql +436 -0
  74. package/prisma/migrations/migration_lock.toml +3 -0
  75. package/prisma/schema.prisma +67 -0
  76. package/src/index.ts +2 -2
  77. package/src/lib/fileUpload.ts +16 -7
  78. package/src/middleware/auth.ts +0 -2
  79. package/src/routers/_app.ts +5 -1
  80. package/src/routers/assignment.ts +82 -22
  81. package/src/routers/auth.ts +80 -54
  82. package/src/routers/class.ts +330 -36
  83. package/src/routers/file.ts +283 -20
  84. package/src/routers/folder.ts +755 -0
  85. package/src/routers/notifications.ts +93 -0
  86. package/src/seedDatabase.ts +66 -0
  87. package/src/socket/handlers.ts +4 -4
  88. package/src/trpc.ts +13 -0
  89. package/src/utils/logger.ts +14 -4
  90. package/src/utils/prismaErrorHandler.ts +275 -0
  91. package/src/utils/prismaWrapper.ts +91 -0
  92. package/tests/auth.test.ts +25 -0
  93. package/tests/class.test.ts +281 -0
  94. package/tests/setup.ts +98 -0
  95. package/tests/startup.test.ts +5 -0
  96. package/tsconfig.json +2 -1
  97. package/vitest.config.ts +11 -0
  98. package/dist/logger.d.ts +0 -26
  99. package/dist/logger.d.ts.map +0 -1
  100. package/dist/logger.js +0 -135
  101. package/src/logger.ts +0 -163
@@ -0,0 +1,436 @@
1
+ -- CreateEnum
2
+ CREATE TYPE "AssignmentType" AS ENUM ('HOMEWORK', 'QUIZ', 'TEST', 'PROJECT', 'ESSAY', 'DISCUSSION', 'PRESENTATION', 'LAB', 'OTHER');
3
+
4
+ -- CreateEnum
5
+ CREATE TYPE "UserRole" AS ENUM ('STUDENT', 'TEACHER', 'ADMIN', 'NONE');
6
+
7
+ -- CreateTable
8
+ CREATE TABLE "School" (
9
+ "id" TEXT NOT NULL,
10
+ "name" TEXT NOT NULL,
11
+ "logoId" TEXT NOT NULL,
12
+ "subdomain" TEXT,
13
+
14
+ CONSTRAINT "School_pkey" PRIMARY KEY ("id")
15
+ );
16
+
17
+ -- CreateTable
18
+ CREATE TABLE "User" (
19
+ "id" TEXT NOT NULL,
20
+ "username" TEXT NOT NULL,
21
+ "email" TEXT NOT NULL,
22
+ "password" TEXT NOT NULL,
23
+ "verified" BOOLEAN NOT NULL DEFAULT false,
24
+ "role" "UserRole" NOT NULL DEFAULT 'NONE',
25
+ "profileId" TEXT,
26
+ "schoolId" TEXT,
27
+
28
+ CONSTRAINT "User_pkey" PRIMARY KEY ("id")
29
+ );
30
+
31
+ -- CreateTable
32
+ CREATE TABLE "UserProfile" (
33
+ "id" TEXT NOT NULL,
34
+ "userId" TEXT NOT NULL,
35
+
36
+ CONSTRAINT "UserProfile_pkey" PRIMARY KEY ("id")
37
+ );
38
+
39
+ -- CreateTable
40
+ CREATE TABLE "Class" (
41
+ "id" TEXT NOT NULL,
42
+ "name" TEXT NOT NULL,
43
+ "subject" TEXT NOT NULL,
44
+ "color" TEXT DEFAULT '#3B82F6',
45
+ "section" TEXT NOT NULL,
46
+ "syllabus" TEXT,
47
+ "schoolId" TEXT,
48
+
49
+ CONSTRAINT "Class_pkey" PRIMARY KEY ("id")
50
+ );
51
+
52
+ -- CreateTable
53
+ CREATE TABLE "MarkScheme" (
54
+ "id" TEXT NOT NULL,
55
+ "classId" TEXT NOT NULL,
56
+ "structured" TEXT NOT NULL,
57
+
58
+ CONSTRAINT "MarkScheme_pkey" PRIMARY KEY ("id")
59
+ );
60
+
61
+ -- CreateTable
62
+ CREATE TABLE "GradingBoundary" (
63
+ "id" TEXT NOT NULL,
64
+ "classId" TEXT NOT NULL,
65
+ "structured" TEXT NOT NULL,
66
+
67
+ CONSTRAINT "GradingBoundary_pkey" PRIMARY KEY ("id")
68
+ );
69
+
70
+ -- CreateTable
71
+ CREATE TABLE "Folder" (
72
+ "id" TEXT NOT NULL,
73
+ "name" TEXT NOT NULL,
74
+ "parentFolderId" TEXT,
75
+ "classId" TEXT,
76
+
77
+ CONSTRAINT "Folder_pkey" PRIMARY KEY ("id")
78
+ );
79
+
80
+ -- CreateTable
81
+ CREATE TABLE "File" (
82
+ "id" TEXT NOT NULL,
83
+ "name" TEXT NOT NULL,
84
+ "path" TEXT NOT NULL,
85
+ "size" INTEGER,
86
+ "type" TEXT NOT NULL,
87
+ "userId" TEXT,
88
+ "uploadedAt" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
89
+ "thumbnailId" TEXT,
90
+ "assignmentId" TEXT,
91
+ "submissionId" TEXT,
92
+ "annotationId" TEXT,
93
+ "classDraftId" TEXT,
94
+ "folderId" TEXT,
95
+
96
+ CONSTRAINT "File_pkey" PRIMARY KEY ("id")
97
+ );
98
+
99
+ -- CreateTable
100
+ CREATE TABLE "Assignment" (
101
+ "id" TEXT NOT NULL,
102
+ "title" TEXT NOT NULL,
103
+ "instructions" TEXT NOT NULL,
104
+ "dueDate" TIMESTAMP(3) NOT NULL,
105
+ "createdAt" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
106
+ "modifiedAt" TIMESTAMP(3),
107
+ "teacherId" TEXT NOT NULL,
108
+ "classId" TEXT NOT NULL,
109
+ "sectionId" TEXT,
110
+ "graded" BOOLEAN NOT NULL DEFAULT false,
111
+ "maxGrade" INTEGER DEFAULT 0,
112
+ "weight" DOUBLE PRECISION NOT NULL DEFAULT 1,
113
+ "type" "AssignmentType" NOT NULL DEFAULT 'HOMEWORK',
114
+ "inProgress" BOOLEAN NOT NULL DEFAULT false,
115
+ "template" BOOLEAN NOT NULL DEFAULT false,
116
+ "eventId" TEXT,
117
+ "markSchemeId" TEXT,
118
+ "gradingBoundaryId" TEXT,
119
+
120
+ CONSTRAINT "Assignment_pkey" PRIMARY KEY ("id")
121
+ );
122
+
123
+ -- CreateTable
124
+ CREATE TABLE "Announcement" (
125
+ "id" TEXT NOT NULL,
126
+ "remarks" TEXT NOT NULL,
127
+ "teacherId" TEXT NOT NULL,
128
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
129
+ "classId" TEXT NOT NULL,
130
+
131
+ CONSTRAINT "Announcement_pkey" PRIMARY KEY ("id")
132
+ );
133
+
134
+ -- CreateTable
135
+ CREATE TABLE "Submission" (
136
+ "id" TEXT NOT NULL,
137
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
138
+ "modifiedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
139
+ "assignmentId" TEXT NOT NULL,
140
+ "studentId" TEXT NOT NULL,
141
+ "gradeReceived" INTEGER,
142
+ "rubricState" TEXT,
143
+ "submittedAt" TIMESTAMP(3),
144
+ "submitted" BOOLEAN DEFAULT false,
145
+ "returned" BOOLEAN DEFAULT false,
146
+
147
+ CONSTRAINT "Submission_pkey" PRIMARY KEY ("id")
148
+ );
149
+
150
+ -- CreateTable
151
+ CREATE TABLE "Section" (
152
+ "id" TEXT NOT NULL,
153
+ "name" TEXT NOT NULL,
154
+ "classId" TEXT NOT NULL,
155
+
156
+ CONSTRAINT "Section_pkey" PRIMARY KEY ("id")
157
+ );
158
+
159
+ -- CreateTable
160
+ CREATE TABLE "Session" (
161
+ "id" TEXT NOT NULL,
162
+ "createdAt" TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP,
163
+ "expiresAt" TIMESTAMP(3),
164
+ "userId" TEXT,
165
+ "classId" TEXT,
166
+
167
+ CONSTRAINT "Session_pkey" PRIMARY KEY ("id")
168
+ );
169
+
170
+ -- CreateTable
171
+ CREATE TABLE "Event" (
172
+ "id" TEXT NOT NULL,
173
+ "name" TEXT,
174
+ "startTime" TIMESTAMP(3) NOT NULL,
175
+ "endTime" TIMESTAMP(3) NOT NULL,
176
+ "location" TEXT,
177
+ "remarks" TEXT,
178
+ "userId" TEXT,
179
+ "classId" TEXT,
180
+ "color" TEXT DEFAULT '#3B82F6',
181
+
182
+ CONSTRAINT "Event_pkey" PRIMARY KEY ("id")
183
+ );
184
+
185
+ -- CreateTable
186
+ CREATE TABLE "Attendance" (
187
+ "id" TEXT NOT NULL,
188
+ "date" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
189
+ "classId" TEXT NOT NULL,
190
+ "eventId" TEXT,
191
+
192
+ CONSTRAINT "Attendance_pkey" PRIMARY KEY ("id")
193
+ );
194
+
195
+ -- CreateTable
196
+ CREATE TABLE "Notification" (
197
+ "id" TEXT NOT NULL,
198
+ "title" TEXT NOT NULL,
199
+ "content" TEXT NOT NULL,
200
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
201
+ "senderId" TEXT,
202
+ "receiverId" TEXT NOT NULL,
203
+ "read" BOOLEAN NOT NULL DEFAULT false,
204
+
205
+ CONSTRAINT "Notification_pkey" PRIMARY KEY ("id")
206
+ );
207
+
208
+ -- CreateTable
209
+ CREATE TABLE "_UserStudentToClass" (
210
+ "A" TEXT NOT NULL,
211
+ "B" TEXT NOT NULL,
212
+
213
+ CONSTRAINT "_UserStudentToClass_AB_pkey" PRIMARY KEY ("A","B")
214
+ );
215
+
216
+ -- CreateTable
217
+ CREATE TABLE "_UserTeacherToClass" (
218
+ "A" TEXT NOT NULL,
219
+ "B" TEXT NOT NULL,
220
+
221
+ CONSTRAINT "_UserTeacherToClass_AB_pkey" PRIMARY KEY ("A","B")
222
+ );
223
+
224
+ -- CreateTable
225
+ CREATE TABLE "_ClassToMarkScheme" (
226
+ "A" TEXT NOT NULL,
227
+ "B" TEXT NOT NULL,
228
+
229
+ CONSTRAINT "_ClassToMarkScheme_AB_pkey" PRIMARY KEY ("A","B")
230
+ );
231
+
232
+ -- CreateTable
233
+ CREATE TABLE "_ClassToGradingBoundary" (
234
+ "A" TEXT NOT NULL,
235
+ "B" TEXT NOT NULL,
236
+
237
+ CONSTRAINT "_ClassToGradingBoundary_AB_pkey" PRIMARY KEY ("A","B")
238
+ );
239
+
240
+ -- CreateTable
241
+ CREATE TABLE "_PresentAttendance" (
242
+ "A" TEXT NOT NULL,
243
+ "B" TEXT NOT NULL,
244
+
245
+ CONSTRAINT "_PresentAttendance_AB_pkey" PRIMARY KEY ("A","B")
246
+ );
247
+
248
+ -- CreateTable
249
+ CREATE TABLE "_LateAttendance" (
250
+ "A" TEXT NOT NULL,
251
+ "B" TEXT NOT NULL,
252
+
253
+ CONSTRAINT "_LateAttendance_AB_pkey" PRIMARY KEY ("A","B")
254
+ );
255
+
256
+ -- CreateTable
257
+ CREATE TABLE "_AbsentAttendance" (
258
+ "A" TEXT NOT NULL,
259
+ "B" TEXT NOT NULL,
260
+
261
+ CONSTRAINT "_AbsentAttendance_AB_pkey" PRIMARY KEY ("A","B")
262
+ );
263
+
264
+ -- CreateIndex
265
+ CREATE UNIQUE INDEX "School_subdomain_key" ON "School"("subdomain");
266
+
267
+ -- CreateIndex
268
+ CREATE UNIQUE INDEX "User_profileId_key" ON "User"("profileId");
269
+
270
+ -- CreateIndex
271
+ CREATE UNIQUE INDEX "UserProfile_userId_key" ON "UserProfile"("userId");
272
+
273
+ -- CreateIndex
274
+ CREATE UNIQUE INDEX "Folder_classId_key" ON "Folder"("classId");
275
+
276
+ -- CreateIndex
277
+ CREATE UNIQUE INDEX "File_thumbnailId_key" ON "File"("thumbnailId");
278
+
279
+ -- CreateIndex
280
+ CREATE INDEX "_UserStudentToClass_B_index" ON "_UserStudentToClass"("B");
281
+
282
+ -- CreateIndex
283
+ CREATE INDEX "_UserTeacherToClass_B_index" ON "_UserTeacherToClass"("B");
284
+
285
+ -- CreateIndex
286
+ CREATE INDEX "_ClassToMarkScheme_B_index" ON "_ClassToMarkScheme"("B");
287
+
288
+ -- CreateIndex
289
+ CREATE INDEX "_ClassToGradingBoundary_B_index" ON "_ClassToGradingBoundary"("B");
290
+
291
+ -- CreateIndex
292
+ CREATE INDEX "_PresentAttendance_B_index" ON "_PresentAttendance"("B");
293
+
294
+ -- CreateIndex
295
+ CREATE INDEX "_LateAttendance_B_index" ON "_LateAttendance"("B");
296
+
297
+ -- CreateIndex
298
+ CREATE INDEX "_AbsentAttendance_B_index" ON "_AbsentAttendance"("B");
299
+
300
+ -- AddForeignKey
301
+ ALTER TABLE "School" ADD CONSTRAINT "School_logoId_fkey" FOREIGN KEY ("logoId") REFERENCES "File"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
302
+
303
+ -- AddForeignKey
304
+ ALTER TABLE "User" ADD CONSTRAINT "User_schoolId_fkey" FOREIGN KEY ("schoolId") REFERENCES "School"("id") ON DELETE SET NULL ON UPDATE CASCADE;
305
+
306
+ -- AddForeignKey
307
+ ALTER TABLE "UserProfile" ADD CONSTRAINT "UserProfile_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
308
+
309
+ -- AddForeignKey
310
+ ALTER TABLE "Class" ADD CONSTRAINT "Class_schoolId_fkey" FOREIGN KEY ("schoolId") REFERENCES "School"("id") ON DELETE SET NULL ON UPDATE CASCADE;
311
+
312
+ -- AddForeignKey
313
+ ALTER TABLE "Folder" ADD CONSTRAINT "Folder_parentFolderId_fkey" FOREIGN KEY ("parentFolderId") REFERENCES "Folder"("id") ON DELETE SET NULL ON UPDATE CASCADE;
314
+
315
+ -- AddForeignKey
316
+ ALTER TABLE "Folder" ADD CONSTRAINT "Folder_classId_fkey" FOREIGN KEY ("classId") REFERENCES "Class"("id") ON DELETE SET NULL ON UPDATE CASCADE;
317
+
318
+ -- AddForeignKey
319
+ ALTER TABLE "File" ADD CONSTRAINT "File_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
320
+
321
+ -- AddForeignKey
322
+ ALTER TABLE "File" ADD CONSTRAINT "File_thumbnailId_fkey" FOREIGN KEY ("thumbnailId") REFERENCES "File"("id") ON DELETE SET NULL ON UPDATE CASCADE;
323
+
324
+ -- AddForeignKey
325
+ ALTER TABLE "File" ADD CONSTRAINT "File_assignmentId_fkey" FOREIGN KEY ("assignmentId") REFERENCES "Assignment"("id") ON DELETE CASCADE ON UPDATE CASCADE;
326
+
327
+ -- AddForeignKey
328
+ ALTER TABLE "File" ADD CONSTRAINT "File_submissionId_fkey" FOREIGN KEY ("submissionId") REFERENCES "Submission"("id") ON DELETE CASCADE ON UPDATE CASCADE;
329
+
330
+ -- AddForeignKey
331
+ ALTER TABLE "File" ADD CONSTRAINT "File_annotationId_fkey" FOREIGN KEY ("annotationId") REFERENCES "Submission"("id") ON DELETE CASCADE ON UPDATE CASCADE;
332
+
333
+ -- AddForeignKey
334
+ ALTER TABLE "File" ADD CONSTRAINT "File_classDraftId_fkey" FOREIGN KEY ("classDraftId") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
335
+
336
+ -- AddForeignKey
337
+ ALTER TABLE "File" ADD CONSTRAINT "File_folderId_fkey" FOREIGN KEY ("folderId") REFERENCES "Folder"("id") ON DELETE CASCADE ON UPDATE CASCADE;
338
+
339
+ -- AddForeignKey
340
+ ALTER TABLE "Assignment" ADD CONSTRAINT "Assignment_teacherId_fkey" FOREIGN KEY ("teacherId") REFERENCES "User"("id") ON DELETE NO ACTION ON UPDATE CASCADE;
341
+
342
+ -- AddForeignKey
343
+ ALTER TABLE "Assignment" ADD CONSTRAINT "Assignment_classId_fkey" FOREIGN KEY ("classId") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
344
+
345
+ -- AddForeignKey
346
+ ALTER TABLE "Assignment" ADD CONSTRAINT "Assignment_sectionId_fkey" FOREIGN KEY ("sectionId") REFERENCES "Section"("id") ON DELETE CASCADE ON UPDATE CASCADE;
347
+
348
+ -- AddForeignKey
349
+ ALTER TABLE "Assignment" ADD CONSTRAINT "Assignment_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE NO ACTION ON UPDATE CASCADE;
350
+
351
+ -- AddForeignKey
352
+ ALTER TABLE "Assignment" ADD CONSTRAINT "Assignment_markSchemeId_fkey" FOREIGN KEY ("markSchemeId") REFERENCES "MarkScheme"("id") ON DELETE CASCADE ON UPDATE CASCADE;
353
+
354
+ -- AddForeignKey
355
+ ALTER TABLE "Assignment" ADD CONSTRAINT "Assignment_gradingBoundaryId_fkey" FOREIGN KEY ("gradingBoundaryId") REFERENCES "GradingBoundary"("id") ON DELETE CASCADE ON UPDATE CASCADE;
356
+
357
+ -- AddForeignKey
358
+ ALTER TABLE "Announcement" ADD CONSTRAINT "Announcement_teacherId_fkey" FOREIGN KEY ("teacherId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
359
+
360
+ -- AddForeignKey
361
+ ALTER TABLE "Announcement" ADD CONSTRAINT "Announcement_classId_fkey" FOREIGN KEY ("classId") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
362
+
363
+ -- AddForeignKey
364
+ ALTER TABLE "Submission" ADD CONSTRAINT "Submission_assignmentId_fkey" FOREIGN KEY ("assignmentId") REFERENCES "Assignment"("id") ON DELETE CASCADE ON UPDATE CASCADE;
365
+
366
+ -- AddForeignKey
367
+ ALTER TABLE "Submission" ADD CONSTRAINT "Submission_studentId_fkey" FOREIGN KEY ("studentId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
368
+
369
+ -- AddForeignKey
370
+ ALTER TABLE "Section" ADD CONSTRAINT "Section_classId_fkey" FOREIGN KEY ("classId") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
371
+
372
+ -- AddForeignKey
373
+ ALTER TABLE "Session" ADD CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE NO ACTION ON UPDATE CASCADE;
374
+
375
+ -- AddForeignKey
376
+ ALTER TABLE "Session" ADD CONSTRAINT "Session_classId_fkey" FOREIGN KEY ("classId") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
377
+
378
+ -- AddForeignKey
379
+ ALTER TABLE "Event" ADD CONSTRAINT "Event_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
380
+
381
+ -- AddForeignKey
382
+ ALTER TABLE "Event" ADD CONSTRAINT "Event_classId_fkey" FOREIGN KEY ("classId") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
383
+
384
+ -- AddForeignKey
385
+ ALTER TABLE "Attendance" ADD CONSTRAINT "Attendance_classId_fkey" FOREIGN KEY ("classId") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
386
+
387
+ -- AddForeignKey
388
+ ALTER TABLE "Attendance" ADD CONSTRAINT "Attendance_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
389
+
390
+ -- AddForeignKey
391
+ ALTER TABLE "Notification" ADD CONSTRAINT "Notification_senderId_fkey" FOREIGN KEY ("senderId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
392
+
393
+ -- AddForeignKey
394
+ ALTER TABLE "Notification" ADD CONSTRAINT "Notification_receiverId_fkey" FOREIGN KEY ("receiverId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
395
+
396
+ -- AddForeignKey
397
+ ALTER TABLE "_UserStudentToClass" ADD CONSTRAINT "_UserStudentToClass_A_fkey" FOREIGN KEY ("A") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
398
+
399
+ -- AddForeignKey
400
+ ALTER TABLE "_UserStudentToClass" ADD CONSTRAINT "_UserStudentToClass_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
401
+
402
+ -- AddForeignKey
403
+ ALTER TABLE "_UserTeacherToClass" ADD CONSTRAINT "_UserTeacherToClass_A_fkey" FOREIGN KEY ("A") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
404
+
405
+ -- AddForeignKey
406
+ ALTER TABLE "_UserTeacherToClass" ADD CONSTRAINT "_UserTeacherToClass_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
407
+
408
+ -- AddForeignKey
409
+ ALTER TABLE "_ClassToMarkScheme" ADD CONSTRAINT "_ClassToMarkScheme_A_fkey" FOREIGN KEY ("A") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
410
+
411
+ -- AddForeignKey
412
+ ALTER TABLE "_ClassToMarkScheme" ADD CONSTRAINT "_ClassToMarkScheme_B_fkey" FOREIGN KEY ("B") REFERENCES "MarkScheme"("id") ON DELETE CASCADE ON UPDATE CASCADE;
413
+
414
+ -- AddForeignKey
415
+ ALTER TABLE "_ClassToGradingBoundary" ADD CONSTRAINT "_ClassToGradingBoundary_A_fkey" FOREIGN KEY ("A") REFERENCES "Class"("id") ON DELETE CASCADE ON UPDATE CASCADE;
416
+
417
+ -- AddForeignKey
418
+ ALTER TABLE "_ClassToGradingBoundary" ADD CONSTRAINT "_ClassToGradingBoundary_B_fkey" FOREIGN KEY ("B") REFERENCES "GradingBoundary"("id") ON DELETE CASCADE ON UPDATE CASCADE;
419
+
420
+ -- AddForeignKey
421
+ ALTER TABLE "_PresentAttendance" ADD CONSTRAINT "_PresentAttendance_A_fkey" FOREIGN KEY ("A") REFERENCES "Attendance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
422
+
423
+ -- AddForeignKey
424
+ ALTER TABLE "_PresentAttendance" ADD CONSTRAINT "_PresentAttendance_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
425
+
426
+ -- AddForeignKey
427
+ ALTER TABLE "_LateAttendance" ADD CONSTRAINT "_LateAttendance_A_fkey" FOREIGN KEY ("A") REFERENCES "Attendance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
428
+
429
+ -- AddForeignKey
430
+ ALTER TABLE "_LateAttendance" ADD CONSTRAINT "_LateAttendance_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
431
+
432
+ -- AddForeignKey
433
+ ALTER TABLE "_AbsentAttendance" ADD CONSTRAINT "_AbsentAttendance_A_fkey" FOREIGN KEY ("A") REFERENCES "Attendance"("id") ON DELETE CASCADE ON UPDATE CASCADE;
434
+
435
+ -- AddForeignKey
436
+ ALTER TABLE "_AbsentAttendance" ADD CONSTRAINT "_AbsentAttendance_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,3 @@
1
+ # Please do not edit this file manually
2
+ # It should be added in your version-control system (e.g., Git)
3
+ provider = "postgresql"
@@ -12,6 +12,7 @@ generator client {
12
12
  datasource db {
13
13
  provider = "postgresql"
14
14
  url = env("DATABASE_URL")
15
+ directUrl = env("DIRECT_URL")
15
16
  }
16
17
 
17
18
  enum AssignmentType {
@@ -26,6 +27,24 @@ enum AssignmentType {
26
27
  OTHER
27
28
  }
28
29
 
30
+ enum UserRole {
31
+ STUDENT
32
+ TEACHER
33
+ ADMIN
34
+ NONE
35
+ }
36
+
37
+ model School {
38
+ id String @id @default(uuid())
39
+ name String
40
+ logo File @relation(references: [id], fields: [logoId])
41
+ logoId String
42
+ subdomain String? @unique
43
+
44
+
45
+ users User[]
46
+ classes Class[]
47
+ }
29
48
 
30
49
  model User {
31
50
  id String @id @default(uuid())
@@ -34,6 +53,7 @@ model User {
34
53
  password String
35
54
  profile UserProfile?
36
55
  verified Boolean @default(false)
56
+ role UserRole @default(NONE)
37
57
 
38
58
  profileId String? @unique
39
59
 
@@ -46,10 +66,16 @@ model User {
46
66
  assignments Assignment[]
47
67
  events Event[]
48
68
  announcements Announcement[]
69
+ notificationsSent Notification[] @relation("SentNotifications")
70
+ notificationsReceived Notification[] @relation("ReceivedNotifications")
49
71
 
50
72
  presentAttendance Attendance[] @relation("PresentAttendance")
51
73
  lateAttendance Attendance[] @relation("LateAttendance")
52
74
  absentAttendance Attendance[] @relation("AbsentAttendance")
75
+
76
+ school School? @relation(fields: [schoolId], references: [id])
77
+ schoolId String?
78
+
53
79
  }
54
80
 
55
81
  model UserProfile {
@@ -65,6 +91,7 @@ model Class {
65
91
  subject String
66
92
  color String? @default("#3B82F6")
67
93
  section String
94
+ syllabus String?
68
95
  announcements Announcement[]
69
96
  assignments Assignment[]
70
97
  attendance Attendance[]
@@ -75,6 +102,11 @@ model Class {
75
102
  teachers User[] @relation("UserTeacherToClass")
76
103
  markSchemes MarkScheme[] @relation("ClassToMarkScheme")
77
104
  gradingBoundaries GradingBoundary[] @relation("ClassToGradingBoundary")
105
+ draftFiles File[] @relation("ClassDraftFiles")
106
+ classFiles Folder? @relation("ClassFiles")
107
+
108
+ school School? @relation(fields: [schoolId], references: [id])
109
+ schoolId String?
78
110
  }
79
111
 
80
112
  model MarkScheme {
@@ -93,6 +125,17 @@ model GradingBoundary {
93
125
  assignments Assignment[]
94
126
  }
95
127
 
128
+ model Folder {
129
+ id String @id @default(uuid())
130
+ name String
131
+ files File[] @relation("FolderFiles")
132
+ childFolders Folder[] @relation("ParentChildFolders")
133
+ parentFolder Folder? @relation("ParentChildFolders", fields: [parentFolderId], references: [id])
134
+ parentFolderId String?
135
+ class Class? @relation("ClassFiles", fields: [classId], references: [id])
136
+ classId String? @unique
137
+ }
138
+
96
139
  model File {
97
140
  id String @id @default(uuid())
98
141
  name String
@@ -116,6 +159,14 @@ model File {
116
159
 
117
160
  annotations Submission? @relation("SubmissionAnnotations", fields: [annotationId], references: [id], onDelete: Cascade)
118
161
  annotationId String?
162
+
163
+ classDraft Class? @relation("ClassDraftFiles", fields: [classDraftId], references: [id], onDelete: Cascade)
164
+ classDraftId String?
165
+
166
+ folder Folder? @relation("FolderFiles", fields: [folderId], references: [id], onDelete: Cascade)
167
+ folderId String?
168
+
169
+ schools School[]
119
170
  }
120
171
 
121
172
  model Assignment {
@@ -137,6 +188,8 @@ model Assignment {
137
188
  maxGrade Int? @default(0)
138
189
  weight Float @default(1)
139
190
  type AssignmentType @default(HOMEWORK)
191
+ inProgress Boolean @default(false)
192
+ template Boolean @default(false)
140
193
  eventAttached Event? @relation(fields: [eventId], references: [id], onDelete: NoAction)
141
194
  eventId String?
142
195
  markScheme MarkScheme? @relation(fields: [markSchemeId], references: [id], onDelete: Cascade)
@@ -145,6 +198,8 @@ model Assignment {
145
198
  gradingBoundaryId String?
146
199
  }
147
200
 
201
+
202
+
148
203
  model Announcement {
149
204
  id String @id @default(uuid())
150
205
  remarks String
@@ -225,4 +280,16 @@ model Attendance {
225
280
  present User[] @relation("PresentAttendance")
226
281
  late User[] @relation("LateAttendance")
227
282
  absent User[] @relation("AbsentAttendance")
283
+ }
284
+
285
+ model Notification {
286
+ id String @id @default(uuid())
287
+ title String
288
+ content String
289
+ createdAt DateTime @default(now())
290
+ senderId String? // no ID means sys
291
+ receiverId String
292
+ read Boolean @default(false)
293
+ sender User? @relation("SentNotifications", fields: [senderId], references: [id])
294
+ receiver User @relation("ReceivedNotifications", fields: [receiverId], references: [id])
228
295
  }
package/src/index.ts CHANGED
@@ -16,7 +16,7 @@ const app = express();
16
16
 
17
17
  // CORS middleware
18
18
  app.use(cors({
19
- origin: process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000',
19
+ origin: [process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000', 'http://localhost:3000'],
20
20
  credentials: true,
21
21
  }));
22
22
 
@@ -55,7 +55,7 @@ const io = new Server(httpServer, {
55
55
  });
56
56
 
57
57
  // Add server-level logging
58
- io.engine.on('connection_error', (err) => {
58
+ io.engine.on('connection_error', (err: Error) => {
59
59
  logger.error('Socket connection error', { error: err.message });
60
60
  });
61
61
 
@@ -39,22 +39,22 @@ export async function uploadFile(
39
39
  const fileExtension = file.name.split('.').pop();
40
40
  const uniqueFilename = `${uuidv4()}.${fileExtension}`;
41
41
 
42
- // Construct the full path
42
+ // // Construct the full path
43
43
  const filePath = directory
44
44
  ? `${directory}/${uniqueFilename}`
45
45
  : uniqueFilename;
46
46
 
47
- // Upload to Google Cloud Storage
47
+ // // Upload to Google Cloud Storage
48
48
  const uploadedPath = await uploadToGCS(file.data, filePath, file.type);
49
49
 
50
- // Generate and store thumbnail if supported
50
+ // // Generate and store thumbnail if supported
51
51
  let thumbnailId: string | undefined;
52
52
  try {
53
- // Convert base64 to buffer for thumbnail generation
53
+ // // Convert base64 to buffer for thumbnail generation
54
54
  const base64Data = file.data.split(',')[1];
55
55
  const fileBuffer = Buffer.from(base64Data, 'base64');
56
56
 
57
- // Generate thumbnail directly from buffer
57
+ // // Generate thumbnail directly from buffer
58
58
  const thumbnailBuffer = await generateMediaThumbnail(fileBuffer, file.type);
59
59
  if (thumbnailBuffer) {
60
60
  // Store thumbnail in a thumbnails directory
@@ -65,9 +65,10 @@ export async function uploadFile(
65
65
  // Create thumbnail file record
66
66
  const thumbnailFile = await prisma.file.create({
67
67
  data: {
68
- name: `${file.name}_thumb.jpg`,
68
+ name: `${file.name}_thumb.jpg${Math.random()}`,
69
69
  type: 'image/jpeg',
70
70
  path: thumbnailPath,
71
+ // path: '/dummyPath' + Math.random().toString(36).substring(2, 15),
71
72
  user: {
72
73
  connect: { id: userId }
73
74
  }
@@ -81,6 +82,8 @@ export async function uploadFile(
81
82
  }
82
83
 
83
84
  // Create file record in database
85
+
86
+ // const uploadedPath = '/dummyPath' + Math.random().toString(36).substring(2, 15);
84
87
  const fileRecord = await prisma.file.create({
85
88
  data: {
86
89
  name: file.name,
@@ -90,6 +93,11 @@ export async function uploadFile(
90
93
  user: {
91
94
  connect: { id: userId }
92
95
  },
96
+ ...(directory && {
97
+ folder: {
98
+ connect: {id: directory},
99
+ },
100
+ }),
93
101
  ...(thumbnailId && {
94
102
  thumbnail: {
95
103
  connect: { id: thumbnailId }
@@ -112,7 +120,8 @@ export async function uploadFile(
112
120
  path: uploadedPath,
113
121
  thumbnailId: thumbnailId
114
122
  };
115
- } catch (error) {
123
+ }
124
+ catch (error) {
116
125
  console.error('Error uploading file:', error);
117
126
  throw new TRPCError({
118
127
  code: 'INTERNAL_SERVER_ERROR',
@@ -43,8 +43,6 @@ export const createAuthMiddleware = (t: any) => {
43
43
  });
44
44
  }
45
45
 
46
- console.log(user)
47
-
48
46
  return next({
49
47
  ctx: {
50
48
  ...ctx,