@studious-lms/server 1.4.5 → 1.4.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 (167) hide show
  1. package/dist/lib/config/cors.d.ts.map +1 -1
  2. package/dist/lib/config/cors.js +8 -3
  3. package/dist/lib/config/cors.js.map +1 -1
  4. package/dist/models/access.d.ts +112 -0
  5. package/dist/models/access.d.ts.map +1 -0
  6. package/dist/models/access.js +49 -0
  7. package/dist/models/access.js.map +1 -0
  8. package/dist/models/announcement.d.ts +17 -2
  9. package/dist/models/announcement.d.ts.map +1 -1
  10. package/dist/models/announcement.js +21 -4
  11. package/dist/models/announcement.js.map +1 -1
  12. package/dist/models/assignment.d.ts +37 -37
  13. package/dist/models/assignment.d.ts.map +1 -1
  14. package/dist/models/assignment.js +15 -15
  15. package/dist/models/assignment.js.map +1 -1
  16. package/dist/models/attendance.d.ts +1 -1
  17. package/dist/models/attendance.d.ts.map +1 -1
  18. package/dist/models/attendance.js +6 -5
  19. package/dist/models/attendance.js.map +1 -1
  20. package/dist/models/auth.d.ts +5 -5
  21. package/dist/models/auth.d.ts.map +1 -1
  22. package/dist/models/auth.js +7 -11
  23. package/dist/models/auth.js.map +1 -1
  24. package/dist/models/class.d.ts +26 -26
  25. package/dist/models/class.d.ts.map +1 -1
  26. package/dist/models/class.js +7 -11
  27. package/dist/models/class.js.map +1 -1
  28. package/dist/models/comment.d.ts +233 -6
  29. package/dist/models/comment.d.ts.map +1 -1
  30. package/dist/models/comment.js +133 -3
  31. package/dist/models/comment.js.map +1 -1
  32. package/dist/models/conversation.d.ts +7 -7
  33. package/dist/models/event.d.ts +52 -3
  34. package/dist/models/event.d.ts.map +1 -1
  35. package/dist/models/event.js +56 -6
  36. package/dist/models/event.js.map +1 -1
  37. package/dist/models/file.d.ts +178 -103
  38. package/dist/models/file.d.ts.map +1 -1
  39. package/dist/models/file.js +54 -14
  40. package/dist/models/file.js.map +1 -1
  41. package/dist/models/folder.d.ts +22 -22
  42. package/dist/models/folder.d.ts.map +1 -1
  43. package/dist/models/folder.js +5 -4
  44. package/dist/models/folder.js.map +1 -1
  45. package/dist/models/labChat.d.ts +20 -20
  46. package/dist/models/labChat.d.ts.map +1 -1
  47. package/dist/models/labChat.js +8 -10
  48. package/dist/models/labChat.js.map +1 -1
  49. package/dist/models/marketing.d.ts +1 -1
  50. package/dist/models/message.d.ts +6 -6
  51. package/dist/models/newtonChat.d.ts +5 -5
  52. package/dist/models/school.d.ts +361 -0
  53. package/dist/models/school.d.ts.map +1 -0
  54. package/dist/models/school.js +314 -0
  55. package/dist/models/school.js.map +1 -0
  56. package/dist/models/section.d.ts +1 -1
  57. package/dist/models/section.d.ts.map +1 -1
  58. package/dist/models/section.js +5 -4
  59. package/dist/models/section.js.map +1 -1
  60. package/dist/models/user.d.ts +4 -4
  61. package/dist/models/worksheet.d.ts +67 -65
  62. package/dist/models/worksheet.d.ts.map +1 -1
  63. package/dist/models/worksheet.js +6 -14
  64. package/dist/models/worksheet.js.map +1 -1
  65. package/dist/pipelines/aiLabChat.d.ts.map +1 -1
  66. package/dist/pipelines/aiLabChat.js +4 -3
  67. package/dist/pipelines/aiLabChat.js.map +1 -1
  68. package/dist/pipelines/gradeWorksheet.d.ts +2 -2
  69. package/dist/pipelines/pdfToWorksheet.d.ts +1 -1
  70. package/dist/routers/_app.d.ts +2462 -1104
  71. package/dist/routers/_app.d.ts.map +1 -1
  72. package/dist/routers/_app.js +4 -2
  73. package/dist/routers/_app.js.map +1 -1
  74. package/dist/routers/announcement.d.ts +13 -5
  75. package/dist/routers/announcement.d.ts.map +1 -1
  76. package/dist/routers/announcement.js +25 -5
  77. package/dist/routers/announcement.js.map +1 -1
  78. package/dist/routers/assignment.d.ts +266 -36
  79. package/dist/routers/assignment.d.ts.map +1 -1
  80. package/dist/routers/assignment.js +221 -3
  81. package/dist/routers/assignment.js.map +1 -1
  82. package/dist/routers/class.d.ts +21 -20
  83. package/dist/routers/class.d.ts.map +1 -1
  84. package/dist/routers/class.js +3 -2
  85. package/dist/routers/class.js.map +1 -1
  86. package/dist/routers/comment.d.ts +40 -3
  87. package/dist/routers/comment.d.ts.map +1 -1
  88. package/dist/routers/comment.js +14 -5
  89. package/dist/routers/comment.js.map +1 -1
  90. package/dist/routers/conversation.d.ts +6 -6
  91. package/dist/routers/event.d.ts +21 -2
  92. package/dist/routers/event.d.ts.map +1 -1
  93. package/dist/routers/file.d.ts +2 -2
  94. package/dist/routers/folder.d.ts +24 -24
  95. package/dist/routers/labChat.d.ts +7 -7
  96. package/dist/routers/school.d.ts +384 -0
  97. package/dist/routers/school.d.ts.map +1 -0
  98. package/dist/routers/school.js +79 -0
  99. package/dist/routers/school.js.map +1 -0
  100. package/dist/routers/search.d.ts +1 -1
  101. package/dist/routers/worksheet.d.ts +23 -21
  102. package/dist/routers/worksheet.d.ts.map +1 -1
  103. package/dist/services/announcement.d.ts.map +1 -1
  104. package/dist/services/announcement.js +10 -6
  105. package/dist/services/announcement.js.map +1 -1
  106. package/dist/services/assignment.d.ts +36 -36
  107. package/dist/services/class.d.ts +20 -19
  108. package/dist/services/class.d.ts.map +1 -1
  109. package/dist/services/class.js +22 -3
  110. package/dist/services/class.js.map +1 -1
  111. package/dist/services/comment.d.ts +31 -5
  112. package/dist/services/comment.d.ts.map +1 -1
  113. package/dist/services/comment.js +102 -19
  114. package/dist/services/comment.js.map +1 -1
  115. package/dist/services/conversation.d.ts +6 -6
  116. package/dist/services/event.d.ts +21 -2
  117. package/dist/services/event.d.ts.map +1 -1
  118. package/dist/services/event.js +11 -7
  119. package/dist/services/event.js.map +1 -1
  120. package/dist/services/file.d.ts +2 -2
  121. package/dist/services/file.d.ts.map +1 -1
  122. package/dist/services/file.js +17 -8
  123. package/dist/services/file.js.map +1 -1
  124. package/dist/services/folder.d.ts +24 -24
  125. package/dist/services/labChat.d.ts +7 -7
  126. package/dist/services/school.d.ts +299 -0
  127. package/dist/services/school.d.ts.map +1 -0
  128. package/dist/services/school.js +225 -0
  129. package/dist/services/school.js.map +1 -0
  130. package/dist/services/worksheet.d.ts +23 -21
  131. package/dist/services/worksheet.d.ts.map +1 -1
  132. package/package.json +1 -1
  133. package/prisma/migrations/20260502230500_assignment_submission_comments/migration.sql +60 -0
  134. package/prisma/migrations/20260504071500_school_memberships/migration.sql +81 -0
  135. package/prisma/schema.prisma +75 -2
  136. package/src/lib/config/cors.ts +8 -1
  137. package/src/models/access.ts +48 -0
  138. package/src/models/announcement.ts +19 -2
  139. package/src/models/assignment.ts +17 -13
  140. package/src/models/attendance.ts +4 -3
  141. package/src/models/auth.ts +8 -9
  142. package/src/models/class.ts +8 -9
  143. package/src/models/comment.ts +137 -1
  144. package/src/models/event.ts +54 -4
  145. package/src/models/file.ts +53 -12
  146. package/src/models/folder.ts +3 -2
  147. package/src/models/labChat.ts +9 -8
  148. package/src/models/school.ts +361 -0
  149. package/src/models/section.ts +3 -2
  150. package/src/models/worksheet.ts +7 -12
  151. package/src/pipelines/aiLabChat.ts +2 -1
  152. package/src/routers/_app.ts +2 -0
  153. package/src/routers/announcement.ts +30 -4
  154. package/src/routers/assignment.ts +243 -2
  155. package/src/routers/class.ts +1 -0
  156. package/src/routers/comment.ts +19 -2
  157. package/src/routers/school.ts +122 -0
  158. package/src/services/announcement.ts +12 -4
  159. package/src/services/class.ts +25 -2
  160. package/src/services/comment.ts +122 -18
  161. package/src/services/event.ts +23 -6
  162. package/src/services/file.ts +20 -6
  163. package/src/services/school.ts +308 -0
  164. package/tests/lib/cors.test.ts +13 -1
  165. package/tests/routers/assignment.test.ts +68 -2
  166. package/tests/routers/comment.test.ts +42 -1
  167. package/vercel.json +8 -0
