@studious-lms/server 1.2.49 → 1.2.50

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.
@@ -5300,10 +5300,31 @@ export declare const appRouter: import("@trpc/server").TRPCBuiltRouter<{
5300
5300
  }) | null;
5301
5301
  meta: object;
5302
5302
  }>;
5303
- cancelAutoGrading: import("@trpc/server").TRPCMutationProcedure<{
5303
+ cancelGrading: import("@trpc/server").TRPCMutationProcedure<{
5304
5304
  input: {
5305
+ worksheetResponseId: string;
5306
+ progressId: string;
5307
+ };
5308
+ output: {
5309
+ status: import(".prisma/client").$Enums.GenerationStatus | null;
5310
+ id: string;
5311
+ feedback: string | null;
5312
+ studentId: string;
5313
+ createdAt: Date;
5314
+ updatedAt: Date | null;
5305
5315
  questionId: string;
5316
+ response: string;
5317
+ isCorrect: boolean;
5318
+ markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
5319
+ points: number;
5320
+ studentWorksheetResponseId: string | null;
5321
+ };
5322
+ meta: object;
5323
+ }>;
5324
+ regradeQuestion: import("@trpc/server").TRPCMutationProcedure<{
5325
+ input: {
5306
5326
  worksheetResponseId: string;
5327
+ progressId: string;
5307
5328
  };
5308
5329
  output: {
5309
5330
  status: import(".prisma/client").$Enums.GenerationStatus | null;
@@ -10809,10 +10830,31 @@ export declare const createCaller: import("@trpc/server").TRPCRouterCaller<{
10809
10830
  }) | null;
10810
10831
  meta: object;
10811
10832
  }>;
10812
- cancelAutoGrading: import("@trpc/server").TRPCMutationProcedure<{
10833
+ cancelGrading: import("@trpc/server").TRPCMutationProcedure<{
10813
10834
  input: {
10835
+ worksheetResponseId: string;
10836
+ progressId: string;
10837
+ };
10838
+ output: {
10839
+ status: import(".prisma/client").$Enums.GenerationStatus | null;
10840
+ id: string;
10841
+ feedback: string | null;
10842
+ studentId: string;
10843
+ createdAt: Date;
10844
+ updatedAt: Date | null;
10814
10845
  questionId: string;
10846
+ response: string;
10847
+ isCorrect: boolean;
10848
+ markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
10849
+ points: number;
10850
+ studentWorksheetResponseId: string | null;
10851
+ };
10852
+ meta: object;
10853
+ }>;
10854
+ regradeQuestion: import("@trpc/server").TRPCMutationProcedure<{
10855
+ input: {
10815
10856
  worksheetResponseId: string;
10857
+ progressId: string;
10816
10858
  };
10817
10859
  output: {
10818
10860
  status: import(".prisma/client").$Enums.GenerationStatus | null;
@@ -1 +1 @@
1
- {"version":3,"file":"_app.d.ts","sourceRoot":"/","sources":["routers/_app.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAiB1E,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoBpB,CAAC;AAGH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC;AACzC,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;AACxD,MAAM,MAAM,aAAa,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAG1D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAiC,CAAC"}
1
+ {"version":3,"file":"_app.d.ts","sourceRoot":"/","sources":["routers/_app.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAiB1E,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoBpB,CAAC;AAGH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC;AACzC,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;AACxD,MAAM,MAAM,aAAa,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAG1D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAAiC,CAAC"}
@@ -271,10 +271,31 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
271
271
  }) | null;
272
272
  meta: object;
273
273
  }>;
274
- cancelAutoGrading: import("@trpc/server").TRPCMutationProcedure<{
274
+ cancelGrading: import("@trpc/server").TRPCMutationProcedure<{
275
275
  input: {
276
+ worksheetResponseId: string;
277
+ progressId: string;
278
+ };
279
+ output: {
280
+ status: import(".prisma/client").$Enums.GenerationStatus | null;
281
+ id: string;
282
+ feedback: string | null;
283
+ studentId: string;
284
+ createdAt: Date;
285
+ updatedAt: Date | null;
276
286
  questionId: string;
287
+ response: string;
288
+ isCorrect: boolean;
289
+ markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
290
+ points: number;
291
+ studentWorksheetResponseId: string | null;
292
+ };
293
+ meta: object;
294
+ }>;
295
+ regradeQuestion: import("@trpc/server").TRPCMutationProcedure<{
296
+ input: {
277
297
  worksheetResponseId: string;
298
+ progressId: string;
278
299
  };
279
300
  output: {
280
301
  status: import(".prisma/client").$Enums.GenerationStatus | null;
@@ -1 +1 @@
1
- {"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["routers/worksheet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA8LA,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6UhC,CAAC"}
1
+ {"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["routers/worksheet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA8LA,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+UhC,CAAC"}
@@ -1,10 +1,11 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="2c030eda-ac5e-571a-992d-93eceb0062bc")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="bc564b69-66bf-5edf-8550-e097ecad9496")}catch(e){}}();
3
3
  import { TRPCError } from "@trpc/server";
4
4
  import { createTRPCRouter, protectedClassMemberProcedure, protectedProcedure } from "../trpc.js";
5
5
  import { z } from "zod";
6
6
  import { prisma } from "../lib/prisma.js";
7
7
  import { GenerationStatus } from "@prisma/client";
8
+ import { cancelGradePipeline, regradeWorksheetPipeline } from "../server/pipelines/gradeWorksheet.js";
8
9
  export const worksheetRouter = createTRPCRouter({
9
10
  // Get a single worksheet with all questions
10
11
  getWorksheet: protectedProcedure
@@ -349,20 +350,23 @@ export const worksheetRouter = createTRPCRouter({
349
350
  });
350
351
  return updatedWorksheetResponse;
351
352
  }),
352
- cancelAutoGrading: protectedProcedure
353
+ cancelGrading: protectedProcedure
353
354
  .input(z.object({
354
355
  worksheetResponseId: z.string(),
355
- questionId: z.string(),
356
+ progressId: z.string(),
356
357
  }))
357
358
  .mutation(async ({ ctx, input }) => {
358
- const { worksheetResponseId, questionId } = input;
359
- const updatedQuestion = await prisma.studentQuestionProgress.update({
360
- where: { id: questionId, studentWorksheetResponseId: worksheetResponseId },
361
- data: {
362
- status: GenerationStatus.CANCELLED,
363
- },
364
- });
365
- return updatedQuestion;
359
+ const { worksheetResponseId, progressId } = input;
360
+ return cancelGradePipeline(worksheetResponseId, progressId);
361
+ }),
362
+ regradeQuestion: protectedProcedure
363
+ .input(z.object({
364
+ worksheetResponseId: z.string(),
365
+ progressId: z.string(),
366
+ }))
367
+ .mutation(async ({ ctx, input }) => {
368
+ const { worksheetResponseId, progressId } = input;
369
+ return regradeWorksheetPipeline(worksheetResponseId, progressId);
366
370
  }),
367
371
  // Grade a student's answer
368
372
  gradeAnswer: protectedProcedure
@@ -461,4 +465,4 @@ export const worksheetRouter = createTRPCRouter({
461
465
  }),
462
466
  });
463
467
  //# sourceMappingURL=worksheet.js.map
464
- //# debugId=2c030eda-ac5e-571a-992d-93eceb0062bc
468
+ //# debugId=bc564b69-66bf-5edf-8550-e097ecad9496
@@ -1 +1 @@
1
- {"version":3,"file":"worksheet.js","sources":["routers/worksheet.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from \"@trpc/server\";\nimport { createTRPCRouter, protectedClassMemberProcedure, protectedProcedure } from \"../trpc.js\";\nimport { z } from \"zod\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { GenerationStatus, WorksheetQuestionType } from \"@prisma/client\";\nimport { commentSelect } from \"./comment.js\";\n\ntype MCQOptions = {\n id: string;\n text: string;\n isCorrect: boolean;\n}[];\n\nexport const worksheetRouter = createTRPCRouter({\n // Get a single worksheet with all questions\n getWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { worksheetId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n include: {\n questions: {\n orderBy: { createdAt: 'asc' },\n // select: { id: true, type: true, question: true, answer: true, points: true },\n },\n class: true,\n },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n return worksheet;\n }),\n\n exists: protectedClassMemberProcedure\n .input(z.object({\n id: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'User must be authenticated' });\n }\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: input.id },\n });\n\n return worksheet ? true : false;\n }),\n\n // List all worksheets for a class\n listWorksheets: protectedProcedure\n .input(z.object({\n classId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { classId } = input;\n\n const worksheets = await prisma.worksheet.findMany({\n where: { classId },\n include: {\n questions: {\n select: { id: true },\n },\n },\n orderBy: { createdAt: 'desc' },\n });\n\n return worksheets.map(worksheet => ({\n ...worksheet,\n questionCount: worksheet.questions.length,\n }));\n }),\n\n // Update worksheet metadata\n updateWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n name: z.string().optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, name } = input;\n\n const worksheet = await prisma.worksheet.update({\n where: { id: worksheetId },\n data: {\n ...(name !== undefined && { name }),\n },\n });\n\n return worksheet;\n }),\n\n // Delete a worksheet\n deleteWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId } = input;\n\n // This will cascade delete all questions and responses\n const deletedWorksheet = await prisma.worksheet.delete({\n where: { id: worksheetId },\n });\n\n return deletedWorksheet;\n }),\n\n create: protectedProcedure\n .input(z.object({\n classId: z.string(),\n name: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { classId, name } = input;\n\n // Create the worksheet\n const worksheet = await prisma.worksheet.create({\n data: {\n name,\n classId,\n },\n });\n\n return worksheet;\n }),\n addQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n question: z.string(),\n answer: z.string(),\n points: z.number().optional(),\n options: z.any().optional(), // JSON field\n markScheme: z.any().optional(), // JSON field\n type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, question, points, answer, options, markScheme, type } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const newQuestion = await prisma.worksheetQuestion.create({\n data: {\n worksheetId,\n type,\n points,\n question,\n answer,\n options,\n markScheme,\n },\n });\n\n return newQuestion;\n }),\n reorderQuestions: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n movedId: z.string(),\n position: z.enum(['before', 'after']),\n targetId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, movedId, position, targetId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const questions = await prisma.worksheetQuestion.findMany({\n where: { worksheetId },\n orderBy: { order: 'asc' },\n });\n\n const movedIdx = questions.findIndex(question => question.id === movedId);\n if (movedIdx === -1) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Moved question not found' });\n }\n\n const targetIdx = questions.findIndex(question => question.id === targetId);\n if (targetIdx === -1) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Target question not found' });\n }\n\n const withoutMoved = questions.filter(question => question.id !== movedId);\n\n let next: Array<{ id: string }> = [];\n\n if (position === 'before') {\n next = [...withoutMoved.slice(0, targetIdx).map(item => ({ id: item.id })), { id: movedId }, ...withoutMoved.slice(targetIdx).map(item => ({ id: item.id }))];\n } else {\n next = [...withoutMoved.slice(0, targetIdx + 1).map(item => ({ id: item.id })), { id: movedId }, ...withoutMoved.slice(targetIdx + 1).map(item => ({ id: item.id }))];\n }\n\n // Update the order of each question\n await prisma.$transaction(\n next.map((item, index) =>\n prisma.worksheetQuestion.update({\n where: { id: item.id },\n data: { order: index },\n })\n )\n );\n\n return next;\n }),\n updateQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n question: z.string().optional(),\n answer: z.string().optional(),\n points: z.number().optional(),\n options: z.any().optional(), // JSON field\n markScheme: z.any().optional(), // JSON field\n type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']).optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, questionId, points, question, answer, options, markScheme, type } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const updatedQuestion = await prisma.worksheetQuestion.update({\n where: { id: questionId },\n data: {\n ...(question !== undefined && { question }),\n ...(answer !== undefined && { answer }),\n ...(markScheme !== undefined && { markScheme }),\n ...(type !== undefined && { type }),\n ...(options !== undefined && { options }),\n ...(points !== undefined && { points }),\n },\n });\n\n return updatedQuestion;\n }),\n deleteQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, questionId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const deletedQuestion = await prisma.worksheetQuestion.delete({\n where: { id: questionId },\n });\n\n return deletedQuestion;\n }),\n\n getWorksheetSubmission: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n submissionId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { worksheetId, submissionId } = input;\n\n const submission = await prisma.submission.findUnique({\n where: { id: submissionId },\n });\n\n if (!submission) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Submission not found' });\n }\n\n // Find or create worksheet response for this submission\n const worksheetResponse = await prisma.$transaction(async (tx) => {\n // First check if a response exists\n const existing = await tx.studentWorksheetResponse.findFirst({\n where: { \n submissionId,\n worksheetId \n },\n include: {\n responses: {\n include: {\n comments: {\n select: {\n id: true,\n },\n },\n },\n },\n },\n });\n\n if (existing) {\n return existing;\n }\n\n // Create new response if it doesn't exist\n const created = await tx.studentWorksheetResponse.create({\n data: {\n worksheetId,\n submissionId,\n studentId: submission.studentId,\n },\n include: {\n responses: {\n include: {\n comments: {\n select: {\n id: true,\n },\n },\n },\n },\n },\n });\n\n return created;\n });\n\n\n return worksheetResponse;\n }),\n answerQuestion: protectedProcedure\n .input(z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n response: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetResponseId, questionId, response } = input;\n\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n responses: {\n where: { questionId },\n },\n },\n });\n\n if (!worksheetResponse) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet response not found' });\n }\n\n const question = await prisma.worksheetQuestion.findUnique({\n where: { id: questionId },\n });\n\n const isMarkableByAlgo = question?.type === 'MULTIPLE_CHOICE' || question?.type === 'TRUE_FALSE';\n const marksAwardedIfCorrect = question?.points || 0;\n \n const correctAnswer = isMarkableByAlgo ? (question?.type === 'MULTIPLE_CHOICE' ? (question?.options as MCQOptions).find((option) => option.isCorrect)?.id : question?.answer.toString()) : null;\n\n // Check if a response already exists for this question\n const existingResponse = worksheetResponse.responses[0];\n\n if (existingResponse) {\n // Update existing response\n await prisma.studentQuestionProgress.update({\n where: { id: existingResponse.id },\n data: { response, \n ...(isMarkableByAlgo && { isCorrect: response === correctAnswer }),\n ...(isMarkableByAlgo && { points: response === correctAnswer ? marksAwardedIfCorrect : 0 }),\n status: GenerationStatus.NOT_STARTED,\n },\n });\n } else {\n // Create new response\n await prisma.studentQuestionProgress.create({\n data: {\n studentId: worksheetResponse.studentId,\n questionId,\n response,\n studentWorksheetResponseId: worksheetResponseId,\n ...(isMarkableByAlgo && { isCorrect: response === correctAnswer }),\n ...(isMarkableByAlgo && { points: response === correctAnswer ? marksAwardedIfCorrect : 0 }),\n },\n });\n }\n\n // Return the updated worksheet response with all responses\n const updatedWorksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n responses: true,\n },\n });\n\n return updatedWorksheetResponse;\n }),\n cancelAutoGrading: protectedProcedure\n .input(z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetResponseId, questionId } = input;\n\n const updatedQuestion = await prisma.studentQuestionProgress.update({\n where: { id: questionId, studentWorksheetResponseId: worksheetResponseId },\n data: {\n status: GenerationStatus.CANCELLED,\n },\n });\n\n return updatedQuestion;\n }),\n // Grade a student's answer\n gradeAnswer: protectedProcedure\n .input(z.object({\n questionId: z.string(),\n responseId: z.string().optional(), // StudentQuestionProgress ID (optional for upsert)\n studentWorksheetResponseId: z.string(), // Required for linking to worksheet response\n response: z.string().optional(), // The actual response text (needed if creating new)\n isCorrect: z.boolean(),\n feedback: z.string().optional(),\n markschemeState: z.any().optional(),\n points: z.number().optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { responseId, questionId, studentWorksheetResponseId, response, isCorrect, feedback, markschemeState, points } = input;\n\n let gradedResponse;\n \n if (responseId) {\n // Update existing progress by ID\n gradedResponse = await prisma.studentQuestionProgress.update({\n where: { id: responseId },\n data: {\n isCorrect,\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points }),\n },\n });\n } else {\n // Get the studentId from the worksheet response\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: studentWorksheetResponseId },\n select: { studentId: true },\n });\n\n if (!worksheetResponse) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Student worksheet response not found',\n });\n }\n\n const { studentId } = worksheetResponse;\n\n // Upsert - find or create the progress record\n const existing = await prisma.studentQuestionProgress.findFirst({\n where: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n },\n });\n\n if (existing) {\n // Update existing\n gradedResponse = await prisma.studentQuestionProgress.update({\n where: { id: existing.id },\n data: {\n isCorrect,\n ...(response !== undefined && { response }),\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points }),\n },\n });\n } else {\n // Create new\n gradedResponse = await prisma.studentQuestionProgress.create({\n data: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n response: response || '',\n isCorrect,\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points: points || 0 }),\n },\n });\n }\n }\n\n return gradedResponse;\n }),\n addComment: protectedProcedure\n .input(z.object({\n responseId: z.string(),\n comment: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { responseId, comment } = input;\n\n const newComment = await prisma.comment.create({\n data: {\n studentQuestionProgressId: responseId,\n content: comment,\n authorId: ctx.user!.id,\n },\n });\n\n return newComment;\n }),\n});"],"names":[],"mappings":"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","debug_id":"2c030eda-ac5e-571a-992d-93eceb0062bc"}
1
+ {"version":3,"file":"worksheet.js","sources":["routers/worksheet.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from \"@trpc/server\";\nimport { createTRPCRouter, protectedClassMemberProcedure, protectedProcedure } from \"../trpc.js\";\nimport { z } from \"zod\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { GenerationStatus, WorksheetQuestionType } from \"@prisma/client\";\nimport { commentSelect } from \"./comment.js\";\nimport { cancelGradePipeline, regradeWorksheetPipeline } from \"../server/pipelines/gradeWorksheet.js\";\n\ntype MCQOptions = {\n id: string;\n text: string;\n isCorrect: boolean;\n}[];\n\nexport const worksheetRouter = createTRPCRouter({\n // Get a single worksheet with all questions\n getWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { worksheetId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n include: {\n questions: {\n orderBy: { createdAt: 'asc' },\n // select: { id: true, type: true, question: true, answer: true, points: true },\n },\n class: true,\n },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n return worksheet;\n }),\n\n exists: protectedClassMemberProcedure\n .input(z.object({\n id: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'User must be authenticated' });\n }\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: input.id },\n });\n\n return worksheet ? true : false;\n }),\n\n // List all worksheets for a class\n listWorksheets: protectedProcedure\n .input(z.object({\n classId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { classId } = input;\n\n const worksheets = await prisma.worksheet.findMany({\n where: { classId },\n include: {\n questions: {\n select: { id: true },\n },\n },\n orderBy: { createdAt: 'desc' },\n });\n\n return worksheets.map(worksheet => ({\n ...worksheet,\n questionCount: worksheet.questions.length,\n }));\n }),\n\n // Update worksheet metadata\n updateWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n name: z.string().optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, name } = input;\n\n const worksheet = await prisma.worksheet.update({\n where: { id: worksheetId },\n data: {\n ...(name !== undefined && { name }),\n },\n });\n\n return worksheet;\n }),\n\n // Delete a worksheet\n deleteWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId } = input;\n\n // This will cascade delete all questions and responses\n const deletedWorksheet = await prisma.worksheet.delete({\n where: { id: worksheetId },\n });\n\n return deletedWorksheet;\n }),\n\n create: protectedProcedure\n .input(z.object({\n classId: z.string(),\n name: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { classId, name } = input;\n\n // Create the worksheet\n const worksheet = await prisma.worksheet.create({\n data: {\n name,\n classId,\n },\n });\n\n return worksheet;\n }),\n addQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n question: z.string(),\n answer: z.string(),\n points: z.number().optional(),\n options: z.any().optional(), // JSON field\n markScheme: z.any().optional(), // JSON field\n type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, question, points, answer, options, markScheme, type } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const newQuestion = await prisma.worksheetQuestion.create({\n data: {\n worksheetId,\n type,\n points,\n question,\n answer,\n options,\n markScheme,\n },\n });\n\n return newQuestion;\n }),\n reorderQuestions: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n movedId: z.string(),\n position: z.enum(['before', 'after']),\n targetId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, movedId, position, targetId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const questions = await prisma.worksheetQuestion.findMany({\n where: { worksheetId },\n orderBy: { order: 'asc' },\n });\n\n const movedIdx = questions.findIndex(question => question.id === movedId);\n if (movedIdx === -1) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Moved question not found' });\n }\n\n const targetIdx = questions.findIndex(question => question.id === targetId);\n if (targetIdx === -1) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Target question not found' });\n }\n\n const withoutMoved = questions.filter(question => question.id !== movedId);\n\n let next: Array<{ id: string }> = [];\n\n if (position === 'before') {\n next = [...withoutMoved.slice(0, targetIdx).map(item => ({ id: item.id })), { id: movedId }, ...withoutMoved.slice(targetIdx).map(item => ({ id: item.id }))];\n } else {\n next = [...withoutMoved.slice(0, targetIdx + 1).map(item => ({ id: item.id })), { id: movedId }, ...withoutMoved.slice(targetIdx + 1).map(item => ({ id: item.id }))];\n }\n\n // Update the order of each question\n await prisma.$transaction(\n next.map((item, index) =>\n prisma.worksheetQuestion.update({\n where: { id: item.id },\n data: { order: index },\n })\n )\n );\n\n return next;\n }),\n updateQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n question: z.string().optional(),\n answer: z.string().optional(),\n points: z.number().optional(),\n options: z.any().optional(), // JSON field\n markScheme: z.any().optional(), // JSON field\n type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']).optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, questionId, points, question, answer, options, markScheme, type } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const updatedQuestion = await prisma.worksheetQuestion.update({\n where: { id: questionId },\n data: {\n ...(question !== undefined && { question }),\n ...(answer !== undefined && { answer }),\n ...(markScheme !== undefined && { markScheme }),\n ...(type !== undefined && { type }),\n ...(options !== undefined && { options }),\n ...(points !== undefined && { points }),\n },\n });\n\n return updatedQuestion;\n }),\n deleteQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, questionId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const deletedQuestion = await prisma.worksheetQuestion.delete({\n where: { id: questionId },\n });\n\n return deletedQuestion;\n }),\n\n getWorksheetSubmission: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n submissionId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { worksheetId, submissionId } = input;\n\n const submission = await prisma.submission.findUnique({\n where: { id: submissionId },\n });\n\n if (!submission) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Submission not found' });\n }\n\n // Find or create worksheet response for this submission\n const worksheetResponse = await prisma.$transaction(async (tx) => {\n // First check if a response exists\n const existing = await tx.studentWorksheetResponse.findFirst({\n where: { \n submissionId,\n worksheetId \n },\n include: {\n responses: {\n include: {\n comments: {\n select: {\n id: true,\n },\n },\n },\n },\n },\n });\n\n if (existing) {\n return existing;\n }\n\n // Create new response if it doesn't exist\n const created = await tx.studentWorksheetResponse.create({\n data: {\n worksheetId,\n submissionId,\n studentId: submission.studentId,\n },\n include: {\n responses: {\n include: {\n comments: {\n select: {\n id: true,\n },\n },\n },\n },\n },\n });\n\n return created;\n });\n\n\n return worksheetResponse;\n }),\n answerQuestion: protectedProcedure\n .input(z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n response: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetResponseId, questionId, response } = input;\n\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n responses: {\n where: { questionId },\n },\n },\n });\n\n if (!worksheetResponse) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet response not found' });\n }\n\n const question = await prisma.worksheetQuestion.findUnique({\n where: { id: questionId },\n });\n\n const isMarkableByAlgo = question?.type === 'MULTIPLE_CHOICE' || question?.type === 'TRUE_FALSE';\n const marksAwardedIfCorrect = question?.points || 0;\n \n const correctAnswer = isMarkableByAlgo ? (question?.type === 'MULTIPLE_CHOICE' ? (question?.options as MCQOptions).find((option) => option.isCorrect)?.id : question?.answer.toString()) : null;\n\n // Check if a response already exists for this question\n const existingResponse = worksheetResponse.responses[0];\n\n if (existingResponse) {\n // Update existing response\n await prisma.studentQuestionProgress.update({\n where: { id: existingResponse.id },\n data: { response, \n ...(isMarkableByAlgo && { isCorrect: response === correctAnswer }),\n ...(isMarkableByAlgo && { points: response === correctAnswer ? marksAwardedIfCorrect : 0 }),\n status: GenerationStatus.NOT_STARTED,\n },\n });\n } else {\n // Create new response\n await prisma.studentQuestionProgress.create({\n data: {\n studentId: worksheetResponse.studentId,\n questionId,\n response,\n studentWorksheetResponseId: worksheetResponseId,\n ...(isMarkableByAlgo && { isCorrect: response === correctAnswer }),\n ...(isMarkableByAlgo && { points: response === correctAnswer ? marksAwardedIfCorrect : 0 }),\n },\n });\n }\n\n // Return the updated worksheet response with all responses\n const updatedWorksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n responses: true,\n },\n });\n\n return updatedWorksheetResponse;\n }),\n cancelGrading: protectedProcedure\n .input(z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetResponseId, progressId } = input;\n\n return cancelGradePipeline(worksheetResponseId, progressId);\n }),\n regradeQuestion: protectedProcedure\n .input(z.object({\n worksheetResponseId: z.string(),\n progressId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetResponseId, progressId } = input;\n return regradeWorksheetPipeline(worksheetResponseId, progressId);\n }),\n // Grade a student's answer\n gradeAnswer: protectedProcedure\n .input(z.object({\n questionId: z.string(),\n responseId: z.string().optional(), // StudentQuestionProgress ID (optional for upsert)\n studentWorksheetResponseId: z.string(), // Required for linking to worksheet response\n response: z.string().optional(), // The actual response text (needed if creating new)\n isCorrect: z.boolean(),\n feedback: z.string().optional(),\n markschemeState: z.any().optional(),\n points: z.number().optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { responseId, questionId, studentWorksheetResponseId, response, isCorrect, feedback, markschemeState, points } = input;\n\n let gradedResponse;\n \n if (responseId) {\n // Update existing progress by ID\n gradedResponse = await prisma.studentQuestionProgress.update({\n where: { id: responseId },\n data: {\n isCorrect,\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points }),\n },\n });\n } else {\n // Get the studentId from the worksheet response\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: studentWorksheetResponseId },\n select: { studentId: true },\n });\n\n if (!worksheetResponse) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Student worksheet response not found',\n });\n }\n\n const { studentId } = worksheetResponse;\n\n // Upsert - find or create the progress record\n const existing = await prisma.studentQuestionProgress.findFirst({\n where: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n },\n });\n\n if (existing) {\n // Update existing\n gradedResponse = await prisma.studentQuestionProgress.update({\n where: { id: existing.id },\n data: {\n isCorrect,\n ...(response !== undefined && { response }),\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points }),\n },\n });\n } else {\n // Create new\n gradedResponse = await prisma.studentQuestionProgress.create({\n data: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n response: response || '',\n isCorrect,\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points: points || 0 }),\n },\n });\n }\n }\n\n return gradedResponse;\n }),\n addComment: protectedProcedure\n .input(z.object({\n responseId: z.string(),\n comment: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { responseId, comment } = input;\n\n const newComment = await prisma.comment.create({\n data: {\n studentQuestionProgressId: responseId,\n content: comment,\n authorId: ctx.user!.id,\n },\n });\n\n return newComment;\n }),\n});"],"names":[],"mappings":"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","debug_id":"bc564b69-66bf-5edf-8550-e097ecad9496"}
@@ -1,4 +1,5 @@
1
- export declare const gradeWorksheetPipeline: (worksheetResponseId: string) => Promise<{
1
+ export declare const gradeWorksheetPipeline: (worksheetResponseId: string) => Promise<void>;
2
+ export declare const cancelGradePipeline: (worksheetResponseId: string, worksheetQuestionProgressId: string) => Promise<{
2
3
  status: import(".prisma/client").$Enums.GenerationStatus | null;
3
4
  id: string;
4
5
  feedback: string | null;
@@ -11,5 +12,19 @@ export declare const gradeWorksheetPipeline: (worksheetResponseId: string) => Pr
11
12
  markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
12
13
  points: number;
13
14
  studentWorksheetResponseId: string | null;
14
- } | undefined>;
15
+ }>;
16
+ export declare const regradeWorksheetPipeline: (worksheetResponseId: string, worksheetQuestionProgressId: string) => Promise<{
17
+ status: import(".prisma/client").$Enums.GenerationStatus | null;
18
+ id: string;
19
+ feedback: string | null;
20
+ studentId: string;
21
+ createdAt: Date;
22
+ updatedAt: Date | null;
23
+ questionId: string;
24
+ response: string;
25
+ isCorrect: boolean;
26
+ markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
27
+ points: number;
28
+ studentWorksheetResponseId: string | null;
29
+ }>;
15
30
  //# sourceMappingURL=gradeWorksheet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gradeWorksheet.d.ts","sourceRoot":"/","sources":["server/pipelines/gradeWorksheet.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,sBAAsB,GAAU,qBAAqB,MAAM;;;;;;;;;;;;;cAsIvE,CAAC"}
1
+ {"version":3,"file":"gradeWorksheet.d.ts","sourceRoot":"/","sources":["server/pipelines/gradeWorksheet.ts"],"names":[],"mappings":"AAqJA,eAAO,MAAM,sBAAsB,GAAU,qBAAqB,MAAM,kBAsDvE,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAU,qBAAqB,MAAM,EAAE,6BAA6B,MAAM;;;;;;;;;;;;;EAyBzG,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,qBAAqB,MAAM,EAAE,6BAA6B,MAAM;;;;;;;;;;;;;EAuB9G,CAAC"}
@@ -1,5 +1,5 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="1b23ac7f-6ff8-51c0-8cc7-e0276b542625")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="8de476c6-24be-55c4-ade4-500ee17dbfc4")}catch(e){}}();
3
3
  import { GenerationStatus, WorksheetQuestionType } from "@prisma/client";
