@studious-lms/server 1.4.6 → 1.4.7
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/dist/models/access.d.ts +112 -0
- package/dist/models/access.d.ts.map +1 -0
- package/dist/models/access.js +49 -0
- package/dist/models/access.js.map +1 -0
- package/dist/models/announcement.d.ts +17 -2
- package/dist/models/announcement.d.ts.map +1 -1
- package/dist/models/announcement.js +21 -4
- package/dist/models/announcement.js.map +1 -1
- package/dist/models/assignment.d.ts +37 -37
- package/dist/models/assignment.d.ts.map +1 -1
- package/dist/models/assignment.js +15 -15
- package/dist/models/assignment.js.map +1 -1
- package/dist/models/attendance.d.ts +1 -1
- package/dist/models/attendance.d.ts.map +1 -1
- package/dist/models/attendance.js +6 -5
- package/dist/models/attendance.js.map +1 -1
- package/dist/models/auth.d.ts +5 -5
- package/dist/models/auth.d.ts.map +1 -1
- package/dist/models/auth.js +7 -11
- package/dist/models/auth.js.map +1 -1
- package/dist/models/class.d.ts +26 -26
- package/dist/models/class.d.ts.map +1 -1
- package/dist/models/class.js +7 -11
- package/dist/models/class.js.map +1 -1
- package/dist/models/comment.d.ts +134 -70
- package/dist/models/comment.d.ts.map +1 -1
- package/dist/models/comment.js +30 -42
- package/dist/models/comment.js.map +1 -1
- package/dist/models/conversation.d.ts +7 -7
- package/dist/models/event.d.ts +52 -3
- package/dist/models/event.d.ts.map +1 -1
- package/dist/models/event.js +56 -6
- package/dist/models/event.js.map +1 -1
- package/dist/models/file.d.ts +178 -103
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/file.js +54 -14
- package/dist/models/file.js.map +1 -1
- package/dist/models/folder.d.ts +22 -22
- package/dist/models/folder.d.ts.map +1 -1
- package/dist/models/folder.js +5 -4
- package/dist/models/folder.js.map +1 -1
- package/dist/models/labChat.d.ts +20 -20
- package/dist/models/labChat.d.ts.map +1 -1
- package/dist/models/labChat.js +8 -10
- package/dist/models/labChat.js.map +1 -1
- package/dist/models/marketing.d.ts +1 -1
- package/dist/models/message.d.ts +6 -6
- package/dist/models/newtonChat.d.ts +5 -5
- package/dist/models/school.d.ts +361 -0
- package/dist/models/school.d.ts.map +1 -0
- package/dist/models/school.js +314 -0
- package/dist/models/school.js.map +1 -0
- package/dist/models/section.d.ts +1 -1
- package/dist/models/section.d.ts.map +1 -1
- package/dist/models/section.js +5 -4
- package/dist/models/section.js.map +1 -1
- package/dist/models/user.d.ts +4 -4
- package/dist/models/worksheet.d.ts +65 -65
- package/dist/models/worksheet.d.ts.map +1 -1
- package/dist/models/worksheet.js +6 -14
- package/dist/models/worksheet.js.map +1 -1
- package/dist/pipelines/gradeWorksheet.d.ts +2 -2
- package/dist/pipelines/pdfToWorksheet.d.ts +1 -1
- package/dist/routers/_app.d.ts +2855 -2051
- 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/announcement.d.ts +5 -5
- package/dist/routers/announcement.d.ts.map +1 -1
- package/dist/routers/announcement.js +25 -5
- package/dist/routers/announcement.js.map +1 -1
- package/dist/routers/assignment.d.ts +44 -44
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +24 -11
- package/dist/routers/assignment.js.map +1 -1
- package/dist/routers/class.d.ts +21 -20
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +3 -2
- package/dist/routers/class.js.map +1 -1
- package/dist/routers/comment.d.ts +5 -5
- package/dist/routers/conversation.d.ts +6 -6
- package/dist/routers/event.d.ts +21 -2
- package/dist/routers/event.d.ts.map +1 -1
- package/dist/routers/file.d.ts +2 -2
- package/dist/routers/folder.d.ts +24 -24
- package/dist/routers/labChat.d.ts +7 -7
- package/dist/routers/school.d.ts +384 -0
- package/dist/routers/school.d.ts.map +1 -0
- package/dist/routers/school.js +79 -0
- package/dist/routers/school.js.map +1 -0
- package/dist/routers/search.d.ts +1 -1
- package/dist/routers/worksheet.d.ts +21 -21
- package/dist/services/announcement.d.ts.map +1 -1
- package/dist/services/announcement.js +10 -6
- package/dist/services/announcement.js.map +1 -1
- package/dist/services/assignment.d.ts +36 -36
- package/dist/services/class.d.ts +20 -19
- package/dist/services/class.d.ts.map +1 -1
- package/dist/services/class.js +22 -3
- package/dist/services/class.js.map +1 -1
- package/dist/services/comment.d.ts +5 -5
- package/dist/services/comment.d.ts.map +1 -1
- package/dist/services/comment.js +8 -3
- package/dist/services/comment.js.map +1 -1
- package/dist/services/conversation.d.ts +6 -6
- package/dist/services/event.d.ts +21 -2
- package/dist/services/event.d.ts.map +1 -1
- package/dist/services/event.js +11 -7
- package/dist/services/event.js.map +1 -1
- package/dist/services/file.d.ts +2 -2
- package/dist/services/file.d.ts.map +1 -1
- package/dist/services/file.js +17 -8
- package/dist/services/file.js.map +1 -1
- package/dist/services/folder.d.ts +24 -24
- package/dist/services/labChat.d.ts +7 -7
- package/dist/services/school.d.ts +299 -0
- package/dist/services/school.d.ts.map +1 -0
- package/dist/services/school.js +225 -0
- package/dist/services/school.js.map +1 -0
- package/dist/services/worksheet.d.ts +21 -21
- package/package.json +1 -1
- package/prisma/migrations/20260504071500_school_memberships/migration.sql +81 -0
- package/prisma/schema.prisma +66 -2
- package/src/models/access.ts +48 -0
- package/src/models/announcement.ts +19 -2
- package/src/models/assignment.ts +17 -13
- package/src/models/attendance.ts +4 -3
- package/src/models/auth.ts +8 -9
- package/src/models/class.ts +8 -9
- package/src/models/comment.ts +29 -40
- package/src/models/event.ts +54 -4
- package/src/models/file.ts +53 -12
- package/src/models/folder.ts +3 -2
- package/src/models/labChat.ts +9 -8
- package/src/models/school.ts +361 -0
- package/src/models/section.ts +3 -2
- package/src/models/worksheet.ts +7 -12
- package/src/routers/_app.ts +2 -0
- package/src/routers/announcement.ts +30 -4
- package/src/routers/assignment.ts +27 -9
- package/src/routers/class.ts +1 -0
- package/src/routers/school.ts +122 -0
- package/src/services/announcement.ts +12 -4
- package/src/services/class.ts +25 -2
- package/src/services/comment.ts +10 -1
- package/src/services/event.ts +23 -6
- package/src/services/file.ts +20 -6
- package/src/services/school.ts +308 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* School service - school admin workflow, memberships, and invites.
|
|
3
|
+
*/
|
|
4
|
+
import { SchoolMembershipRole } from "@prisma/client";
|
|
5
|
+
export declare function getCurrentSchool(userId: string, schoolId?: string): Promise<{
|
|
6
|
+
activeSchool: {
|
|
7
|
+
name: string;
|
|
8
|
+
id: string;
|
|
9
|
+
logoId: string | null;
|
|
10
|
+
subdomain: string | null;
|
|
11
|
+
createdAt: Date;
|
|
12
|
+
updatedAt: Date;
|
|
13
|
+
} | null;
|
|
14
|
+
activeRole: import(".prisma/client").$Enums.SchoolMembershipRole | null;
|
|
15
|
+
memberships: ({
|
|
16
|
+
school: {
|
|
17
|
+
name: string;
|
|
18
|
+
id: string;
|
|
19
|
+
logoId: string | null;
|
|
20
|
+
subdomain: string | null;
|
|
21
|
+
createdAt: Date;
|
|
22
|
+
updatedAt: Date;
|
|
23
|
+
};
|
|
24
|
+
} & {
|
|
25
|
+
status: import(".prisma/client").$Enums.SchoolMembershipStatus;
|
|
26
|
+
id: string;
|
|
27
|
+
createdAt: Date;
|
|
28
|
+
updatedAt: Date;
|
|
29
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
30
|
+
schoolId: string;
|
|
31
|
+
userId: string;
|
|
32
|
+
})[];
|
|
33
|
+
}>;
|
|
34
|
+
export declare function createSchoolRecord(userId: string, input: {
|
|
35
|
+
name: string;
|
|
36
|
+
subdomain?: string;
|
|
37
|
+
logoId?: string;
|
|
38
|
+
}): Promise<{
|
|
39
|
+
school: {
|
|
40
|
+
memberships: {
|
|
41
|
+
status: import(".prisma/client").$Enums.SchoolMembershipStatus;
|
|
42
|
+
id: string;
|
|
43
|
+
createdAt: Date;
|
|
44
|
+
updatedAt: Date;
|
|
45
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
46
|
+
schoolId: string;
|
|
47
|
+
userId: string;
|
|
48
|
+
}[];
|
|
49
|
+
} & {
|
|
50
|
+
name: string;
|
|
51
|
+
id: string;
|
|
52
|
+
logoId: string | null;
|
|
53
|
+
subdomain: string | null;
|
|
54
|
+
createdAt: Date;
|
|
55
|
+
updatedAt: Date;
|
|
56
|
+
};
|
|
57
|
+
}>;
|
|
58
|
+
export declare function getAdminOverview(userId: string, schoolId: string): Promise<{
|
|
59
|
+
school: {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
subdomain: string | null;
|
|
63
|
+
counts: {
|
|
64
|
+
ADMIN: number;
|
|
65
|
+
TEACHER: number;
|
|
66
|
+
STUDENT: number;
|
|
67
|
+
classes: number;
|
|
68
|
+
members: number;
|
|
69
|
+
pendingInvites: number;
|
|
70
|
+
};
|
|
71
|
+
recentClasses: {
|
|
72
|
+
name: string;
|
|
73
|
+
id: string;
|
|
74
|
+
subject: string;
|
|
75
|
+
color: string | null;
|
|
76
|
+
section: string;
|
|
77
|
+
_count: {
|
|
78
|
+
teachers: number;
|
|
79
|
+
students: number;
|
|
80
|
+
};
|
|
81
|
+
}[];
|
|
82
|
+
recentInvites: {
|
|
83
|
+
id: string;
|
|
84
|
+
createdAt: Date;
|
|
85
|
+
email: string;
|
|
86
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
87
|
+
expiresAt: Date;
|
|
88
|
+
}[];
|
|
89
|
+
};
|
|
90
|
+
}>;
|
|
91
|
+
export declare function listClasses(userId: string, schoolId: string): Promise<{
|
|
92
|
+
classes: ({
|
|
93
|
+
_count: {
|
|
94
|
+
assignments: number;
|
|
95
|
+
teachers: number;
|
|
96
|
+
students: number;
|
|
97
|
+
};
|
|
98
|
+
teachers: {
|
|
99
|
+
id: string;
|
|
100
|
+
username: string;
|
|
101
|
+
profile: {
|
|
102
|
+
displayName: string | null;
|
|
103
|
+
profilePicture: string | null;
|
|
104
|
+
profilePictureThumbnail: string | null;
|
|
105
|
+
} | null;
|
|
106
|
+
}[];
|
|
107
|
+
students: {
|
|
108
|
+
id: string;
|
|
109
|
+
}[];
|
|
110
|
+
} & {
|
|
111
|
+
name: string;
|
|
112
|
+
id: string;
|
|
113
|
+
schoolId: string | null;
|
|
114
|
+
subject: string;
|
|
115
|
+
color: string | null;
|
|
116
|
+
section: string;
|
|
117
|
+
syllabus: string | null;
|
|
118
|
+
})[];
|
|
119
|
+
}>;
|
|
120
|
+
export declare function createSchoolClass(userId: string, input: {
|
|
121
|
+
schoolId: string;
|
|
122
|
+
name: string;
|
|
123
|
+
section: string;
|
|
124
|
+
subject: string;
|
|
125
|
+
color?: string;
|
|
126
|
+
teachers?: string[];
|
|
127
|
+
students?: string[];
|
|
128
|
+
}): Promise<{
|
|
129
|
+
class: {
|
|
130
|
+
teachers: {
|
|
131
|
+
id: string;
|
|
132
|
+
username: string;
|
|
133
|
+
email: string;
|
|
134
|
+
password: string;
|
|
135
|
+
verified: boolean;
|
|
136
|
+
role: import(".prisma/client").$Enums.UserRole;
|
|
137
|
+
schoolId: string | null;
|
|
138
|
+
}[];
|
|
139
|
+
students: {
|
|
140
|
+
id: string;
|
|
141
|
+
username: string;
|
|
142
|
+
email: string;
|
|
143
|
+
password: string;
|
|
144
|
+
verified: boolean;
|
|
145
|
+
role: import(".prisma/client").$Enums.UserRole;
|
|
146
|
+
schoolId: string | null;
|
|
147
|
+
}[];
|
|
148
|
+
} & {
|
|
149
|
+
name: string;
|
|
150
|
+
id: string;
|
|
151
|
+
schoolId: string | null;
|
|
152
|
+
subject: string;
|
|
153
|
+
color: string | null;
|
|
154
|
+
section: string;
|
|
155
|
+
syllabus: string | null;
|
|
156
|
+
};
|
|
157
|
+
}>;
|
|
158
|
+
export declare function listMembers(userId: string, schoolId: string): Promise<{
|
|
159
|
+
members: {
|
|
160
|
+
status: import(".prisma/client").$Enums.SchoolMembershipStatus;
|
|
161
|
+
id: string;
|
|
162
|
+
createdAt: Date;
|
|
163
|
+
updatedAt: Date;
|
|
164
|
+
user: {
|
|
165
|
+
id: string;
|
|
166
|
+
username: string;
|
|
167
|
+
email: string;
|
|
168
|
+
profile: {
|
|
169
|
+
displayName: string | null;
|
|
170
|
+
profilePicture: string | null;
|
|
171
|
+
profilePictureThumbnail: string | null;
|
|
172
|
+
} | null;
|
|
173
|
+
};
|
|
174
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
175
|
+
}[];
|
|
176
|
+
}>;
|
|
177
|
+
export declare function addMember(userId: string, input: {
|
|
178
|
+
schoolId: string;
|
|
179
|
+
memberUserId: string;
|
|
180
|
+
role: SchoolMembershipRole;
|
|
181
|
+
}): Promise<{
|
|
182
|
+
membership: {
|
|
183
|
+
status: import(".prisma/client").$Enums.SchoolMembershipStatus;
|
|
184
|
+
id: string;
|
|
185
|
+
createdAt: Date;
|
|
186
|
+
updatedAt: Date;
|
|
187
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
188
|
+
schoolId: string;
|
|
189
|
+
userId: string;
|
|
190
|
+
};
|
|
191
|
+
}>;
|
|
192
|
+
export declare function updateMemberRole(userId: string, input: {
|
|
193
|
+
schoolId: string;
|
|
194
|
+
memberUserId: string;
|
|
195
|
+
role: SchoolMembershipRole;
|
|
196
|
+
}): Promise<{
|
|
197
|
+
membership: {
|
|
198
|
+
status: import(".prisma/client").$Enums.SchoolMembershipStatus;
|
|
199
|
+
id: string;
|
|
200
|
+
createdAt: Date;
|
|
201
|
+
updatedAt: Date;
|
|
202
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
203
|
+
schoolId: string;
|
|
204
|
+
userId: string;
|
|
205
|
+
};
|
|
206
|
+
}>;
|
|
207
|
+
export declare function removeMember(userId: string, input: {
|
|
208
|
+
schoolId: string;
|
|
209
|
+
memberUserId: string;
|
|
210
|
+
}): Promise<{
|
|
211
|
+
success: boolean;
|
|
212
|
+
}>;
|
|
213
|
+
export declare function listInvites(userId: string, schoolId: string): Promise<{
|
|
214
|
+
invites: {
|
|
215
|
+
status: import(".prisma/client").$Enums.SchoolInviteStatus;
|
|
216
|
+
id: string;
|
|
217
|
+
createdAt: Date;
|
|
218
|
+
email: string;
|
|
219
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
220
|
+
expiresAt: Date;
|
|
221
|
+
acceptedAt: Date | null;
|
|
222
|
+
revokedAt: Date | null;
|
|
223
|
+
invitedBy: {
|
|
224
|
+
id: string;
|
|
225
|
+
username: string;
|
|
226
|
+
profile: {
|
|
227
|
+
displayName: string | null;
|
|
228
|
+
} | null;
|
|
229
|
+
};
|
|
230
|
+
}[];
|
|
231
|
+
}>;
|
|
232
|
+
export declare function createInvite(userId: string, input: {
|
|
233
|
+
schoolId: string;
|
|
234
|
+
email: string;
|
|
235
|
+
role: SchoolMembershipRole;
|
|
236
|
+
}): Promise<{
|
|
237
|
+
invite: {
|
|
238
|
+
school: {
|
|
239
|
+
name: string;
|
|
240
|
+
id: string;
|
|
241
|
+
};
|
|
242
|
+
} & {
|
|
243
|
+
status: import(".prisma/client").$Enums.SchoolInviteStatus;
|
|
244
|
+
id: string;
|
|
245
|
+
createdAt: Date;
|
|
246
|
+
updatedAt: Date;
|
|
247
|
+
email: string;
|
|
248
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
249
|
+
schoolId: string;
|
|
250
|
+
token: string;
|
|
251
|
+
expiresAt: Date;
|
|
252
|
+
acceptedAt: Date | null;
|
|
253
|
+
revokedAt: Date | null;
|
|
254
|
+
invitedById: string;
|
|
255
|
+
};
|
|
256
|
+
}>;
|
|
257
|
+
export declare function revokeInvite(userId: string, input: {
|
|
258
|
+
schoolId: string;
|
|
259
|
+
inviteId: string;
|
|
260
|
+
}): Promise<{
|
|
261
|
+
invite: {
|
|
262
|
+
status: import(".prisma/client").$Enums.SchoolInviteStatus;
|
|
263
|
+
id: string;
|
|
264
|
+
createdAt: Date;
|
|
265
|
+
updatedAt: Date;
|
|
266
|
+
email: string;
|
|
267
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
268
|
+
schoolId: string;
|
|
269
|
+
token: string;
|
|
270
|
+
expiresAt: Date;
|
|
271
|
+
acceptedAt: Date | null;
|
|
272
|
+
revokedAt: Date | null;
|
|
273
|
+
invitedById: string;
|
|
274
|
+
};
|
|
275
|
+
}>;
|
|
276
|
+
export declare function getInvite(token: string): Promise<{
|
|
277
|
+
invite: {
|
|
278
|
+
id: string;
|
|
279
|
+
email: string;
|
|
280
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
281
|
+
school: {
|
|
282
|
+
name: string;
|
|
283
|
+
id: string;
|
|
284
|
+
};
|
|
285
|
+
expiresAt: Date;
|
|
286
|
+
};
|
|
287
|
+
}>;
|
|
288
|
+
export declare function acceptInvite(userId: string, token: string): Promise<{
|
|
289
|
+
membership: {
|
|
290
|
+
status: import(".prisma/client").$Enums.SchoolMembershipStatus;
|
|
291
|
+
id: string;
|
|
292
|
+
createdAt: Date;
|
|
293
|
+
updatedAt: Date;
|
|
294
|
+
role: import(".prisma/client").$Enums.SchoolMembershipRole;
|
|
295
|
+
schoolId: string;
|
|
296
|
+
userId: string;
|
|
297
|
+
};
|
|
298
|
+
}>;
|
|
299
|
+
//# sourceMappingURL=school.d.ts.map
|
|
@@ -0,0 +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;AAkDtD,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAWvE;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;GAU7D;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BtE;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAGjE;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqBF;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;GAGjE;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE;;;;;;;;;;GAS9E;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE;;;;;;;;;;GAwB9E;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE;;GAoBlD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;GAGjE;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;GA6BvE;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;GAI9C;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM;;;;;;;;;;;GAiB5C;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;;;;;;;;;;GAsB/D"}
|
|
@@ -0,0 +1,225 @@
|
|
|
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]="eb106c0e-5f2a-504b-9b64-f273c0b7478e")}catch(e){}}();
|
|
3
|
+
import { TRPCError } from "@trpc/server";
|
|
4
|
+
import { v4 as uuidv4 } from "uuid";
|
|
5
|
+
import { env } from "../lib/config/env.js";
|
|
6
|
+
import { prisma } from "../lib/prisma.js";
|
|
7
|
+
import { sendMail } from "../utils/email.js";
|
|
8
|
+
import { logger } from "../utils/logger.js";
|
|
9
|
+
import { acceptSchoolInvite, countActiveAdmins, createSchoolInvite, createSchoolWithAdmin, findActiveSchoolAdminMembership, findPendingInviteByToken, findSchoolMembership, findUserByIdForSchool, getSchoolOverview, listSchoolClasses, listSchoolInvites, listSchoolMembers, listUserSchoolMemberships, removeSchoolMembershipPreservingContent, revokeSchoolInvite, updateSchoolMembershipRole, upsertSchoolMembership, } from "../models/school.js";
|
|
10
|
+
async function requireSchoolAdmin(schoolId, userId) {
|
|
11
|
+
const membership = await findActiveSchoolAdminMembership(schoolId, userId);
|
|
12
|
+
if (!membership) {
|
|
13
|
+
throw new TRPCError({
|
|
14
|
+
code: "FORBIDDEN",
|
|
15
|
+
message: "Only school admins can perform this action",
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return membership;
|
|
19
|
+
}
|
|
20
|
+
async function requireSchoolMember(schoolId, userId) {
|
|
21
|
+
const membership = await findSchoolMembership(schoolId, userId);
|
|
22
|
+
if (!membership || membership.status !== "ACTIVE") {
|
|
23
|
+
throw new TRPCError({
|
|
24
|
+
code: "FORBIDDEN",
|
|
25
|
+
message: "You are not a member of this school",
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return membership;
|
|
29
|
+
}
|
|
30
|
+
export async function getCurrentSchool(userId, schoolId) {
|
|
31
|
+
const memberships = await listUserSchoolMemberships(userId);
|
|
32
|
+
const activeMembership = schoolId
|
|
33
|
+
? memberships.find((membership) => membership.schoolId === schoolId)
|
|
34
|
+
: memberships[0];
|
|
35
|
+
return {
|
|
36
|
+
activeSchool: activeMembership?.school ?? null,
|
|
37
|
+
activeRole: activeMembership?.role ?? null,
|
|
38
|
+
memberships,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export async function createSchoolRecord(userId, input) {
|
|
42
|
+
const school = await createSchoolWithAdmin({
|
|
43
|
+
userId,
|
|
44
|
+
name: input.name,
|
|
45
|
+
subdomain: input.subdomain,
|
|
46
|
+
logoId: input.logoId,
|
|
47
|
+
});
|
|
48
|
+
return { school };
|
|
49
|
+
}
|
|
50
|
+
export async function getAdminOverview(userId, schoolId) {
|
|
51
|
+
await requireSchoolAdmin(schoolId, userId);
|
|
52
|
+
const school = await getSchoolOverview(schoolId);
|
|
53
|
+
if (!school) {
|
|
54
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "School not found" });
|
|
55
|
+
}
|
|
56
|
+
const roleCounts = school.memberships.reduce((counts, membership) => {
|
|
57
|
+
counts[membership.role] += 1;
|
|
58
|
+
return counts;
|
|
59
|
+
}, { ADMIN: 0, TEACHER: 0, STUDENT: 0 });
|
|
60
|
+
return {
|
|
61
|
+
school: {
|
|
62
|
+
id: school.id,
|
|
63
|
+
name: school.name,
|
|
64
|
+
subdomain: school.subdomain,
|
|
65
|
+
counts: {
|
|
66
|
+
classes: school._count.classes,
|
|
67
|
+
members: school._count.memberships,
|
|
68
|
+
pendingInvites: school._count.invites,
|
|
69
|
+
...roleCounts,
|
|
70
|
+
},
|
|
71
|
+
recentClasses: school.classes,
|
|
72
|
+
recentInvites: school.invites,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
export async function listClasses(userId, schoolId) {
|
|
77
|
+
await requireSchoolAdmin(schoolId, userId);
|
|
78
|
+
return { classes: await listSchoolClasses(schoolId) };
|
|
79
|
+
}
|
|
80
|
+
export async function createSchoolClass(userId, input) {
|
|
81
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
82
|
+
const createdClass = await prisma.class.create({
|
|
83
|
+
data: {
|
|
84
|
+
name: input.name,
|
|
85
|
+
section: input.section,
|
|
86
|
+
subject: input.subject,
|
|
87
|
+
color: input.color,
|
|
88
|
+
schoolId: input.schoolId,
|
|
89
|
+
teachers: input.teachers?.length
|
|
90
|
+
? { connect: input.teachers.map((id) => ({ id })) }
|
|
91
|
+
: undefined,
|
|
92
|
+
students: input.students?.length
|
|
93
|
+
? { connect: input.students.map((id) => ({ id })) }
|
|
94
|
+
: undefined,
|
|
95
|
+
},
|
|
96
|
+
include: { teachers: true, students: true },
|
|
97
|
+
});
|
|
98
|
+
return { class: createdClass };
|
|
99
|
+
}
|
|
100
|
+
export async function listMembers(userId, schoolId) {
|
|
101
|
+
await requireSchoolAdmin(schoolId, userId);
|
|
102
|
+
return { members: await listSchoolMembers(schoolId) };
|
|
103
|
+
}
|
|
104
|
+
export async function addMember(userId, input) {
|
|
105
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
106
|
+
const membership = await upsertSchoolMembership({
|
|
107
|
+
schoolId: input.schoolId,
|
|
108
|
+
userId: input.memberUserId,
|
|
109
|
+
role: input.role,
|
|
110
|
+
});
|
|
111
|
+
return { membership };
|
|
112
|
+
}
|
|
113
|
+
export async function updateMemberRole(userId, input) {
|
|
114
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
115
|
+
const current = await findSchoolMembership(input.schoolId, input.memberUserId);
|
|
116
|
+
if (!current) {
|
|
117
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "Member not found" });
|
|
118
|
+
}
|
|
119
|
+
if (current.role === "ADMIN" && input.role !== "ADMIN") {
|
|
120
|
+
const adminCount = await countActiveAdmins(input.schoolId);
|
|
121
|
+
if (adminCount <= 1) {
|
|
122
|
+
throw new TRPCError({
|
|
123
|
+
code: "BAD_REQUEST",
|
|
124
|
+
message: "A school must have at least one active admin",
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const membership = await updateSchoolMembershipRole(input.schoolId, input.memberUserId, input.role);
|
|
129
|
+
return { membership };
|
|
130
|
+
}
|
|
131
|
+
export async function removeMember(userId, input) {
|
|
132
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
133
|
+
const current = await findSchoolMembership(input.schoolId, input.memberUserId);
|
|
134
|
+
if (!current) {
|
|
135
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "Member not found" });
|
|
136
|
+
}
|
|
137
|
+
if (current.role === "ADMIN" && current.status === "ACTIVE") {
|
|
138
|
+
const adminCount = await countActiveAdmins(input.schoolId);
|
|
139
|
+
if (adminCount <= 1) {
|
|
140
|
+
throw new TRPCError({
|
|
141
|
+
code: "BAD_REQUEST",
|
|
142
|
+
message: "A school must have at least one active admin",
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
await removeSchoolMembershipPreservingContent(input.schoolId, input.memberUserId);
|
|
147
|
+
return { success: true };
|
|
148
|
+
}
|
|
149
|
+
export async function listInvites(userId, schoolId) {
|
|
150
|
+
await requireSchoolAdmin(schoolId, userId);
|
|
151
|
+
return { invites: await listSchoolInvites(schoolId) };
|
|
152
|
+
}
|
|
153
|
+
export async function createInvite(userId, input) {
|
|
154
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
155
|
+
const token = uuidv4();
|
|
156
|
+
const invite = await createSchoolInvite({
|
|
157
|
+
schoolId: input.schoolId,
|
|
158
|
+
invitedById: userId,
|
|
159
|
+
email: input.email,
|
|
160
|
+
role: input.role,
|
|
161
|
+
token,
|
|
162
|
+
expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 14),
|
|
163
|
+
});
|
|
164
|
+
try {
|
|
165
|
+
await sendMail({
|
|
166
|
+
from: "hello@studious.sh",
|
|
167
|
+
to: input.email,
|
|
168
|
+
subject: `Join ${invite.school.name} on Studious`,
|
|
169
|
+
text: `Click the link to join ${invite.school.name}: ${env.NEXT_PUBLIC_APP_URL}/school/invite/${token}`,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
logger.error("Failed to send school invite email", {
|
|
174
|
+
schoolId: input.schoolId,
|
|
175
|
+
email: input.email,
|
|
176
|
+
err,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return { invite };
|
|
180
|
+
}
|
|
181
|
+
export async function revokeInvite(userId, input) {
|
|
182
|
+
await requireSchoolAdmin(input.schoolId, userId);
|
|
183
|
+
return { invite: await revokeSchoolInvite(input.inviteId, input.schoolId) };
|
|
184
|
+
}
|
|
185
|
+
export async function getInvite(token) {
|
|
186
|
+
const invite = await findPendingInviteByToken(token);
|
|
187
|
+
if (!invite || invite.status !== "PENDING") {
|
|
188
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "Invite not found" });
|
|
189
|
+
}
|
|
190
|
+
if (invite.expiresAt < new Date()) {
|
|
191
|
+
throw new TRPCError({ code: "UNAUTHORIZED", message: "Invite expired" });
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
invite: {
|
|
195
|
+
id: invite.id,
|
|
196
|
+
email: invite.email,
|
|
197
|
+
role: invite.role,
|
|
198
|
+
school: invite.school,
|
|
199
|
+
expiresAt: invite.expiresAt,
|
|
200
|
+
},
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
export async function acceptInvite(userId, token) {
|
|
204
|
+
const invite = await findPendingInviteByToken(token);
|
|
205
|
+
if (!invite || invite.status !== "PENDING") {
|
|
206
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "Invite not found" });
|
|
207
|
+
}
|
|
208
|
+
if (invite.expiresAt < new Date()) {
|
|
209
|
+
throw new TRPCError({ code: "UNAUTHORIZED", message: "Invite expired" });
|
|
210
|
+
}
|
|
211
|
+
const user = await findUserByIdForSchool(userId);
|
|
212
|
+
if (!user) {
|
|
213
|
+
throw new TRPCError({ code: "NOT_FOUND", message: "User not found" });
|
|
214
|
+
}
|
|
215
|
+
if (user.email.toLowerCase() !== invite.email.toLowerCase()) {
|
|
216
|
+
throw new TRPCError({
|
|
217
|
+
code: "FORBIDDEN",
|
|
218
|
+
message: "This invite was sent to a different account",
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
const membership = await acceptSchoolInvite(invite.id, userId);
|
|
222
|
+
return { membership };
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=school.js.map
|
|
225
|
+
//# debugId=eb106c0e-5f2a-504b-9b64-f273c0b7478e
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"school.js","sources":["services/school.ts"],"sourceRoot":"/","sourcesContent":["/**\n * School service - school admin workflow, memberships, and invites.\n */\nimport { SchoolMembershipRole } from \"@prisma/client\";\nimport { TRPCError } from \"@trpc/server\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { env } from \"../lib/config/env.js\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { sendMail } from \"../utils/email.js\";\nimport { logger } from \"../utils/logger.js\";\nimport {\n acceptSchoolInvite,\n countActiveAdmins,\n createSchoolInvite,\n createSchoolWithAdmin,\n findActiveSchoolAdminMembership,\n findPendingInviteByToken,\n findSchoolMembership,\n findUserByIdForSchool,\n getSchoolById,\n getSchoolOverview,\n listSchoolClasses,\n listSchoolInvites,\n listSchoolMembers,\n listUserSchoolMemberships,\n removeSchoolMembershipPreservingContent,\n revokeSchoolInvite,\n updateSchoolMembershipRole,\n upsertSchoolMembership,\n} from \"../models/school.js\";\n\nasync function requireSchoolAdmin(schoolId: string, userId: string) {\n const membership = await findActiveSchoolAdminMembership(schoolId, userId);\n if (!membership) {\n throw new TRPCError({\n code: \"FORBIDDEN\",\n message: \"Only school admins can perform this action\",\n });\n }\n return membership;\n}\n\nasync function requireSchoolMember(schoolId: string, userId: string) {\n const membership = await findSchoolMembership(schoolId, userId);\n if (!membership || membership.status !== \"ACTIVE\") {\n throw new TRPCError({\n code: \"FORBIDDEN\",\n message: \"You are not a member of this school\",\n });\n }\n return membership;\n}\n\nexport async function getCurrentSchool(userId: string, schoolId?: string) {\n const memberships = await listUserSchoolMemberships(userId);\n const activeMembership = schoolId\n ? memberships.find((membership) => membership.schoolId === schoolId)\n : memberships[0];\n\n return {\n activeSchool: activeMembership?.school ?? null,\n activeRole: activeMembership?.role ?? null,\n memberships,\n };\n}\n\nexport async function createSchoolRecord(\n userId: string,\n input: { name: string; subdomain?: string; logoId?: string }\n) {\n const school = await createSchoolWithAdmin({\n userId,\n name: input.name,\n subdomain: input.subdomain,\n logoId: input.logoId,\n });\n\n return { school };\n}\n\nexport async function getAdminOverview(userId: string, schoolId: string) {\n await requireSchoolAdmin(schoolId, userId);\n const school = await getSchoolOverview(schoolId);\n if (!school) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"School not found\" });\n }\n\n const roleCounts = school.memberships.reduce(\n (counts, membership) => {\n counts[membership.role] += 1;\n return counts;\n },\n { ADMIN: 0, TEACHER: 0, STUDENT: 0 } satisfies Record<SchoolMembershipRole, number>\n );\n\n return {\n school: {\n id: school.id,\n name: school.name,\n subdomain: school.subdomain,\n counts: {\n classes: school._count.classes,\n members: school._count.memberships,\n pendingInvites: school._count.invites,\n ...roleCounts,\n },\n recentClasses: school.classes,\n recentInvites: school.invites,\n },\n };\n}\n\nexport async function listClasses(userId: string, schoolId: string) {\n await requireSchoolAdmin(schoolId, userId);\n return { classes: await listSchoolClasses(schoolId) };\n}\n\nexport async function createSchoolClass(\n userId: string,\n input: {\n schoolId: string;\n name: string;\n section: string;\n subject: string;\n color?: string;\n teachers?: string[];\n students?: string[];\n }\n) {\n await requireSchoolAdmin(input.schoolId, userId);\n const createdClass = await prisma.class.create({\n data: {\n name: input.name,\n section: input.section,\n subject: input.subject,\n color: input.color,\n schoolId: input.schoolId,\n teachers: input.teachers?.length\n ? { connect: input.teachers.map((id) => ({ id })) }\n : undefined,\n students: input.students?.length\n ? { connect: input.students.map((id) => ({ id })) }\n : undefined,\n },\n include: { teachers: true, students: true },\n });\n\n return { class: createdClass };\n}\n\nexport async function listMembers(userId: string, schoolId: string) {\n await requireSchoolAdmin(schoolId, userId);\n return { members: await listSchoolMembers(schoolId) };\n}\n\nexport async function addMember(\n userId: string,\n input: { schoolId: string; memberUserId: string; role: SchoolMembershipRole }\n) {\n await requireSchoolAdmin(input.schoolId, userId);\n const membership = await upsertSchoolMembership({\n schoolId: input.schoolId,\n userId: input.memberUserId,\n role: input.role,\n });\n return { membership };\n}\n\nexport async function updateMemberRole(\n userId: string,\n input: { schoolId: string; memberUserId: string; role: SchoolMembershipRole }\n) {\n await requireSchoolAdmin(input.schoolId, userId);\n const current = await findSchoolMembership(input.schoolId, input.memberUserId);\n if (!current) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Member not found\" });\n }\n\n if (current.role === \"ADMIN\" && input.role !== \"ADMIN\") {\n const adminCount = await countActiveAdmins(input.schoolId);\n if (adminCount <= 1) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"A school must have at least one active admin\",\n });\n }\n }\n\n const membership = await updateSchoolMembershipRole(\n input.schoolId,\n input.memberUserId,\n input.role\n );\n return { membership };\n}\n\nexport async function removeMember(\n userId: string,\n input: { schoolId: string; memberUserId: string }\n) {\n await requireSchoolAdmin(input.schoolId, userId);\n const current = await findSchoolMembership(input.schoolId, input.memberUserId);\n if (!current) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Member not found\" });\n }\n\n if (current.role === \"ADMIN\" && current.status === \"ACTIVE\") {\n const adminCount = await countActiveAdmins(input.schoolId);\n if (adminCount <= 1) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"A school must have at least one active admin\",\n });\n }\n }\n\n await removeSchoolMembershipPreservingContent(input.schoolId, input.memberUserId);\n return { success: true };\n}\n\nexport async function listInvites(userId: string, schoolId: string) {\n await requireSchoolAdmin(schoolId, userId);\n return { invites: await listSchoolInvites(schoolId) };\n}\n\nexport async function createInvite(\n userId: string,\n input: { schoolId: string; email: string; role: SchoolMembershipRole }\n) {\n await requireSchoolAdmin(input.schoolId, userId);\n const token = uuidv4();\n const invite = await createSchoolInvite({\n schoolId: input.schoolId,\n invitedById: userId,\n email: input.email,\n role: input.role,\n token,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 14),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: input.email,\n subject: `Join ${invite.school.name} on Studious`,\n text: `Click the link to join ${invite.school.name}: ${env.NEXT_PUBLIC_APP_URL}/school/invite/${token}`,\n });\n } catch (err) {\n logger.error(\"Failed to send school invite email\", {\n schoolId: input.schoolId,\n email: input.email,\n err,\n });\n }\n\n return { invite };\n}\n\nexport async function revokeInvite(\n userId: string,\n input: { schoolId: string; inviteId: string }\n) {\n await requireSchoolAdmin(input.schoolId, userId);\n return { invite: await revokeSchoolInvite(input.inviteId, input.schoolId) };\n}\n\nexport async function getInvite(token: string) {\n const invite = await findPendingInviteByToken(token);\n if (!invite || invite.status !== \"PENDING\") {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Invite not found\" });\n }\n if (invite.expiresAt < new Date()) {\n throw new TRPCError({ code: \"UNAUTHORIZED\", message: \"Invite expired\" });\n }\n return {\n invite: {\n id: invite.id,\n email: invite.email,\n role: invite.role,\n school: invite.school,\n expiresAt: invite.expiresAt,\n },\n };\n}\n\nexport async function acceptInvite(userId: string, token: string) {\n const invite = await findPendingInviteByToken(token);\n if (!invite || invite.status !== \"PENDING\") {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Invite not found\" });\n }\n if (invite.expiresAt < new Date()) {\n throw new TRPCError({ code: \"UNAUTHORIZED\", message: \"Invite expired\" });\n }\n\n const user = await findUserByIdForSchool(userId);\n if (!user) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"User not found\" });\n }\n if (user.email.toLowerCase() !== invite.email.toLowerCase()) {\n throw new TRPCError({\n code: \"FORBIDDEN\",\n message: \"This invite was sent to a different account\",\n });\n }\n\n const membership = await acceptSchoolInvite(invite.id, userId);\n return { membership };\n}\n"],"names":[],"mappings":"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","debug_id":"eb106c0e-5f2a-504b-9b64-f273c0b7478e"}
|