@@ -15,9 +15,9 @@ export declare function getWorksheet(worksheetId: string, userId: string): Promi
15
15
  options: import("@prisma/client/runtime/library.js").JsonValue | null;
16
16
  id: string;
17
17
  createdAt: Date;
18
+ updatedAt: Date;
18
19
  order: number | null;
19
20
  points: number;
20
- updatedAt: Date;
21
21
  worksheetId: string;
22
22
  markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
23
23
  question: string;
@@ -27,8 +27,8 @@ export declare function getWorksheet(worksheetId: string, userId: string): Promi
27
27
  name: string;
28
28
  id: string;
29
29
  createdAt: Date;
30
- classId: string;
31
30
  updatedAt: Date;
31
+ classId: string;
32
32
  }>;
33
33
  /** Check if worksheet exists. */
34
34
  export declare function worksheetExists(id: string): Promise<boolean>;
@@ -40,8 +40,8 @@ export declare function listWorksheets(classId: string): Promise<{
40
40
  name: string;
41
41
  id: string;
42
42
  createdAt: Date;
43
- classId: string;
44
43
  updatedAt: Date;
44
+ classId: string;
45
45
  }[]>;
46
46
  export declare function updateWorksheetRecord(worksheetId: string, userId: string, data: {
47
47
  name?: string;
@@ -49,22 +49,22 @@ export declare function updateWorksheetRecord(worksheetId: string, userId: strin
49
49
  name: string;
50
50
  id: string;
51
51
  createdAt: Date;
52
- classId: string;
53
52
  updatedAt: Date;
53
+ classId: string;
54
54
  }>;
55
55
  export declare function deleteWorksheetRecord(worksheetId: string, userId: string): Promise<{
56
56
  name: string;
57
57
  id: string;
58
58
  createdAt: Date;
59
- classId: string;
60
59
  updatedAt: Date;
60
+ classId: string;
61
61
  }>;
62
62
  export declare function createWorksheetRecord(classId: string, name: string): Promise<{
63
63
  name: string;
64
64
  id: string;
65
65
  createdAt: Date;
66
- classId: string;
67
66
  updatedAt: Date;
67
+ classId: string;
68
68
  }>;
69
69
  /**
70
70
  * Create a worksheet by converting a PDF (URL) into structured questions.
@@ -74,8 +74,8 @@ export declare function createWorksheetFromPdf(classId: string, url: string): Pr
74
74
  name: string;
75
75
  id: string;
76
76
  createdAt: Date;
77
- classId: string;
78
77
  updatedAt: Date;
78
+ classId: string;
79
79
  }>;
80
80
  /**
81
81
  * Create a worksheet from a PDF that was uploaded through the direct-upload flow.
@@ -84,8 +84,8 @@ export declare function createWorksheetFromUploadedPdf(classId: string, fileId:
84
84
  name: string;
85
85
  id: string;
86
86
  createdAt: Date;
87
- classId: string;
88
87
  updatedAt: Date;
88
+ classId: string;
89
89
  }>;
90
90
  export declare function addQuestionToWorksheet(worksheetId: string, userId: string, data: {
91
91
  question: string;
@@ -99,9 +99,9 @@ export declare function addQuestionToWorksheet(worksheetId: string, userId: stri
99
99
  options: import("@prisma/client/runtime/library.js").JsonValue | null;
100
100
  id: string;
101
101
  createdAt: Date;
102
+ updatedAt: Date;
102
103
  order: number | null;
103
104
  points: number;
104
- updatedAt: Date;
105
105
  worksheetId: string;
106
106
  markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
107
107
  question: string;
@@ -122,9 +122,9 @@ export declare function updateWorksheetQuestionRecord(worksheetId: string, quest
122
122
  options: import("@prisma/client/runtime/library.js").JsonValue | null;
123
123
  id: string;
124
124
  createdAt: Date;
125
+ updatedAt: Date;
125
126
  order: number | null;
126
127
  points: number;
127
- updatedAt: Date;
128
128
  worksheetId: string;
129
129
  markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
130
130
  question: string;
@@ -135,9 +135,9 @@ export declare function deleteWorksheetQuestionRecord(worksheetId: string, quest
135
135
  options: import("@prisma/client/runtime/library.js").JsonValue | null;
136
136
  id: string;
137
137
  createdAt: Date;
138
+ updatedAt: Date;
138
139
  order: number | null;
139
140
  points: number;
140
- updatedAt: Date;
141
141
  worksheetId: string;
142
142
  markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
143
143
  question: string;
@@ -152,6 +152,7 @@ export declare function getWorksheetSubmission(worksheetId: string, submissionId
152
152
  status: import(".prisma/client").$Enums.GenerationStatus | null;
153
153
  id: string;
154
154
  createdAt: Date;
155
+ updatedAt: Date | null;
155
156
  studentId: string;
156
157
  questionId: string;
157
158
  response: string;
@@ -159,17 +160,16 @@ export declare function getWorksheetSubmission(worksheetId: string, submissionId
159
160
  markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
160
161
  points: number;
161
162
  feedback: string | null;
162
- updatedAt: Date | null;
163
163
  studentWorksheetResponseId: string | null;
164
164
  })[];
165
165
  } & {
166
166
  id: string;
167
- submissionId: string | null;
168
167
  createdAt: Date;
168
+ updatedAt: Date;
169
+ submissionId: string | null;
169
170
  studentId: string;
170
171
  submittedAt: Date | null;
171
172
  submitted: boolean;
172
- updatedAt: Date;
173
173
  worksheetId: string;
174
174
  }>;
175
175
  export declare function answerWorksheetQuestion(worksheetResponseId: string, questionId: string, response: string, userId: string): Promise<{
@@ -177,6 +177,7 @@ export declare function answerWorksheetQuestion(worksheetResponseId: string, que
177
177
  status: import(".prisma/client").$Enums.GenerationStatus | null;
178
178
  id: string;
179
179
  createdAt: Date;
180
+ updatedAt: Date | null;
180
181
  studentId: string;
181
182
  questionId: string;
182
183
  response: string;
@@ -184,23 +185,23 @@ export declare function answerWorksheetQuestion(worksheetResponseId: string, que
184
185
  markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
185
186
  points: number;
186
187
  feedback: string | null;
187
- updatedAt: Date | null;
188
188
  studentWorksheetResponseId: string | null;
189
189
  }[];
190
190
  } & {
191
191
  id: string;
192
- submissionId: string | null;
193
192
  createdAt: Date;
193
+ updatedAt: Date;
194
+ submissionId: string | null;
194
195
  studentId: string;
195
196
  submittedAt: Date | null;
196
197
  submitted: boolean;
197
- updatedAt: Date;
198
198
  worksheetId: string;
199
199
  }>;
200
200
  export declare function cancelGrading(worksheetResponseId: string, progressId: string, userId: string): Promise<{
201
201
  status: import(".prisma/client").$Enums.GenerationStatus | null;
202
202
  id: string;
203
203
  createdAt: Date;
204
+ updatedAt: Date | null;
204
205
  studentId: string;
205
206
  questionId: string;
206
207
  response: string;
@@ -208,13 +209,13 @@ export declare function cancelGrading(worksheetResponseId: string, progressId: s
208
209
  markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
209
210
  points: number;
210
211
  feedback: string | null;
211
- updatedAt: Date | null;
212
212
  studentWorksheetResponseId: string | null;
213
213
  }>;
214
214
  export declare function regradeQuestion(worksheetResponseId: string, progressId: string, userId: string): Promise<{
215
215
  status: import(".prisma/client").$Enums.GenerationStatus | null;
216
216
  id: string;
217
217
  createdAt: Date;
218
+ updatedAt: Date | null;
218
219
  studentId: string;
219
220
  questionId: string;
220
221
  response: string;
@@ -222,7 +223,6 @@ export declare function regradeQuestion(worksheetResponseId: string, progressId:
222
223
  markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
223
224
  points: number;
224
225
  feedback: string | null;
225
- updatedAt: Date | null;
226
226
  studentWorksheetResponseId: string | null;
227
227
  }>;
228
228
  export declare function gradeAnswer(questionId: string, studentWorksheetResponseId: string, userId: string, data: {
@@ -236,6 +236,7 @@ export declare function gradeAnswer(questionId: string, studentWorksheetResponse
236
236
  status: import(".prisma/client").$Enums.GenerationStatus | null;
237
237
  id: string;
238
238
  createdAt: Date;
239
+ updatedAt: Date | null;
239
240
  studentId: string;
240
241
  questionId: string;
241
242
  response: string;
@@ -243,14 +244,15 @@ export declare function gradeAnswer(questionId: string, studentWorksheetResponse
243
244
  markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
244
245
  points: number;
245
246
  feedback: string | null;
246
- updatedAt: Date | null;
247
247
  studentWorksheetResponseId: string | null;
248
248
  }>;
249
249
  export declare function addCommentToResponse(responseId: string, comment: string, authorId: string): Promise<{
250
250
  status: import(".prisma/client").$Enums.GenerationStatus | null;
251
251
  id: string;
252
- announcementId: string | null;
253
252
  createdAt: Date;
253
+ assignmentId: string | null;
254
+ submissionId: string | null;
255
+ announcementId: string | null;
254
256
  modifiedAt: Date | null;
255
257
  content: string;
256
258
  authorId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["services/worksheet.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["services/worksheet.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studious-lms/server",
3
- "version": "1.4.5",
3
+ "version": "1.4.7",
4
4
  "description": "Backend server for Studious application",
5
5
  "main": "dist/exportType.js",
6
6
  "types": "dist/exportType.d.ts",
@@ -0,0 +1,60 @@
1
+ ALTER TABLE "public"."Comment" ADD COLUMN "assignmentId" TEXT;
2
+ ALTER TABLE "public"."Comment" ADD COLUMN "submissionId" TEXT;
3
+
4
+ CREATE INDEX "Comment_assignmentId_idx" ON "public"."Comment"("assignmentId");
5
+ CREATE INDEX "Comment_submissionId_idx" ON "public"."Comment"("submissionId");
6
+
7
+ ALTER TABLE "public"."Comment" ADD CONSTRAINT "Comment_assignmentId_fkey" FOREIGN KEY ("assignmentId") REFERENCES "public"."Assignment"("id") ON DELETE CASCADE ON UPDATE CASCADE;
8
+ ALTER TABLE "public"."Comment" ADD CONSTRAINT "Comment_submissionId_fkey" FOREIGN KEY ("submissionId") REFERENCES "public"."Submission"("id") ON DELETE CASCADE ON UPDATE CASCADE;
9
+
10
+ WITH RECURSIVE "CommentOwnerContext" AS (
11
+ SELECT
12
+ "id",
13
+ "parentCommentId",
14
+ "announcementId",
15
+ "assignmentId",
16
+ "submissionId",
17
+ "studentQuestionProgressId"
18
+ FROM "public"."Comment"
19
+ WHERE "parentCommentId" IS NULL
20
+
21
+ UNION ALL
22
+
23
+ SELECT
24
+ child."id",
25
+ child."parentCommentId",
26
+ COALESCE(child."announcementId", parent."announcementId"),
27
+ COALESCE(child."assignmentId", parent."assignmentId"),
28
+ COALESCE(child."submissionId", parent."submissionId"),
29
+ COALESCE(child."studentQuestionProgressId", parent."studentQuestionProgressId")
30
+ FROM "public"."Comment" child
31
+ INNER JOIN "CommentOwnerContext" parent ON child."parentCommentId" = parent."id"
32
+ )
33
+ UPDATE "public"."Comment" c
34
+ SET
35
+ "announcementId" = owner."announcementId",
36
+ "assignmentId" = owner."assignmentId",
37
+ "submissionId" = owner."submissionId",
38
+ "studentQuestionProgressId" = owner."studentQuestionProgressId"
39
+ FROM "CommentOwnerContext" owner
40
+ WHERE c."id" = owner."id"
41
+ AND c."parentCommentId" IS NOT NULL
42
+ AND (
43
+ (CASE WHEN c."assignmentId" IS NOT NULL THEN 1 ELSE 0 END) +
44
+ (CASE WHEN c."submissionId" IS NOT NULL THEN 1 ELSE 0 END) +
45
+ (CASE WHEN c."announcementId" IS NOT NULL THEN 1 ELSE 0 END) +
46
+ (CASE WHEN c."studentQuestionProgressId" IS NOT NULL THEN 1 ELSE 0 END)
47
+ ) = 0
48
+ AND (
49
+ (CASE WHEN owner."assignmentId" IS NOT NULL THEN 1 ELSE 0 END) +
50
+ (CASE WHEN owner."submissionId" IS NOT NULL THEN 1 ELSE 0 END) +
51
+ (CASE WHEN owner."announcementId" IS NOT NULL THEN 1 ELSE 0 END) +
52
+ (CASE WHEN owner."studentQuestionProgressId" IS NOT NULL THEN 1 ELSE 0 END)
53
+ ) = 1;
54
+
55
+ ALTER TABLE "public"."Comment" ADD CONSTRAINT "Comment_single_owner_check" CHECK (
56
+ (CASE WHEN "assignmentId" IS NOT NULL THEN 1 ELSE 0 END) +
57
+ (CASE WHEN "submissionId" IS NOT NULL THEN 1 ELSE 0 END) +
58
+ (CASE WHEN "announcementId" IS NOT NULL THEN 1 ELSE 0 END) +
59
+ (CASE WHEN "studentQuestionProgressId" IS NOT NULL THEN 1 ELSE 0 END) = 1
60
+ );
@@ -0,0 +1,81 @@
1
+ -- Add durable multi-school membership and invite support.
2
+
3
+ CREATE TYPE "SchoolMembershipRole" AS ENUM ('ADMIN', 'TEACHER', 'STUDENT');
4
+ CREATE TYPE "SchoolMembershipStatus" AS ENUM ('ACTIVE', 'INVITED', 'SUSPENDED');
5
+ CREATE TYPE "SchoolInviteStatus" AS ENUM ('PENDING', 'ACCEPTED', 'REVOKED', 'EXPIRED');
6
+
7
+ ALTER TABLE "School"
8
+ ALTER COLUMN "logoId" DROP NOT NULL,
9
+ ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
10
+ ADD COLUMN "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
11
+
12
+ CREATE TABLE "SchoolMembership" (
13
+ "id" TEXT NOT NULL,
14
+ "schoolId" TEXT NOT NULL,
15
+ "userId" TEXT NOT NULL,
16
+ "role" "SchoolMembershipRole" NOT NULL,
17
+ "status" "SchoolMembershipStatus" NOT NULL DEFAULT 'ACTIVE',
18
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
19
+ "updatedAt" TIMESTAMP(3) NOT NULL,
20
+
21
+ CONSTRAINT "SchoolMembership_pkey" PRIMARY KEY ("id")
22
+ );
23
+
24
+ CREATE TABLE "SchoolInvite" (
25
+ "id" TEXT NOT NULL,
26
+ "token" TEXT NOT NULL,
27
+ "email" TEXT NOT NULL,
28
+ "role" "SchoolMembershipRole" NOT NULL,
29
+ "status" "SchoolInviteStatus" NOT NULL DEFAULT 'PENDING',
30
+ "expiresAt" TIMESTAMP(3) NOT NULL,
31
+ "acceptedAt" TIMESTAMP(3),
32
+ "revokedAt" TIMESTAMP(3),
33
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
34
+ "updatedAt" TIMESTAMP(3) NOT NULL,
35
+ "schoolId" TEXT NOT NULL,
36
+ "invitedById" TEXT NOT NULL,
37
+
38
+ CONSTRAINT "SchoolInvite_pkey" PRIMARY KEY ("id")
39
+ );
40
+
41
+ INSERT INTO "SchoolMembership" ("id", "schoolId", "userId", "role", "status", "createdAt", "updatedAt")
42
+ SELECT
43
+ "id",
44
+ "schoolId",
45
+ "id",
46
+ CASE
47
+ WHEN "role" = 'ADMIN' THEN 'ADMIN'::"SchoolMembershipRole"
48
+ WHEN "role" = 'TEACHER' THEN 'TEACHER'::"SchoolMembershipRole"
49
+ ELSE 'STUDENT'::"SchoolMembershipRole"
50
+ END,
51
+ 'ACTIVE'::"SchoolMembershipStatus",
52
+ CURRENT_TIMESTAMP,
53
+ CURRENT_TIMESTAMP
54
+ FROM "User"
55
+ WHERE "schoolId" IS NOT NULL
56
+ ON CONFLICT DO NOTHING;
57
+
58
+ CREATE UNIQUE INDEX "SchoolMembership_schoolId_userId_key" ON "SchoolMembership"("schoolId", "userId");
59
+ CREATE INDEX "SchoolMembership_userId_idx" ON "SchoolMembership"("userId");
60
+ CREATE INDEX "SchoolMembership_schoolId_role_idx" ON "SchoolMembership"("schoolId", "role");
61
+ CREATE INDEX "SchoolMembership_schoolId_status_idx" ON "SchoolMembership"("schoolId", "status");
62
+
63
+ CREATE UNIQUE INDEX "SchoolInvite_token_key" ON "SchoolInvite"("token");
64
+ CREATE INDEX "SchoolInvite_schoolId_status_idx" ON "SchoolInvite"("schoolId", "status");
65
+ CREATE INDEX "SchoolInvite_email_idx" ON "SchoolInvite"("email");
66
+
67
+ ALTER TABLE "SchoolMembership"
68
+ ADD CONSTRAINT "SchoolMembership_schoolId_fkey"
69
+ FOREIGN KEY ("schoolId") REFERENCES "School"("id") ON DELETE CASCADE ON UPDATE CASCADE;
70
+
71
+ ALTER TABLE "SchoolMembership"
72
+ ADD CONSTRAINT "SchoolMembership_userId_fkey"
73
+ FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
74
+
75
+ ALTER TABLE "SchoolInvite"
76
+ ADD CONSTRAINT "SchoolInvite_schoolId_fkey"
77
+ FOREIGN KEY ("schoolId") REFERENCES "School"("id") ON DELETE CASCADE ON UPDATE CASCADE;
78
+
79
+ ALTER TABLE "SchoolInvite"
80
+ ADD CONSTRAINT "SchoolInvite_invitedById_fkey"
81
+ FOREIGN KEY ("invitedById") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -81,15 +81,38 @@ enum SubmissionRecommendationState {
81
81
  DISMISSED
82
82
  }
83
83
 
84
+ enum SchoolMembershipRole {
85
+ ADMIN
86
+ TEACHER
87
+ STUDENT
88
+ }
89
+
90
+ enum SchoolMembershipStatus {
91
+ ACTIVE
92
+ INVITED
93
+ SUSPENDED
94
+ }
95
+
96
+ enum SchoolInviteStatus {
97
+ PENDING
98
+ ACCEPTED
99
+ REVOKED
100
+ EXPIRED
101
+ }
102
+
84
103
  model School {
85
104
  id String @id @default(uuid())
86
105
  name String
87
- logo File @relation(references: [id], fields: [logoId])
88
- logoId String
106
+ logo File? @relation(references: [id], fields: [logoId])
107
+ logoId String?
89
108
  subdomain String? @unique
109
+ createdAt DateTime @default(now())
110
+ updatedAt DateTime @updatedAt
90
111
 
91
112
 
92
113
  users User[]
114
+ memberships SchoolMembership[]
115
+ invites SchoolInvite[]
93
116
  classes Class[]
94
117
  }
95
118
 
@@ -123,6 +146,8 @@ model User {
123
146
 
124
147
  school School? @relation(fields: [schoolId], references: [id])
125
148
  schoolId String?
149
+ schoolMemberships SchoolMembership[]
150
+ sentSchoolInvites SchoolInvite[] @relation("SchoolInviteInvitedBy")
126
151
 
127
152
  // Chat relations
128
153
  conversationMemberships ConversationMember[]
@@ -134,6 +159,45 @@ model User {
134
159
 
135
160
  }
136
161
 
162
+ model SchoolMembership {
163
+ id String @id @default(uuid())
164
+ schoolId String
165
+ userId String
166
+ role SchoolMembershipRole
167
+ status SchoolMembershipStatus @default(ACTIVE)
168
+ createdAt DateTime @default(now())
169
+ updatedAt DateTime @updatedAt
170
+
171
+ school School @relation(fields: [schoolId], references: [id], onDelete: Cascade)
172
+ user User @relation(fields: [userId], references: [id], onDelete: Cascade)
173
+
174
+ @@unique([schoolId, userId])
175
+ @@index([userId])
176
+ @@index([schoolId, role])
177
+ @@index([schoolId, status])
178
+ }
179
+
180
+ model SchoolInvite {
181
+ id String @id @default(uuid())
182
+ token String @unique
183
+ email String
184
+ role SchoolMembershipRole
185
+ status SchoolInviteStatus @default(PENDING)
186
+ expiresAt DateTime
187
+ acceptedAt DateTime?
188
+ revokedAt DateTime?
189
+ createdAt DateTime @default(now())
190
+ updatedAt DateTime @updatedAt
191
+
192
+ schoolId String
193
+ school School @relation(fields: [schoolId], references: [id], onDelete: Cascade)
194
+ invitedById String
195
+ invitedBy User @relation("SchoolInviteInvitedBy", fields: [invitedById], references: [id], onDelete: Cascade)
196
+
197
+ @@index([schoolId, status])
198
+ @@index([email])
199
+ }
200
+
137
201
  model UserProfile {
138
202
  id String @id @default(uuid())
139
203
  userId String @unique
@@ -282,6 +346,7 @@ model Assignment {
282
346
  aiPolicyLevel Int @default(0)
283
347
 
284
348
  submissions Submission[]
349
+ comments Comment[] @relation("AssignmentComments")
285
350
  assignedTo User[] @relation("SpecificAssignmentAssignedTo")
286
351
  section Section? @relation(fields: [sectionId], references: [id], onDelete: Cascade)
287
352
  sectionId String?
@@ -325,6 +390,10 @@ model Comment {
325
390
  authorId String
326
391
  announcement Announcement? @relation(fields: [announcementId], references: [id], onDelete: Cascade)
327
392
  announcementId String?
393
+ assignment Assignment? @relation("AssignmentComments", fields: [assignmentId], references: [id], onDelete: Cascade)
394
+ assignmentId String?
395
+ submission Submission? @relation("SubmissionComments", fields: [submissionId], references: [id], onDelete: Cascade)
396
+ submissionId String?
328
397
  parentComment Comment? @relation("CommentReplies", fields: [parentCommentId], references: [id], onDelete: Cascade)
329
398
  parentCommentId String?
330
399
  status GenerationStatus?
@@ -334,6 +403,9 @@ model Comment {
334
403
  modifiedAt DateTime? @updatedAt
335
404
  studentQuestionProgress StudentQuestionProgress? @relation("StudentQuestionProgressComments", fields: [studentQuestionProgressId], references: [id], onDelete: Cascade)
336
405
  studentQuestionProgressId String?
406
+
407
+ @@index([assignmentId])
408
+ @@index([submissionId])
337
409
  }
338
410
 
339
411
  model Reaction {
@@ -366,6 +438,7 @@ model Submission {
366
438
 
367
439
  attachments File[] @relation("SubmissionFile")
368
440
  annotations File[] @relation("SubmissionAnnotations")
441
+ comments Comment[] @relation("SubmissionComments")
369
442
  worksheetResponses StudentWorksheetResponse[]
370
443
  extendedResponse String?
371
444
  gradeReceived Int?
@@ -18,6 +18,10 @@ const nonProductionOrigins = [
18
18
  'http://127.0.0.1:3000',
19
19
  'http://127.0.0.1:3001',
20
20
  ];
21
+
22
+ /** Any preview / prod deployment on *.vercel.app (HTTPS only). */
23
+ const vercelAppOriginPattern = /^https:\/\/[a-z0-9][a-z0-9.-]*\.vercel\.app$/i;
24
+
21
25
  const MAX_PATTERN_LENGTH = 200;
22
26
  // This heuristic only targets common nested-quantifier cases like `(a+)+`.
23
27
  // It does not catch every risky construct (for example `.*.*` or deep alternation nesting),
@@ -77,7 +81,10 @@ export const createCorsOriginMatcher = (env: CorsEnv) => {
77
81
  ...parseCorsOrigins(env.CORS_ALLOWED_ORIGINS),
78
82
  ].filter(isDefined)));
