@studious-lms/server 1.0.6 → 1.0.8
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.
- package/API_SPECIFICATION.md +1461 -0
- package/dist/exportType.d.ts +3 -3
- package/dist/exportType.d.ts.map +1 -1
- package/dist/exportType.js +1 -2
- package/dist/index.js +25 -30
- package/dist/lib/fileUpload.d.ts.map +1 -1
- package/dist/lib/fileUpload.js +31 -29
- package/dist/lib/googleCloudStorage.js +9 -14
- package/dist/lib/prisma.js +4 -7
- package/dist/lib/thumbnailGenerator.js +12 -20
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +17 -22
- package/dist/middleware/logging.js +5 -9
- package/dist/routers/_app.d.ts +3619 -1937
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +28 -27
- package/dist/routers/agenda.d.ts +14 -9
- package/dist/routers/agenda.d.ts.map +1 -1
- package/dist/routers/agenda.js +14 -17
- package/dist/routers/announcement.d.ts +5 -4
- package/dist/routers/announcement.d.ts.map +1 -1
- package/dist/routers/announcement.js +28 -31
- package/dist/routers/assignment.d.ts +283 -197
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +256 -202
- package/dist/routers/attendance.d.ts +6 -5
- package/dist/routers/attendance.d.ts.map +1 -1
- package/dist/routers/attendance.js +31 -34
- package/dist/routers/auth.d.ts +2 -1
- package/dist/routers/auth.d.ts.map +1 -1
- package/dist/routers/auth.js +80 -75
- package/dist/routers/class.d.ts +285 -15
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +440 -164
- package/dist/routers/event.d.ts +48 -39
- package/dist/routers/event.d.ts.map +1 -1
- package/dist/routers/event.js +76 -79
- package/dist/routers/file.d.ts +72 -2
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/file.js +260 -32
- package/dist/routers/folder.d.ts +296 -0
- package/dist/routers/folder.d.ts.map +1 -0
- package/dist/routers/folder.js +693 -0
- package/dist/routers/notifications.d.ts +103 -0
- package/dist/routers/notifications.d.ts.map +1 -0
- package/dist/routers/notifications.js +91 -0
- package/dist/routers/school.d.ts +208 -0
- package/dist/routers/school.d.ts.map +1 -0
- package/dist/routers/school.js +481 -0
- package/dist/routers/section.d.ts +2 -1
- package/dist/routers/section.d.ts.map +1 -1
- package/dist/routers/section.js +30 -33
- package/dist/routers/user.d.ts +3 -2
- package/dist/routers/user.d.ts.map +1 -1
- package/dist/routers/user.js +21 -24
- package/dist/seedDatabase.d.ts +22 -0
- package/dist/seedDatabase.d.ts.map +1 -0
- package/dist/seedDatabase.js +75 -0
- package/dist/socket/handlers.js +26 -30
- package/dist/trpc.d.ts +5 -0
- package/dist/trpc.d.ts.map +1 -1
- package/dist/trpc.js +35 -26
- package/dist/types/trpc.d.ts +1 -1
- package/dist/types/trpc.d.ts.map +1 -1
- package/dist/types/trpc.js +1 -2
- package/dist/utils/email.js +2 -8
- package/dist/utils/generateInviteCode.js +1 -5
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +13 -9
- package/dist/utils/prismaErrorHandler.d.ts +9 -0
- package/dist/utils/prismaErrorHandler.d.ts.map +1 -0
- package/dist/utils/prismaErrorHandler.js +234 -0
- package/dist/utils/prismaWrapper.d.ts +14 -0
- package/dist/utils/prismaWrapper.d.ts.map +1 -0
- package/dist/utils/prismaWrapper.js +64 -0
- package/package.json +12 -4
- package/prisma/migrations/20250807062924_init/migration.sql +436 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +68 -1
- package/src/exportType.ts +3 -3
- package/src/index.ts +6 -6
- package/src/lib/fileUpload.ts +19 -10
- package/src/lib/thumbnailGenerator.ts +2 -2
- package/src/middleware/auth.ts +2 -4
- package/src/middleware/logging.ts +2 -2
- package/src/routers/_app.ts +17 -13
- package/src/routers/agenda.ts +2 -2
- package/src/routers/announcement.ts +2 -2
- package/src/routers/assignment.ts +86 -26
- package/src/routers/attendance.ts +2 -2
- package/src/routers/auth.ts +83 -57
- package/src/routers/class.ts +339 -39
- package/src/routers/event.ts +2 -2
- package/src/routers/file.ts +276 -21
- package/src/routers/folder.ts +755 -0
- package/src/routers/notifications.ts +93 -0
- package/src/routers/section.ts +2 -2
- package/src/routers/user.ts +3 -3
- package/src/seedDatabase.ts +88 -0
- package/src/socket/handlers.ts +5 -5
- package/src/trpc.ts +17 -4
- package/src/types/trpc.ts +1 -1
- package/src/utils/logger.ts +14 -4
- package/src/utils/prismaErrorHandler.ts +275 -0
- package/src/utils/prismaWrapper.ts +91 -0
- package/tests/auth.test.ts +25 -0
- package/tests/class.test.ts +281 -0
- package/tests/setup.ts +98 -0
- package/tests/startup.test.ts +5 -0
- package/tsconfig.json +2 -1
- package/vitest.config.ts +11 -0
- package/dist/logger.d.ts +0 -26
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -135
- 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;
|
package/prisma/schema.prisma
CHANGED
|
@@ -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,16 +66,22 @@ 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 {
|
|
56
82
|
id String @id @default(uuid())
|
|
57
83
|
userId String @unique
|
|
58
|
-
user User? @relation(fields: [userId], references: [id])
|
|
84
|
+
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
59
85
|
|
|
60
86
|
}
|
|
61
87
|
|
|
@@ -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], onDelete: Cascade)
|
|
228
295
|
}
|
package/src/exportType.ts
CHANGED
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
* to the client via npmjs
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export type { AppRouter } from "./routers/_app";
|
|
8
|
-
export type { RouterInputs } from "./routers/_app";
|
|
9
|
-
export type { RouterOutputs } from "./routers/_app";
|
|
7
|
+
export type { AppRouter } from "./routers/_app.js";
|
|
8
|
+
export type { RouterInputs } from "./routers/_app.js";
|
|
9
|
+
export type { RouterOutputs } from "./routers/_app.js";
|
package/src/index.ts
CHANGED
|
@@ -5,10 +5,10 @@ import { Server } from 'socket.io';
|
|
|
5
5
|
import cors from 'cors';
|
|
6
6
|
import dotenv from 'dotenv';
|
|
7
7
|
import { createExpressMiddleware } from '@trpc/server/adapters/express';
|
|
8
|
-
import { appRouter } from './routers/_app';
|
|
9
|
-
import { createTRPCContext, createCallerFactory } from './trpc';
|
|
10
|
-
import { logger } from './utils/logger';
|
|
11
|
-
import { setupSocketHandlers } from './socket/handlers';
|
|
8
|
+
import { appRouter } from './routers/_app.js';
|
|
9
|
+
import { createTRPCContext, createCallerFactory } from './trpc.js';
|
|
10
|
+
import { logger } from './utils/logger.js';
|
|
11
|
+
import { setupSocketHandlers } from './socket/handlers.js';
|
|
12
12
|
|
|
13
13
|
dotenv.config();
|
|
14
14
|
|
|
@@ -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
|
|