@studious-lms/server 1.0.4 → 1.0.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/API_SPECIFICATION.md +1117 -0
- package/dist/exportType.js +1 -2
- package/dist/index.js +25 -30
- package/dist/lib/fileUpload.d.ts.map +1 -1
- package/dist/lib/fileUpload.js +31 -29
- package/dist/lib/googleCloudStorage.js +9 -14
- package/dist/lib/prisma.js +4 -7
- package/dist/lib/thumbnailGenerator.js +12 -20
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +17 -22
- package/dist/middleware/logging.js +5 -9
- package/dist/routers/_app.d.ts +3483 -1801
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +28 -27
- package/dist/routers/agenda.d.ts +13 -8
- package/dist/routers/agenda.d.ts.map +1 -1
- package/dist/routers/agenda.js +14 -17
- package/dist/routers/announcement.d.ts +4 -3
- package/dist/routers/announcement.d.ts.map +1 -1
- package/dist/routers/announcement.js +28 -31
- package/dist/routers/assignment.d.ts +282 -196
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +256 -202
- package/dist/routers/attendance.d.ts +5 -4
- package/dist/routers/attendance.d.ts.map +1 -1
- package/dist/routers/attendance.js +31 -34
- package/dist/routers/auth.d.ts +1 -0
- package/dist/routers/auth.d.ts.map +1 -1
- package/dist/routers/auth.js +80 -75
- package/dist/routers/class.d.ts +284 -14
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +435 -164
- package/dist/routers/event.d.ts +47 -38
- package/dist/routers/event.d.ts.map +1 -1
- package/dist/routers/event.js +76 -79
- package/dist/routers/file.d.ts +71 -1
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/file.js +267 -32
- package/dist/routers/folder.d.ts +296 -0
- package/dist/routers/folder.d.ts.map +1 -0
- package/dist/routers/folder.js +693 -0
- package/dist/routers/notifications.d.ts +103 -0
- package/dist/routers/notifications.d.ts.map +1 -0
- package/dist/routers/notifications.js +91 -0
- package/dist/routers/school.d.ts +208 -0
- package/dist/routers/school.d.ts.map +1 -0
- package/dist/routers/school.js +481 -0
- package/dist/routers/section.d.ts +1 -0
- package/dist/routers/section.d.ts.map +1 -1
- package/dist/routers/section.js +30 -33
- package/dist/routers/user.d.ts +2 -1
- package/dist/routers/user.d.ts.map +1 -1
- package/dist/routers/user.js +21 -24
- package/dist/seedDatabase.d.ts +22 -0
- package/dist/seedDatabase.d.ts.map +1 -0
- package/dist/seedDatabase.js +57 -0
- package/dist/socket/handlers.js +26 -30
- package/dist/trpc.d.ts +5 -0
- package/dist/trpc.d.ts.map +1 -1
- package/dist/trpc.js +35 -26
- package/dist/types/trpc.js +1 -2
- package/dist/utils/email.js +2 -8
- package/dist/utils/generateInviteCode.js +1 -5
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +13 -9
- package/dist/utils/prismaErrorHandler.d.ts +9 -0
- package/dist/utils/prismaErrorHandler.d.ts.map +1 -0
- package/dist/utils/prismaErrorHandler.js +234 -0
- package/dist/utils/prismaWrapper.d.ts +14 -0
- package/dist/utils/prismaWrapper.d.ts.map +1 -0
- package/dist/utils/prismaWrapper.js +64 -0
- package/package.json +17 -4
- package/prisma/migrations/20250807062924_init/migration.sql +436 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +67 -0
- package/src/index.ts +2 -2
- package/src/lib/fileUpload.ts +16 -7
- package/src/middleware/auth.ts +0 -2
- package/src/routers/_app.ts +5 -1
- package/src/routers/assignment.ts +82 -22
- package/src/routers/auth.ts +80 -54
- package/src/routers/class.ts +330 -36
- package/src/routers/file.ts +283 -20
- package/src/routers/folder.ts +755 -0
- package/src/routers/notifications.ts +93 -0
- package/src/seedDatabase.ts +66 -0
- package/src/socket/handlers.ts +4 -4
- package/src/trpc.ts +13 -0
- package/src/utils/logger.ts +14 -4
- package/src/utils/prismaErrorHandler.ts +275 -0
- package/src/utils/prismaWrapper.ts +91 -0
- package/tests/auth.test.ts +25 -0
- package/tests/class.test.ts +281 -0
- package/tests/setup.ts +98 -0
- package/tests/startup.test.ts +5 -0
- package/tsconfig.json +2 -1
- package/vitest.config.ts +11 -0
- package/dist/logger.d.ts +0 -26
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -135
- package/src/logger.ts +0 -163
package/dist/routers/event.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
5
5
|
errorShape: {
|
|
6
6
|
data: {
|
|
7
7
|
zodError: z.typeToFlattenedError<any, string> | null;
|
|
8
|
+
prismaError: import("../utils/prismaErrorHandler").PrismaErrorInfo | null;
|
|
8
9
|
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
9
10
|
httpStatus: number;
|
|
10
11
|
path?: string;
|
|
@@ -27,14 +28,18 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
27
28
|
email: string;
|
|
28
29
|
password: string;
|
|
29
30
|
verified: boolean;
|
|
31
|
+
role: import(".prisma/client").$Enums.UserRole;
|
|
30
32
|
profileId: string | null;
|
|
33
|
+
schoolId: string | null;
|
|
31
34
|
} | null;
|
|
32
35
|
class: {
|
|
33
36
|
id: string;
|
|
37
|
+
schoolId: string | null;
|
|
34
38
|
name: string;
|
|
35
39
|
subject: string;
|
|
36
40
|
color: string | null;
|
|
37
41
|
section: string;
|
|
42
|
+
syllabus: string | null;
|
|
38
43
|
} | null;
|
|
39
44
|
assignmentsAttached: {
|
|
40
45
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
@@ -43,16 +48,16 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
43
48
|
id: string;
|
|
44
49
|
name: string;
|
|
45
50
|
} | null;
|
|
51
|
+
title: string;
|
|
52
|
+
dueDate: Date;
|
|
53
|
+
maxGrade: number | null;
|
|
46
54
|
teacher: {
|
|
47
55
|
id: string;
|
|
48
56
|
username: string;
|
|
49
57
|
};
|
|
50
|
-
title: string;
|
|
51
58
|
instructions: string;
|
|
52
|
-
dueDate: Date;
|
|
53
|
-
graded: boolean;
|
|
54
|
-
maxGrade: number | null;
|
|
55
59
|
weight: number;
|
|
60
|
+
graded: boolean;
|
|
56
61
|
attachments: {
|
|
57
62
|
type: string;
|
|
58
63
|
id: string;
|
|
@@ -63,12 +68,12 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
63
68
|
id: string;
|
|
64
69
|
name: string | null;
|
|
65
70
|
color: string | null;
|
|
66
|
-
|
|
67
|
-
userId: string | null;
|
|
68
|
-
remarks: string | null;
|
|
71
|
+
location: string | null;
|
|
69
72
|
startTime: Date;
|
|
70
73
|
endTime: Date;
|
|
71
|
-
|
|
74
|
+
remarks: string | null;
|
|
75
|
+
classId: string | null;
|
|
76
|
+
userId: string | null;
|
|
72
77
|
};
|
|
73
78
|
};
|
|
74
79
|
meta: object;
|
|
@@ -79,9 +84,9 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
79
84
|
endTime: string;
|
|
80
85
|
name?: string | undefined;
|
|
81
86
|
color?: string | undefined;
|
|
82
|
-
classId?: string | undefined;
|
|
83
|
-
remarks?: string | undefined;
|
|
84
87
|
location?: string | undefined;
|
|
88
|
+
remarks?: string | undefined;
|
|
89
|
+
classId?: string | undefined;
|
|
85
90
|
};
|
|
86
91
|
output: {
|
|
87
92
|
event: {
|
|
@@ -92,12 +97,12 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
92
97
|
name: string;
|
|
93
98
|
} | null;
|
|
94
99
|
color: string | null;
|
|
95
|
-
|
|
96
|
-
userId: string | null;
|
|
97
|
-
remarks: string | null;
|
|
100
|
+
location: string | null;
|
|
98
101
|
startTime: Date;
|
|
99
102
|
endTime: Date;
|
|
100
|
-
|
|
103
|
+
remarks: string | null;
|
|
104
|
+
classId: string | null;
|
|
105
|
+
userId: string | null;
|
|
101
106
|
};
|
|
102
107
|
};
|
|
103
108
|
meta: object;
|
|
@@ -110,9 +115,9 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
110
115
|
endTime: string;
|
|
111
116
|
name?: string | undefined;
|
|
112
117
|
color?: string | undefined;
|
|
113
|
-
classId?: string | undefined;
|
|
114
|
-
remarks?: string | undefined;
|
|
115
118
|
location?: string | undefined;
|
|
119
|
+
remarks?: string | undefined;
|
|
120
|
+
classId?: string | undefined;
|
|
116
121
|
};
|
|
117
122
|
};
|
|
118
123
|
output: {
|
|
@@ -120,12 +125,12 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
120
125
|
id: string;
|
|
121
126
|
name: string | null;
|
|
122
127
|
color: string | null;
|
|
123
|
-
|
|
124
|
-
userId: string | null;
|
|
125
|
-
remarks: string | null;
|
|
128
|
+
location: string | null;
|
|
126
129
|
startTime: Date;
|
|
127
130
|
endTime: Date;
|
|
128
|
-
|
|
131
|
+
remarks: string | null;
|
|
132
|
+
classId: string | null;
|
|
133
|
+
userId: string | null;
|
|
129
134
|
};
|
|
130
135
|
};
|
|
131
136
|
meta: object;
|
|
@@ -162,20 +167,22 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
162
167
|
} & {
|
|
163
168
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
164
169
|
id: string;
|
|
170
|
+
title: string;
|
|
171
|
+
dueDate: Date;
|
|
172
|
+
maxGrade: number | null;
|
|
165
173
|
classId: string;
|
|
174
|
+
eventId: string | null;
|
|
166
175
|
markSchemeId: string | null;
|
|
167
176
|
gradingBoundaryId: string | null;
|
|
168
|
-
title: string;
|
|
169
177
|
instructions: string;
|
|
170
|
-
|
|
178
|
+
weight: number;
|
|
179
|
+
graded: boolean;
|
|
180
|
+
sectionId: string | null;
|
|
181
|
+
template: boolean;
|
|
171
182
|
createdAt: Date | null;
|
|
172
183
|
modifiedAt: Date | null;
|
|
173
184
|
teacherId: string;
|
|
174
|
-
|
|
175
|
-
graded: boolean;
|
|
176
|
-
maxGrade: number | null;
|
|
177
|
-
weight: number;
|
|
178
|
-
eventId: string | null;
|
|
185
|
+
inProgress: boolean;
|
|
179
186
|
};
|
|
180
187
|
};
|
|
181
188
|
meta: object;
|
|
@@ -203,20 +210,22 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
203
210
|
} & {
|
|
204
211
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
205
212
|
id: string;
|
|
213
|
+
title: string;
|
|
214
|
+
dueDate: Date;
|
|
215
|
+
maxGrade: number | null;
|
|
206
216
|
classId: string;
|
|
217
|
+
eventId: string | null;
|
|
207
218
|
markSchemeId: string | null;
|
|
208
219
|
gradingBoundaryId: string | null;
|
|
209
|
-
title: string;
|
|
210
220
|
instructions: string;
|
|
211
|
-
|
|
221
|
+
weight: number;
|
|
222
|
+
graded: boolean;
|
|
223
|
+
sectionId: string | null;
|
|
224
|
+
template: boolean;
|
|
212
225
|
createdAt: Date | null;
|
|
213
226
|
modifiedAt: Date | null;
|
|
214
227
|
teacherId: string;
|
|
215
|
-
|
|
216
|
-
graded: boolean;
|
|
217
|
-
maxGrade: number | null;
|
|
218
|
-
weight: number;
|
|
219
|
-
eventId: string | null;
|
|
228
|
+
inProgress: boolean;
|
|
220
229
|
};
|
|
221
230
|
};
|
|
222
231
|
meta: object;
|
|
@@ -233,16 +242,16 @@ export declare const eventRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
233
242
|
id: string;
|
|
234
243
|
name: string;
|
|
235
244
|
} | null;
|
|
245
|
+
title: string;
|
|
246
|
+
dueDate: Date;
|
|
247
|
+
maxGrade: number | null;
|
|
236
248
|
teacher: {
|
|
237
249
|
id: string;
|
|
238
250
|
username: string;
|
|
239
251
|
};
|
|
240
|
-
title: string;
|
|
241
252
|
instructions: string;
|
|
242
|
-
dueDate: Date;
|
|
243
|
-
graded: boolean;
|
|
244
|
-
maxGrade: number | null;
|
|
245
253
|
weight: number;
|
|
254
|
+
graded: boolean;
|
|
246
255
|
attachments: {
|
|
247
256
|
type: string;
|
|
248
257
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/routers/event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../../src/routers/event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4etB,CAAC"}
|
package/dist/routers/event.js
CHANGED
|
@@ -1,33 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
endTime: zod_1.z.string(),
|
|
15
|
-
classId: zod_1.z.string().optional(),
|
|
16
|
-
color: zod_1.z.string().optional(),
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
|
3
|
+
import { TRPCError } from "@trpc/server";
|
|
4
|
+
import { prisma } from "../lib/prisma";
|
|
5
|
+
import { parseISO } from "date-fns";
|
|
6
|
+
const eventSchema = z.object({
|
|
7
|
+
name: z.string().optional(),
|
|
8
|
+
location: z.string().optional(),
|
|
9
|
+
remarks: z.string().optional(),
|
|
10
|
+
startTime: z.string(),
|
|
11
|
+
endTime: z.string(),
|
|
12
|
+
classId: z.string().optional(),
|
|
13
|
+
color: z.string().optional(),
|
|
17
14
|
});
|
|
18
|
-
|
|
19
|
-
get:
|
|
20
|
-
.input(
|
|
21
|
-
id:
|
|
15
|
+
export const eventRouter = createTRPCRouter({
|
|
16
|
+
get: protectedProcedure
|
|
17
|
+
.input(z.object({
|
|
18
|
+
id: z.string(),
|
|
22
19
|
}))
|
|
23
20
|
.query(async ({ ctx, input }) => {
|
|
24
21
|
if (!ctx.user) {
|
|
25
|
-
throw new
|
|
22
|
+
throw new TRPCError({
|
|
26
23
|
code: "UNAUTHORIZED",
|
|
27
24
|
message: "You must be logged in to get an event",
|
|
28
25
|
});
|
|
29
26
|
}
|
|
30
|
-
const event = await
|
|
27
|
+
const event = await prisma.event.findUnique({
|
|
31
28
|
where: { id: input.id },
|
|
32
29
|
include: {
|
|
33
30
|
class: true,
|
|
@@ -66,31 +63,31 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
66
63
|
},
|
|
67
64
|
});
|
|
68
65
|
if (!event) {
|
|
69
|
-
throw new
|
|
66
|
+
throw new TRPCError({
|
|
70
67
|
code: "NOT_FOUND",
|
|
71
68
|
message: "Event not found",
|
|
72
69
|
});
|
|
73
70
|
}
|
|
74
71
|
if (event.userId !== ctx.user.id) {
|
|
75
|
-
throw new
|
|
72
|
+
throw new TRPCError({
|
|
76
73
|
code: "UNAUTHORIZED",
|
|
77
74
|
message: "You are not authorized to view this event",
|
|
78
75
|
});
|
|
79
76
|
}
|
|
80
77
|
return { event };
|
|
81
78
|
}),
|
|
82
|
-
create:
|
|
79
|
+
create: protectedProcedure
|
|
83
80
|
.input(eventSchema)
|
|
84
81
|
.mutation(async ({ ctx, input }) => {
|
|
85
82
|
if (!ctx.user) {
|
|
86
|
-
throw new
|
|
83
|
+
throw new TRPCError({
|
|
87
84
|
code: "UNAUTHORIZED",
|
|
88
85
|
message: "You must be logged in to create an event",
|
|
89
86
|
});
|
|
90
87
|
}
|
|
91
88
|
// If classId is provided, check if user is a teacher of the class
|
|
92
89
|
if (input.classId) {
|
|
93
|
-
const classData = await
|
|
90
|
+
const classData = await prisma.class.findUnique({
|
|
94
91
|
where: {
|
|
95
92
|
id: input.classId,
|
|
96
93
|
teachers: {
|
|
@@ -101,19 +98,19 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
101
98
|
},
|
|
102
99
|
});
|
|
103
100
|
if (!classData) {
|
|
104
|
-
throw new
|
|
101
|
+
throw new TRPCError({
|
|
105
102
|
code: "UNAUTHORIZED",
|
|
106
103
|
message: "You are not authorized to create events for this class",
|
|
107
104
|
});
|
|
108
105
|
}
|
|
109
106
|
}
|
|
110
|
-
const event = await
|
|
107
|
+
const event = await prisma.event.create({
|
|
111
108
|
data: {
|
|
112
109
|
name: input.name,
|
|
113
110
|
location: input.location,
|
|
114
111
|
remarks: input.remarks,
|
|
115
|
-
startTime:
|
|
116
|
-
endTime:
|
|
112
|
+
startTime: parseISO(input.startTime),
|
|
113
|
+
endTime: parseISO(input.endTime),
|
|
117
114
|
userId: ctx.user.id,
|
|
118
115
|
color: input.color,
|
|
119
116
|
...(input.classId ? { classId: input.classId } : {}),
|
|
@@ -138,92 +135,92 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
138
135
|
});
|
|
139
136
|
return { event };
|
|
140
137
|
}),
|
|
141
|
-
update:
|
|
142
|
-
.input(
|
|
143
|
-
id:
|
|
138
|
+
update: protectedProcedure
|
|
139
|
+
.input(z.object({
|
|
140
|
+
id: z.string(),
|
|
144
141
|
data: eventSchema,
|
|
145
142
|
}))
|
|
146
143
|
.mutation(async ({ ctx, input }) => {
|
|
147
144
|
if (!ctx.user) {
|
|
148
|
-
throw new
|
|
145
|
+
throw new TRPCError({
|
|
149
146
|
code: "UNAUTHORIZED",
|
|
150
147
|
message: "You must be logged in to update an event",
|
|
151
148
|
});
|
|
152
149
|
}
|
|
153
|
-
const event = await
|
|
150
|
+
const event = await prisma.event.findUnique({
|
|
154
151
|
where: { id: input.id },
|
|
155
152
|
});
|
|
156
153
|
if (!event) {
|
|
157
|
-
throw new
|
|
154
|
+
throw new TRPCError({
|
|
158
155
|
code: "NOT_FOUND",
|
|
159
156
|
message: "Event not found",
|
|
160
157
|
});
|
|
161
158
|
}
|
|
162
159
|
if (event.userId !== ctx.user.id) {
|
|
163
|
-
throw new
|
|
160
|
+
throw new TRPCError({
|
|
164
161
|
code: "UNAUTHORIZED",
|
|
165
162
|
message: "You are not authorized to update this event",
|
|
166
163
|
});
|
|
167
164
|
}
|
|
168
|
-
const updatedEvent = await
|
|
165
|
+
const updatedEvent = await prisma.event.update({
|
|
169
166
|
where: { id: input.id },
|
|
170
167
|
data: {
|
|
171
168
|
name: input.data.name,
|
|
172
169
|
location: input.data.location,
|
|
173
170
|
remarks: input.data.remarks,
|
|
174
|
-
startTime:
|
|
175
|
-
endTime:
|
|
171
|
+
startTime: parseISO(input.data.startTime),
|
|
172
|
+
endTime: parseISO(input.data.endTime),
|
|
176
173
|
color: input.data.color,
|
|
177
174
|
...(input.data.classId ? { classId: input.data.classId } : {}),
|
|
178
175
|
},
|
|
179
176
|
});
|
|
180
177
|
return { event: updatedEvent };
|
|
181
178
|
}),
|
|
182
|
-
delete:
|
|
183
|
-
.input(
|
|
184
|
-
id:
|
|
179
|
+
delete: protectedProcedure
|
|
180
|
+
.input(z.object({
|
|
181
|
+
id: z.string(),
|
|
185
182
|
}))
|
|
186
183
|
.mutation(async ({ ctx, input }) => {
|
|
187
184
|
if (!ctx.user) {
|
|
188
|
-
throw new
|
|
185
|
+
throw new TRPCError({
|
|
189
186
|
code: "UNAUTHORIZED",
|
|
190
187
|
message: "You must be logged in to delete an event",
|
|
191
188
|
});
|
|
192
189
|
}
|
|
193
|
-
const event = await
|
|
190
|
+
const event = await prisma.event.findUnique({
|
|
194
191
|
where: { id: input.id },
|
|
195
192
|
});
|
|
196
193
|
if (!event) {
|
|
197
|
-
throw new
|
|
194
|
+
throw new TRPCError({
|
|
198
195
|
code: "NOT_FOUND",
|
|
199
196
|
message: "Event not found",
|
|
200
197
|
});
|
|
201
198
|
}
|
|
202
199
|
if (event.userId !== ctx.user.id) {
|
|
203
|
-
throw new
|
|
200
|
+
throw new TRPCError({
|
|
204
201
|
code: "UNAUTHORIZED",
|
|
205
202
|
message: "You are not authorized to delete this event",
|
|
206
203
|
});
|
|
207
204
|
}
|
|
208
|
-
await
|
|
205
|
+
await prisma.event.delete({
|
|
209
206
|
where: { id: input.id },
|
|
210
207
|
});
|
|
211
208
|
return { success: true };
|
|
212
209
|
}),
|
|
213
|
-
attachAssignment:
|
|
214
|
-
.input(
|
|
215
|
-
eventId:
|
|
216
|
-
assignmentId:
|
|
210
|
+
attachAssignment: protectedProcedure
|
|
211
|
+
.input(z.object({
|
|
212
|
+
eventId: z.string(),
|
|
213
|
+
assignmentId: z.string(),
|
|
217
214
|
}))
|
|
218
215
|
.mutation(async ({ ctx, input }) => {
|
|
219
216
|
if (!ctx.user || !ctx.user.id) {
|
|
220
|
-
throw new
|
|
217
|
+
throw new TRPCError({
|
|
221
218
|
code: "UNAUTHORIZED",
|
|
222
219
|
message: "You must be logged in to attach an assignment",
|
|
223
220
|
});
|
|
224
221
|
}
|
|
225
222
|
// Check if user owns the event
|
|
226
|
-
const event = await
|
|
223
|
+
const event = await prisma.event.findUnique({
|
|
227
224
|
where: { id: input.eventId },
|
|
228
225
|
include: {
|
|
229
226
|
class: {
|
|
@@ -236,7 +233,7 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
236
233
|
}
|
|
237
234
|
});
|
|
238
235
|
if (!event) {
|
|
239
|
-
throw new
|
|
236
|
+
throw new TRPCError({
|
|
240
237
|
code: "NOT_FOUND",
|
|
241
238
|
message: "Event not found",
|
|
242
239
|
});
|
|
@@ -244,13 +241,13 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
244
241
|
// Check if user is the event owner or a teacher of the class
|
|
245
242
|
if (event.userId !== ctx.user.id &&
|
|
246
243
|
!event.class?.teachers.some(teacher => teacher.id === ctx.user.id)) {
|
|
247
|
-
throw new
|
|
244
|
+
throw new TRPCError({
|
|
248
245
|
code: "UNAUTHORIZED",
|
|
249
246
|
message: "You are not authorized to modify this event",
|
|
250
247
|
});
|
|
251
248
|
}
|
|
252
249
|
// Check if assignment exists and belongs to the same class
|
|
253
|
-
const assignment = await
|
|
250
|
+
const assignment = await prisma.assignment.findUnique({
|
|
254
251
|
where: { id: input.assignmentId },
|
|
255
252
|
include: {
|
|
256
253
|
class: {
|
|
@@ -263,27 +260,27 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
263
260
|
}
|
|
264
261
|
});
|
|
265
262
|
if (!assignment) {
|
|
266
|
-
throw new
|
|
263
|
+
throw new TRPCError({
|
|
267
264
|
code: "NOT_FOUND",
|
|
268
265
|
message: "Assignment not found",
|
|
269
266
|
});
|
|
270
267
|
}
|
|
271
268
|
// Check if user is a teacher of the assignment's class
|
|
272
269
|
if (!assignment.class.teachers.some(teacher => teacher.id === ctx.user.id)) {
|
|
273
|
-
throw new
|
|
270
|
+
throw new TRPCError({
|
|
274
271
|
code: "UNAUTHORIZED",
|
|
275
272
|
message: "You are not authorized to modify this assignment",
|
|
276
273
|
});
|
|
277
274
|
}
|
|
278
275
|
// Check if event and assignment belong to the same class
|
|
279
276
|
if (event.classId !== assignment.classId) {
|
|
280
|
-
throw new
|
|
277
|
+
throw new TRPCError({
|
|
281
278
|
code: "BAD_REQUEST",
|
|
282
279
|
message: "Event and assignment must belong to the same class",
|
|
283
280
|
});
|
|
284
281
|
}
|
|
285
282
|
// Attach assignment to event
|
|
286
|
-
const updatedAssignment = await
|
|
283
|
+
const updatedAssignment = await prisma.assignment.update({
|
|
287
284
|
where: { id: input.assignmentId },
|
|
288
285
|
data: {
|
|
289
286
|
eventAttached: {
|
|
@@ -314,20 +311,20 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
314
311
|
});
|
|
315
312
|
return { assignment: updatedAssignment };
|
|
316
313
|
}),
|
|
317
|
-
detachAssignment:
|
|
318
|
-
.input(
|
|
319
|
-
eventId:
|
|
320
|
-
assignmentId:
|
|
314
|
+
detachAssignment: protectedProcedure
|
|
315
|
+
.input(z.object({
|
|
316
|
+
eventId: z.string(),
|
|
317
|
+
assignmentId: z.string(),
|
|
321
318
|
}))
|
|
322
319
|
.mutation(async ({ ctx, input }) => {
|
|
323
320
|
if (!ctx.user) {
|
|
324
|
-
throw new
|
|
321
|
+
throw new TRPCError({
|
|
325
322
|
code: "UNAUTHORIZED",
|
|
326
323
|
message: "You must be logged in to detach an assignment",
|
|
327
324
|
});
|
|
328
325
|
}
|
|
329
326
|
// Check if user owns the event
|
|
330
|
-
const event = await
|
|
327
|
+
const event = await prisma.event.findUnique({
|
|
331
328
|
where: { id: input.eventId },
|
|
332
329
|
include: {
|
|
333
330
|
class: {
|
|
@@ -340,7 +337,7 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
340
337
|
}
|
|
341
338
|
});
|
|
342
339
|
if (!event) {
|
|
343
|
-
throw new
|
|
340
|
+
throw new TRPCError({
|
|
344
341
|
code: "NOT_FOUND",
|
|
345
342
|
message: "Event not found",
|
|
346
343
|
});
|
|
@@ -348,13 +345,13 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
348
345
|
// Check if user is the event owner or a teacher of the class
|
|
349
346
|
if (event.userId !== ctx.user.id &&
|
|
350
347
|
!event.class?.teachers.some(teacher => teacher.id === ctx.user.id)) {
|
|
351
|
-
throw new
|
|
348
|
+
throw new TRPCError({
|
|
352
349
|
code: "UNAUTHORIZED",
|
|
353
350
|
message: "You are not authorized to modify this event",
|
|
354
351
|
});
|
|
355
352
|
}
|
|
356
353
|
// Detach assignment from event
|
|
357
|
-
const updatedAssignment = await
|
|
354
|
+
const updatedAssignment = await prisma.assignment.update({
|
|
358
355
|
where: { id: input.assignmentId },
|
|
359
356
|
data: {
|
|
360
357
|
eventAttached: {
|
|
@@ -385,19 +382,19 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
385
382
|
});
|
|
386
383
|
return { assignment: updatedAssignment };
|
|
387
384
|
}),
|
|
388
|
-
getAvailableAssignments:
|
|
389
|
-
.input(
|
|
390
|
-
eventId:
|
|
385
|
+
getAvailableAssignments: protectedProcedure
|
|
386
|
+
.input(z.object({
|
|
387
|
+
eventId: z.string(),
|
|
391
388
|
}))
|
|
392
389
|
.query(async ({ ctx, input }) => {
|
|
393
390
|
if (!ctx.user) {
|
|
394
|
-
throw new
|
|
391
|
+
throw new TRPCError({
|
|
395
392
|
code: "UNAUTHORIZED",
|
|
396
393
|
message: "You must be logged in to get available assignments",
|
|
397
394
|
});
|
|
398
395
|
}
|
|
399
396
|
// Get the event to find the class
|
|
400
|
-
const event = await
|
|
397
|
+
const event = await prisma.event.findUnique({
|
|
401
398
|
where: { id: input.eventId },
|
|
402
399
|
include: {
|
|
403
400
|
class: {
|
|
@@ -410,7 +407,7 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
410
407
|
}
|
|
411
408
|
});
|
|
412
409
|
if (!event || !event.classId) {
|
|
413
|
-
throw new
|
|
410
|
+
throw new TRPCError({
|
|
414
411
|
code: "NOT_FOUND",
|
|
415
412
|
message: "Event not found",
|
|
416
413
|
});
|
|
@@ -418,13 +415,13 @@ exports.eventRouter = (0, trpc_1.createTRPCRouter)({
|
|
|
418
415
|
// Check if user is authorized to access this event/class
|
|
419
416
|
if (event.userId !== ctx.user.id &&
|
|
420
417
|
!event.class?.teachers.some(teacher => teacher.id === ctx.user.id)) {
|
|
421
|
-
throw new
|
|
418
|
+
throw new TRPCError({
|
|
422
419
|
code: "UNAUTHORIZED",
|
|
423
420
|
message: "You are not authorized to access this event",
|
|
424
421
|
});
|
|
425
422
|
}
|
|
426
423
|
// Get all assignments for the class that are not already attached to an event
|
|
427
|
-
const assignments = await
|
|
424
|
+
const assignments = await prisma.assignment.findMany({
|
|
428
425
|
where: {
|
|
429
426
|
classId: event.classId,
|
|
430
427
|
eventId: null, // Not already attached to any event
|
package/dist/routers/file.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare const fileRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
5
5
|
errorShape: {
|
|
6
6
|
data: {
|
|
7
7
|
zodError: z.typeToFlattenedError<any, string> | null;
|
|
8
|
+
prismaError: import("../utils/prismaErrorHandler").PrismaErrorInfo | null;
|
|
8
9
|
code: import("@trpc/server").TRPC_ERROR_CODE_KEY;
|
|
9
10
|
httpStatus: number;
|
|
10
11
|
path?: string;
|
|
@@ -20,7 +21,76 @@ export declare const fileRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
20
21
|
fileId: string;
|
|
21
22
|
};
|
|
22
23
|
output: {
|
|
23
|
-
|
|
24
|
+
url: string;
|
|
25
|
+
};
|
|
26
|
+
meta: object;
|
|
27
|
+
}>;
|
|
28
|
+
move: import("@trpc/server").TRPCMutationProcedure<{
|
|
29
|
+
input: {
|
|
30
|
+
[x: string]: unknown;
|
|
31
|
+
classId: string;
|
|
32
|
+
fileId: string;
|
|
33
|
+
targetFolderId: string;
|
|
34
|
+
};
|
|
35
|
+
output: {
|
|
36
|
+
user: {
|
|
37
|
+
id: string;
|
|
38
|
+
username: string;
|
|
39
|
+
} | null;
|
|
40
|
+
} & {
|
|
41
|
+
path: string;
|
|
42
|
+
type: string;
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
size: number | null;
|
|
46
|
+
uploadedAt: Date | null;
|
|
47
|
+
assignmentId: string | null;
|
|
48
|
+
submissionId: string | null;
|
|
49
|
+
userId: string | null;
|
|
50
|
+
thumbnailId: string | null;
|
|
51
|
+
annotationId: string | null;
|
|
52
|
+
classDraftId: string | null;
|
|
53
|
+
folderId: string | null;
|
|
54
|
+
};
|
|
55
|
+
meta: object;
|
|
56
|
+
}>;
|
|
57
|
+
rename: import("@trpc/server").TRPCMutationProcedure<{
|
|
58
|
+
input: {
|
|
59
|
+
[x: string]: unknown;
|
|
60
|
+
classId: string;
|
|
61
|
+
fileId: string;
|
|
62
|
+
newName: string;
|
|
63
|
+
};
|
|
64
|
+
output: {
|
|
65
|
+
user: {
|
|
66
|
+
id: string;
|
|
67
|
+
username: string;
|
|
68
|
+
} | null;
|
|
69
|
+
} & {
|
|
70
|
+
path: string;
|
|
71
|
+
type: string;
|
|
72
|
+
id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
size: number | null;
|
|
75
|
+
uploadedAt: Date | null;
|
|
76
|
+
assignmentId: string | null;
|
|
77
|
+
submissionId: string | null;
|
|
78
|
+
userId: string | null;
|
|
79
|
+
thumbnailId: string | null;
|
|
80
|
+
annotationId: string | null;
|
|
81
|
+
classDraftId: string | null;
|
|
82
|
+
folderId: string | null;
|
|
83
|
+
};
|
|
84
|
+
meta: object;
|
|
85
|
+
}>;
|
|
86
|
+
delete: import("@trpc/server").TRPCMutationProcedure<{
|
|
87
|
+
input: {
|
|
88
|
+
[x: string]: unknown;
|
|
89
|
+
classId: string;
|
|
90
|
+
fileId: string;
|
|
91
|
+
};
|
|
92
|
+
output: {
|
|
93
|
+
success: boolean;
|
|
24
94
|
};
|
|
25
95
|
meta: object;
|
|
26
96
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/routers/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/routers/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8VrB,CAAC"}
|