@studious-lms/server 1.23.0 → 1.25.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/.env.example +0 -1
- package/data/curriculum/nepal-cdc-g4-g5/README.md +90 -0
- package/data/curriculum/nepal-cdc-g4-g5/manifest.json +97 -0
- package/data/curriculum/nepal-cdc-g4-g5/proficiency-scale.json +76 -0
- package/data/curriculum/nepal-cdc-g4-g5/subjects/english.json +6936 -0
- package/data/curriculum/nepal-cdc-g4-g5/subjects/health-physical-creative-arts.json +3401 -0
- package/data/curriculum/nepal-cdc-g4-g5/subjects/mathematics.json +1511 -0
- package/data/curriculum/nepal-cdc-g4-g5/subjects/nepali.json +7928 -0
- package/data/curriculum/nepal-cdc-g4-g5/subjects/science-technology.json +2420 -0
- package/data/curriculum/nepal-cdc-g4-g5/subjects/social-studies.json +2177 -0
- package/dist/lib/assignmentTypeDefaults.d.ts +41 -0
- package/dist/lib/assignmentTypeDefaults.d.ts.map +1 -0
- package/dist/lib/assignmentTypeDefaults.js +167 -0
- package/dist/lib/assignmentTypeDefaults.js.map +1 -0
- package/dist/lib/config/env.d.ts +0 -8
- package/dist/lib/config/env.d.ts.map +1 -1
- package/dist/lib/config/env.js +2 -5
- package/dist/lib/config/env.js.map +1 -1
- package/dist/lib/feePdf.d.ts +19 -0
- package/dist/lib/feePdf.d.ts.map +1 -0
- package/dist/lib/feePdf.js +167 -0
- package/dist/lib/feePdf.js.map +1 -0
- package/dist/lib/feePdfFormat.d.ts +4 -0
- package/dist/lib/feePdfFormat.d.ts.map +1 -0
- package/dist/lib/feePdfFormat.js +16 -0
- package/dist/lib/feePdfFormat.js.map +1 -0
- package/dist/lib/idCardPdf.d.ts +26 -0
- package/dist/lib/idCardPdf.d.ts.map +1 -0
- package/dist/lib/idCardPdf.js +272 -0
- package/dist/lib/idCardPdf.js.map +1 -0
- package/dist/lib/pdfLetterhead.d.ts +41 -0
- package/dist/lib/pdfLetterhead.d.ts.map +1 -0
- package/dist/lib/pdfLetterhead.js +86 -0
- package/dist/lib/pdfLetterhead.js.map +1 -0
- package/dist/lib/transcriptPdf.d.ts +55 -0
- package/dist/lib/transcriptPdf.d.ts.map +1 -0
- package/dist/lib/transcriptPdf.js +303 -0
- package/dist/lib/transcriptPdf.js.map +1 -0
- package/dist/models/academicCalendar.d.ts +198 -0
- package/dist/models/academicCalendar.d.ts.map +1 -0
- package/dist/models/academicCalendar.js +106 -0
- package/dist/models/academicCalendar.js.map +1 -0
- package/dist/models/agenda.d.ts +8 -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 +66 -0
- package/dist/models/assignment.d.ts.map +1 -1
- package/dist/models/attendance.d.ts +659 -21
- package/dist/models/attendance.d.ts.map +1 -1
- package/dist/models/attendance.js +547 -75
- package/dist/models/attendance.js.map +1 -1
- package/dist/models/auth.d.ts +2 -0
- package/dist/models/auth.d.ts.map +1 -1
- package/dist/models/class.d.ts +12 -0
- package/dist/models/class.d.ts.map +1 -1
- package/dist/models/class.js +3 -2
- package/dist/models/class.js.map +1 -1
- package/dist/models/event.d.ts +16 -0
- package/dist/models/event.d.ts.map +1 -1
- package/dist/models/fees.d.ts +554 -0
- package/dist/models/fees.d.ts.map +1 -0
- package/dist/models/fees.js +278 -0
- package/dist/models/fees.js.map +1 -0
- package/dist/models/file.d.ts +29 -0
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/folder.d.ts +2 -0
- package/dist/models/folder.d.ts.map +1 -1
- package/dist/models/labChat.d.ts +2 -0
- package/dist/models/labChat.d.ts.map +1 -1
- package/dist/models/marketplace.d.ts +180 -0
- package/dist/models/marketplace.d.ts.map +1 -0
- package/dist/models/marketplace.js +116 -0
- package/dist/models/marketplace.js.map +1 -0
- package/dist/models/moduleItem.d.ts +308 -0
- package/dist/models/moduleItem.d.ts.map +1 -0
- package/dist/models/moduleItem.js +93 -0
- package/dist/models/moduleItem.js.map +1 -0
- package/dist/models/newtonChat.d.ts +1 -0
- package/dist/models/newtonChat.d.ts.map +1 -1
- package/dist/models/school.d.ts +18 -0
- package/dist/models/school.d.ts.map +1 -1
- package/dist/models/school.js +7 -2
- package/dist/models/school.js.map +1 -1
- package/dist/models/section.d.ts +4 -0
- package/dist/models/section.d.ts.map +1 -1
- package/dist/models/worksheet.d.ts +19 -0
- package/dist/models/worksheet.d.ts.map +1 -1
- package/dist/models/worksheet.js +2 -2
- package/dist/models/worksheet.js.map +1 -1
- package/dist/routers/_app.d.ts +12024 -7778
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +12 -2
- package/dist/routers/_app.js.map +1 -1
- package/dist/routers/academicCalendar.d.ts +229 -0
- package/dist/routers/academicCalendar.d.ts.map +1 -0
- package/dist/routers/academicCalendar.js +75 -0
- package/dist/routers/academicCalendar.js.map +1 -0
- package/dist/routers/admin.d.ts +2 -0
- package/dist/routers/admin.d.ts.map +1 -1
- package/dist/routers/agenda.d.ts +8 -0
- package/dist/routers/agenda.d.ts.map +1 -1
- package/dist/routers/assignment.d.ts +75 -0
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +10 -2
- package/dist/routers/assignment.js.map +1 -1
- package/dist/routers/attendance.d.ts +103 -0
- package/dist/routers/attendance.d.ts.map +1 -1
- package/dist/routers/attendance.js +8 -5
- package/dist/routers/attendance.js.map +1 -1
- package/dist/routers/class.d.ts +27 -0
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +6 -2
- package/dist/routers/class.js.map +1 -1
- package/dist/routers/event.d.ts +8 -0
- package/dist/routers/event.d.ts.map +1 -1
- package/dist/routers/fees.d.ts +513 -0
- package/dist/routers/fees.d.ts.map +1 -0
- package/dist/routers/fees.js +88 -0
- package/dist/routers/fees.js.map +1 -0
- package/dist/routers/file.d.ts +2 -0
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/gradebook.d.ts +4 -1
- package/dist/routers/gradebook.d.ts.map +1 -1
- package/dist/routers/marketplace.d.ts +371 -0
- package/dist/routers/marketplace.d.ts.map +1 -0
- package/dist/routers/marketplace.js +87 -0
- package/dist/routers/marketplace.js.map +1 -0
- package/dist/routers/moduleItem.d.ts +263 -0
- package/dist/routers/moduleItem.d.ts.map +1 -0
- package/dist/routers/moduleItem.js +61 -0
- package/dist/routers/moduleItem.js.map +1 -0
- package/dist/routers/parent.d.ts +170 -0
- package/dist/routers/parent.d.ts.map +1 -0
- package/dist/routers/parent.js +49 -0
- package/dist/routers/parent.js.map +1 -0
- package/dist/routers/school.d.ts +363 -7
- package/dist/routers/school.d.ts.map +1 -1
- package/dist/routers/school.js +110 -3
- package/dist/routers/school.js.map +1 -1
- package/dist/routers/worksheet.d.ts +27 -0
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/routers/worksheet.js +10 -3
- package/dist/routers/worksheet.js.map +1 -1
- package/dist/services/academicCalendar.d.ts +173 -0
- package/dist/services/academicCalendar.d.ts.map +1 -0
- package/dist/services/academicCalendar.js +242 -0
- package/dist/services/academicCalendar.js.map +1 -0
- package/dist/services/adminInstitution.d.ts +2 -0
- package/dist/services/adminInstitution.d.ts.map +1 -1
- package/dist/services/agenda.d.ts +8 -0
- package/dist/services/agenda.d.ts.map +1 -1
- package/dist/services/assignment.d.ts +75 -0
- package/dist/services/assignment.d.ts.map +1 -1
- package/dist/services/assignment.js +91 -12
- package/dist/services/assignment.js.map +1 -1
- package/dist/services/attendance.d.ts +327 -10
- package/dist/services/attendance.d.ts.map +1 -1
- package/dist/services/attendance.js +389 -25
- package/dist/services/attendance.js.map +1 -1
- package/dist/services/attendanceMerge.d.ts +53 -0
- package/dist/services/attendanceMerge.d.ts.map +1 -0
- package/dist/services/attendanceMerge.js +87 -0
- package/dist/services/attendanceMerge.js.map +1 -0
- package/dist/services/attendanceRate.d.ts +24 -0
- package/dist/services/attendanceRate.d.ts.map +1 -0
- package/dist/services/attendanceRate.js +31 -0
- package/dist/services/attendanceRate.js.map +1 -0
- package/dist/services/attendanceStats.d.ts +22 -0
- package/dist/services/attendanceStats.d.ts.map +1 -0
- package/dist/services/attendanceStats.js +45 -0
- package/dist/services/attendanceStats.js.map +1 -0
- package/dist/services/class.d.ts +34 -2
- package/dist/services/class.d.ts.map +1 -1
- package/dist/services/class.js +27 -4
- package/dist/services/class.js.map +1 -1
- package/dist/services/event.d.ts +8 -0
- package/dist/services/event.d.ts.map +1 -1
- package/dist/services/fees.d.ts +422 -0
- package/dist/services/fees.d.ts.map +1 -0
- package/dist/services/fees.js +330 -0
- package/dist/services/fees.js.map +1 -0
- package/dist/services/feesAuthz.d.ts +46 -0
- package/dist/services/feesAuthz.d.ts.map +1 -0
- package/dist/services/feesAuthz.js +49 -0
- package/dist/services/feesAuthz.js.map +1 -0
- package/dist/services/file.d.ts +4 -0
- package/dist/services/file.d.ts.map +1 -1
- package/dist/services/gradebook.d.ts +18 -1
- package/dist/services/gradebook.d.ts.map +1 -1
- package/dist/services/gradebook.js +57 -2
- package/dist/services/gradebook.js.map +1 -1
- package/dist/services/idCard.d.ts +11 -0
- package/dist/services/idCard.d.ts.map +1 -0
- package/dist/services/idCard.js +122 -0
- package/dist/services/idCard.js.map +1 -0
- package/dist/services/marketplace.d.ts +301 -0
- package/dist/services/marketplace.d.ts.map +1 -0
- package/dist/services/marketplace.js +631 -0
- package/dist/services/marketplace.js.map +1 -0
- package/dist/services/moduleItem.d.ts +196 -0
- package/dist/services/moduleItem.d.ts.map +1 -0
- package/dist/services/moduleItem.js +204 -0
- package/dist/services/moduleItem.js.map +1 -0
- package/dist/services/notification.d.ts +58 -0
- package/dist/services/notification.d.ts.map +1 -1
- package/dist/services/notification.js +30 -2
- package/dist/services/notification.js.map +1 -1
- package/dist/services/parentPortal.d.ts +131 -0
- package/dist/services/parentPortal.d.ts.map +1 -0
- package/dist/services/parentPortal.js +314 -0
- package/dist/services/parentPortal.js.map +1 -0
- package/dist/services/school.d.ts +28 -3
- package/dist/services/school.d.ts.map +1 -1
- package/dist/services/school.js +98 -54
- package/dist/services/school.js.map +1 -1
- package/dist/services/studentImport.d.ts +34 -0
- package/dist/services/studentImport.d.ts.map +1 -0
- package/dist/services/studentImport.js +249 -0
- package/dist/services/studentImport.js.map +1 -0
- package/dist/services/transcript.d.ts +60 -0
- package/dist/services/transcript.d.ts.map +1 -0
- package/dist/services/transcript.js +231 -0
- package/dist/services/transcript.js.map +1 -0
- package/dist/services/worksheet.d.ts +22 -0
- package/dist/services/worksheet.d.ts.map +1 -1
- package/dist/services/worksheet.js +94 -2
- package/dist/services/worksheet.js.map +1 -1
- package/dist/trpc.d.ts +1 -1
- package/dist/trpc.d.ts.map +1 -1
- package/dist/trpc.js +5 -5
- package/dist/trpc.js.map +1 -1
- package/dist/utils/adminPanelAccess.d.ts +4 -5
- package/dist/utils/adminPanelAccess.d.ts.map +1 -1
- package/dist/utils/adminPanelAccess.js +12 -34
- package/dist/utils/adminPanelAccess.js.map +1 -1
- package/package.json +2 -1
- package/prisma/migrations/20260804120000_add_attendance_records_and_excusals/migration.sql +114 -0
- package/prisma/migrations/20260804120100_add_fee_plans_invoices_payments/migration.sql +101 -0
- package/prisma/migrations/20260804120200_add_marketplace_listings/migration.sql +54 -0
- package/prisma/migrations/20260804120300_content_platform_b3_b9/migration.sql +63 -0
- package/prisma/migrations/20260804120400_c_academic_ops/migration.sql +77 -0
- package/prisma/schema.prisma +371 -11
- package/scripts/import-nepal-cdc-curriculum.ts +402 -0
- package/src/lib/assignmentTypeDefaults.ts +222 -0
- package/src/lib/config/env.ts +0 -3
- package/src/lib/feePdf.ts +199 -0
- package/src/lib/feePdfFormat.ts +14 -0
- package/src/lib/idCardPdf.ts +336 -0
- package/src/lib/pdfLetterhead.ts +124 -0
- package/src/lib/transcriptPdf.ts +502 -0
- package/src/models/academicCalendar.ts +139 -0
- package/src/models/attendance.ts +702 -73
- package/src/models/class.ts +1 -0
- package/src/models/fees.ts +349 -0
- package/src/models/marketplace.ts +161 -0
- package/src/models/moduleItem.ts +125 -0
- package/src/models/school.ts +6 -0
- package/src/models/worksheet.ts +2 -0
- package/src/routers/_app.ts +10 -0
- package/src/routers/academicCalendar.ts +103 -0
- package/src/routers/assignment.ts +8 -0
- package/src/routers/attendance.ts +7 -3
- package/src/routers/class.ts +4 -0
- package/src/routers/fees.ts +126 -0
- package/src/routers/marketplace.ts +134 -0
- package/src/routers/moduleItem.ts +91 -0
- package/src/routers/parent.ts +68 -0
- package/src/routers/school.ts +149 -1
- package/src/routers/worksheet.ts +11 -0
- package/src/services/academicCalendar.ts +327 -0
- package/src/services/assignment.ts +122 -12
- package/src/services/attendance.ts +552 -26
- package/src/services/attendanceMerge.ts +139 -0
- package/src/services/attendanceRate.ts +41 -0
- package/src/services/attendanceStats.ts +63 -0
- package/src/services/class.ts +26 -2
- package/src/services/fees.ts +447 -0
- package/src/services/feesAuthz.ts +73 -0
- package/src/services/gradebook.ts +70 -0
- package/src/services/idCard.ts +147 -0
- package/src/services/marketplace.ts +790 -0
- package/src/services/moduleItem.ts +298 -0
- package/src/services/notification.ts +43 -0
- package/src/services/parentPortal.ts +367 -0
- package/src/services/school.ts +100 -54
- package/src/services/studentImport.ts +285 -0
- package/src/services/transcript.ts +301 -0
- package/src/services/worksheet.ts +111 -0
- package/src/trpc.ts +3 -3
- package/src/utils/adminPanelAccess.ts +12 -35
- package/tests/unit/assignmentTypeDefaults.test.ts +52 -0
- package/tests/unit/lib/feePdf.test.ts +15 -0
- package/tests/unit/lib/idCardPdf.test.ts +40 -0
- package/tests/unit/lib/transcriptPdf.test.ts +111 -0
- package/tests/unit/services/attendanceMerge.test.ts +90 -0
- package/tests/unit/services/attendanceRate.test.ts +38 -0
- package/tests/unit/services/attendanceStats.test.ts +54 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build present/late/absent/excused lists + per-student records.
|
|
3
|
+
* Active excusal locks always win (status EXCUSED + excusedByExcusalId set).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
!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]="6e1acd0c-2620-5bd7-a02a-abc12a114aeb")}catch(e){}}();
|
|
7
|
+
export function mergeAttendanceUpdateWithLocks(input) {
|
|
8
|
+
const lockByStudent = new Map(input.locks.map((lock) => [lock.studentId, lock]));
|
|
9
|
+
const lockedStudentIds = [...lockByStudent.keys()];
|
|
10
|
+
const stripLocked = (students) => students.filter((s) => !lockByStudent.has(s.id));
|
|
11
|
+
const presentIds = stripLocked(input.present).map((s) => s.id);
|
|
12
|
+
const lateIds = stripLocked(input.late).map((s) => s.id);
|
|
13
|
+
const absentIds = stripLocked(input.absent).map((s) => s.id);
|
|
14
|
+
const manualExcusedIds = stripLocked(input.excused ?? []).map((s) => s.id);
|
|
15
|
+
const excusedIds = [...new Set([...manualExcusedIds, ...lockedStudentIds])];
|
|
16
|
+
const records = [];
|
|
17
|
+
for (const studentId of presentIds) {
|
|
18
|
+
records.push({
|
|
19
|
+
studentId,
|
|
20
|
+
status: "PRESENT",
|
|
21
|
+
updatedById: input.updatedById,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
for (const studentId of lateIds) {
|
|
25
|
+
records.push({
|
|
26
|
+
studentId,
|
|
27
|
+
status: "LATE",
|
|
28
|
+
updatedById: input.updatedById,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
for (const studentId of absentIds) {
|
|
32
|
+
records.push({
|
|
33
|
+
studentId,
|
|
34
|
+
status: "ABSENT",
|
|
35
|
+
updatedById: input.updatedById,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
for (const studentId of manualExcusedIds) {
|
|
39
|
+
records.push({
|
|
40
|
+
studentId,
|
|
41
|
+
status: "EXCUSED",
|
|
42
|
+
excusedByExcusalId: null,
|
|
43
|
+
updatedById: input.updatedById,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
for (const lock of input.locks) {
|
|
47
|
+
records.push({
|
|
48
|
+
studentId: lock.studentId,
|
|
49
|
+
status: "EXCUSED",
|
|
50
|
+
note: input.existingNotesByStudentId?.get(lock.studentId) ?? lock.note ?? null,
|
|
51
|
+
excusedByExcusalId: lock.excusalId,
|
|
52
|
+
updatedById: input.updatedById,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
presentIds,
|
|
57
|
+
lateIds,
|
|
58
|
+
absentIds,
|
|
59
|
+
excusedIds,
|
|
60
|
+
records,
|
|
61
|
+
lockedStudentIds,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Map active excusals (with student join rows) to per-student locks. */
|
|
65
|
+
export function buildExcusalLocks(excusals, studentIds) {
|
|
66
|
+
const allow = studentIds === undefined ? null : new Set(studentIds);
|
|
67
|
+
const locks = [];
|
|
68
|
+
const seen = new Set();
|
|
69
|
+
for (const excusal of excusals) {
|
|
70
|
+
for (const row of excusal.students) {
|
|
71
|
+
if (allow && !allow.has(row.studentId))
|
|
72
|
+
continue;
|
|
73
|
+
if (seen.has(row.studentId))
|
|
74
|
+
continue;
|
|
75
|
+
seen.add(row.studentId);
|
|
76
|
+
locks.push({
|
|
77
|
+
studentId: row.studentId,
|
|
78
|
+
excusalId: excusal.id,
|
|
79
|
+
reason: excusal.reason,
|
|
80
|
+
note: excusal.note,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return locks;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=attendanceMerge.js.map
|
|
87
|
+
//# debugId=6e1acd0c-2620-5bd7-a02a-abc12a114aeb
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attendanceMerge.js","sources":["services/attendanceMerge.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Pure helpers for merging teacher attendance updates with excusal locks.\n */\nimport type { AttendanceStatus } from \"@prisma/client\";\n\nexport type StudentRef = { id: string; username: string };\n\nexport type AttendanceLock = {\n studentId: string;\n excusalId: string;\n reason?: string | null;\n note?: string | null;\n};\n\nexport type MergedAttendanceUpdate = {\n presentIds: string[];\n lateIds: string[];\n absentIds: string[];\n excusedIds: string[];\n records: Array<{\n studentId: string;\n status: AttendanceStatus;\n note?: string | null;\n excusedByExcusalId?: string | null;\n updatedById?: string | null;\n }>;\n /** Students whose status was forced to EXCUSED by an active excusal. */\n lockedStudentIds: string[];\n};\n\n/**\n * Build present/late/absent/excused lists + per-student records.\n * Active excusal locks always win (status EXCUSED + excusedByExcusalId set).\n */\nexport function mergeAttendanceUpdateWithLocks(input: {\n present: StudentRef[];\n late: StudentRef[];\n absent: StudentRef[];\n excused?: StudentRef[];\n locks: AttendanceLock[];\n updatedById?: string | null;\n /** Preserve notes for locked students when available. */\n existingNotesByStudentId?: Map<string, string | null | undefined>;\n}): MergedAttendanceUpdate {\n const lockByStudent = new Map(input.locks.map((lock) => [lock.studentId, lock]));\n const lockedStudentIds = [...lockByStudent.keys()];\n\n const stripLocked = (students: StudentRef[]) =>\n students.filter((s) => !lockByStudent.has(s.id));\n\n const presentIds = stripLocked(input.present).map((s) => s.id);\n const lateIds = stripLocked(input.late).map((s) => s.id);\n const absentIds = stripLocked(input.absent).map((s) => s.id);\n const manualExcusedIds = stripLocked(input.excused ?? []).map((s) => s.id);\n const excusedIds = [...new Set([...manualExcusedIds, ...lockedStudentIds])];\n\n const records: MergedAttendanceUpdate[\"records\"] = [];\n\n for (const studentId of presentIds) {\n records.push({\n studentId,\n status: \"PRESENT\",\n updatedById: input.updatedById,\n });\n }\n for (const studentId of lateIds) {\n records.push({\n studentId,\n status: \"LATE\",\n updatedById: input.updatedById,\n });\n }\n for (const studentId of absentIds) {\n records.push({\n studentId,\n status: \"ABSENT\",\n updatedById: input.updatedById,\n });\n }\n for (const studentId of manualExcusedIds) {\n records.push({\n studentId,\n status: \"EXCUSED\",\n excusedByExcusalId: null,\n updatedById: input.updatedById,\n });\n }\n for (const lock of input.locks) {\n records.push({\n studentId: lock.studentId,\n status: \"EXCUSED\",\n note:\n input.existingNotesByStudentId?.get(lock.studentId) ?? lock.note ?? null,\n excusedByExcusalId: lock.excusalId,\n updatedById: input.updatedById,\n });\n }\n\n return {\n presentIds,\n lateIds,\n absentIds,\n excusedIds,\n records,\n lockedStudentIds,\n };\n}\n\n/** Map active excusals (with student join rows) to per-student locks. */\nexport function buildExcusalLocks(\n excusals: Array<{\n id: string;\n reason?: string | null;\n note?: string | null;\n students: Array<{ studentId: string }>;\n }>,\n studentIds?: Iterable<string>\n): AttendanceLock[] {\n const allow =\n studentIds === undefined ? null : new Set(studentIds);\n const locks: AttendanceLock[] = [];\n const seen = new Set<string>();\n\n for (const excusal of excusals) {\n for (const row of excusal.students) {\n if (allow && !allow.has(row.studentId)) continue;\n if (seen.has(row.studentId)) continue;\n seen.add(row.studentId);\n locks.push({\n studentId: row.studentId,\n excusalId: excusal.id,\n reason: excusal.reason,\n note: excusal.note,\n });\n }\n }\n\n return locks;\n}\n"],"names":[],"mappings":"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","debug_id":"6e1acd0c-2620-5bd7-a02a-abc12a114aeb"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attendance rate helpers for transcripts / progress reports.
|
|
3
|
+
*
|
|
4
|
+
* Reads the current Attendance M2M shape only (present / late / absent).
|
|
5
|
+
* Do NOT write Attendance schema here — A1 may introduce EXCUSED /
|
|
6
|
+
* AttendanceRecord; keep rate logic in this one place so A1 can extend it.
|
|
7
|
+
*/
|
|
8
|
+
export type AttendanceStatus = "PRESENT" | "LATE" | "ABSENT";
|
|
9
|
+
export interface AttendanceRateSummary {
|
|
10
|
+
present: number;
|
|
11
|
+
late: number;
|
|
12
|
+
absent: number;
|
|
13
|
+
total: number;
|
|
14
|
+
/** (present + late) / total * 100, or null when total is 0. */
|
|
15
|
+
percent: number | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Computes attendance counts and rate from shaped status records.
|
|
19
|
+
* Late counts toward attendance (present for rate purposes).
|
|
20
|
+
*/
|
|
21
|
+
export declare function computeAttendanceRate(records: {
|
|
22
|
+
status: AttendanceStatus;
|
|
23
|
+
}[]): AttendanceRateSummary;
|
|
24
|
+
//# sourceMappingURL=attendanceRate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attendanceRate.d.ts","sourceRoot":"/","sources":["services/attendanceRate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE;IAAE,MAAM,EAAE,gBAAgB,CAAA;CAAE,EAAE,GACtC,qBAAqB,CAevB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attendance rate helpers for transcripts / progress reports.
|
|
3
|
+
*
|
|
4
|
+
* Reads the current Attendance M2M shape only (present / late / absent).
|
|
5
|
+
* Do NOT write Attendance schema here — A1 may introduce EXCUSED /
|
|
6
|
+
* AttendanceRecord; keep rate logic in this one place so A1 can extend it.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Computes attendance counts and rate from shaped status records.
|
|
10
|
+
* Late counts toward attendance (present for rate purposes).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
!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]="3b5d6840-42f1-543a-8bb1-66c2b53ea1ac")}catch(e){}}();
|
|
14
|
+
export function computeAttendanceRate(records) {
|
|
15
|
+
let present = 0;
|
|
16
|
+
let late = 0;
|
|
17
|
+
let absent = 0;
|
|
18
|
+
for (const record of records) {
|
|
19
|
+
if (record.status === "PRESENT")
|
|
20
|
+
present += 1;
|
|
21
|
+
else if (record.status === "LATE")
|
|
22
|
+
late += 1;
|
|
23
|
+
else if (record.status === "ABSENT")
|
|
24
|
+
absent += 1;
|
|
25
|
+
}
|
|
26
|
+
const total = present + late + absent;
|
|
27
|
+
const percent = total === 0 ? null : ((present + late) / total) * 100;
|
|
28
|
+
return { present, late, absent, total, percent };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=attendanceRate.js.map
|
|
31
|
+
//# debugId=3b5d6840-42f1-543a-8bb1-66c2b53ea1ac
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attendanceRate.js","sources":["services/attendanceRate.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Attendance rate helpers for transcripts / progress reports.\n *\n * Reads the current Attendance M2M shape only (present / late / absent).\n * Do NOT write Attendance schema here — A1 may introduce EXCUSED /\n * AttendanceRecord; keep rate logic in this one place so A1 can extend it.\n */\n\nexport type AttendanceStatus = \"PRESENT\" | \"LATE\" | \"ABSENT\";\n\nexport interface AttendanceRateSummary {\n present: number;\n late: number;\n absent: number;\n total: number;\n /** (present + late) / total * 100, or null when total is 0. */\n percent: number | null;\n}\n\n/**\n * Computes attendance counts and rate from shaped status records.\n * Late counts toward attendance (present for rate purposes).\n */\nexport function computeAttendanceRate(\n records: { status: AttendanceStatus }[]\n): AttendanceRateSummary {\n let present = 0;\n let late = 0;\n let absent = 0;\n\n for (const record of records) {\n if (record.status === \"PRESENT\") present += 1;\n else if (record.status === \"LATE\") late += 1;\n else if (record.status === \"ABSENT\") absent += 1;\n }\n\n const total = present + late + absent;\n const percent = total === 0 ? null : ((present + late) / total) * 100;\n\n return { present, late, absent, total, percent };\n}\n"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH;;;GAGG;;;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAuC;IAEvC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,CAAC;aACzC,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;YAAE,IAAI,IAAI,CAAC,CAAC;aACxC,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ;YAAE,MAAM,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;IACtC,MAAM,OAAO,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;IAEtE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACnD,CAAC","debug_id":"3b5d6840-42f1-543a-8bb1-66c2b53ea1ac"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure attendance percentage helpers.
|
|
3
|
+
* EXCUSED days are excluded from both numerator and denominator.
|
|
4
|
+
*/
|
|
5
|
+
import type { AttendanceStatus } from "@prisma/client";
|
|
6
|
+
export type AttendanceStatusCount = {
|
|
7
|
+
present: number;
|
|
8
|
+
late: number;
|
|
9
|
+
absent: number;
|
|
10
|
+
excused: number;
|
|
11
|
+
};
|
|
12
|
+
export declare function emptyAttendanceCounts(): AttendanceStatusCount;
|
|
13
|
+
export declare function tallyAttendanceStatuses(statuses: Iterable<AttendanceStatus | string>): AttendanceStatusCount;
|
|
14
|
+
/**
|
|
15
|
+
* Attendance rate as a percentage.
|
|
16
|
+
* Formula: (present + late) / (present + late + absent) * 100
|
|
17
|
+
* Excused records are ignored entirely.
|
|
18
|
+
* Returns null when there are no countable (non-excused) records.
|
|
19
|
+
*/
|
|
20
|
+
export declare function computeAttendancePercentage(counts: Pick<AttendanceStatusCount, "present" | "late" | "absent">): number | null;
|
|
21
|
+
export declare function computeAttendancePercentageFromStatuses(statuses: Iterable<AttendanceStatus | string>): number | null;
|
|
22
|
+
//# sourceMappingURL=attendanceStats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attendanceStats.d.ts","sourceRoot":"/","sources":["services/attendanceStats.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAgB,qBAAqB,IAAI,qBAAqB,CAE7D;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,GAAG,MAAM,CAAC,GAC5C,qBAAqB,CAqBvB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC,GACjE,MAAM,GAAG,IAAI,CAMf;AAED,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,QAAQ,CAAC,gBAAgB,GAAG,MAAM,CAAC,GAC5C,MAAM,GAAG,IAAI,CAEf"}
|
|
@@ -0,0 +1,45 @@
|
|
|
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]="06540105-70ee-5c9c-b347-8a5eed8f020d")}catch(e){}}();
|
|
3
|
+
export function emptyAttendanceCounts() {
|
|
4
|
+
return { present: 0, late: 0, absent: 0, excused: 0 };
|
|
5
|
+
}
|
|
6
|
+
export function tallyAttendanceStatuses(statuses) {
|
|
7
|
+
const counts = emptyAttendanceCounts();
|
|
8
|
+
for (const status of statuses) {
|
|
9
|
+
switch (status) {
|
|
10
|
+
case "PRESENT":
|
|
11
|
+
counts.present += 1;
|
|
12
|
+
break;
|
|
13
|
+
case "LATE":
|
|
14
|
+
counts.late += 1;
|
|
15
|
+
break;
|
|
16
|
+
case "ABSENT":
|
|
17
|
+
counts.absent += 1;
|
|
18
|
+
break;
|
|
19
|
+
case "EXCUSED":
|
|
20
|
+
counts.excused += 1;
|
|
21
|
+
break;
|
|
22
|
+
default:
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return counts;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Attendance rate as a percentage.
|
|
30
|
+
* Formula: (present + late) / (present + late + absent) * 100
|
|
31
|
+
* Excused records are ignored entirely.
|
|
32
|
+
* Returns null when there are no countable (non-excused) records.
|
|
33
|
+
*/
|
|
34
|
+
export function computeAttendancePercentage(counts) {
|
|
35
|
+
const countable = counts.present + counts.late + counts.absent;
|
|
36
|
+
if (countable === 0) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return ((counts.present + counts.late) / countable) * 100;
|
|
40
|
+
}
|
|
41
|
+
export function computeAttendancePercentageFromStatuses(statuses) {
|
|
42
|
+
return computeAttendancePercentage(tallyAttendanceStatuses(statuses));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=attendanceStats.js.map
|
|
45
|
+
//# debugId=06540105-70ee-5c9c-b347-8a5eed8f020d
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attendanceStats.js","sources":["services/attendanceStats.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Pure attendance percentage helpers.\n * EXCUSED days are excluded from both numerator and denominator.\n */\nimport type { AttendanceStatus } from \"@prisma/client\";\n\nexport type AttendanceStatusCount = {\n present: number;\n late: number;\n absent: number;\n excused: number;\n};\n\nexport function emptyAttendanceCounts(): AttendanceStatusCount {\n return { present: 0, late: 0, absent: 0, excused: 0 };\n}\n\nexport function tallyAttendanceStatuses(\n statuses: Iterable<AttendanceStatus | string>\n): AttendanceStatusCount {\n const counts = emptyAttendanceCounts();\n for (const status of statuses) {\n switch (status) {\n case \"PRESENT\":\n counts.present += 1;\n break;\n case \"LATE\":\n counts.late += 1;\n break;\n case \"ABSENT\":\n counts.absent += 1;\n break;\n case \"EXCUSED\":\n counts.excused += 1;\n break;\n default:\n break;\n }\n }\n return counts;\n}\n\n/**\n * Attendance rate as a percentage.\n * Formula: (present + late) / (present + late + absent) * 100\n * Excused records are ignored entirely.\n * Returns null when there are no countable (non-excused) records.\n */\nexport function computeAttendancePercentage(\n counts: Pick<AttendanceStatusCount, \"present\" | \"late\" | \"absent\">\n): number | null {\n const countable = counts.present + counts.late + counts.absent;\n if (countable === 0) {\n return null;\n }\n return ((counts.present + counts.late) / countable) * 100;\n}\n\nexport function computeAttendancePercentageFromStatuses(\n statuses: Iterable<AttendanceStatus | string>\n): number | null {\n return computeAttendancePercentage(tallyAttendanceStatuses(statuses));\n}\n"],"names":[],"mappings":";;AAaA,MAAM,UAAU,qBAAqB;IACnC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,QAA6C;IAE7C,MAAM,MAAM,GAAG,qBAAqB,EAAE,CAAC;IACvC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,QAAQ,MAAM,EAAE,CAAC;YACf,KAAK,SAAS;gBACZ,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;gBACpB,MAAM;YACR,KAAK,MAAM;gBACT,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;gBACjB,MAAM;YACR,KAAK,QAAQ;gBACX,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;gBACnB,MAAM;YACR,KAAK,SAAS;gBACZ,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;gBACpB,MAAM;YACR;gBACE,MAAM;QACV,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CACzC,MAAkE;IAElE,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/D,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,uCAAuC,CACrD,QAA6C;IAE7C,OAAO,2BAA2B,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC;AACxE,CAAC","debug_id":"06540105-70ee-5c9c-b347-8a5eed8f020d"}
|
package/dist/services/class.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Class service – CRUD for classes, members, grades, mark schemes, grading boundaries,
|
|
3
|
+
* syllabus, lab drafts, and invite codes.
|
|
4
|
+
*/
|
|
5
|
+
import { Prisma } from "@prisma/client";
|
|
1
6
|
import { Class, Folder } from "@prisma/client";
|
|
2
7
|
/** Get all classes where user is teacher or student, with assignments and members. */
|
|
3
8
|
export declare function getAllClasses(userId: string): Promise<{
|
|
@@ -226,6 +231,7 @@ export declare function getClass(userId: string, classId: string): Promise<{
|
|
|
226
231
|
discussionsEnabled: boolean;
|
|
227
232
|
studentsCanCreateDiscussions: boolean;
|
|
228
233
|
studentsCanReply: boolean;
|
|
234
|
+
sidebarFeatures: Prisma.JsonValue | null;
|
|
229
235
|
treatMissingAsZero: boolean;
|
|
230
236
|
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
231
237
|
};
|
|
@@ -240,18 +246,24 @@ export declare function updateClass(classId: string, data: {
|
|
|
240
246
|
discussionsEnabled?: boolean;
|
|
241
247
|
studentsCanCreateDiscussions?: boolean;
|
|
242
248
|
studentsCanReply?: boolean;
|
|
249
|
+
sidebarFeatures?: Record<string, boolean> | null;
|
|
243
250
|
}): Promise<{
|
|
244
251
|
updatedClass: {
|
|
245
252
|
symbol: string | null;
|
|
246
253
|
section: string;
|
|
247
254
|
id: string;
|
|
248
255
|
name: string;
|
|
256
|
+
schoolId: string | null;
|
|
249
257
|
color: string | null;
|
|
250
258
|
subject: string;
|
|
259
|
+
syllabus: string | null;
|
|
251
260
|
departmentId: string | null;
|
|
252
261
|
discussionsEnabled: boolean;
|
|
253
262
|
studentsCanCreateDiscussions: boolean;
|
|
254
263
|
studentsCanReply: boolean;
|
|
264
|
+
sidebarFeatures: Prisma.JsonValue | null;
|
|
265
|
+
treatMissingAsZero: boolean;
|
|
266
|
+
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
255
267
|
};
|
|
256
268
|
}>;
|
|
257
269
|
export declare function createClass(userId: string, input: {
|
|
@@ -298,6 +310,7 @@ export declare function createClass(userId: string, input: {
|
|
|
298
310
|
discussionsEnabled: boolean;
|
|
299
311
|
studentsCanCreateDiscussions: boolean;
|
|
300
312
|
studentsCanReply: boolean;
|
|
313
|
+
sidebarFeatures: Prisma.JsonValue | null;
|
|
301
314
|
treatMissingAsZero: boolean;
|
|
302
315
|
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
303
316
|
}>;
|
|
@@ -332,6 +345,7 @@ export declare function changeRole(classId: string, userId: string, type: "teach
|
|
|
332
345
|
discussionsEnabled: boolean;
|
|
333
346
|
studentsCanCreateDiscussions: boolean;
|
|
334
347
|
studentsCanReply: boolean;
|
|
348
|
+
sidebarFeatures: Prisma.JsonValue | null;
|
|
335
349
|
treatMissingAsZero: boolean;
|
|
336
350
|
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
337
351
|
};
|
|
@@ -355,6 +369,7 @@ export declare function removeMember(classId: string, userId: string): Promise<{
|
|
|
355
369
|
discussionsEnabled: boolean;
|
|
356
370
|
studentsCanCreateDiscussions: boolean;
|
|
357
371
|
studentsCanReply: boolean;
|
|
372
|
+
sidebarFeatures: Prisma.JsonValue | null;
|
|
358
373
|
treatMissingAsZero: boolean;
|
|
359
374
|
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
360
375
|
};
|
|
@@ -529,6 +544,7 @@ export declare function updateSyllabus(classId: string, contents: string): Promi
|
|
|
529
544
|
discussionsEnabled: boolean;
|
|
530
545
|
studentsCanCreateDiscussions: boolean;
|
|
531
546
|
studentsCanReply: boolean;
|
|
547
|
+
sidebarFeatures: Prisma.JsonValue | null;
|
|
532
548
|
treatMissingAsZero: boolean;
|
|
533
549
|
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
534
550
|
}>;
|
|
@@ -558,6 +574,9 @@ export declare function listLabDrafts(classId: string, teacherId: string): Promi
|
|
|
558
574
|
order: number | null;
|
|
559
575
|
gradingBoundaryId: string | null;
|
|
560
576
|
gradeCategoryId: string | null;
|
|
577
|
+
timeLimitMinutes: number | null;
|
|
578
|
+
singleAttempt: boolean;
|
|
579
|
+
allowLateSubmissions: boolean;
|
|
561
580
|
}[]>;
|
|
562
581
|
export declare function createLabDraft(classId: string, teacherId: string, input: {
|
|
563
582
|
title: string;
|
|
@@ -596,6 +615,9 @@ export declare function createLabDraft(classId: string, teacherId: string, input
|
|
|
596
615
|
order: number | null;
|
|
597
616
|
gradingBoundaryId: string | null;
|
|
598
617
|
gradeCategoryId: string | null;
|
|
618
|
+
timeLimitMinutes: number | null;
|
|
619
|
+
singleAttempt: boolean;
|
|
620
|
+
allowLateSubmissions: boolean;
|
|
599
621
|
}>;
|
|
600
622
|
export declare function updateLabDraft(classId: string, teacherId: string, draftId: string, input: Record<string, unknown>): Promise<{
|
|
601
623
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
@@ -623,6 +645,9 @@ export declare function updateLabDraft(classId: string, teacherId: string, draft
|
|
|
623
645
|
order: number | null;
|
|
624
646
|
gradingBoundaryId: string | null;
|
|
625
647
|
gradeCategoryId: string | null;
|
|
648
|
+
timeLimitMinutes: number | null;
|
|
649
|
+
singleAttempt: boolean;
|
|
650
|
+
allowLateSubmissions: boolean;
|
|
626
651
|
}>;
|
|
627
652
|
export declare function deleteLabDraft(classId: string, teacherId: string, draftId: string): Promise<{
|
|
628
653
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
@@ -650,6 +675,9 @@ export declare function deleteLabDraft(classId: string, teacherId: string, draft
|
|
|
650
675
|
order: number | null;
|
|
651
676
|
gradingBoundaryId: string | null;
|
|
652
677
|
gradeCategoryId: string | null;
|
|
678
|
+
timeLimitMinutes: number | null;
|
|
679
|
+
singleAttempt: boolean;
|
|
680
|
+
allowLateSubmissions: boolean;
|
|
653
681
|
}>;
|
|
654
682
|
export declare function publishLabDraft(classId: string, teacherId: string, draftId: string, input: {
|
|
655
683
|
dueDate?: Date;
|
|
@@ -682,6 +710,9 @@ export declare function publishLabDraft(classId: string, teacherId: string, draf
|
|
|
682
710
|
order: number | null;
|
|
683
711
|
gradingBoundaryId: string | null;
|
|
684
712
|
gradeCategoryId: string | null;
|
|
713
|
+
timeLimitMinutes: number | null;
|
|
714
|
+
singleAttempt: boolean;
|
|
715
|
+
allowLateSubmissions: boolean;
|
|
685
716
|
}>;
|
|
686
717
|
export declare function getFiles(classId: string): Promise<{
|
|
687
718
|
id: string;
|
|
@@ -788,8 +819,8 @@ export declare function exportClass(classId: string, userId: string): Promise<{
|
|
|
788
819
|
classId: string;
|
|
789
820
|
questions: {
|
|
790
821
|
type: import(".prisma/client").$Enums.WorksheetQuestionType;
|
|
791
|
-
options:
|
|
792
|
-
markScheme:
|
|
822
|
+
options: Prisma.JsonValue;
|
|
823
|
+
markScheme: Prisma.JsonValue;
|
|
793
824
|
points: number;
|
|
794
825
|
question: string;
|
|
795
826
|
worksheetId: string;
|
|
@@ -819,6 +850,7 @@ export declare function exportClass(classId: string, userId: string): Promise<{
|
|
|
819
850
|
discussionsEnabled: boolean;
|
|
820
851
|
studentsCanCreateDiscussions: boolean;
|
|
821
852
|
studentsCanReply: boolean;
|
|
853
|
+
sidebarFeatures: Prisma.JsonValue | null;
|
|
822
854
|
treatMissingAsZero: boolean;
|
|
823
855
|
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
824
856
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"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"}
|
package/dist/services/class.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* syllabus, lab drafts, and invite codes.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
!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]="
|
|
7
|
-
import { SessionType } from "@prisma/client";
|
|
6
|
+
!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]="838e82cf-2053-5dee-a9f1-bc5d20761f0d")}catch(e){}}();
|
|
7
|
+
import { Prisma, SessionType } from "@prisma/client";
|
|
8
8
|
import { TRPCError } from "@trpc/server";
|
|
9
9
|
import { prisma } from "../lib/prisma.js";
|
|
10
10
|
import { generateInviteCode } from "../utils/generateInviteCode.js";
|
|
@@ -173,7 +173,29 @@ export async function updateClass(classId, data) {
|
|
|
173
173
|
}
|
|
174
174
|
const updatedClass = await prisma.class.update({
|
|
175
175
|
where: { id: classId },
|
|
176
|
-
|
|
176
|
+
// Prisma Exact<> rejects mixed relation/unchecked shapes; pass unchecked scalars.
|
|
177
|
+
data: {
|
|
178
|
+
...(data.name !== undefined && { name: data.name }),
|
|
179
|
+
...(data.section !== undefined && { section: data.section }),
|
|
180
|
+
...(data.subject !== undefined && { subject: data.subject }),
|
|
181
|
+
...(data.color !== undefined && { color: data.color }),
|
|
182
|
+
...(data.symbol !== undefined && { symbol: data.symbol }),
|
|
183
|
+
...(data.departmentId !== undefined && {
|
|
184
|
+
departmentId: data.departmentId,
|
|
185
|
+
}),
|
|
186
|
+
...(data.discussionsEnabled !== undefined && {
|
|
187
|
+
discussionsEnabled: data.discussionsEnabled,
|
|
188
|
+
}),
|
|
189
|
+
...(data.studentsCanCreateDiscussions !== undefined && {
|
|
190
|
+
studentsCanCreateDiscussions: data.studentsCanCreateDiscussions,
|
|
191
|
+
}),
|
|
192
|
+
...(data.studentsCanReply !== undefined && {
|
|
193
|
+
studentsCanReply: data.studentsCanReply,
|
|
194
|
+
}),
|
|
195
|
+
...(data.sidebarFeatures !== undefined && {
|
|
196
|
+
sidebarFeatures: data.sidebarFeatures ?? Prisma.DbNull,
|
|
197
|
+
}),
|
|
198
|
+
},
|
|
177
199
|
select: {
|
|
178
200
|
id: true,
|
|
179
201
|
name: true,
|
|
@@ -185,6 +207,7 @@ export async function updateClass(classId, data) {
|
|
|
185
207
|
discussionsEnabled: true,
|
|
186
208
|
studentsCanCreateDiscussions: true,
|
|
187
209
|
studentsCanReply: true,
|
|
210
|
+
sidebarFeatures: true,
|
|
188
211
|
},
|
|
189
212
|
});
|
|
190
213
|
return { updatedClass };
|
|
@@ -655,4 +678,4 @@ export async function importClass(classId, userId, year, classData) {
|
|
|
655
678
|
}
|
|
656
679
|
}
|
|
657
680
|
//# sourceMappingURL=class.js.map
|
|
658
|
-
//# debugId=
|
|
681
|
+
//# debugId=838e82cf-2053-5dee-a9f1-bc5d20761f0d
|