@studious-lms/server 1.20.0 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Dockerfile +5 -2
- package/dist/models/agenda.d.ts +6 -0
- package/dist/models/agenda.d.ts.map +1 -1
- package/dist/models/announcement.d.ts +2 -0
- package/dist/models/announcement.d.ts.map +1 -1
- package/dist/models/assignment.d.ts +27 -0
- package/dist/models/assignment.d.ts.map +1 -1
- package/dist/models/auth.d.ts +4 -0
- package/dist/models/auth.d.ts.map +1 -1
- package/dist/models/class.d.ts +14 -0
- package/dist/models/class.d.ts.map +1 -1
- package/dist/models/event.d.ts +11 -0
- package/dist/models/event.d.ts.map +1 -1
- package/dist/models/file.d.ts +19 -0
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/folder.d.ts +4 -0
- package/dist/models/folder.d.ts.map +1 -1
- package/dist/models/gradebook.d.ts +180 -0
- package/dist/models/gradebook.d.ts.map +1 -0
- package/dist/models/gradebook.js +88 -0
- package/dist/models/gradebook.js.map +1 -0
- package/dist/models/labChat.d.ts +4 -0
- package/dist/models/labChat.d.ts.map +1 -1
- package/dist/models/newtonChat.d.ts +2 -0
- package/dist/models/newtonChat.d.ts.map +1 -1
- package/dist/models/school.d.ts +2 -0
- package/dist/models/school.d.ts.map +1 -1
- package/dist/models/section.d.ts +3 -0
- package/dist/models/section.d.ts.map +1 -1
- package/dist/models/worksheet.d.ts +6 -0
- package/dist/models/worksheet.d.ts.map +1 -1
- package/dist/routers/_app.d.ts +1359 -37
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +4 -2
- package/dist/routers/_app.js.map +1 -1
- package/dist/routers/admin.d.ts +164 -0
- package/dist/routers/admin.d.ts.map +1 -1
- package/dist/routers/admin.js +23 -4
- package/dist/routers/admin.js.map +1 -1
- package/dist/routers/agenda.d.ts +6 -0
- package/dist/routers/agenda.d.ts.map +1 -1
- package/dist/routers/assignment.d.ts +102 -1
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +180 -2
- package/dist/routers/assignment.js.map +1 -1
- package/dist/routers/class.d.ts +17 -0
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/event.d.ts +4 -0
- package/dist/routers/event.d.ts.map +1 -1
- package/dist/routers/file.d.ts +66 -0
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/file.js +111 -2
- package/dist/routers/file.js.map +1 -1
- package/dist/routers/gradebook.d.ts +299 -0
- package/dist/routers/gradebook.d.ts.map +1 -0
- package/dist/routers/gradebook.js +107 -0
- package/dist/routers/gradebook.js.map +1 -0
- package/dist/routers/school.d.ts +4 -0
- package/dist/routers/school.d.ts.map +1 -1
- package/dist/routers/section.d.ts +1 -1
- package/dist/routers/worksheet.d.ts +3 -1
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/services/adminInstitution.d.ts +51 -0
- package/dist/services/adminInstitution.d.ts.map +1 -1
- package/dist/services/adminInstitution.js +52 -2
- package/dist/services/adminInstitution.js.map +1 -1
- package/dist/services/adminMetrics.d.ts +17 -0
- package/dist/services/adminMetrics.d.ts.map +1 -0
- package/dist/services/adminMetrics.js +37 -0
- package/dist/services/adminMetrics.js.map +1 -0
- package/dist/services/adminRunJob.d.ts +9 -0
- package/dist/services/adminRunJob.d.ts.map +1 -1
- package/dist/services/adminRunJob.js +18 -2
- package/dist/services/adminRunJob.js.map +1 -1
- package/dist/services/adminUser.d.ts +67 -0
- package/dist/services/adminUser.d.ts.map +1 -0
- package/dist/services/adminUser.js +87 -0
- package/dist/services/adminUser.js.map +1 -0
- package/dist/services/agenda.d.ts +6 -0
- package/dist/services/agenda.d.ts.map +1 -1
- package/dist/services/assignment.d.ts +27 -0
- package/dist/services/assignment.d.ts.map +1 -1
- package/dist/services/class.d.ts +17 -0
- package/dist/services/class.d.ts.map +1 -1
- package/dist/services/event.d.ts +4 -0
- package/dist/services/event.d.ts.map +1 -1
- package/dist/services/gradeCalculation.d.ts +70 -0
- package/dist/services/gradeCalculation.d.ts.map +1 -0
- package/dist/services/gradeCalculation.js +148 -0
- package/dist/services/gradeCalculation.js.map +1 -0
- package/dist/services/gradebook.d.ts +197 -0
- package/dist/services/gradebook.d.ts.map +1 -0
- package/dist/services/gradebook.js +263 -0
- package/dist/services/gradebook.js.map +1 -0
- package/dist/services/school.d.ts +4 -0
- package/dist/services/school.d.ts.map +1 -1
- package/dist/services/worksheet.d.ts +2 -0
- package/dist/services/worksheet.d.ts.map +1 -1
- package/docker-entrypoint.sh +7 -0
- package/package.json +1 -1
- package/prisma/migrations/20260708011456_add_file_annotations/migration.sql +35 -0
- package/prisma/migrations/20260708011629_add_gradebook_categories_columns_policies/migration.sql +78 -0
- package/prisma/migrations/20260723142314_make_file_annotation_submission_optional/migration.sql +2 -0
- package/prisma/schema.prisma +130 -38
- package/src/models/gradebook.ts +91 -0
- package/src/routers/_app.ts +2 -0
- package/src/routers/admin.ts +28 -0
- package/src/routers/assignment.ts +204 -0
- package/src/routers/file.ts +128 -0
- package/src/routers/gradebook.ts +173 -0
- package/src/services/adminInstitution.ts +52 -0
- package/src/services/adminMetrics.ts +46 -0
- package/src/services/adminRunJob.ts +24 -0
- package/src/services/adminUser.ts +93 -0
- package/src/services/gradeCalculation.ts +253 -0
- package/src/services/gradebook.ts +383 -0
- package/tests/unit/services/gradeCalculation.test.ts +206 -0
|
@@ -88,6 +88,7 @@ export declare function getAssignment(id: string, _classId: string): Promise<{
|
|
|
88
88
|
markSchemeId: string | null;
|
|
89
89
|
order: number | null;
|
|
90
90
|
gradingBoundaryId: string | null;
|
|
91
|
+
gradeCategoryId: string | null;
|
|
91
92
|
}>;
|
|
92
93
|
export declare function getSubmission(assignmentId: string, studentId: string): Promise<{
|
|
93
94
|
late: boolean;
|
|
@@ -105,6 +106,8 @@ export declare function getSubmission(assignmentId: string, studentId: string):
|
|
|
105
106
|
discussionsEnabled: boolean;
|
|
106
107
|
studentsCanCreateDiscussions: boolean;
|
|
107
108
|
studentsCanReply: boolean;
|
|
109
|
+
treatMissingAsZero: boolean;
|
|
110
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
108
111
|
};
|
|
109
112
|
markScheme: {
|
|
110
113
|
id: string;
|
|
@@ -143,6 +146,7 @@ export declare function getSubmission(assignmentId: string, studentId: string):
|
|
|
143
146
|
markSchemeId: string | null;
|
|
144
147
|
order: number | null;
|
|
145
148
|
gradingBoundaryId: string | null;
|
|
149
|
+
gradeCategoryId: string | null;
|
|
146
150
|
};
|
|
147
151
|
attachments: {
|
|
148
152
|
path: string;
|
|
@@ -240,6 +244,8 @@ export declare function getSubmissionById(submissionId: string, classId: string,
|
|
|
240
244
|
discussionsEnabled: boolean;
|
|
241
245
|
studentsCanCreateDiscussions: boolean;
|
|
242
246
|
studentsCanReply: boolean;
|
|
247
|
+
treatMissingAsZero: boolean;
|
|
248
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
243
249
|
};
|
|
244
250
|
markScheme: {
|
|
245
251
|
id: string;
|
|
@@ -278,6 +284,7 @@ export declare function getSubmissionById(submissionId: string, classId: string,
|
|
|
278
284
|
markSchemeId: string | null;
|
|
279
285
|
order: number | null;
|
|
280
286
|
gradingBoundaryId: string | null;
|
|
287
|
+
gradeCategoryId: string | null;
|
|
281
288
|
};
|
|
282
289
|
attachments: {
|
|
283
290
|
path: string;
|
|
@@ -387,6 +394,8 @@ export declare function getSubmissions(assignmentId: string, teacherId: string):
|
|
|
387
394
|
discussionsEnabled: boolean;
|
|
388
395
|
studentsCanCreateDiscussions: boolean;
|
|
389
396
|
studentsCanReply: boolean;
|
|
397
|
+
treatMissingAsZero: boolean;
|
|
398
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
390
399
|
};
|
|
391
400
|
markScheme: {
|
|
392
401
|
id: string;
|
|
@@ -421,6 +430,7 @@ export declare function getSubmissions(assignmentId: string, teacherId: string):
|
|
|
421
430
|
markSchemeId: string | null;
|
|
422
431
|
order: number | null;
|
|
423
432
|
gradingBoundaryId: string | null;
|
|
433
|
+
gradeCategoryId: string | null;
|
|
424
434
|
};
|
|
425
435
|
attachments: ({
|
|
426
436
|
thumbnail: {
|
|
@@ -592,6 +602,7 @@ export declare function duplicateAssignmentRecord(assignmentId: string, classId:
|
|
|
592
602
|
markSchemeId: string | null;
|
|
593
603
|
order: number | null;
|
|
594
604
|
gradingBoundaryId: string | null;
|
|
605
|
+
gradeCategoryId: string | null;
|
|
595
606
|
}>;
|
|
596
607
|
export declare function updateAssignmentRecord(userId: string, input: {
|
|
597
608
|
id: string;
|
|
@@ -634,6 +645,8 @@ export declare function updateAssignmentRecord(userId: string, input: {
|
|
|
634
645
|
discussionsEnabled: boolean;
|
|
635
646
|
studentsCanCreateDiscussions: boolean;
|
|
636
647
|
studentsCanReply: boolean;
|
|
648
|
+
treatMissingAsZero: boolean;
|
|
649
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
637
650
|
};
|
|
638
651
|
section: {
|
|
639
652
|
id: string;
|
|
@@ -738,6 +751,8 @@ export declare function updateSubmissionRecord(userId: string, input: {
|
|
|
738
751
|
discussionsEnabled: boolean;
|
|
739
752
|
studentsCanCreateDiscussions: boolean;
|
|
740
753
|
studentsCanReply: boolean;
|
|
754
|
+
treatMissingAsZero: boolean;
|
|
755
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
741
756
|
};
|
|
742
757
|
markScheme: {
|
|
743
758
|
id: string;
|
|
@@ -772,6 +787,7 @@ export declare function updateSubmissionRecord(userId: string, input: {
|
|
|
772
787
|
markSchemeId: string | null;
|
|
773
788
|
order: number | null;
|
|
774
789
|
gradingBoundaryId: string | null;
|
|
790
|
+
gradeCategoryId: string | null;
|
|
775
791
|
};
|
|
776
792
|
attachments: {
|
|
777
793
|
path: string;
|
|
@@ -859,6 +875,8 @@ export declare function updateSubmissionAsTeacherRecord(teacherId: string, input
|
|
|
859
875
|
discussionsEnabled: boolean;
|
|
860
876
|
studentsCanCreateDiscussions: boolean;
|
|
861
877
|
studentsCanReply: boolean;
|
|
878
|
+
treatMissingAsZero: boolean;
|
|
879
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
862
880
|
};
|
|
863
881
|
markScheme: {
|
|
864
882
|
id: string;
|
|
@@ -893,6 +911,7 @@ export declare function updateSubmissionAsTeacherRecord(teacherId: string, input
|
|
|
893
911
|
markSchemeId: string | null;
|
|
894
912
|
order: number | null;
|
|
895
913
|
gradingBoundaryId: string | null;
|
|
914
|
+
gradeCategoryId: string | null;
|
|
896
915
|
};
|
|
897
916
|
attachments: ({
|
|
898
917
|
thumbnail: {
|
|
@@ -1089,6 +1108,7 @@ export declare function attachAssignmentToEventRecord(teacherId: string, assignm
|
|
|
1089
1108
|
markSchemeId: string | null;
|
|
1090
1109
|
order: number | null;
|
|
1091
1110
|
gradingBoundaryId: string | null;
|
|
1111
|
+
gradeCategoryId: string | null;
|
|
1092
1112
|
};
|
|
1093
1113
|
}>;
|
|
1094
1114
|
export declare function detachAssignmentFromEventRecord(teacherId: string, assignmentId: string): Promise<{
|
|
@@ -1138,6 +1158,7 @@ export declare function detachAssignmentFromEventRecord(teacherId: string, assig
|
|
|
1138
1158
|
markSchemeId: string | null;
|
|
1139
1159
|
order: number | null;
|
|
1140
1160
|
gradingBoundaryId: string | null;
|
|
1161
|
+
gradeCategoryId: string | null;
|
|
1141
1162
|
};
|
|
1142
1163
|
}>;
|
|
1143
1164
|
export declare function getAvailableEventsForAssignment(teacherId: string, assignmentId: string): Promise<{
|
|
@@ -1242,6 +1263,7 @@ export declare function attachMarkSchemeRecord(teacherId: string, assignmentId:
|
|
|
1242
1263
|
markSchemeId: string | null;
|
|
1243
1264
|
order: number | null;
|
|
1244
1265
|
gradingBoundaryId: string | null;
|
|
1266
|
+
gradeCategoryId: string | null;
|
|
1245
1267
|
}>;
|
|
1246
1268
|
export declare function detachMarkSchemeRecord(teacherId: string, assignmentId: string): Promise<{
|
|
1247
1269
|
markScheme: {
|
|
@@ -1334,6 +1356,7 @@ export declare function detachMarkSchemeRecord(teacherId: string, assignmentId:
|
|
|
1334
1356
|
markSchemeId: string | null;
|
|
1335
1357
|
order: number | null;
|
|
1336
1358
|
gradingBoundaryId: string | null;
|
|
1359
|
+
gradeCategoryId: string | null;
|
|
1337
1360
|
}>;
|
|
1338
1361
|
export declare function attachGradingBoundaryRecord(teacherId: string, assignmentId: string, gradingBoundaryId: string | null): Promise<{
|
|
1339
1362
|
gradingBoundary: {
|
|
@@ -1426,6 +1449,7 @@ export declare function attachGradingBoundaryRecord(teacherId: string, assignmen
|
|
|
1426
1449
|
markSchemeId: string | null;
|
|
1427
1450
|
order: number | null;
|
|
1428
1451
|
gradingBoundaryId: string | null;
|
|
1452
|
+
gradeCategoryId: string | null;
|
|
1429
1453
|
}>;
|
|
1430
1454
|
export declare function detachGradingBoundaryRecord(teacherId: string, assignmentId: string): Promise<{
|
|
1431
1455
|
gradingBoundary: {
|
|
@@ -1518,6 +1542,7 @@ export declare function detachGradingBoundaryRecord(teacherId: string, assignmen
|
|
|
1518
1542
|
markSchemeId: string | null;
|
|
1519
1543
|
order: number | null;
|
|
1520
1544
|
gradingBoundaryId: string | null;
|
|
1545
|
+
gradeCategoryId: string | null;
|
|
1521
1546
|
}>;
|
|
1522
1547
|
export declare function reorderAssignmentRecord(teacherId: string, input: {
|
|
1523
1548
|
classId: string;
|
|
@@ -1549,6 +1574,7 @@ export declare function reorderAssignmentRecord(teacherId: string, input: {
|
|
|
1549
1574
|
markSchemeId: string | null;
|
|
1550
1575
|
order: number | null;
|
|
1551
1576
|
gradingBoundaryId: string | null;
|
|
1577
|
+
gradeCategoryId: string | null;
|
|
1552
1578
|
} | null>;
|
|
1553
1579
|
export declare function moveAssignmentRecord(teacherId: string, input: {
|
|
1554
1580
|
id: string;
|
|
@@ -1579,5 +1605,6 @@ export declare function moveAssignmentRecord(teacherId: string, input: {
|
|
|
1579
1605
|
markSchemeId: string | null;
|
|
1580
1606
|
order: number | null;
|
|
1581
1607
|
gradingBoundaryId: string | null;
|
|
1608
|
+
gradeCategoryId: string | null;
|
|
1582
1609
|
} | null>;
|
|
1583
1610
|
//# sourceMappingURL=assignment.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assignment.d.ts","sourceRoot":"/","sources":["services/assignment.ts"],"names":[],"mappings":"AA+BA,wBAAsB,gBAAgB,CAAC,EAAE,EAAE,MAAM,oBAGhD;AAED,wBAAsB,WAAW;;;;;;;;;;;KAMhC;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"assignment.d.ts","sourceRoot":"/","sources":["services/assignment.ts"],"names":[],"mappings":"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"}
|
package/dist/services/class.d.ts
CHANGED
|
@@ -226,6 +226,8 @@ export declare function getClass(userId: string, classId: string): Promise<{
|
|
|
226
226
|
discussionsEnabled: boolean;
|
|
227
227
|
studentsCanCreateDiscussions: boolean;
|
|
228
228
|
studentsCanReply: boolean;
|
|
229
|
+
treatMissingAsZero: boolean;
|
|
230
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
229
231
|
};
|
|
230
232
|
}>;
|
|
231
233
|
export declare function updateClass(classId: string, data: {
|
|
@@ -296,6 +298,8 @@ export declare function createClass(userId: string, input: {
|
|
|
296
298
|
discussionsEnabled: boolean;
|
|
297
299
|
studentsCanCreateDiscussions: boolean;
|
|
298
300
|
studentsCanReply: boolean;
|
|
301
|
+
treatMissingAsZero: boolean;
|
|
302
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
299
303
|
}>;
|
|
300
304
|
export declare function deleteClass(classId: string): Promise<{
|
|
301
305
|
deletedClass: {
|
|
@@ -328,6 +332,8 @@ export declare function changeRole(classId: string, userId: string, type: "teach
|
|
|
328
332
|
discussionsEnabled: boolean;
|
|
329
333
|
studentsCanCreateDiscussions: boolean;
|
|
330
334
|
studentsCanReply: boolean;
|
|
335
|
+
treatMissingAsZero: boolean;
|
|
336
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
331
337
|
};
|
|
332
338
|
user: {
|
|
333
339
|
type: "student" | "teacher";
|
|
@@ -349,6 +355,8 @@ export declare function removeMember(classId: string, userId: string): Promise<{
|
|
|
349
355
|
discussionsEnabled: boolean;
|
|
350
356
|
studentsCanCreateDiscussions: boolean;
|
|
351
357
|
studentsCanReply: boolean;
|
|
358
|
+
treatMissingAsZero: boolean;
|
|
359
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
352
360
|
};
|
|
353
361
|
removedUserId: string;
|
|
354
362
|
}>;
|
|
@@ -521,6 +529,8 @@ export declare function updateSyllabus(classId: string, contents: string): Promi
|
|
|
521
529
|
discussionsEnabled: boolean;
|
|
522
530
|
studentsCanCreateDiscussions: boolean;
|
|
523
531
|
studentsCanReply: boolean;
|
|
532
|
+
treatMissingAsZero: boolean;
|
|
533
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
524
534
|
}>;
|
|
525
535
|
export declare function listLabDrafts(classId: string, teacherId: string): Promise<{
|
|
526
536
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
@@ -547,6 +557,7 @@ export declare function listLabDrafts(classId: string, teacherId: string): Promi
|
|
|
547
557
|
markSchemeId: string | null;
|
|
548
558
|
order: number | null;
|
|
549
559
|
gradingBoundaryId: string | null;
|
|
560
|
+
gradeCategoryId: string | null;
|
|
550
561
|
}[]>;
|
|
551
562
|
export declare function createLabDraft(classId: string, teacherId: string, input: {
|
|
552
563
|
title: string;
|
|
@@ -584,6 +595,7 @@ export declare function createLabDraft(classId: string, teacherId: string, input
|
|
|
584
595
|
markSchemeId: string | null;
|
|
585
596
|
order: number | null;
|
|
586
597
|
gradingBoundaryId: string | null;
|
|
598
|
+
gradeCategoryId: string | null;
|
|
587
599
|
}>;
|
|
588
600
|
export declare function updateLabDraft(classId: string, teacherId: string, draftId: string, input: Record<string, unknown>): Promise<{
|
|
589
601
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
@@ -610,6 +622,7 @@ export declare function updateLabDraft(classId: string, teacherId: string, draft
|
|
|
610
622
|
markSchemeId: string | null;
|
|
611
623
|
order: number | null;
|
|
612
624
|
gradingBoundaryId: string | null;
|
|
625
|
+
gradeCategoryId: string | null;
|
|
613
626
|
}>;
|
|
614
627
|
export declare function deleteLabDraft(classId: string, teacherId: string, draftId: string): Promise<{
|
|
615
628
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
@@ -636,6 +649,7 @@ export declare function deleteLabDraft(classId: string, teacherId: string, draft
|
|
|
636
649
|
markSchemeId: string | null;
|
|
637
650
|
order: number | null;
|
|
638
651
|
gradingBoundaryId: string | null;
|
|
652
|
+
gradeCategoryId: string | null;
|
|
639
653
|
}>;
|
|
640
654
|
export declare function publishLabDraft(classId: string, teacherId: string, draftId: string, input: {
|
|
641
655
|
dueDate?: Date;
|
|
@@ -667,6 +681,7 @@ export declare function publishLabDraft(classId: string, teacherId: string, draf
|
|
|
667
681
|
markSchemeId: string | null;
|
|
668
682
|
order: number | null;
|
|
669
683
|
gradingBoundaryId: string | null;
|
|
684
|
+
gradeCategoryId: string | null;
|
|
670
685
|
}>;
|
|
671
686
|
export declare function getFiles(classId: string): Promise<{
|
|
672
687
|
id: string;
|
|
@@ -804,6 +819,8 @@ export declare function exportClass(classId: string, userId: string): Promise<{
|
|
|
804
819
|
discussionsEnabled: boolean;
|
|
805
820
|
studentsCanCreateDiscussions: boolean;
|
|
806
821
|
studentsCanReply: boolean;
|
|
822
|
+
treatMissingAsZero: boolean;
|
|
823
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
807
824
|
}>;
|
|
808
825
|
export declare function importClass(classId: string, userId: string, year: number, classData: Class & {
|
|
809
826
|
classFiles: Folder | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAgC/C,sFAAsF;AACtF,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDjD;AAED,0EAA0E;AAC1E,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"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"}
|
package/dist/services/event.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export declare function getEvent(userId: string, id: string): Promise<{
|
|
|
44
44
|
discussionsEnabled: boolean;
|
|
45
45
|
studentsCanCreateDiscussions: boolean;
|
|
46
46
|
studentsCanReply: boolean;
|
|
47
|
+
treatMissingAsZero: boolean;
|
|
48
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
47
49
|
}) | null;
|
|
48
50
|
assignmentsAttached: {
|
|
49
51
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
@@ -170,6 +172,7 @@ export declare function attachAssignment(userId: string, eventId: string, assign
|
|
|
170
172
|
markSchemeId: string | null;
|
|
171
173
|
order: number | null;
|
|
172
174
|
gradingBoundaryId: string | null;
|
|
175
|
+
gradeCategoryId: string | null;
|
|
173
176
|
};
|
|
174
177
|
}>;
|
|
175
178
|
export declare function detachAssignment(userId: string, eventId: string, assignmentId: string): Promise<{
|
|
@@ -212,6 +215,7 @@ export declare function detachAssignment(userId: string, eventId: string, assign
|
|
|
212
215
|
markSchemeId: string | null;
|
|
213
216
|
order: number | null;
|
|
214
217
|
gradingBoundaryId: string | null;
|
|
218
|
+
gradeCategoryId: string | null;
|
|
215
219
|
};
|
|
216
220
|
}>;
|
|
217
221
|
export declare function getAvailableAssignments(userId: string, eventId: string): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.d.ts","sourceRoot":"/","sources":["services/event.ts"],"names":[],"mappings":"AAmBA,6DAA6D;AAC7D,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"/","sources":["services/event.ts"],"names":[],"mappings":"AAmBA,6DAA6D;AAC7D,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAexD;AAED,wCAAwC;AACxC,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;;;;;;;;;;;;;;GAwBF;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;IACJ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;;;GA2BF;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;GAiBjE;AAuBD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CrB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBrB;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;GAkBhB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grade calculation – pure functions for computing final class grades from
|
|
3
|
+
* categories, weights, and grade-calculation policies. No I/O; unit-testable.
|
|
4
|
+
*
|
|
5
|
+
* Future policies (standards-based grading, etc.) should extend
|
|
6
|
+
* `GradeCalculationPolicies` and be handled inside `computeFinalGrade` so
|
|
7
|
+
* callers never need to change.
|
|
8
|
+
*/
|
|
9
|
+
export type GradeRoundingMode = "NONE" | "HALF_UP" | "FLOOR" | "CEILING";
|
|
10
|
+
export interface GradeCalculationPolicies {
|
|
11
|
+
/** Count ungraded/missing scores as 0% instead of excluding them. */
|
|
12
|
+
treatMissingAsZero: boolean;
|
|
13
|
+
/** How the final percentage is rounded to a whole number. */
|
|
14
|
+
roundingMode: GradeRoundingMode;
|
|
15
|
+
}
|
|
16
|
+
export interface GradeCategoryInput {
|
|
17
|
+
id: string;
|
|
18
|
+
name: string;
|
|
19
|
+
/** Relative weight of this category toward the final grade. */
|
|
20
|
+
weight: number;
|
|
21
|
+
/** Number of lowest-percentage scores dropped within this category. */
|
|
22
|
+
dropLowest: number;
|
|
23
|
+
}
|
|
24
|
+
export interface ScoreInput {
|
|
25
|
+
/** Category the score belongs to; null falls into the default category. */
|
|
26
|
+
categoryId: string | null;
|
|
27
|
+
/** Points earned; null means missing/ungraded. */
|
|
28
|
+
pointsEarned: number | null;
|
|
29
|
+
/** Maximum points for the item; items with maxPoints <= 0 are ignored. */
|
|
30
|
+
maxPoints: number;
|
|
31
|
+
/** Relative weight of the item within its category (defaults to 1). */
|
|
32
|
+
weight?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface CategoryAverage {
|
|
35
|
+
categoryId: string | null;
|
|
36
|
+
name: string;
|
|
37
|
+
weight: number;
|
|
38
|
+
/** Percentage 0–100, or null when no scores counted. */
|
|
39
|
+
average: number | null;
|
|
40
|
+
countedScores: number;
|
|
41
|
+
droppedScores: number;
|
|
42
|
+
}
|
|
43
|
+
export interface FinalGradeResult {
|
|
44
|
+
/** Final percentage 0–100 (rounded per policy), or null when no data. */
|
|
45
|
+
percentage: number | null;
|
|
46
|
+
categories: CategoryAverage[];
|
|
47
|
+
}
|
|
48
|
+
/** Synthetic category used for scores without a category. */
|
|
49
|
+
export declare const DEFAULT_CATEGORY: {
|
|
50
|
+
readonly id: null;
|
|
51
|
+
readonly weight: 1;
|
|
52
|
+
readonly dropLowest: 0;
|
|
53
|
+
};
|
|
54
|
+
export declare function roundPercentage(value: number, mode: GradeRoundingMode): number;
|
|
55
|
+
/**
|
|
56
|
+
* Computes the final class grade as the weighted average of category
|
|
57
|
+
* averages. Scores with no category fall into a default category with
|
|
58
|
+
* weight `DEFAULT_CATEGORY.weight`. Categories without counted scores are
|
|
59
|
+
* excluded from the weighted average.
|
|
60
|
+
*/
|
|
61
|
+
export declare function computeFinalGrade(policies: GradeCalculationPolicies, categories: GradeCategoryInput[], scores: ScoreInput[], options?: {
|
|
62
|
+
defaultCategoryName?: string;
|
|
63
|
+
}): FinalGradeResult;
|
|
64
|
+
/**
|
|
65
|
+
* Maps a percentage to a letter grade using a GradingBoundary `structured`
|
|
66
|
+
* JSON payload (`{ boundaries: [{ grade, minPercentage, maxPercentage }] }`).
|
|
67
|
+
* Returns null when the payload is unparseable or nothing matches.
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveLetterGrade(structured: string, percentage: number): string | null;
|
|
70
|
+
//# sourceMappingURL=gradeCalculation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gradeCalculation.d.ts","sourceRoot":"/","sources":["services/gradeCalculation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,wBAAwB;IACvC,qEAAqE;IACrE,kBAAkB,EAAE,OAAO,CAAC;IAC5B,6DAA6D;IAC7D,YAAY,EAAE,iBAAiB,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,kDAAkD;IAClD,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,eAAe,EAAE,CAAC;CAC/B;AAED,6DAA6D;AAC7D,eAAO,MAAM,gBAAgB;;;;CAInB,CAAC;AAEX,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,iBAAiB,GACtB,MAAM,CAYR;AAsDD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,wBAAwB,EAClC,UAAU,EAAE,kBAAkB,EAAE,EAChC,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,CAAC,EAAE;IAAE,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,gBAAgB,CAuElB;AAQD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAwBf"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grade calculation – pure functions for computing final class grades from
|
|
3
|
+
* categories, weights, and grade-calculation policies. No I/O; unit-testable.
|
|
4
|
+
*
|
|
5
|
+
* Future policies (standards-based grading, etc.) should extend
|
|
6
|
+
* `GradeCalculationPolicies` and be handled inside `computeFinalGrade` so
|
|
7
|
+
* callers never need to change.
|
|
8
|
+
*/
|
|
9
|
+
/** Synthetic category used for scores without a category. */
|
|
10
|
+
|
|
11
|
+
!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]="f05b8c2d-15ff-58b1-b01e-d40dba432326")}catch(e){}}();
|
|
12
|
+
export const DEFAULT_CATEGORY = {
|
|
13
|
+
id: null,
|
|
14
|
+
weight: 1,
|
|
15
|
+
dropLowest: 0,
|
|
16
|
+
};
|
|
17
|
+
export function roundPercentage(value, mode) {
|
|
18
|
+
switch (mode) {
|
|
19
|
+
case "HALF_UP":
|
|
20
|
+
return Math.round(value);
|
|
21
|
+
case "FLOOR":
|
|
22
|
+
return Math.floor(value);
|
|
23
|
+
case "CEILING":
|
|
24
|
+
return Math.ceil(value);
|
|
25
|
+
case "NONE":
|
|
26
|
+
default:
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function collectCountableScores(scores, policies) {
|
|
31
|
+
const countable = [];
|
|
32
|
+
for (const score of scores) {
|
|
33
|
+
if (score.maxPoints <= 0)
|
|
34
|
+
continue;
|
|
35
|
+
if (score.pointsEarned === null) {
|
|
36
|
+
if (!policies.treatMissingAsZero)
|
|
37
|
+
continue;
|
|
38
|
+
countable.push({ percentage: 0, weight: score.weight ?? 1 });
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
countable.push({
|
|
42
|
+
percentage: (score.pointsEarned / score.maxPoints) * 100,
|
|
43
|
+
weight: score.weight ?? 1,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return countable;
|
|
47
|
+
}
|
|
48
|
+
function averageCategory(countable, dropLowest) {
|
|
49
|
+
// Always keep at least one score so a category never collapses to null
|
|
50
|
+
// just because dropLowest >= score count.
|
|
51
|
+
const dropCount = Math.min(Math.max(dropLowest, 0), countable.length - 1);
|
|
52
|
+
const kept = dropCount > 0
|
|
53
|
+
? [...countable]
|
|
54
|
+
.sort((a, b) => a.percentage - b.percentage)
|
|
55
|
+
.slice(dropCount)
|
|
56
|
+
: countable;
|
|
57
|
+
const totalWeight = kept.reduce((sum, s) => sum + s.weight, 0);
|
|
58
|
+
if (kept.length === 0 || totalWeight <= 0) {
|
|
59
|
+
return { average: null, counted: 0, dropped: 0 };
|
|
60
|
+
}
|
|
61
|
+
const weighted = kept.reduce((sum, s) => sum + s.percentage * s.weight, 0);
|
|
62
|
+
return {
|
|
63
|
+
average: weighted / totalWeight,
|
|
64
|
+
counted: kept.length,
|
|
65
|
+
dropped: dropCount,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Computes the final class grade as the weighted average of category
|
|
70
|
+
* averages. Scores with no category fall into a default category with
|
|
71
|
+
* weight `DEFAULT_CATEGORY.weight`. Categories without counted scores are
|
|
72
|
+
* excluded from the weighted average.
|
|
73
|
+
*/
|
|
74
|
+
export function computeFinalGrade(policies, categories, scores, options) {
|
|
75
|
+
const knownIds = new Set(categories.map((c) => c.id));
|
|
76
|
+
const byCategory = new Map();
|
|
77
|
+
for (const score of scores) {
|
|
78
|
+
const key = score.categoryId !== null && knownIds.has(score.categoryId)
|
|
79
|
+
? score.categoryId
|
|
80
|
+
: null;
|
|
81
|
+
const bucket = byCategory.get(key);
|
|
82
|
+
if (bucket) {
|
|
83
|
+
bucket.push(score);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
byCategory.set(key, [score]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const categoryAverages = [];
|
|
90
|
+
for (const category of categories) {
|
|
91
|
+
const countable = collectCountableScores(byCategory.get(category.id) ?? [], policies);
|
|
92
|
+
const { average, counted, dropped } = averageCategory(countable, category.dropLowest);
|
|
93
|
+
categoryAverages.push({
|
|
94
|
+
categoryId: category.id,
|
|
95
|
+
name: category.name,
|
|
96
|
+
weight: category.weight,
|
|
97
|
+
average,
|
|
98
|
+
countedScores: counted,
|
|
99
|
+
droppedScores: dropped,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const uncategorized = byCategory.get(null) ?? [];
|
|
103
|
+
if (uncategorized.length > 0) {
|
|
104
|
+
const countable = collectCountableScores(uncategorized, policies);
|
|
105
|
+
const { average, counted, dropped } = averageCategory(countable, DEFAULT_CATEGORY.dropLowest);
|
|
106
|
+
categoryAverages.push({
|
|
107
|
+
categoryId: DEFAULT_CATEGORY.id,
|
|
108
|
+
name: options?.defaultCategoryName ?? "Uncategorized",
|
|
109
|
+
weight: DEFAULT_CATEGORY.weight,
|
|
110
|
+
average,
|
|
111
|
+
countedScores: counted,
|
|
112
|
+
droppedScores: dropped,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const contributing = categoryAverages.filter((c) => c.average !== null && c.weight > 0);
|
|
116
|
+
const totalWeight = contributing.reduce((sum, c) => sum + c.weight, 0);
|
|
117
|
+
const percentage = totalWeight > 0
|
|
118
|
+
? roundPercentage(contributing.reduce((sum, c) => sum + c.average * c.weight, 0) / totalWeight, policies.roundingMode)
|
|
119
|
+
: null;
|
|
120
|
+
return { percentage, categories: categoryAverages };
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Maps a percentage to a letter grade using a GradingBoundary `structured`
|
|
124
|
+
* JSON payload (`{ boundaries: [{ grade, minPercentage, maxPercentage }] }`).
|
|
125
|
+
* Returns null when the payload is unparseable or nothing matches.
|
|
126
|
+
*/
|
|
127
|
+
export function resolveLetterGrade(structured, percentage) {
|
|
128
|
+
let boundaries;
|
|
129
|
+
try {
|
|
130
|
+
const parsed = JSON.parse(structured);
|
|
131
|
+
if (!Array.isArray(parsed.boundaries))
|
|
132
|
+
return null;
|
|
133
|
+
boundaries = parsed.boundaries;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const sorted = [...boundaries].sort((a, b) => b.minPercentage - a.minPercentage);
|
|
139
|
+
for (const boundary of sorted) {
|
|
140
|
+
if (typeof boundary.minPercentage === "number" &&
|
|
141
|
+
percentage >= boundary.minPercentage) {
|
|
142
|
+
return boundary.grade ?? null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=gradeCalculation.js.map
|
|
148
|
+
//# debugId=f05b8c2d-15ff-58b1-b01e-d40dba432326
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gradeCalculation.js","sources":["services/gradeCalculation.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Grade calculation – pure functions for computing final class grades from\n * categories, weights, and grade-calculation policies. No I/O; unit-testable.\n *\n * Future policies (standards-based grading, etc.) should extend\n * `GradeCalculationPolicies` and be handled inside `computeFinalGrade` so\n * callers never need to change.\n */\n\nexport type GradeRoundingMode = \"NONE\" | \"HALF_UP\" | \"FLOOR\" | \"CEILING\";\n\nexport interface GradeCalculationPolicies {\n /** Count ungraded/missing scores as 0% instead of excluding them. */\n treatMissingAsZero: boolean;\n /** How the final percentage is rounded to a whole number. */\n roundingMode: GradeRoundingMode;\n}\n\nexport interface GradeCategoryInput {\n id: string;\n name: string;\n /** Relative weight of this category toward the final grade. */\n weight: number;\n /** Number of lowest-percentage scores dropped within this category. */\n dropLowest: number;\n}\n\nexport interface ScoreInput {\n /** Category the score belongs to; null falls into the default category. */\n categoryId: string | null;\n /** Points earned; null means missing/ungraded. */\n pointsEarned: number | null;\n /** Maximum points for the item; items with maxPoints <= 0 are ignored. */\n maxPoints: number;\n /** Relative weight of the item within its category (defaults to 1). */\n weight?: number;\n}\n\nexport interface CategoryAverage {\n categoryId: string | null;\n name: string;\n weight: number;\n /** Percentage 0–100, or null when no scores counted. */\n average: number | null;\n countedScores: number;\n droppedScores: number;\n}\n\nexport interface FinalGradeResult {\n /** Final percentage 0–100 (rounded per policy), or null when no data. */\n percentage: number | null;\n categories: CategoryAverage[];\n}\n\n/** Synthetic category used for scores without a category. */\nexport const DEFAULT_CATEGORY = {\n id: null,\n weight: 1,\n dropLowest: 0,\n} as const;\n\nexport function roundPercentage(\n value: number,\n mode: GradeRoundingMode\n): number {\n switch (mode) {\n case \"HALF_UP\":\n return Math.round(value);\n case \"FLOOR\":\n return Math.floor(value);\n case \"CEILING\":\n return Math.ceil(value);\n case \"NONE\":\n default:\n return value;\n }\n}\n\ninterface CountableScore {\n percentage: number;\n weight: number;\n}\n\nfunction collectCountableScores(\n scores: ScoreInput[],\n policies: GradeCalculationPolicies\n): CountableScore[] {\n const countable: CountableScore[] = [];\n for (const score of scores) {\n if (score.maxPoints <= 0) continue;\n if (score.pointsEarned === null) {\n if (!policies.treatMissingAsZero) continue;\n countable.push({ percentage: 0, weight: score.weight ?? 1 });\n continue;\n }\n countable.push({\n percentage: (score.pointsEarned / score.maxPoints) * 100,\n weight: score.weight ?? 1,\n });\n }\n return countable;\n}\n\nfunction averageCategory(\n countable: CountableScore[],\n dropLowest: number\n): { average: number | null; counted: number; dropped: number } {\n // Always keep at least one score so a category never collapses to null\n // just because dropLowest >= score count.\n const dropCount = Math.min(Math.max(dropLowest, 0), countable.length - 1);\n const kept =\n dropCount > 0\n ? [...countable]\n .sort((a, b) => a.percentage - b.percentage)\n .slice(dropCount)\n : countable;\n\n const totalWeight = kept.reduce((sum, s) => sum + s.weight, 0);\n if (kept.length === 0 || totalWeight <= 0) {\n return { average: null, counted: 0, dropped: 0 };\n }\n\n const weighted = kept.reduce((sum, s) => sum + s.percentage * s.weight, 0);\n return {\n average: weighted / totalWeight,\n counted: kept.length,\n dropped: dropCount,\n };\n}\n\n/**\n * Computes the final class grade as the weighted average of category\n * averages. Scores with no category fall into a default category with\n * weight `DEFAULT_CATEGORY.weight`. Categories without counted scores are\n * excluded from the weighted average.\n */\nexport function computeFinalGrade(\n policies: GradeCalculationPolicies,\n categories: GradeCategoryInput[],\n scores: ScoreInput[],\n options?: { defaultCategoryName?: string }\n): FinalGradeResult {\n const knownIds = new Set(categories.map((c) => c.id));\n const byCategory = new Map<string | null, ScoreInput[]>();\n for (const score of scores) {\n const key =\n score.categoryId !== null && knownIds.has(score.categoryId)\n ? score.categoryId\n : null;\n const bucket = byCategory.get(key);\n if (bucket) {\n bucket.push(score);\n } else {\n byCategory.set(key, [score]);\n }\n }\n\n const categoryAverages: CategoryAverage[] = [];\n\n for (const category of categories) {\n const countable = collectCountableScores(\n byCategory.get(category.id) ?? [],\n policies\n );\n const { average, counted, dropped } = averageCategory(\n countable,\n category.dropLowest\n );\n categoryAverages.push({\n categoryId: category.id,\n name: category.name,\n weight: category.weight,\n average,\n countedScores: counted,\n droppedScores: dropped,\n });\n }\n\n const uncategorized = byCategory.get(null) ?? [];\n if (uncategorized.length > 0) {\n const countable = collectCountableScores(uncategorized, policies);\n const { average, counted, dropped } = averageCategory(\n countable,\n DEFAULT_CATEGORY.dropLowest\n );\n categoryAverages.push({\n categoryId: DEFAULT_CATEGORY.id,\n name: options?.defaultCategoryName ?? \"Uncategorized\",\n weight: DEFAULT_CATEGORY.weight,\n average,\n countedScores: counted,\n droppedScores: dropped,\n });\n }\n\n const contributing = categoryAverages.filter(\n (c) => c.average !== null && c.weight > 0\n );\n const totalWeight = contributing.reduce((sum, c) => sum + c.weight, 0);\n\n const percentage =\n totalWeight > 0\n ? roundPercentage(\n contributing.reduce(\n (sum, c) => sum + (c.average as number) * c.weight,\n 0\n ) / totalWeight,\n policies.roundingMode\n )\n : null;\n\n return { percentage, categories: categoryAverages };\n}\n\ninterface ParsedBoundary {\n grade: string;\n minPercentage: number;\n maxPercentage: number;\n}\n\n/**\n * Maps a percentage to a letter grade using a GradingBoundary `structured`\n * JSON payload (`{ boundaries: [{ grade, minPercentage, maxPercentage }] }`).\n * Returns null when the payload is unparseable or nothing matches.\n */\nexport function resolveLetterGrade(\n structured: string,\n percentage: number\n): string | null {\n let boundaries: ParsedBoundary[];\n try {\n const parsed = JSON.parse(structured) as {\n boundaries?: ParsedBoundary[];\n };\n if (!Array.isArray(parsed.boundaries)) return null;\n boundaries = parsed.boundaries;\n } catch {\n return null;\n }\n\n const sorted = [...boundaries].sort(\n (a, b) => b.minPercentage - a.minPercentage\n );\n for (const boundary of sorted) {\n if (\n typeof boundary.minPercentage === \"number\" &&\n percentage >= boundary.minPercentage\n ) {\n return boundary.grade ?? null;\n }\n }\n return null;\n}\n"],"names":[],"mappings":"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","debug_id":"f05b8c2d-15ff-58b1-b01e-d40dba432326"}
|