@studious-lms/server 1.22.0 → 1.24.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 +544 -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 +178 -0
- package/dist/models/marketplace.d.ts.map +1 -0
- package/dist/models/marketplace.js +115 -0
- package/dist/models/marketplace.js.map +1 -0
- package/dist/models/moduleItem.d.ts +304 -0
- package/dist/models/moduleItem.d.ts.map +1 -0
- package/dist/models/moduleItem.js +78 -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 +193 -0
- package/dist/models/school.d.ts.map +1 -1
- package/dist/models/school.js +80 -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 +11605 -7133
- 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 +60 -0
- package/dist/routers/moduleItem.js.map +1 -0
- package/dist/routers/parent.d.ts +169 -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 +476 -6
- package/dist/routers/school.d.ts.map +1 -1
- package/dist/routers/school.js +130 -4
- 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 +214 -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 +323 -10
- package/dist/services/attendance.d.ts.map +1 -1
- package/dist/services/attendance.js +385 -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 +27 -0
- package/dist/services/class.d.ts.map +1 -1
- package/dist/services/class.js +26 -3
- 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 +310 -0
- package/dist/services/fees.js.map +1 -0
- package/dist/services/feesAuthz.d.ts +49 -0
- package/dist/services/feesAuthz.d.ts.map +1 -0
- package/dist/services/feesAuthz.js +52 -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 +628 -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 +188 -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 +133 -0
- package/dist/services/parentPortal.d.ts.map +1 -0
- package/dist/services/parentPortal.js +328 -0
- package/dist/services/parentPortal.js.map +1 -0
- package/dist/services/school.d.ts +122 -3
- package/dist/services/school.d.ts.map +1 -1
- package/dist/services/school.js +179 -47
- 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 +236 -0
- package/dist/services/studentImport.js.map +1 -0
- package/dist/services/transcript.d.ts +61 -0
- package/dist/services/transcript.d.ts.map +1 -0
- package/dist/services/transcript.js +243 -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 +379 -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 +704 -73
- package/src/models/class.ts +1 -0
- package/src/models/fees.ts +349 -0
- package/src/models/marketplace.ts +158 -0
- package/src/models/moduleItem.ts +107 -0
- package/src/models/school.ts +95 -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 +89 -0
- package/src/routers/parent.ts +68 -0
- package/src/routers/school.ts +184 -1
- package/src/routers/worksheet.ts +11 -0
- package/src/services/academicCalendar.ts +299 -0
- package/src/services/assignment.ts +122 -12
- package/src/services/attendance.ts +548 -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 +25 -1
- package/src/services/fees.ts +424 -0
- package/src/services/feesAuthz.ts +77 -0
- package/src/services/gradebook.ts +70 -0
- package/src/services/idCard.ts +147 -0
- package/src/services/marketplace.ts +785 -0
- package/src/services/moduleItem.ts +274 -0
- package/src/services/notification.ts +43 -0
- package/src/services/parentPortal.ts +380 -0
- package/src/services/school.ts +243 -45
- package/src/services/studentImport.ts +273 -0
- package/src/services/transcript.ts +313 -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
|
@@ -11,6 +11,9 @@ export declare function getCurrentSchool(userId: string, schoolId?: string): Pro
|
|
|
11
11
|
logoId: string | null;
|
|
12
12
|
logoPath: string | null;
|
|
13
13
|
logoType: string | null;
|
|
14
|
+
letterheadFileId: string | null;
|
|
15
|
+
letterheadPath: string | null;
|
|
16
|
+
letterheadType: string | null;
|
|
14
17
|
} | null;
|
|
15
18
|
activeRole: import(".prisma/client").$Enums.SchoolMembershipRole | null;
|
|
16
19
|
memberships: ({
|
|
@@ -21,12 +24,19 @@ export declare function getCurrentSchool(userId: string, schoolId?: string): Pro
|
|
|
21
24
|
name: string;
|
|
22
25
|
description: string | null;
|
|
23
26
|
logoId: string | null;
|
|
27
|
+
letterheadFileId: string | null;
|
|
24
28
|
subdomain: string | null;
|
|
25
29
|
logo: {
|
|
26
30
|
path: string;
|
|
27
31
|
type: string;
|
|
28
32
|
id: string;
|
|
29
33
|
} | null;
|
|
34
|
+
letterhead: {
|
|
35
|
+
path: string;
|
|
36
|
+
type: string;
|
|
37
|
+
id: string;
|
|
38
|
+
name: string;
|
|
39
|
+
} | null;
|
|
30
40
|
};
|
|
31
41
|
} & {
|
|
32
42
|
status: import(".prisma/client").$Enums.SchoolMembershipStatus;
|
|
@@ -61,6 +71,7 @@ export declare function createSchoolRecord(userId: string, input: {
|
|
|
61
71
|
name: string;
|
|
62
72
|
description: string | null;
|
|
63
73
|
logoId: string | null;
|
|
74
|
+
letterheadFileId: string | null;
|
|
64
75
|
subdomain: string | null;
|
|
65
76
|
};
|
|
66
77
|
}>;
|
|
@@ -70,12 +81,14 @@ export declare function updateSchoolDetails(userId: string, input: {
|
|
|
70
81
|
description?: string | null;
|
|
71
82
|
subdomain?: string | null;
|
|
72
83
|
logoId?: string | null;
|
|
84
|
+
letterheadFileId?: string | null;
|
|
73
85
|
}): Promise<{
|
|
74
86
|
school: {
|
|
75
87
|
id: string;
|
|
76
88
|
name: string;
|
|
77
89
|
description: string | null;
|
|
78
90
|
logoId: string | null;
|
|
91
|
+
letterheadFileId: string | null;
|
|
79
92
|
subdomain: string | null;
|
|
80
93
|
};
|
|
81
94
|
}>;
|
|
@@ -88,6 +101,8 @@ export declare function getAdminOverview(userId: string, schoolId: string): Prom
|
|
|
88
101
|
ADMIN: number;
|
|
89
102
|
TEACHER: number;
|
|
90
103
|
STUDENT: number;
|
|
104
|
+
ACCOUNTANT: number;
|
|
105
|
+
PARENT: number;
|
|
91
106
|
classes: number;
|
|
92
107
|
members: number;
|
|
93
108
|
pendingInvites: number;
|
|
@@ -110,6 +125,23 @@ export declare function getAdminOverview(userId: string, schoolId: string): Prom
|
|
|
110
125
|
expiresAt: Date;
|
|
111
126
|
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
112
127
|
}[];
|
|
128
|
+
recentMembers: {
|
|
129
|
+
status: import(".prisma/client").$Enums.SchoolMembershipStatus;
|
|
130
|
+
user: {
|
|
131
|
+
id: string;
|
|
132
|
+
username: string;
|
|
133
|
+
email: string;
|
|
134
|
+
profile: {
|
|
135
|
+
profilePicture: string | null;
|
|
136
|
+
displayName: string | null;
|
|
137
|
+
profilePictureThumbnail: string | null;
|
|
138
|
+
} | null;
|
|
139
|
+
};
|
|
140
|
+
id: string;
|
|
141
|
+
createdAt: Date;
|
|
142
|
+
updatedAt: Date;
|
|
143
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
144
|
+
}[];
|
|
113
145
|
};
|
|
114
146
|
}>;
|
|
115
147
|
export declare function listClasses(userId: string, schoolId: string): Promise<{
|
|
@@ -144,6 +176,7 @@ export declare function listClasses(userId: string, schoolId: string): Promise<{
|
|
|
144
176
|
discussionsEnabled: boolean;
|
|
145
177
|
studentsCanCreateDiscussions: boolean;
|
|
146
178
|
studentsCanReply: boolean;
|
|
179
|
+
sidebarFeatures: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
147
180
|
treatMissingAsZero: boolean;
|
|
148
181
|
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
149
182
|
})[];
|
|
@@ -193,6 +226,7 @@ export declare function createSchoolClass(userId: string, input: {
|
|
|
193
226
|
discussionsEnabled: boolean;
|
|
194
227
|
studentsCanCreateDiscussions: boolean;
|
|
195
228
|
studentsCanReply: boolean;
|
|
229
|
+
sidebarFeatures: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
196
230
|
treatMissingAsZero: boolean;
|
|
197
231
|
gradeRoundingMode: import(".prisma/client").$Enums.GradeRoundingMode;
|
|
198
232
|
};
|
|
@@ -246,6 +280,83 @@ export declare function updateMemberRole(userId: string, input: {
|
|
|
246
280
|
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
247
281
|
};
|
|
248
282
|
}>;
|
|
283
|
+
export declare function getMemberDetail(userId: string, input: {
|
|
284
|
+
schoolId: string;
|
|
285
|
+
memberUserId: string;
|
|
286
|
+
}): Promise<{
|
|
287
|
+
membership: {
|
|
288
|
+
status: import(".prisma/client").$Enums.SchoolMembershipStatus;
|
|
289
|
+
user: {
|
|
290
|
+
id: string;
|
|
291
|
+
username: string;
|
|
292
|
+
email: string;
|
|
293
|
+
profile: {
|
|
294
|
+
profilePicture: string | null;
|
|
295
|
+
displayName: string | null;
|
|
296
|
+
profilePictureThumbnail: string | null;
|
|
297
|
+
} | null;
|
|
298
|
+
};
|
|
299
|
+
id: string;
|
|
300
|
+
createdAt: Date;
|
|
301
|
+
updatedAt: Date;
|
|
302
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
303
|
+
};
|
|
304
|
+
teachingClasses: {
|
|
305
|
+
id: string;
|
|
306
|
+
name: string;
|
|
307
|
+
section: string;
|
|
308
|
+
subject: string;
|
|
309
|
+
color: string | null;
|
|
310
|
+
teacherCount: number;
|
|
311
|
+
studentCount: number;
|
|
312
|
+
}[];
|
|
313
|
+
enrolledClasses: {
|
|
314
|
+
id: string;
|
|
315
|
+
name: string;
|
|
316
|
+
section: string;
|
|
317
|
+
subject: string;
|
|
318
|
+
color: string | null;
|
|
319
|
+
teacherCount: number;
|
|
320
|
+
studentCount: number;
|
|
321
|
+
}[];
|
|
322
|
+
}>;
|
|
323
|
+
export declare function bulkUpdateMemberRoles(userId: string, input: {
|
|
324
|
+
schoolId: string;
|
|
325
|
+
memberUserIds: string[];
|
|
326
|
+
role: SchoolMembershipRole;
|
|
327
|
+
}): Promise<{
|
|
328
|
+
updatedCount: number;
|
|
329
|
+
}>;
|
|
330
|
+
export declare function bulkRemoveMembers(userId: string, input: {
|
|
331
|
+
schoolId: string;
|
|
332
|
+
memberUserIds: string[];
|
|
333
|
+
}): Promise<{
|
|
334
|
+
removedCount: number;
|
|
335
|
+
}>;
|
|
336
|
+
export declare function deleteSchoolClass(userId: string, input: {
|
|
337
|
+
schoolId: string;
|
|
338
|
+
classId: string;
|
|
339
|
+
}): Promise<{
|
|
340
|
+
deletedClass: {
|
|
341
|
+
id: string;
|
|
342
|
+
};
|
|
343
|
+
}>;
|
|
344
|
+
export declare function updateClassMembers(userId: string, input: {
|
|
345
|
+
schoolId: string;
|
|
346
|
+
classId: string;
|
|
347
|
+
addTeacherIds?: string[];
|
|
348
|
+
removeTeacherIds?: string[];
|
|
349
|
+
addStudentIds?: string[];
|
|
350
|
+
removeStudentIds?: string[];
|
|
351
|
+
}): Promise<{
|
|
352
|
+
class: {
|
|
353
|
+
id: string;
|
|
354
|
+
_count: {
|
|
355
|
+
teachers: number;
|
|
356
|
+
students: number;
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
}>;
|
|
249
360
|
export declare function removeMember(userId: string, input: {
|
|
250
361
|
schoolId: string;
|
|
251
362
|
memberUserId: string;
|
|
@@ -290,7 +401,7 @@ export declare function confirmSchoolAssetUpload(userId: string, fileId: string,
|
|
|
290
401
|
*/
|
|
291
402
|
export declare function listMemberIds(userId: string, schoolId: string): Promise<string[]>;
|
|
292
403
|
/** Search active institution members by username, displayName, or email. */
|
|
293
|
-
export declare function searchMembers(userId: string, schoolId: string, query: string, limit?: number, role?:
|
|
404
|
+
export declare function searchMembers(userId: string, schoolId: string, query: string, limit?: number, role?: SchoolMembershipRole): Promise<{
|
|
294
405
|
id: string;
|
|
295
406
|
username: string;
|
|
296
407
|
profile: {
|
|
@@ -360,13 +471,17 @@ export declare function getStudentTimeline(userId: string, input: {
|
|
|
360
471
|
}[];
|
|
361
472
|
attendance: {
|
|
362
473
|
id: string;
|
|
474
|
+
recordId: string;
|
|
363
475
|
date: Date;
|
|
364
476
|
class: {
|
|
365
477
|
id: string;
|
|
366
478
|
name: string;
|
|
367
479
|
color: string | null;
|
|
368
480
|
};
|
|
369
|
-
status: "
|
|
481
|
+
status: import(".prisma/client").$Enums.AttendanceStatus;
|
|
482
|
+
note: string | null;
|
|
483
|
+
lockedFromExcusal: boolean;
|
|
484
|
+
reason: string | null;
|
|
370
485
|
}[];
|
|
371
486
|
}>;
|
|
372
487
|
/**
|
|
@@ -437,13 +552,17 @@ export declare function getMemberTimeline(userId: string, input: {
|
|
|
437
552
|
}[];
|
|
438
553
|
attendance: {
|
|
439
554
|
id: string;
|
|
555
|
+
recordId: string;
|
|
440
556
|
date: Date;
|
|
441
557
|
class: {
|
|
442
558
|
id: string;
|
|
443
559
|
name: string;
|
|
444
560
|
color: string | null;
|
|
445
561
|
};
|
|
446
|
-
status: "
|
|
562
|
+
status: import(".prisma/client").$Enums.AttendanceStatus;
|
|
563
|
+
note: string | null;
|
|
564
|
+
lockedFromExcusal: boolean;
|
|
565
|
+
reason: string | null;
|
|
447
566
|
}[];
|
|
448
567
|
classes?: undefined;
|
|
449
568
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"school.d.ts","sourceRoot":"/","sources":["services/school.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,oBAAoB,EAAe,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"school.d.ts","sourceRoot":"/","sources":["services/school.ts"],"names":[],"mappings":"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"}
|
package/dist/services/school.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* School service - school admin workflow, memberships, and invites.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
!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]="
|
|
5
|
+
!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]="63d2144c-911d-56ab-8693-f7615b26334e")}catch(e){}}();
|
|
6
6
|
import { SessionType } from "@prisma/client";
|
|
7
7
|
import { TRPCError } from "@trpc/server";
|
|
8
8
|
import { hash } from "bcryptjs";
|
|
@@ -14,7 +14,7 @@ import { generateUniqueUsername } from "../utils/generateUsername.js";
|
|
|
14
14
|
import { logger } from "../utils/logger.js";
|
|
15
15
|
import { createSession, createUser, findUserByEmail, findUserById, findUserByUsername, } from "../models/auth.js";
|
|
16
16
|
import { upsertUserProfile } from "../models/user.js";
|
|
17
|
-
import { acceptSchoolInvite, countActiveAdmins, createSchoolInvite, createSchoolWithAdmin, findActiveSchoolAdminMembership, findPendingInviteByToken, findSchoolMembership, getSchoolOverview, listSchoolClasses, listSchoolInvites, listSchoolMembers, listUserSchoolMemberships, removeSchoolMembershipPreservingContent, revokeSchoolInvite, updateSchoolMembershipRole, updateSchoolRecord, upsertSchoolMembership, } from "../models/school.js";
|
|
17
|
+
import { acceptSchoolInvite, countActiveAdmins, createSchoolInvite, createSchoolWithAdmin, deleteSchoolClassRecord, findActiveSchoolAdminMembership, findPendingInviteByToken, findSchoolClass, findSchoolMembership, getSchoolMemberDetail, getSchoolOverview, listActiveSchoolMemberships, listMemberClasses, listRecentSchoolMembers, listSchoolClasses, listSchoolInvites, listSchoolMembers, listUserSchoolMemberships, removeSchoolMembershipPreservingContent, revokeSchoolInvite, updateSchoolClassMembers, updateSchoolMembershipRole, updateSchoolRecord, upsertSchoolMembership, } from "../models/school.js";
|
|
18
18
|
async function requireSchoolAdmin(schoolId, userId) {
|
|
19
19
|
const membership = await findActiveSchoolAdminMembership(schoolId, userId);
|
|
20
20
|
if (!membership) {
|
|
@@ -51,6 +51,9 @@ export async function getCurrentSchool(userId, schoolId) {
|
|
|
51
51
|
// signed URL through trpc.file.getSignedUrl when needed.
|
|
52
52
|
logoPath: activeMembership.school.logo?.path ?? null,
|
|
53
53
|
logoType: activeMembership.school.logo?.type ?? null,
|
|
54
|
+
letterheadFileId: activeMembership.school.letterheadFileId ?? null,
|
|
55
|
+
letterheadPath: activeMembership.school.letterhead?.path ?? null,
|
|
56
|
+
letterheadType: activeMembership.school.letterhead?.type ?? null,
|
|
54
57
|
}
|
|
55
58
|
: null;
|
|
56
59
|
return {
|
|
@@ -78,19 +81,29 @@ export async function updateSchoolDetails(userId, input) {
|
|
|
78
81
|
description: input.description,
|
|
79
82
|
subdomain: input.subdomain,
|
|
80
83
|
logoId: input.logoId,
|
|
84
|
+
letterheadFileId: input.letterheadFileId,
|
|
81
85
|
});
|
|
82
86
|
return { school: updated };
|
|
83
87
|
}
|
|
84
88
|
export async function getAdminOverview(userId, schoolId) {
|
|
85
89
|
await requireSchoolAdmin(schoolId, userId);
|
|
86
|
-
const school = await
|
|
90
|
+
const [school, recentMembers] = await Promise.all([
|
|
91
|
+
getSchoolOverview(schoolId),
|
|
92
|
+
listRecentSchoolMembers(schoolId),
|
|
93
|
+
]);
|
|
87
94
|
if (!school) {
|
|
88
95
|
throw new TRPCError({ code: "NOT_FOUND", message: "School not found" });
|
|
89
96
|
}
|
|
90
97
|
const roleCounts = school.memberships.reduce((counts, membership) => {
|
|
91
98
|
counts[membership.role] += 1;
|
|
92
99
|
return counts;
|
|
93
|
-
}, {
|
|
100
|
+
}, {
|
|
101
|
+
ADMIN: 0,
|
|
102
|
+
TEACHER: 0,
|
|
103
|
+
STUDENT: 0,
|
|
104
|
+
ACCOUNTANT: 0,
|
|
105
|
+
PARENT: 0,
|
|
106
|
+
});
|
|
94
107
|
return {
|
|
95
108
|
school: {
|
|
96
109
|
id: school.id,
|
|
@@ -104,6 +117,7 @@ export async function getAdminOverview(userId, schoolId) {
|
|
|
104
117
|
},
|
|
105
118
|
recentClasses: school.classes,
|
|
106
119
|
recentInvites: school.invites,
|
|
120
|
+
recentMembers,
|
|
107
121
|
},
|
|
108
122
|
};
|
|
109
123
|
}
|
|
@@ -176,6 +190,114 @@ export async function updateMemberRole(userId, input) {
|
|
|
176
190
|
const membership = await updateSchoolMembershipRole(input.schoolId, input.memberUserId, input.role);
|
|
177
191
|
return { membership };
|
|
178
192
|
}
|
|
193
|
+
export async function getMemberDetail(userId, input) {
|
|
194
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
195
|
+
const membership = await getSchoolMemberDetail(input.schoolId, input.memberUserId);
|
|
196
|
+
if (!membership) {
|
|
197
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "Member not found" });
|
|
198
|
+
}
|
|
199
|
+
const [teachingClasses, enrolledClasses] = await listMemberClasses(input.schoolId, input.memberUserId);
|
|
200
|
+
const toClassSummary = (cls) => ({
|
|
201
|
+
id: cls.id,
|
|
202
|
+
name: cls.name,
|
|
203
|
+
section: cls.section,
|
|
204
|
+
subject: cls.subject,
|
|
205
|
+
color: cls.color,
|
|
206
|
+
teacherCount: cls._count.teachers,
|
|
207
|
+
studentCount: cls._count.students,
|
|
208
|
+
});
|
|
209
|
+
return {
|
|
210
|
+
membership,
|
|
211
|
+
teachingClasses: teachingClasses.map(toClassSummary),
|
|
212
|
+
enrolledClasses: enrolledClasses.map(toClassSummary),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
export async function bulkUpdateMemberRoles(userId, input) {
|
|
216
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
217
|
+
const memberships = await listActiveSchoolMemberships(input.schoolId, input.memberUserIds);
|
|
218
|
+
if (memberships.length === 0) {
|
|
219
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "No members found" });
|
|
220
|
+
}
|
|
221
|
+
if (input.role !== "ADMIN") {
|
|
222
|
+
const demotedAdmins = memberships.filter((m) => m.role === "ADMIN").length;
|
|
223
|
+
if (demotedAdmins > 0) {
|
|
224
|
+
const adminCount = await countActiveAdmins(input.schoolId);
|
|
225
|
+
if (adminCount - demotedAdmins < 1) {
|
|
226
|
+
throw new TRPCError({
|
|
227
|
+
code: "BAD_REQUEST",
|
|
228
|
+
message: "A school must have at least one active admin",
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
await prisma.schoolMembership.updateMany({
|
|
234
|
+
where: {
|
|
235
|
+
schoolId: input.schoolId,
|
|
236
|
+
userId: { in: memberships.map((m) => m.userId) },
|
|
237
|
+
status: "ACTIVE",
|
|
238
|
+
},
|
|
239
|
+
data: { role: input.role },
|
|
240
|
+
});
|
|
241
|
+
return { updatedCount: memberships.length };
|
|
242
|
+
}
|
|
243
|
+
export async function bulkRemoveMembers(userId, input) {
|
|
244
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
245
|
+
const targetIds = input.memberUserIds.filter((id) => id !== userId);
|
|
246
|
+
const memberships = await listActiveSchoolMemberships(input.schoolId, targetIds);
|
|
247
|
+
if (memberships.length === 0) {
|
|
248
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "No members found" });
|
|
249
|
+
}
|
|
250
|
+
const removedAdmins = memberships.filter((m) => m.role === "ADMIN").length;
|
|
251
|
+
if (removedAdmins > 0) {
|
|
252
|
+
const adminCount = await countActiveAdmins(input.schoolId);
|
|
253
|
+
if (adminCount - removedAdmins < 1) {
|
|
254
|
+
throw new TRPCError({
|
|
255
|
+
code: "BAD_REQUEST",
|
|
256
|
+
message: "A school must have at least one active admin",
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
for (const membership of memberships) {
|
|
261
|
+
await removeSchoolMembershipPreservingContent(input.schoolId, membership.userId);
|
|
262
|
+
}
|
|
263
|
+
return { removedCount: memberships.length };
|
|
264
|
+
}
|
|
265
|
+
export async function deleteSchoolClass(userId, input) {
|
|
266
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
267
|
+
const cls = await findSchoolClass(input.schoolId, input.classId);
|
|
268
|
+
if (!cls) {
|
|
269
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "Class not found" });
|
|
270
|
+
}
|
|
271
|
+
await deleteSchoolClassRecord(input.schoolId, input.classId);
|
|
272
|
+
return { deletedClass: { id: input.classId } };
|
|
273
|
+
}
|
|
274
|
+
export async function updateClassMembers(userId, input) {
|
|
275
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
276
|
+
const cls = await findSchoolClass(input.schoolId, input.classId);
|
|
277
|
+
if (!cls) {
|
|
278
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "Class not found" });
|
|
279
|
+
}
|
|
280
|
+
const addTeacherIds = input.addTeacherIds ?? [];
|
|
281
|
+
const addStudentIds = input.addStudentIds ?? [];
|
|
282
|
+
const addedIds = [...addTeacherIds, ...addStudentIds];
|
|
283
|
+
if (addedIds.length > 0) {
|
|
284
|
+
const memberships = await listActiveSchoolMemberships(input.schoolId, addedIds);
|
|
285
|
+
const activeIds = new Set(memberships.map((m) => m.userId));
|
|
286
|
+
if (addedIds.some((id) => !activeIds.has(id))) {
|
|
287
|
+
throw new TRPCError({
|
|
288
|
+
code: "BAD_REQUEST",
|
|
289
|
+
message: "All added users must be active members of this school",
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const updated = await updateSchoolClassMembers(input.classId, {
|
|
294
|
+
addTeacherIds,
|
|
295
|
+
removeTeacherIds: input.removeTeacherIds ?? [],
|
|
296
|
+
addStudentIds,
|
|
297
|
+
removeStudentIds: input.removeStudentIds ?? [],
|
|
298
|
+
});
|
|
299
|
+
return { class: updated };
|
|
300
|
+
}
|
|
179
301
|
export async function removeMember(userId, input) {
|
|
180
302
|
await requireSchoolAdmin(input.schoolId, userId);
|
|
181
303
|
const current = await findSchoolMembership(input.schoolId, input.memberUserId);
|
|
@@ -372,35 +494,40 @@ export async function getStudentTimeline(userId, input) {
|
|
|
372
494
|
},
|
|
373
495
|
orderBy: { dueDate: "asc" },
|
|
374
496
|
}),
|
|
375
|
-
prisma.
|
|
497
|
+
prisma.attendanceRecord.findMany({
|
|
376
498
|
where: {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
...(hasRange ? { date: range } : {}),
|
|
499
|
+
studentId: input.studentId,
|
|
500
|
+
attendance: {
|
|
501
|
+
class: { schoolId: input.schoolId },
|
|
502
|
+
...(hasRange ? { date: range } : {}),
|
|
503
|
+
},
|
|
383
504
|
},
|
|
384
505
|
select: {
|
|
385
506
|
id: true,
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
507
|
+
status: true,
|
|
508
|
+
note: true,
|
|
509
|
+
excusedByExcusalId: true,
|
|
510
|
+
attendance: {
|
|
511
|
+
select: {
|
|
512
|
+
id: true,
|
|
513
|
+
date: true,
|
|
514
|
+
class: { select: { id: true, name: true, color: true } },
|
|
515
|
+
},
|
|
516
|
+
},
|
|
517
|
+
excusedByExcusal: { select: { id: true, reason: true } },
|
|
391
518
|
},
|
|
392
|
-
orderBy: { date: "asc" },
|
|
519
|
+
orderBy: { attendance: { date: "asc" } },
|
|
393
520
|
}),
|
|
394
521
|
]);
|
|
395
522
|
const attendanceShaped = attendance.map((record) => ({
|
|
396
|
-
id: record.id,
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
523
|
+
id: record.attendance.id,
|
|
524
|
+
recordId: record.id,
|
|
525
|
+
date: record.attendance.date,
|
|
526
|
+
class: record.attendance.class,
|
|
527
|
+
status: record.status,
|
|
528
|
+
note: record.note,
|
|
529
|
+
lockedFromExcusal: Boolean(record.excusedByExcusalId),
|
|
530
|
+
reason: record.excusedByExcusal?.reason ?? null,
|
|
404
531
|
}));
|
|
405
532
|
return {
|
|
406
533
|
student: studentMembership.user,
|
|
@@ -524,35 +651,40 @@ export async function getMemberTimeline(userId, input) {
|
|
|
524
651
|
},
|
|
525
652
|
orderBy: { dueDate: "asc" },
|
|
526
653
|
}),
|
|
527
|
-
prisma.
|
|
654
|
+
prisma.attendanceRecord.findMany({
|
|
528
655
|
where: {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
...(hasRange ? { date: range } : {}),
|
|
656
|
+
studentId: input.memberId,
|
|
657
|
+
attendance: {
|
|
658
|
+
class: { schoolId: input.schoolId },
|
|
659
|
+
...(hasRange ? { date: range } : {}),
|
|
660
|
+
},
|
|
535
661
|
},
|
|
536
662
|
select: {
|
|
537
663
|
id: true,
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
664
|
+
status: true,
|
|
665
|
+
note: true,
|
|
666
|
+
excusedByExcusalId: true,
|
|
667
|
+
attendance: {
|
|
668
|
+
select: {
|
|
669
|
+
id: true,
|
|
670
|
+
date: true,
|
|
671
|
+
class: { select: { id: true, name: true, color: true } },
|
|
672
|
+
},
|
|
673
|
+
},
|
|
674
|
+
excusedByExcusal: { select: { id: true, reason: true } },
|
|
543
675
|
},
|
|
544
|
-
orderBy: { date: "asc" },
|
|
676
|
+
orderBy: { attendance: { date: "asc" } },
|
|
545
677
|
}),
|
|
546
678
|
]);
|
|
547
679
|
const attendanceShaped = attendance.map((record) => ({
|
|
548
|
-
id: record.id,
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
680
|
+
id: record.attendance.id,
|
|
681
|
+
recordId: record.id,
|
|
682
|
+
date: record.attendance.date,
|
|
683
|
+
class: record.attendance.class,
|
|
684
|
+
status: record.status,
|
|
685
|
+
note: record.note,
|
|
686
|
+
lockedFromExcusal: Boolean(record.excusedByExcusalId),
|
|
687
|
+
reason: record.excusedByExcusal?.reason ?? null,
|
|
556
688
|
}));
|
|
557
689
|
return {
|
|
558
690
|
role: "STUDENT",
|
|
@@ -753,4 +885,4 @@ export async function acceptInvite(userId, token) {
|
|
|
753
885
|
return { membership };
|
|
754
886
|
}
|
|
755
887
|
//# sourceMappingURL=school.js.map
|
|
756
|
-
//# debugId=
|
|
888
|
+
//# debugId=63d2144c-911d-56ab-8693-f7615b26334e
|