79
83
 
80
- const allowedOriginPatterns = parseCorsOriginPatterns(env.CORS_ALLOWED_ORIGIN_PATTERNS);
84
+ const allowedOriginPatterns = [
85
+ vercelAppOriginPattern,
86
+ ...parseCorsOriginPatterns(env.CORS_ALLOWED_ORIGIN_PATTERNS),
87
+ ];
81
88
 
82
89
  const isAllowedOrigin = (origin?: string) => {
83
90
  const corsOrigin = origin ? toCorsOrigin(origin) : undefined;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Shared class access filters.
3
+ */
4
+
5
+ export const schoolAdminForClassWhere = (userId: string) => ({
6
+ OR: [
7
+ {
8
+ school: {
9
+ is: {
10
+ memberships: {
11
+ some: {
12
+ userId,
13
+ role: "ADMIN" as const,
14
+ status: "ACTIVE" as const,
15
+ },
16
+ },
17
+ },
18
+ },
19
+ },
20
+ {
21
+ school: {
22
+ is: {
23
+ users: {
24
+ some: {
25
+ id: userId,
26
+ role: "ADMIN" as const,
27
+ },
28
+ },
29
+ },
30
+ },
31
+ },
32
+ ],
33
+ });
34
+
35
+ export const classTeacherOrSchoolAdminWhere = (userId: string) => ({
36
+ OR: [
37
+ { teachers: { some: { id: userId } } },
38
+ schoolAdminForClassWhere(userId),
39
+ ],
40
+ });
41
+
42
+ export const classMemberOrSchoolAdminWhere = (userId: string) => ({
43
+ OR: [
44
+ { teachers: { some: { id: userId } } },
45
+ { students: { some: { id: userId } } },
46
+ schoolAdminForClassWhere(userId),
47
+ ],
48
+ });
@@ -56,13 +56,30 @@ export function findAnnouncementByIdAndClass(id: string, classId: string) {
56
56
  });
57
57
  }
58
58
 
59
- /** @returns Announcement by ID with class and teachers. */
59
+ /** @returns Announcement by ID with class teachers and school admins. */
60
60
  export function findAnnouncementWithClass(id: string) {
61
61
  return prisma.announcement.findUnique({
62
62
  where: { id },
63
63
  include: {
64
64
  class: {
65
- include: { teachers: true },
65
+ include: {
66
+ teachers: true,
67
+ school: {
68
+ include: {
69
+ users: {
70
+ where: { role: "ADMIN" as const },
71
+ select: { id: true },
72
+ },
73
+ memberships: {
74
+ where: {
75
+ role: "ADMIN" as const,
76
+ status: "ACTIVE" as const,
77
+ },
78
+ select: { userId: true },
79
+ },
80
+ },
81
+ },
82
+ },
66
83
  },
67
84
  attachments: {
68
85
  select: {