4
4
  import { prisma } from "../../lib/prisma.js";
5
5
  import { logger } from "../../utils/logger.js";
@@ -7,6 +7,119 @@ import z from "zod";
7
7
  import { inference } from "../../utils/inference.js";
8
8
  import { getAIUserId } from "../../utils/aiUser.js";
9
9
  import { pusher } from "../../lib/pusher.js";
10
+ const removeAllPreviousAIComments = async (worksheetQuestionProgressId) => {
11
+ await prisma.comment.deleteMany({
12
+ where: {
13
+ studentQuestionProgressId: worksheetQuestionProgressId,
14
+ authorId: getAIUserId(),
15
+ },
16
+ });
17
+ };
18
+ const gradeWorksheetQuestion = async (worksheetResponseId) => {
19
+ const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({
20
+ where: { id: worksheetResponseId },
21
+ include: {
22
+ worksheet: true,
23
+ },
24
+ });
25
+ if (!worksheetResponse) {
26
+ logger.error('Worksheet response not found');
27
+ throw new Error('Worksheet response not found');
28
+ }
29
+ const studentQuestionProgress = await prisma.studentQuestionProgress.findFirst({
30
+ where: {
31
+ studentWorksheetResponseId: worksheetResponseId,
32
+ status: {
33
+ not: {
34
+ in: DO_NOT_INFERENCE_STATUSES,
35
+ },
36
+ },
37
+ },
38
+ include: {
39
+ question: true,
40
+ comments: true,
41
+ },
42
+ });
43
+ if (!studentQuestionProgress) {
44
+ logger.error('Student question progress not found');
45
+ throw new Error('Student question progress not found');
46
+ }
47
+ pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `status-pending`, {
48
+ id: studentQuestionProgress.id,
49
+ });
50
+ const question = studentQuestionProgress.question;
51
+ const comments = studentQuestionProgress.comments;
52
+ const responseText = studentQuestionProgress.response;
53
+ try {
54
+ const apiResponse = await inference(`Grade the following worksheet response:
55
+
56
+ Question: ${question.question}
57
+ Response: ${responseText}
58
+
59
+ Comments: ${comments.map((comment) => comment.content).join('\n')}
60
+ Mark Scheme: ${JSON.stringify(question.markScheme)}
61
+
62
+ Justify your reasoning by including comment(s) and mark the question please.
63
+ Return ONLY JSON in the following format (fill in the values as per the question):
64
+ {
65
+ "isCorrect": <boolean>,
66
+ "points": <number>,
67
+ "markschemeState": [
68
+ { "id": <string>, "correct": <boolean> }
69
+ ],
70
+ "comments": [<string>, ...]
71
+ }
72
+ `, z.object({
73
+ isCorrect: z.boolean(),
74
+ points: z.number(),
75
+ markschemeState: z.array(z.object({
76
+ id: z.string(),
77
+ correct: z.boolean(),
78
+ })), // @note: this has to be converted to [id: string]: correct boolean
79
+ comments: z.array(z.string()),
80
+ })).catch((error) => {
81
+ logger.error('Failed to grade worksheet response', { error });
82
+ throw error;
83
+ });
84
+ const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({
85
+ where: { id: studentQuestionProgress.id, status: {
86
+ not: {
87
+ in: ['CANCELLED'],
88
+ },
89
+ } },
90
+ data: {
91
+ status: GenerationStatus.COMPLETED,
92
+ isCorrect: apiResponse.isCorrect,
93
+ points: apiResponse.points,
94
+ markschemeState: apiResponse.markschemeState.reduce((acc, curr) => {
95
+ acc["item-" + curr.id] = curr.correct;
96
+ return acc;
97
+ }, {}),
98
+ comments: {
99
+ create: apiResponse.comments.map((commentContent) => ({
100
+ content: commentContent,
101
+ authorId: getAIUserId(),
102
+ })),
103
+ },
104
+ },
105
+ });
106
+ pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `set-completed`, {
107
+ id: updatedStudentQuestionProgress.id,
108
+ });
109
+ return updatedStudentQuestionProgress;
110
+ }
111
+ catch (error) {
112
+ logger.error('Failed to grade worksheet response', { error, worksheetResponseId });
113
+ pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `set-failed`, {
114
+ id: studentQuestionProgress.id,
115
+ });
116
+ await prisma.studentQuestionProgress.update({
117
+ where: { id: studentQuestionProgress.id },
118
+ data: { status: GenerationStatus.FAILED },
119
+ });
120
+ throw error;
121
+ }
122
+ };
10
123
  /**
11
124
  * Grades and regrades worksheet (can fixed failed responses)
12
125
  * @param worksheetResponseId worksheet response id
@@ -48,9 +161,6 @@ export const gradeWorksheetPipeline = async (worksheetResponseId) => {
48
161
  // Use for...of instead of forEach to properly handle async operations
49
162
  for (const response of worksheetResponse.responses) {
50
163
  logger.info('Grading question', { questionId: response.questionId });
51
- const question = response.question;
52
- const comments = response.comments;
53
- const responseText = response.response;
54
164
  const studentQuestionProgress = await prisma.studentQuestionProgress.update({
55
165
  where: { id: response.id, status: {
56
166
  not: {
@@ -62,78 +172,50 @@ export const gradeWorksheetPipeline = async (worksheetResponseId) => {
62
172
  if (studentQuestionProgress.status !== GenerationStatus.PENDING) {
63
173
  return;
64
174
  }
65
- try {
66
- const apiResponse = await inference(`Grade the following worksheet response:
67
-
68
- Question: ${question.question}
69
- Response: ${responseText}
70
-
71
- Comments: ${comments.map((comment) => comment.content).join('\n')}
72
- Mark Scheme: ${JSON.stringify(question.markScheme)}
73
-
74
- Justify your reasoning by including comment(s) and mark the question please.
75
- Return ONLY JSON in the following format (fill in the values as per the question):
76
- {
77
- "isCorrect": <boolean>,
78
- "points": <number>,
79
- "markschemeState": [
80
- { "id": <string>, "correct": <boolean> }
81
- ],
82
- "comments": [<string>, ...]
83
- }
84
- `, z.object({
85
- isCorrect: z.boolean(),
86
- points: z.number(),
87
- markschemeState: z.array(z.object({
88
- id: z.string(),
89
- correct: z.boolean(),
90
- })), // @note: this has to be converted to [id: string]: correct boolean
91
- comments: z.array(z.string()),
92
- })).catch((error) => {
93
- logger.error('Failed to grade worksheet response', { error });
94
- throw error;
95
- });
96
- console.log(apiResponse);
97
- const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({
98
- where: { id: studentQuestionProgress.id, status: {
99
- not: {
100
- in: ['CANCELLED'],
101
- },
102
- } },
103
- data: {
104
- status: GenerationStatus.COMPLETED,
105
- isCorrect: apiResponse.isCorrect,
106
- points: apiResponse.points,
107
- markschemeState: apiResponse.markschemeState.reduce((acc, curr) => {
108
- acc["item-" + curr.id] = curr.correct;
109
- return acc;
110
- }, {}),
111
- comments: {
112
- create: apiResponse.comments.map((commentContent) => ({
113
- content: commentContent,
114
- authorId: getAIUserId(),
115
- })),
116
- },
117
- },
118
- });
119
- pusher.trigger(`class-${worksheetResponse.worksheet.classId}`, `ai-worksheet-updated-${worksheetResponse.id}`, {
120
- success: true,
121
- });
122
- return updatedStudentQuestionProgress;
123
- }
124
- catch (error) {
125
- logger.error('Failed to grade worksheet response', { error, worksheetResponseId });
126
- pusher.trigger(`class-${worksheetResponse.worksheet.classId}`, `ai-worksheet-updated-${worksheetResponse.id}`, {
127
- success: false,
128
- });
129
- await prisma.studentQuestionProgress.update({
130
- where: { id: studentQuestionProgress.id },
131
- data: { status: GenerationStatus.FAILED },
132
- });
133
- throw error;
134
- }
175
+ gradeWorksheetQuestion(response.id);
135
176
  }
136
177
  ;
137
178
  };
179
+ export const cancelGradePipeline = async (worksheetResponseId, worksheetQuestionProgressId) => {
180
+ logger.info('Cancelling auto grading', { worksheetResponseId, worksheetQuestionProgressId });
181
+ const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({
182
+ where: { id: worksheetResponseId },
183
+ include: {
184
+ worksheet: true,
185
+ },
186
+ });
187
+ if (!worksheetResponse) {
188
+ logger.error('Worksheet response not found');
189
+ throw new Error('Worksheet response not found');
190
+ }
191
+ const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({
192
+ where: { id: worksheetQuestionProgressId },
193
+ data: { status: GenerationStatus.CANCELLED },
194
+ });
195
+ await removeAllPreviousAIComments(worksheetQuestionProgressId);
196
+ pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `set-cancelled`, {
197
+ id: updatedStudentQuestionProgress.id,
198
+ });
199
+ return updatedStudentQuestionProgress;
200
+ };
201
+ export const regradeWorksheetPipeline = async (worksheetResponseId, worksheetQuestionProgressId) => {
202
+ logger.info('Regrading worksheet response', { worksheetResponseId, worksheetQuestionProgressId });
203
+ const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({
204
+ where: { id: worksheetResponseId, },
205
+ include: {
206
+ worksheet: true,
207
+ },
208
+ });
209
+ if (!worksheetResponse) {
210
+ logger.error('Worksheet response not found');
211
+ throw new Error('Worksheet response not found');
212
+ }
213
+ const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({
214
+ where: { id: worksheetQuestionProgressId },
215
+ data: { status: GenerationStatus.PENDING },
216
+ });
217
+ gradeWorksheetQuestion(worksheetQuestionProgressId);
218
+ return updatedStudentQuestionProgress;
219
+ };
138
220
  //# sourceMappingURL=gradeWorksheet.js.map
139
- //# debugId=1b23ac7f-6ff8-51c0-8cc7-e0276b542625
221
+ //# debugId=8de476c6-24be-55c4-ade4-500ee17dbfc4
@@ -1 +1 @@
1
- {"version":3,"file":"gradeWorksheet.js","sources":["server/pipelines/gradeWorksheet.ts"],"sourceRoot":"/","sourcesContent":["import { GenerationStatus, WorksheetQuestionType } from \"@prisma/client\";\nimport { prisma } from \"../../lib/prisma.js\";\nimport { logger } from \"../../utils/logger.js\";\nimport z from \"zod\";\nimport { inference } from \"../../utils/inference.js\";\nimport { getAIUserId } from \"../../utils/aiUser.js\";\nimport { pusher } from \"../../lib/pusher.js\";\n\n/**\n * Grades and regrades worksheet (can fixed failed responses)\n * @param worksheetResponseId worksheet response id\n * @returns updated worksheet response\n */\n\nconst DO_NOT_INFERENCE_STATUSES = [GenerationStatus.CANCELLED, GenerationStatus.PENDING, GenerationStatus.COMPLETED];\n\nexport const gradeWorksheetPipeline = async (worksheetResponseId: string) => {\n logger.info('Grading worksheet response', { worksheetResponseId });\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n worksheet: true,\n responses: {\n where: {\n status: {\n not: {\n in: DO_NOT_INFERENCE_STATUSES,\n },\n },\n question: {\n type: {\n not: {\n in: [WorksheetQuestionType.MULTIPLE_CHOICE, WorksheetQuestionType.TRUE_FALSE],\n }\n },\n },\n },\n include: {\n question: true,\n comments: true,\n },\n },\n },\n });\n\n if (!worksheetResponse) {\n logger.error('Worksheet response not found');\n throw new Error('Worksheet response not found');\n }\n\n // Use for...of instead of forEach to properly handle async operations\n for (const response of worksheetResponse.responses) {\n logger.info('Grading question', { questionId: response.questionId });\n const question = response.question;\n const comments = response.comments;\n const responseText = response.response;\n\n const studentQuestionProgress = await prisma.studentQuestionProgress.update({\n where: { id: response.id, status: {\n not: {\n in: DO_NOT_INFERENCE_STATUSES,\n }\n } },\n data: { status: GenerationStatus.PENDING },\n });\n\n if (studentQuestionProgress.status !== GenerationStatus.PENDING) {\n return;\n }\n\n try {\n const apiResponse = await inference(\n `Grade the following worksheet response:\n \n Question: ${question.question}\n Response: ${responseText}\n\n Comments: ${comments.map((comment) => comment.content).join('\\n')}\n Mark Scheme: ${JSON.stringify(question.markScheme)}\n \n Justify your reasoning by including comment(s) and mark the question please. \n Return ONLY JSON in the following format (fill in the values as per the question):\n {\n \"isCorrect\": <boolean>,\n \"points\": <number>,\n \"markschemeState\": [\n { \"id\": <string>, \"correct\": <boolean> }\n ],\n \"comments\": [<string>, ...]\n }\n `,\n z.object({\n isCorrect: z.boolean(),\n points: z.number(),\n markschemeState: z.array(z.object({\n id: z.string(),\n correct: z.boolean(),\n })), // @note: this has to be converted to [id: string]: correct boolean\n comments: z.array(z.string()),\n }),\n ).catch((error) => {\n logger.error('Failed to grade worksheet response', { error });\n throw error;\n });\n\n console.log(apiResponse);\n\n const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({\n where: { id: studentQuestionProgress.id, status: {\n not: {\n in: ['CANCELLED'],\n },\n } },\n data: {\n status: GenerationStatus.COMPLETED,\n isCorrect: (apiResponse as { isCorrect: boolean }).isCorrect,\n points: (apiResponse as { points: number }).points,\n markschemeState: (apiResponse as {\n markschemeState: { id: string; correct: boolean }[];\n }).markschemeState.reduce((acc, curr) => {\n acc[\"item-\" + curr.id] = curr.correct;\n return acc;\n }, {} as Record<string, boolean>),\n comments: {\n create: (apiResponse as {\n comments: string[];\n }).comments.map((commentContent) => ({\n content: commentContent,\n authorId: getAIUserId(),\n })),\n },\n },\n });\n pusher.trigger(`class-${worksheetResponse.worksheet.classId}`, `ai-worksheet-updated-${worksheetResponse.id}`, {\n success: true,\n });\n\n return updatedStudentQuestionProgress;\n } catch (error) {\n logger.error('Failed to grade worksheet response', { error, worksheetResponseId });\n pusher.trigger(`class-${worksheetResponse.worksheet.classId}`, `ai-worksheet-updated-${worksheetResponse.id}`, {\n success: false,\n });\n await prisma.studentQuestionProgress.update({\n where: { id: studentQuestionProgress.id },\n data: { status: GenerationStatus.FAILED },\n });\n throw error;\n }\n };\n};"],"names":[],"mappings":"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","debug_id":"1b23ac7f-6ff8-51c0-8cc7-e0276b542625"}
1
+ {"version":3,"file":"gradeWorksheet.js","sources":["server/pipelines/gradeWorksheet.ts"],"sourceRoot":"/","sourcesContent":["import { GenerationStatus, WorksheetQuestionType } from \"@prisma/client\";\nimport { prisma } from \"../../lib/prisma.js\";\nimport { logger } from \"../../utils/logger.js\";\nimport z from \"zod\";\nimport { inference } from \"../../utils/inference.js\";\nimport { getAIUserId } from \"../../utils/aiUser.js\";\nimport { pusher } from \"../../lib/pusher.js\";\n\n\nconst removeAllPreviousAIComments = async (worksheetQuestionProgressId: string) => {\n await prisma.comment.deleteMany({\n where: {\n studentQuestionProgressId: worksheetQuestionProgressId,\n authorId: getAIUserId(),\n },\n });\n};\n\nconst gradeWorksheetQuestion = async (worksheetResponseId: string) => {\n\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n worksheet: true,\n },\n });\n\n if (!worksheetResponse) {\n logger.error('Worksheet response not found');\n throw new Error('Worksheet response not found');\n }\n\n\n const studentQuestionProgress = await prisma.studentQuestionProgress.findFirst({\n where: {\n studentWorksheetResponseId: worksheetResponseId,\n status: {\n not: {\n in: DO_NOT_INFERENCE_STATUSES,\n },\n },\n },\n include: {\n question: true,\n comments: true,\n },\n });\n\n if (!studentQuestionProgress) {\n logger.error('Student question progress not found');\n throw new Error('Student question progress not found');\n }\n\n pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `status-pending`, {\n id: studentQuestionProgress.id,\n });\n\n const question = studentQuestionProgress.question;\n const comments = studentQuestionProgress.comments;\n const responseText = studentQuestionProgress.response;\n\n\n try {\n const apiResponse = await inference(\n `Grade the following worksheet response:\n \n Question: ${question.question}\n Response: ${responseText}\n\n Comments: ${comments.map((comment) => comment.content).join('\\n')}\n Mark Scheme: ${JSON.stringify(question.markScheme)}\n \n Justify your reasoning by including comment(s) and mark the question please. \n Return ONLY JSON in the following format (fill in the values as per the question):\n {\n \"isCorrect\": <boolean>,\n \"points\": <number>,\n \"markschemeState\": [\n { \"id\": <string>, \"correct\": <boolean> }\n ],\n \"comments\": [<string>, ...]\n }\n `,\n z.object({\n isCorrect: z.boolean(),\n points: z.number(),\n markschemeState: z.array(z.object({\n id: z.string(),\n correct: z.boolean(),\n })), // @note: this has to be converted to [id: string]: correct boolean\n comments: z.array(z.string()),\n }),\n ).catch((error) => {\n logger.error('Failed to grade worksheet response', { error });\n throw error;\n });\n\n const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({\n where: { id: studentQuestionProgress.id, status: {\n not: {\n in: ['CANCELLED'],\n },\n } },\n data: {\n status: GenerationStatus.COMPLETED,\n isCorrect: (apiResponse as { isCorrect: boolean }).isCorrect,\n points: (apiResponse as { points: number }).points,\n markschemeState: (apiResponse as {\n markschemeState: { id: string; correct: boolean }[];\n }).markschemeState.reduce((acc, curr) => {\n acc[\"item-\" + curr.id] = curr.correct;\n return acc;\n }, {} as Record<string, boolean>),\n comments: {\n create: (apiResponse as {\n comments: string[];\n }).comments.map((commentContent) => ({\n content: commentContent,\n authorId: getAIUserId(),\n })),\n },\n },\n });\n pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `set-completed`, {\n id: updatedStudentQuestionProgress.id,\n });\n\n return updatedStudentQuestionProgress;\n } catch (error) {\n logger.error('Failed to grade worksheet response', { error, worksheetResponseId });\n pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `set-failed`, {\n id: studentQuestionProgress.id,\n });\n await prisma.studentQuestionProgress.update({\n where: { id: studentQuestionProgress.id },\n data: { status: GenerationStatus.FAILED },\n });\n throw error;\n }\n}\n\n/**\n * Grades and regrades worksheet (can fixed failed responses)\n * @param worksheetResponseId worksheet response id\n * @returns updated worksheet response\n */\n\nconst DO_NOT_INFERENCE_STATUSES = [GenerationStatus.CANCELLED, GenerationStatus.PENDING, GenerationStatus.COMPLETED];\n\nexport const gradeWorksheetPipeline = async (worksheetResponseId: string) => {\n logger.info('Grading worksheet response', { worksheetResponseId });\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n worksheet: true,\n responses: {\n where: {\n status: {\n not: {\n in: DO_NOT_INFERENCE_STATUSES,\n },\n },\n question: {\n type: {\n not: {\n in: [WorksheetQuestionType.MULTIPLE_CHOICE, WorksheetQuestionType.TRUE_FALSE],\n }\n },\n },\n },\n include: {\n question: true,\n comments: true,\n },\n },\n },\n });\n\n if (!worksheetResponse) {\n logger.error('Worksheet response not found');\n throw new Error('Worksheet response not found');\n }\n\n // Use for...of instead of forEach to properly handle async operations\n for (const response of worksheetResponse.responses) {\n logger.info('Grading question', { questionId: response.questionId });\n\n const studentQuestionProgress = await prisma.studentQuestionProgress.update({\n where: { id: response.id, status: {\n not: {\n in: DO_NOT_INFERENCE_STATUSES,\n }\n } },\n data: { status: GenerationStatus.PENDING },\n });\n\n if (studentQuestionProgress.status !== GenerationStatus.PENDING) {\n return;\n }\n\n gradeWorksheetQuestion(response.id);\n\n };\n};\n\nexport const cancelGradePipeline = async (worksheetResponseId: string, worksheetQuestionProgressId: string) => {\n logger.info('Cancelling auto grading', { worksheetResponseId, worksheetQuestionProgressId });\n\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n worksheet: true,\n },\n });\n if (!worksheetResponse) {\n logger.error('Worksheet response not found');\n throw new Error('Worksheet response not found');\n }\n const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({\n where: { id: worksheetQuestionProgressId },\n data: { status: GenerationStatus.CANCELLED },\n });\n\n await removeAllPreviousAIComments(worksheetQuestionProgressId);\n\n pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `set-cancelled`, {\n id: updatedStudentQuestionProgress.id,\n });\n\n return updatedStudentQuestionProgress;\n};\n\nexport const regradeWorksheetPipeline = async (worksheetResponseId: string, worksheetQuestionProgressId: string) => {\n logger.info('Regrading worksheet response', { worksheetResponseId, worksheetQuestionProgressId });\n\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId, },\n include: {\n worksheet: true,\n },\n });\n\n if (!worksheetResponse) {\n logger.error('Worksheet response not found');\n throw new Error('Worksheet response not found');\n }\n\n const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({\n where: { id: worksheetQuestionProgressId },\n data: { status: GenerationStatus.PENDING },\n });\n\n gradeWorksheetQuestion(worksheetQuestionProgressId);\n\n return updatedStudentQuestionProgress;\n};\n"],"names":[],"mappings":"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","debug_id":"8de476c6-24be-55c4-ade4-500ee17dbfc4"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studious-lms/server",
3
- "version": "1.2.49",
3
+ "version": "1.2.50",
4
4
  "description": "Backend server for Studious application",
5
5
  "main": "dist/exportType.js",
6
6
  "types": "dist/exportType.d.ts",
@@ -31,6 +31,7 @@
31
31
  "@prisma/client": "^6.7.0",
32
32
  "@sentry/cli": "^2.58.2",
33
33
  "@sentry/node": "^10.26.0",
34
+ "@studious-lms/server": "^1.2.49",
34
35
  "@trpc/server": "^11.4.3",
35
36
  "@unkey/ratelimit": "^2.1.3",
36
37
  "bcryptjs": "^3.0.2",
@@ -4,6 +4,7 @@ import { z } from "zod";
4
4
  import { prisma } from "../lib/prisma.js";
5
5
  import { GenerationStatus, WorksheetQuestionType } from "@prisma/client";
6
6
  import { commentSelect } from "./comment.js";
7
+ import { cancelGradePipeline, regradeWorksheetPipeline } from "../server/pipelines/gradeWorksheet.js";
7
8
 
8
9
  type MCQOptions = {
9
10
  id: string;
@@ -415,22 +416,24 @@ export const worksheetRouter = createTRPCRouter({
415
416
 
416
417
  return updatedWorksheetResponse;
417
418
  }),
418
- cancelAutoGrading: protectedProcedure
419
+ cancelGrading: protectedProcedure
419
420
  .input(z.object({
420
421
  worksheetResponseId: z.string(),
421
- questionId: z.string(),
422
+ progressId: z.string(),
422
423
  }))
423
424
  .mutation(async ({ ctx, input }) => {
424
- const { worksheetResponseId, questionId } = input;
425
-
426
- const updatedQuestion = await prisma.studentQuestionProgress.update({
427
- where: { id: questionId, studentWorksheetResponseId: worksheetResponseId },
428
- data: {
429
- status: GenerationStatus.CANCELLED,
430
- },
431
- });
425
+ const { worksheetResponseId, progressId } = input;
432
426
 
433
- return updatedQuestion;
427
+ return cancelGradePipeline(worksheetResponseId, progressId);
428
+ }),
429
+ regradeQuestion: protectedProcedure
430
+ .input(z.object({
431
+ worksheetResponseId: z.string(),
432
+ progressId: z.string(),
433
+ }))
434
+ .mutation(async ({ ctx, input }) => {
435
+ const { worksheetResponseId, progressId } = input;
436
+ return regradeWorksheetPipeline(worksheetResponseId, progressId);
434
437
  }),
435
438
  // Grade a student's answer
436
439
  gradeAnswer: protectedProcedure
@@ -6,6 +6,139 @@ import { inference } from "../../utils/inference.js";
6
6
  import { getAIUserId } from "../../utils/aiUser.js";
7
7
  import { pusher } from "../../lib/pusher.js";
8
8
 
9
+
10
+ const removeAllPreviousAIComments = async (worksheetQuestionProgressId: string) => {
11
+ await prisma.comment.deleteMany({
12
+ where: {
13
+ studentQuestionProgressId: worksheetQuestionProgressId,
14
+ authorId: getAIUserId(),
15
+ },
16
+ });
17
+ };
18
+
19
+ const gradeWorksheetQuestion = async (worksheetResponseId: string) => {
20
+
21
+ const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({
22
+ where: { id: worksheetResponseId },
23
+ include: {
24
+ worksheet: true,
25
+ },
26
+ });
27
+
28
+ if (!worksheetResponse) {
29
+ logger.error('Worksheet response not found');
30
+ throw new Error('Worksheet response not found');
31
+ }
32
+
33
+
34
+ const studentQuestionProgress = await prisma.studentQuestionProgress.findFirst({
35
+ where: {
36
+ studentWorksheetResponseId: worksheetResponseId,
37
+ status: {
38
+ not: {
39
+ in: DO_NOT_INFERENCE_STATUSES,
40
+ },
41
+ },
42
+ },
43
+ include: {
44
+ question: true,
45
+ comments: true,
46
+ },
47
+ });
48
+
49
+ if (!studentQuestionProgress) {
50
+ logger.error('Student question progress not found');
51
+ throw new Error('Student question progress not found');
52
+ }
53
+
54
+ pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `status-pending`, {
55
+ id: studentQuestionProgress.id,
56
+ });
57
+
58
+ const question = studentQuestionProgress.question;
59
+ const comments = studentQuestionProgress.comments;
60
+ const responseText = studentQuestionProgress.response;
61
+
62
+
63
+ try {
64
+ const apiResponse = await inference(
65
+ `Grade the following worksheet response:
66
+
67
+ Question: ${question.question}
68
+ Response: ${responseText}
69
+
70
+ Comments: ${comments.map((comment) => comment.content).join('\n')}
71
+ Mark Scheme: ${JSON.stringify(question.markScheme)}
72
+
73
+ Justify your reasoning by including comment(s) and mark the question please.
74
+ Return ONLY JSON in the following format (fill in the values as per the question):
75
+ {
76
+ "isCorrect": <boolean>,
77
+ "points": <number>,
78
+ "markschemeState": [
79
+ { "id": <string>, "correct": <boolean> }
80
+ ],
81
+ "comments": [<string>, ...]
82
+ }
83
+ `,
84
+ z.object({
85
+ isCorrect: z.boolean(),
86
+ points: z.number(),
87
+ markschemeState: z.array(z.object({
88
+ id: z.string(),
89
+ correct: z.boolean(),
90
+ })), // @note: this has to be converted to [id: string]: correct boolean
91
+ comments: z.array(z.string()),
92
+ }),
93
+ ).catch((error) => {
94
+ logger.error('Failed to grade worksheet response', { error });
95
+ throw error;
96
+ });
97
+
98
+ const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({
99
+ where: { id: studentQuestionProgress.id, status: {
100
+ not: {
101
+ in: ['CANCELLED'],
102
+ },
103
+ } },
104
+ data: {
105
+ status: GenerationStatus.COMPLETED,
106
+ isCorrect: (apiResponse as { isCorrect: boolean }).isCorrect,
107
+ points: (apiResponse as { points: number }).points,
108
+ markschemeState: (apiResponse as {
109
+ markschemeState: { id: string; correct: boolean }[];
110
+ }).markschemeState.reduce((acc, curr) => {
111
+ acc["item-" + curr.id] = curr.correct;
112
+ return acc;
113
+ }, {} as Record<string, boolean>),
114
+ comments: {
115
+ create: (apiResponse as {
116
+ comments: string[];
117
+ }).comments.map((commentContent) => ({
118
+ content: commentContent,
119
+ authorId: getAIUserId(),
120
+ })),
121
+ },
122
+ },
123
+ });
124
+ pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `set-completed`, {
125
+ id: updatedStudentQuestionProgress.id,
126
+ });
127
+
128
+ return updatedStudentQuestionProgress;
129
+ } catch (error) {
130
+ logger.error('Failed to grade worksheet response', { error, worksheetResponseId });
131
+ pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `set-failed`, {
132
+ id: studentQuestionProgress.id,
133
+ });
134
+ await prisma.studentQuestionProgress.update({
135
+ where: { id: studentQuestionProgress.id },
136
+ data: { status: GenerationStatus.FAILED },
137
+ });
138
+ throw error;
139
+ }
140
+ }
141
+
9
142
  /**
10
143
  * Grades and regrades worksheet (can fixed failed responses)
11
144
  * @param worksheetResponseId worksheet response id
@@ -51,9 +184,6 @@ export const gradeWorksheetPipeline = async (worksheetResponseId: string) => {
51
184
  // Use for...of instead of forEach to properly handle async operations
52
185
  for (const response of worksheetResponse.responses) {
53
186
  logger.info('Grading question', { questionId: response.questionId });
54
- const question = response.question;
55
- const comments = response.comments;
56
- const responseText = response.response;
57
187
 
58
188
  const studentQuestionProgress = await prisma.studentQuestionProgress.update({
59
189
  where: { id: response.id, status: {
@@ -68,84 +198,59 @@ export const gradeWorksheetPipeline = async (worksheetResponseId: string) => {
68
198
  return;
69
199
  }
70
200
 
71
- try {
72
- const apiResponse = await inference(
73
- `Grade the following worksheet response:
74
-
75
- Question: ${question.question}
76
- Response: ${responseText}
77
-
78
- Comments: ${comments.map((comment) => comment.content).join('\n')}
79
- Mark Scheme: ${JSON.stringify(question.markScheme)}
80
-
81
- Justify your reasoning by including comment(s) and mark the question please.
82
- Return ONLY JSON in the following format (fill in the values as per the question):
83
- {
84
- "isCorrect": <boolean>,
85
- "points": <number>,
86
- "markschemeState": [
87
- { "id": <string>, "correct": <boolean> }
88
- ],
89
- "comments": [<string>, ...]
90
- }
91
- `,
92
- z.object({
93
- isCorrect: z.boolean(),
94
- points: z.number(),
95
- markschemeState: z.array(z.object({
96
- id: z.string(),
97
- correct: z.boolean(),
98
- })), // @note: this has to be converted to [id: string]: correct boolean
99
- comments: z.array(z.string()),
100
- }),
101
- ).catch((error) => {
102
- logger.error('Failed to grade worksheet response', { error });
103
- throw error;
104
- });
105
-
106
- console.log(apiResponse);
107
-
108
- const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({
109
- where: { id: studentQuestionProgress.id, status: {
110
- not: {
111
- in: ['CANCELLED'],
112
- },
113
- } },
114
- data: {
115
- status: GenerationStatus.COMPLETED,
116
- isCorrect: (apiResponse as { isCorrect: boolean }).isCorrect,
117
- points: (apiResponse as { points: number }).points,
118
- markschemeState: (apiResponse as {
119
- markschemeState: { id: string; correct: boolean }[];
120
- }).markschemeState.reduce((acc, curr) => {
121
- acc["item-" + curr.id] = curr.correct;
122
- return acc;
123
- }, {} as Record<string, boolean>),
124
- comments: {
125
- create: (apiResponse as {
126
- comments: string[];
127
- }).comments.map((commentContent) => ({
128
- content: commentContent,
129
- authorId: getAIUserId(),
130
- })),
131
- },
132
- },
133
- });
134
- pusher.trigger(`class-${worksheetResponse.worksheet.classId}`, `ai-worksheet-updated-${worksheetResponse.id}`, {
135
- success: true,
136
- });
137
-
138
- return updatedStudentQuestionProgress;
139
- } catch (error) {
140
- logger.error('Failed to grade worksheet response', { error, worksheetResponseId });
141
- pusher.trigger(`class-${worksheetResponse.worksheet.classId}`, `ai-worksheet-updated-${worksheetResponse.id}`, {
142
- success: false,
143
- });
144
- await prisma.studentQuestionProgress.update({
145
- where: { id: studentQuestionProgress.id },
146
- data: { status: GenerationStatus.FAILED },
147
- });
148
- throw error;
149
- }
201
+ gradeWorksheetQuestion(response.id);
202
+
150
203
  };
151
- };
204
+ };
205
+
206
+ export const cancelGradePipeline = async (worksheetResponseId: string, worksheetQuestionProgressId: string) => {
207
+ logger.info('Cancelling auto grading', { worksheetResponseId, worksheetQuestionProgressId });
208
+
209
+ const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({
210
+ where: { id: worksheetResponseId },
211
+ include: {
212
+ worksheet: true,
213
+ },
214
+ });
215
+ if (!worksheetResponse) {
216
+ logger.error('Worksheet response not found');
217
+ throw new Error('Worksheet response not found');
218
+ }
219
+ const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({
220
+ where: { id: worksheetQuestionProgressId },
221
+ data: { status: GenerationStatus.CANCELLED },
222
+ });
223
+
224
+ await removeAllPreviousAIComments(worksheetQuestionProgressId);
225
+
226
+ pusher.trigger(`class-${worksheetResponse.worksheet.classId}-worksheetSubmission-${worksheetResponse.id}`, `set-cancelled`, {
227
+ id: updatedStudentQuestionProgress.id,
228
+ });
229
+
230
+ return updatedStudentQuestionProgress;
231
+ };
232
+
233
+ export const regradeWorksheetPipeline = async (worksheetResponseId: string, worksheetQuestionProgressId: string) => {
234
+ logger.info('Regrading worksheet response', { worksheetResponseId, worksheetQuestionProgressId });
235
+
236
+ const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({
237
+ where: { id: worksheetResponseId, },
238
+ include: {
239
+ worksheet: true,
240
+ },
241
+ });
242
+
243
+ if (!worksheetResponse) {
244
+ logger.error('Worksheet response not found');
245
+ throw new Error('Worksheet response not found');
246
+ }
247
+
248
+ const updatedStudentQuestionProgress = await prisma.studentQuestionProgress.update({
249
+ where: { id: worksheetQuestionProgressId },
250
+ data: { status: GenerationStatus.PENDING },
251
+ });
252
+
253
+ gradeWorksheetQuestion(worksheetQuestionProgressId);
254
+
255
+ return updatedStudentQuestionProgress;
256
+ };