@studious-lms/server 1.2.33 → 1.2.35

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.
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
2
  export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
3
- ctx: import("src/trpc").Context;
3
+ ctx: import("../trpc.js").Context;
4
4
  meta: object;
5
5
  errorShape: {
6
6
  data: {
7
7
  zodError: z.typeToFlattenedError<any, string> | null;
8
- prismaError: import("../utils/prismaErrorHandler").PrismaErrorInfo | null;
8
+ prismaError: import("../utils/prismaErrorHandler.js").PrismaErrorInfo | null;
9
9
  code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
10
10
  httpStatus: number;
11
11
  path?: string;
@@ -33,11 +33,12 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
33
33
  questions: {
34
34
  type: import(".prisma/client").$Enums.WorksheetQuestionType;
35
35
  id: string;
36
- options: import("@prisma/client/runtime/library").JsonValue | null;
36
+ options: import("@prisma/client/runtime/library.js").JsonValue | null;
37
37
  createdAt: Date;
38
38
  order: number | null;
39
- markScheme: import("@prisma/client/runtime/library").JsonValue | null;
39
+ markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
40
40
  updatedAt: Date;
41
+ points: number;
41
42
  question: string;
42
43
  worksheetId: string;
43
44
  answer: string;
@@ -117,15 +118,17 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
117
118
  answer: string;
118
119
  options?: any;
119
120
  markScheme?: any;
121
+ points?: number | undefined;
120
122
  };
121
123
  output: {
122
124
  type: import(".prisma/client").$Enums.WorksheetQuestionType;
123
125
  id: string;
124
- options: import("@prisma/client/runtime/library").JsonValue | null;
126
+ options: import("@prisma/client/runtime/library.js").JsonValue | null;
125
127
  createdAt: Date;
126
128
  order: number | null;
127
- markScheme: import("@prisma/client/runtime/library").JsonValue | null;
129
+ markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
128
130
  updatedAt: Date;
131
+ points: number;
129
132
  question: string;
130
133
  worksheetId: string;
131
134
  answer: string;
@@ -151,17 +154,19 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
151
154
  type?: "ESSAY" | "MULTIPLE_CHOICE" | "TRUE_FALSE" | "SHORT_ANSWER" | "LONG_ANSWER" | "MATH_EXPRESSION" | undefined;
152
155
  options?: any;
153
156
  markScheme?: any;
157
+ points?: number | undefined;
154
158
  question?: string | undefined;
155
159
  answer?: string | undefined;
156
160
  };
157
161
  output: {
158
162
  type: import(".prisma/client").$Enums.WorksheetQuestionType;
159
163
  id: string;
160
- options: import("@prisma/client/runtime/library").JsonValue | null;
164
+ options: import("@prisma/client/runtime/library.js").JsonValue | null;
161
165
  createdAt: Date;
162
166
  order: number | null;
163
- markScheme: import("@prisma/client/runtime/library").JsonValue | null;
167
+ markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
164
168
  updatedAt: Date;
169
+ points: number;
165
170
  question: string;
166
171
  worksheetId: string;
167
172
  answer: string;
@@ -176,11 +181,12 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
176
181
  output: {
177
182
  type: import(".prisma/client").$Enums.WorksheetQuestionType;
178
183
  id: string;
179
- options: import("@prisma/client/runtime/library").JsonValue | null;
184
+ options: import("@prisma/client/runtime/library.js").JsonValue | null;
180
185
  createdAt: Date;
181
186
  order: number | null;
182
- markScheme: import("@prisma/client/runtime/library").JsonValue | null;
187
+ markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
183
188
  updatedAt: Date;
189
+ points: number;
184
190
  question: string;
185
191
  worksheetId: string;
186
192
  answer: string;
@@ -198,11 +204,13 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
198
204
  feedback: string | null;
199
205
  studentId: string;
200
206
  createdAt: Date;
201
- updatedAt: Date;
207
+ updatedAt: Date | null;
208
+ points: number;
202
209
  questionId: string;
203
210
  response: string;
204
- isCorrect: boolean;
205
211
  studentWorksheetResponseId: string | null;
212
+ isCorrect: boolean;
213
+ markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
206
214
  }[];
207
215
  } & {
208
216
  id: string;
@@ -228,11 +236,13 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
228
236
  feedback: string | null;
229
237
  studentId: string;
230
238
  createdAt: Date;
231
- updatedAt: Date;
239
+ updatedAt: Date | null;
240
+ points: number;
232
241
  questionId: string;
233
242
  response: string;
234
- isCorrect: boolean;
235
243
  studentWorksheetResponseId: string | null;
244
+ isCorrect: boolean;
245
+ markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
236
246
  }[];
237
247
  } & {
238
248
  id: string;
@@ -256,54 +266,14 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
256
266
  feedback: string | null;
257
267
  studentId: string;
258
268
  createdAt: Date;
259
- updatedAt: Date;
269
+ updatedAt: Date | null;
270
+ points: number;
260
271
  questionId: string;
261
272
  response: string;
262
- isCorrect: boolean;
263
273
  studentWorksheetResponseId: string | null;
264
- }[];
265
- } & {
266
- id: string;
267
- submissionId: string | null;
268
- studentId: string;
269
- createdAt: Date;
270
- updatedAt: Date;
271
- submittedAt: Date | null;
272
- submitted: boolean;
273
- worksheetId: string;
274
- };
275
- meta: object;
276
- }>;
277
- getOrCreateWorksheetResponse: import("@trpc/server").TRPCMutationProcedure<{
278
- input: {
279
- studentId: string;
280
- worksheetId: string;
281
- };
282
- output: {
283
- responses: ({
284
- question: {
285
- type: import(".prisma/client").$Enums.WorksheetQuestionType;
286
- id: string;
287
- options: import("@prisma/client/runtime/library").JsonValue | null;
288
- createdAt: Date;
289
- order: number | null;
290
- markScheme: import("@prisma/client/runtime/library").JsonValue | null;
291
- updatedAt: Date;
292
- question: string;
293
- worksheetId: string;
294
- answer: string;
295
- };
296
- } & {
297
- id: string;
298
- feedback: string | null;
299
- studentId: string;
300
- createdAt: Date;
301
- updatedAt: Date;
302
- questionId: string;
303
- response: string;
304
274
  isCorrect: boolean;
305
- studentWorksheetResponseId: string | null;
306
- })[];
275
+ markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
276
+ }[];
307
277
  } & {
308
278
  id: string;
309
279
  submissionId: string | null;
@@ -316,71 +286,34 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
316
286
  };
317
287
  meta: object;
318
288
  }>;
319
- getWorksheetResponse: import("@trpc/server").TRPCQueryProcedure<{
289
+ gradeAnswer: import("@trpc/server").TRPCMutationProcedure<{
320
290
  input: {
321
- worksheetId: string;
291
+ questionId: string;
292
+ studentWorksheetResponseId: string;
293
+ isCorrect: boolean;
294
+ feedback?: string | undefined;
295
+ points?: number | undefined;
296
+ response?: string | undefined;
297
+ responseId?: string | undefined;
298
+ markschemeState?: any;
322
299
  };
323
- output: ({
324
- student: {
325
- id: string;
326
- username: string;
327
- profile: {
328
- displayName: string | null;
329
- profilePicture: string | null;
330
- } | null;
331
- };
332
- responses: ({
333
- question: {
334
- type: import(".prisma/client").$Enums.WorksheetQuestionType;
335
- id: string;
336
- options: import("@prisma/client/runtime/library").JsonValue | null;
337
- createdAt: Date;
338
- order: number | null;
339
- markScheme: import("@prisma/client/runtime/library").JsonValue | null;
340
- updatedAt: Date;
341
- question: string;
342
- worksheetId: string;
343
- answer: string;
344
- };
345
- } & {
346
- id: string;
347
- feedback: string | null;
348
- studentId: string;
349
- createdAt: Date;
350
- updatedAt: Date;
351
- questionId: string;
352
- response: string;
353
- isCorrect: boolean;
354
- studentWorksheetResponseId: string | null;
355
- })[];
356
- } & {
357
- id: string;
358
- submissionId: string | null;
359
- studentId: string;
360
- createdAt: Date;
361
- updatedAt: Date;
362
- submittedAt: Date | null;
363
- submitted: boolean;
364
- worksheetId: string;
365
- }) | null;
300
+ output: any;
366
301
  meta: object;
367
302
  }>;
368
- gradeAnswer: import("@trpc/server").TRPCMutationProcedure<{
303
+ addComment: import("@trpc/server").TRPCMutationProcedure<{
369
304
  input: {
305
+ comment: string;
370
306
  responseId: string;
371
- isCorrect: boolean;
372
- feedback?: string | undefined;
373
307
  };
374
308
  output: {
375
309
  id: string;
376
- feedback: string | null;
377
- studentId: string;
310
+ content: string;
378
311
  createdAt: Date;
379
- updatedAt: Date;
380
- questionId: string;
381
- response: string;
382
- isCorrect: boolean;
383
- studentWorksheetResponseId: string | null;
312
+ modifiedAt: Date | null;
313
+ announcementId: string | null;
314
+ parentCommentId: string | null;
315
+ authorId: string;
316
+ studentQuestionProgressId: string | null;
384
317
  };
385
318
  meta: object;
386
319
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"worksheet.d.ts","sourceRoot":"","sources":["../../src/routers/worksheet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA2KA,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsUhC,CAAC"}
1
+ {"version":3,"file":"worksheet.d.ts","sourceRoot":"","sources":["../../src/routers/worksheet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA8KA,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4UhC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { TRPCError } from "@trpc/server";
2
- import { createTRPCRouter, protectedProcedure } from "src/trpc";
2
+ import { createTRPCRouter, protectedProcedure } from "../trpc.js";
3
3
  import { z } from "zod";
4
- import { prisma } from "src/lib/prisma";
4
+ import { prisma } from "../lib/prisma.js";
5
5
  export const worksheetRouter = createTRPCRouter({
6
6
  // Get a single worksheet with all questions
7
7
  getWorksheet: protectedProcedure
@@ -15,6 +15,7 @@ export const worksheetRouter = createTRPCRouter({
15
15
  include: {
16
16
  questions: {
17
17
  orderBy: { createdAt: 'asc' },
18
+ // select: { id: true, type: true, question: true, answer: true, points: true },
18
19
  },
19
20
  class: true,
20
21
  },
@@ -95,12 +96,13 @@ export const worksheetRouter = createTRPCRouter({
95
96
  worksheetId: z.string(),
96
97
  question: z.string(),
97
98
  answer: z.string(),
99
+ points: z.number().optional(),
98
100
  options: z.any().optional(), // JSON field
99
101
  markScheme: z.any().optional(), // JSON field
100
102
  type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']),
101
103
  }))
102
104
  .mutation(async ({ ctx, input }) => {
103
- const { worksheetId, question, answer, options, markScheme, type } = input;
105
+ const { worksheetId, question, points, answer, options, markScheme, type } = input;
104
106
  const worksheet = await prisma.worksheet.findUnique({
105
107
  where: { id: worksheetId },
106
108
  });
@@ -111,6 +113,7 @@ export const worksheetRouter = createTRPCRouter({
111
113
  data: {
112
114
  worksheetId,
113
115
  type,
116
+ points,
114
117
  question,
115
118
  answer,
116
119
  options,
@@ -167,12 +170,13 @@ export const worksheetRouter = createTRPCRouter({
167
170
  questionId: z.string(),
168
171
  question: z.string().optional(),
169
172
  answer: z.string().optional(),
173
+ points: z.number().optional(),
170
174
  options: z.any().optional(), // JSON field
171
175
  markScheme: z.any().optional(), // JSON field
172
176
  type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']).optional(),
173
177
  }))
174
178
  .mutation(async ({ ctx, input }) => {
175
- const { worksheetId, questionId, question, answer, options, markScheme, type } = input;
179
+ const { worksheetId, questionId, points, question, answer, options, markScheme, type } = input;
176
180
  const worksheet = await prisma.worksheet.findUnique({
177
181
  where: { id: worksheetId },
178
182
  });
@@ -187,6 +191,7 @@ export const worksheetRouter = createTRPCRouter({
187
191
  ...(markScheme !== undefined && { markScheme }),
188
192
  ...(type !== undefined && { type }),
189
193
  ...(options !== undefined && { options }),
194
+ ...(points !== undefined && { points }),
190
195
  },
191
196
  });
192
197
  return updatedQuestion;
@@ -223,7 +228,7 @@ export const worksheetRouter = createTRPCRouter({
223
228
  throw new TRPCError({ code: 'NOT_FOUND', message: 'Submission not found' });
224
229
  }
225
230
  // Find or create worksheet response for this submission
226
- const worksheetResponses = await prisma.$transaction(async (tx) => {
231
+ const worksheetResponse = await prisma.$transaction(async (tx) => {
227
232
  // First check if a response exists
228
233
  const existing = await tx.studentWorksheetResponse.findFirst({
229
234
  where: {
@@ -250,7 +255,8 @@ export const worksheetRouter = createTRPCRouter({
250
255
  });
251
256
  return created;
252
257
  });
253
- return worksheetResponses;
258
+ console.log(worksheetResponse);
259
+ return worksheetResponse;
254
260
  }),
255
261
  answerQuestion: protectedProcedure
256
262
  .input(z.object({
@@ -339,95 +345,99 @@ export const worksheetRouter = createTRPCRouter({
339
345
  // You could integrate with an AI service to auto-grade certain question types
340
346
  return submittedWorksheet;
341
347
  }),
342
- // Get or create a student's worksheet response
343
- getOrCreateWorksheetResponse: protectedProcedure
348
+ // Grade a student's answer
349
+ gradeAnswer: protectedProcedure
344
350
  .input(z.object({
345
- worksheetId: z.string(),
346
- studentId: z.string(),
351
+ questionId: z.string(),
352
+ responseId: z.string().optional(), // StudentQuestionProgress ID (optional for upsert)
353
+ studentWorksheetResponseId: z.string(), // Required for linking to worksheet response
354
+ response: z.string().optional(), // The actual response text (needed if creating new)
355
+ isCorrect: z.boolean(),
356
+ feedback: z.string().optional(),
357
+ markschemeState: z.any().optional(),
358
+ points: z.number().optional(),
347
359
  }))
348
360
  .mutation(async ({ ctx, input }) => {
349
- const { worksheetId, studentId } = input;
350
- // Try to find existing response
351
- let worksheetResponse = await prisma.studentWorksheetResponse.findFirst({
352
- where: {
353
- worksheetId,
354
- studentId,
355
- submitted: false, // Only get unsubmitted responses
356
- },
357
- include: {
358
- responses: {
359
- include: {
360
- question: true,
361
- },
362
- },
363
- },
364
- });
365
- // Create new response if none exists
366
- if (!worksheetResponse) {
367
- worksheetResponse = await prisma.studentWorksheetResponse.create({
361
+ const { responseId, questionId, studentWorksheetResponseId, response, isCorrect, feedback, markschemeState, points } = input;
362
+ let gradedResponse;
363
+ if (responseId) {
364
+ // Update existing progress by ID
365
+ gradedResponse = await prisma.studentQuestionProgress.update({
366
+ where: { id: responseId },
368
367
  data: {
369
- worksheetId,
370
- studentId,
371
- },
372
- include: {
373
- responses: {
374
- include: {
375
- question: true,
376
- },
377
- },
368
+ isCorrect,
369
+ ...(feedback !== undefined && { feedback }),
370
+ ...(markschemeState !== undefined && { markschemeState }),
371
+ ...(points !== undefined && { points }),
378
372
  },
379
373
  });
380
374
  }
381
- return worksheetResponse;
382
- }),
383
- // Get all student responses for a worksheet (teacher view)
384
- getWorksheetResponse: protectedProcedure
385
- .input(z.object({
386
- worksheetId: z.string(),
387
- }))
388
- .query(async ({ ctx, input }) => {
389
- const { worksheetId } = input;
390
- const responses = await prisma.studentWorksheetResponse.findFirst({
391
- where: { worksheetId },
392
- include: {
393
- student: {
394
- select: {
395
- id: true,
396
- username: true,
397
- profile: {
398
- select: {
399
- displayName: true,
400
- profilePicture: true,
401
- },
402
- },
403
- },
375
+ else {
376
+ // Get the studentId from the worksheet response
377
+ const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({
378
+ where: { id: studentWorksheetResponseId },
379
+ select: { studentId: true },
380
+ });
381
+ if (!worksheetResponse) {
382
+ throw new TRPCError({
383
+ code: 'NOT_FOUND',
384
+ message: 'Student worksheet response not found',
385
+ });
386
+ }
387
+ const { studentId } = worksheetResponse;
388
+ // Upsert - find or create the progress record
389
+ const existing = await prisma.studentQuestionProgress.findFirst({
390
+ where: {
391
+ studentId,
392
+ questionId,
393
+ studentWorksheetResponseId,
404
394
  },
405
- responses: {
406
- include: {
407
- question: true,
395
+ });
396
+ if (existing) {
397
+ // Update existing
398
+ gradedResponse = await prisma.studentQuestionProgress.update({
399
+ where: { id: existing.id },
400
+ data: {
401
+ isCorrect,
402
+ ...(response !== undefined && { response }),
403
+ ...(feedback !== undefined && { feedback }),
404
+ ...(markschemeState !== undefined && { markschemeState }),
405
+ ...(points !== undefined && { points }),
408
406
  },
409
- },
410
- },
411
- orderBy: { submittedAt: 'desc' },
412
- });
413
- return responses;
407
+ });
408
+ }
409
+ else {
410
+ // Create new
411
+ gradedResponse = await prisma.studentQuestionProgress.create({
412
+ data: {
413
+ studentId,
414
+ questionId,
415
+ studentWorksheetResponseId,
416
+ response: response || '',
417
+ isCorrect,
418
+ ...(feedback !== undefined && { feedback }),
419
+ ...(markschemeState !== undefined && { markschemeState }),
420
+ ...(points !== undefined && { points: points || 0 }),
421
+ },
422
+ });
423
+ }
424
+ }
425
+ return gradedResponse;
414
426
  }),
415
- // Grade a student's answer
416
- gradeAnswer: protectedProcedure
427
+ addComment: protectedProcedure
417
428
  .input(z.object({
418
- responseId: z.string(), // StudentQuestionProgress ID
419
- isCorrect: z.boolean(),
420
- feedback: z.string().optional(),
429
+ responseId: z.string(),
430
+ comment: z.string(),
421
431
  }))
422
432
  .mutation(async ({ ctx, input }) => {
423
- const { responseId, isCorrect, feedback } = input;
424
- const gradedResponse = await prisma.studentQuestionProgress.update({
425
- where: { id: responseId },
433
+ const { responseId, comment } = input;
434
+ const newComment = await prisma.comment.create({
426
435
  data: {
427
- isCorrect,
428
- ...(feedback !== undefined && { feedback }),
436
+ studentQuestionProgressId: responseId,
437
+ content: comment,
438
+ authorId: ctx.user.id,
429
439
  },
430
440
  });
431
- return gradedResponse;
441
+ return newComment;
432
442
  }),
433
443
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studious-lms/server",
3
- "version": "1.2.33",
3
+ "version": "1.2.35",
4
4
  "description": "Backend server for Studious application",
5
5
  "main": "dist/exportType.js",
6
6
  "types": "dist/exportType.d.ts",
@@ -108,7 +108,7 @@ model User {
108
108
  sentMessages Message[] @relation("SentMessages")
109
109
  mentions Mention[] @relation("UserMentions")
110
110
  createdLabChats LabChat[] @relation("CreatedLabChats")
111
- announcementComments AnnouncementComment[]
111
+ comments Comment[]
112
112
  reactions Reaction[]
113
113
 
114
114
  }
@@ -292,23 +292,25 @@ model Announcement {
292
292
  class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
293
293
  classId String
294
294
  attachments File[] @relation("AnnouncementAttachments")
295
- comments AnnouncementComment[]
295
+ comments Comment[]
296
296
  reactions Reaction[]
297
297
  }
298
298
 
299
- model AnnouncementComment {
299
+ model Comment {
300
300
  id String @id @default(uuid())
301
301
  content String
302
302
  author User @relation(fields: [authorId], references: [id], onDelete: Cascade)
303
303
  authorId String
304
- announcement Announcement @relation(fields: [announcementId], references: [id], onDelete: Cascade)
305
- announcementId String
306
- parentComment AnnouncementComment? @relation("CommentReplies", fields: [parentCommentId], references: [id], onDelete: Cascade)
304
+ announcement Announcement? @relation(fields: [announcementId], references: [id], onDelete: Cascade)
305
+ announcementId String?
306
+ parentComment Comment? @relation("CommentReplies", fields: [parentCommentId], references: [id], onDelete: Cascade)
307
307
  parentCommentId String?
308
- replies AnnouncementComment[] @relation("CommentReplies")
308
+ replies Comment[] @relation("CommentReplies")
309
309
  reactions Reaction[]
310
310
  createdAt DateTime @default(now())
311
311
  modifiedAt DateTime? @updatedAt
312
+ studentQuestionProgress StudentQuestionProgress? @relation("StudentQuestionProgressComments", fields: [studentQuestionProgressId], references: [id], onDelete: Cascade)
313
+ studentQuestionProgressId String?
312
314
  }
313
315
 
314
316
  model Reaction {
@@ -318,7 +320,7 @@ model Reaction {
318
320
  userId String
319
321
  announcement Announcement? @relation(fields: [announcementId], references: [id], onDelete: Cascade)
320
322
  announcementId String?
321
- comment AnnouncementComment? @relation(fields: [commentId], references: [id], onDelete: Cascade)
323
+ comment Comment? @relation(fields: [commentId], references: [id], onDelete: Cascade)
322
324
  commentId String?
323
325
  createdAt DateTime @default(now())
324
326
 
@@ -517,6 +519,7 @@ model WorksheetQuestion {
517
519
  answer String
518
520
  options Json? @default("{}")
519
521
  markScheme Json? @default("{}")
522
+ points Int @default(0)
520
523
  order Int? @default(0)
521
524
  createdAt DateTime @default(now())
522
525
  updatedAt DateTime @updatedAt
@@ -546,11 +549,16 @@ model StudentQuestionProgress {
546
549
  question WorksheetQuestion @relation(fields: [questionId], references: [id], onDelete: Cascade)
547
550
  response String
548
551
  isCorrect Boolean @default(false)
552
+ markschemeState Json? @default("{}")
553
+ points Int @default(0)
554
+ comments Comment[] @relation("StudentQuestionProgressComments")
549
555
  feedback String?
550
556
  createdAt DateTime @default(now())
551
- updatedAt DateTime @updatedAt
557
+ updatedAt DateTime? @updatedAt
552
558
  studentWorksheetResponseId String?
553
559
  studentWorksheetResponse StudentWorksheetResponse? @relation(fields: [studentWorksheetResponseId], references: [id], onDelete: Cascade)
560
+
561
+ @@index([studentId, questionId])
554
562
  }
555
563
 
556
564
  model SchoolDevelopementProgram {
@@ -18,6 +18,7 @@ import { messageRouter } from "./message.js";
18
18
  import { labChatRouter } from "./labChat.js";
19
19
  import { marketingRouter } from "./marketing.js";
20
20
  import { worksheetRouter } from "./worksheet.js";
21
+ import { commentRouter } from "./comment.js";
21
22
 
22
23
  export const appRouter = createTRPCRouter({
23
24
  class: classRouter,
@@ -37,6 +38,7 @@ export const appRouter = createTRPCRouter({
37
38
  labChat: labChatRouter,
38
39
  marketing: marketingRouter,
39
40
  worksheet: worksheetRouter,
41
+ comment: commentRouter,
40
42
  });
41
43
 
42
44
  // Export type router type definition