@studious-lms/server 1.2.45 → 1.2.47
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 +45 -0
- package/.env.test.example +37 -0
- package/README.md +34 -7
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +12110 -0
- package/coverage/coverage-final.json +44 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +221 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/server/index.html +116 -0
- package/coverage/server/src/exportType.ts.html +109 -0
- package/coverage/server/src/index.html +161 -0
- package/coverage/server/src/index.ts.html +1702 -0
- package/coverage/server/src/instrument.ts.html +130 -0
- package/coverage/server/src/lib/config/env.ts.html +448 -0
- package/coverage/server/src/lib/config/index.html +116 -0
- package/coverage/server/src/lib/fileUpload.ts.html +1138 -0
- package/coverage/server/src/lib/googleCloudStorage.ts.html +334 -0
- package/coverage/server/src/lib/index.html +206 -0
- package/coverage/server/src/lib/jsonConversion.ts.html +2323 -0
- package/coverage/server/src/lib/jsonStyles.ts.html +193 -0
- package/coverage/server/src/lib/notificationHandler.ts.html +193 -0
- package/coverage/server/src/lib/pusher.ts.html +121 -0
- package/coverage/server/src/lib/thumbnailGenerator.ts.html +592 -0
- package/coverage/server/src/middleware/auth.ts.html +646 -0
- package/coverage/server/src/middleware/index.html +146 -0
- package/coverage/server/src/middleware/logging.ts.html +244 -0
- package/coverage/server/src/middleware/security.ts.html +271 -0
- package/coverage/server/src/routers/_app.ts.html +232 -0
- package/coverage/server/src/routers/agenda.ts.html +319 -0
- package/coverage/server/src/routers/announcement.ts.html +3481 -0
- package/coverage/server/src/routers/assignment.ts.html +7633 -0
- package/coverage/server/src/routers/attendance.ts.html +1030 -0
- package/coverage/server/src/routers/auth.ts.html +1081 -0
- package/coverage/server/src/routers/class.ts.html +3535 -0
- package/coverage/server/src/routers/comment.ts.html +991 -0
- package/coverage/server/src/routers/conversation.ts.html +982 -0
- package/coverage/server/src/routers/event.ts.html +1609 -0
- package/coverage/server/src/routers/file.ts.html +1144 -0
- package/coverage/server/src/routers/folder.ts.html +2797 -0
- package/coverage/server/src/routers/index.html +386 -0
- package/coverage/server/src/routers/labChat.ts.html +3073 -0
- package/coverage/server/src/routers/marketing.ts.html +340 -0
- package/coverage/server/src/routers/message.ts.html +1912 -0
- package/coverage/server/src/routers/notifications.ts.html +364 -0
- package/coverage/server/src/routers/section.ts.html +1120 -0
- package/coverage/server/src/routers/user.ts.html +862 -0
- package/coverage/server/src/routers/worksheet.ts.html +1729 -0
- package/coverage/server/src/trpc.ts.html +397 -0
- package/coverage/server/src/types/index.html +116 -0
- package/coverage/server/src/types/trpc.ts.html +127 -0
- package/coverage/server/src/utils/aiUser.ts.html +280 -0
- package/coverage/server/src/utils/email.ts.html +121 -0
- package/coverage/server/src/utils/generateInviteCode.ts.html +106 -0
- package/coverage/server/src/utils/index.html +206 -0
- package/coverage/server/src/utils/inference.ts.html +709 -0
- package/coverage/server/src/utils/logger.ts.html +664 -0
- package/coverage/server/src/utils/prismaErrorHandler.ts.html +907 -0
- package/coverage/server/src/utils/prismaWrapper.ts.html +355 -0
- package/coverage/server/vitest.config.ts.html +196 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -52
- package/dist/index.js.map +1 -1
- package/dist/instrument.js +15 -8
- package/dist/instrument.js.map +1 -1
- package/dist/lib/config/env.d.ts +169 -0
- package/dist/lib/config/env.d.ts.map +1 -0
- package/dist/lib/config/env.js +115 -0
- package/dist/lib/config/env.js.map +1 -0
- package/dist/lib/fileUpload.d.ts.map +1 -1
- package/dist/lib/fileUpload.js +5 -4
- package/dist/lib/fileUpload.js.map +1 -1
- package/dist/lib/googleCloudStorage.d.ts.map +1 -1
- package/dist/lib/googleCloudStorage.js +7 -8
- package/dist/lib/googleCloudStorage.js.map +1 -1
- package/dist/lib/jsonConversion.d.ts.map +1 -1
- package/dist/lib/jsonConversion.js +14 -16
- package/dist/lib/jsonConversion.js.map +1 -1
- package/dist/lib/notificationHandler.d.ts +2 -2
- package/dist/lib/prisma.d.ts +2 -2
- package/dist/lib/prisma.d.ts.map +1 -1
- package/dist/lib/prisma.js +22 -3
- package/dist/lib/prisma.js.map +1 -1
- package/dist/lib/pusher.d.ts.map +1 -1
- package/dist/lib/pusher.js +8 -7
- package/dist/lib/pusher.js.map +1 -1
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +7 -5
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/security.d.ts +5 -0
- package/dist/middleware/security.d.ts.map +1 -0
- package/dist/middleware/security.js +77 -0
- package/dist/middleware/security.js.map +1 -0
- package/dist/routers/_app.d.ts +368 -108
- 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/agenda.d.ts.map +1 -1
- package/dist/routers/agenda.js +12 -9
- package/dist/routers/agenda.js.map +1 -1
- package/dist/routers/announcement.d.ts +8 -0
- package/dist/routers/announcement.d.ts.map +1 -1
- package/dist/routers/announcement.js +6 -4
- package/dist/routers/announcement.js.map +1 -1
- package/dist/routers/assignment.d.ts +17 -4
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/assignment.js +51 -19
- package/dist/routers/assignment.js.map +1 -1
- package/dist/routers/attendance.d.ts +1 -0
- package/dist/routers/attendance.d.ts.map +1 -1
- package/dist/routers/attendance.js +4 -4
- package/dist/routers/attendance.js.map +1 -1
- package/dist/routers/auth.d.ts +20 -0
- package/dist/routers/auth.d.ts.map +1 -1
- package/dist/routers/auth.js +132 -15
- package/dist/routers/auth.js.map +1 -1
- package/dist/routers/class.d.ts +10 -0
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +49 -5
- package/dist/routers/class.js.map +1 -1
- package/dist/routers/comment.d.ts +2 -0
- package/dist/routers/comment.d.ts.map +1 -1
- package/dist/routers/conversation.d.ts +2 -0
- package/dist/routers/conversation.d.ts.map +1 -1
- package/dist/routers/conversation.js +46 -31
- package/dist/routers/conversation.js.map +1 -1
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/file.js +30 -7
- package/dist/routers/file.js.map +1 -1
- package/dist/routers/labChat.d.ts +2 -0
- package/dist/routers/labChat.d.ts.map +1 -1
- package/dist/routers/labChat.js +5 -322
- package/dist/routers/labChat.js.map +1 -1
- package/dist/routers/marketing.d.ts +1 -1
- package/dist/routers/message.d.ts +1 -0
- package/dist/routers/message.d.ts.map +1 -1
- package/dist/routers/message.js +3 -2
- package/dist/routers/message.js.map +1 -1
- package/dist/routers/newtonChat.d.ts +55 -0
- package/dist/routers/newtonChat.d.ts.map +1 -0
- package/dist/routers/newtonChat.js +262 -0
- package/dist/routers/newtonChat.js.map +1 -0
- package/dist/routers/notifications.d.ts +4 -4
- package/dist/routers/section.d.ts +19 -4
- package/dist/routers/section.d.ts.map +1 -1
- package/dist/routers/section.js +26 -8
- package/dist/routers/section.js.map +1 -1
- package/dist/routers/user.d.ts.map +1 -1
- package/dist/routers/user.js +5 -4
- package/dist/routers/user.js.map +1 -1
- package/dist/routers/worksheet.d.ts +44 -41
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/routers/worksheet.js +25 -34
- package/dist/routers/worksheet.js.map +1 -1
- package/dist/seedDatabase.d.ts +1 -1
- package/dist/seedDatabase.js +275 -284
- package/dist/seedDatabase.js.map +1 -1
- package/dist/server/pipelines/aiLabChat.d.ts +21 -0
- package/dist/server/pipelines/aiLabChat.d.ts.map +1 -0
- package/dist/server/pipelines/aiLabChat.js +456 -0
- package/dist/server/pipelines/aiLabChat.js.map +1 -0
- package/dist/server/pipelines/aiNewtonChat.d.ts +30 -0
- package/dist/server/pipelines/aiNewtonChat.d.ts.map +1 -0
- package/dist/server/pipelines/aiNewtonChat.js +280 -0
- package/dist/server/pipelines/aiNewtonChat.js.map +1 -0
- package/dist/server/pipelines/gradeWorksheet.d.ts +15 -0
- package/dist/server/pipelines/gradeWorksheet.d.ts.map +1 -0
- package/dist/server/pipelines/gradeWorksheet.js +139 -0
- package/dist/server/pipelines/gradeWorksheet.js.map +1 -0
- package/dist/trpc.d.ts.map +1 -1
- package/dist/trpc.js +2 -2
- package/dist/trpc.js.map +1 -1
- package/dist/utils/email.d.ts +9 -1
- package/dist/utils/email.d.ts.map +1 -1
- package/dist/utils/email.js +20 -5
- package/dist/utils/email.js.map +1 -1
- package/dist/utils/inference.d.ts +5 -0
- package/dist/utils/inference.d.ts.map +1 -1
- package/dist/utils/inference.js +71 -7
- package/dist/utils/inference.js.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +3 -3
- package/dist/utils/logger.js.map +1 -1
- package/docker-compose.yml +14 -0
- package/package.json +13 -4
- package/prisma/schema.prisma +34 -5
- package/scripts/test-pre-push.ts +14 -0
- package/src/index.ts +98 -54
- package/src/instrument.ts +13 -6
- package/src/lib/config/env.ts +126 -0
- package/src/lib/fileUpload.ts +3 -2
- package/src/lib/googleCloudStorage.ts +6 -6
- package/src/lib/jsonConversion.ts +12 -14
- package/src/lib/prisma.ts +23 -2
- package/src/lib/pusher.ts +6 -5
- package/src/middleware/auth.ts +5 -3
- package/src/middleware/security.ts +80 -0
- package/src/routers/_app.ts +2 -0
- package/src/routers/agenda.ts +10 -7
- package/src/routers/announcement.ts +4 -2
- package/src/routers/assignment.ts +74 -41
- package/src/routers/attendance.ts +2 -2
- package/src/routers/auth.ts +143 -14
- package/src/routers/class.ts +52 -3
- package/src/routers/conversation.ts +49 -29
- package/src/routers/file.ts +29 -5
- package/src/routers/labChat.ts +3 -367
- package/src/routers/message.ts +1 -1
- package/src/routers/newtonChat.ts +299 -0
- package/src/routers/section.ts +26 -6
- package/src/routers/user.ts +3 -2
- package/src/routers/worksheet.ts +26 -38
- package/src/seedDatabase.ts +290 -283
- package/src/server/pipelines/aiLabChat.ts +507 -0
- package/src/server/pipelines/aiNewtonChat.ts +338 -0
- package/src/server/pipelines/gradeWorksheet.ts +151 -0
- package/src/trpc.ts +2 -0
- package/src/utils/email.ts +30 -3
- package/src/utils/inference.ts +85 -5
- package/src/utils/logger.ts +2 -1
- package/tests/announcement.test.ts +164 -0
- package/tests/assignment.test.ts +296 -0
- package/tests/attendance.test.ts +168 -0
- package/tests/auth.test.ts +33 -10
- package/tests/class.test.ts +34 -9
- package/tests/event.test.ts +228 -0
- package/tests/section.test.ts +216 -0
- package/tests/setup.ts +70 -16
- package/tests/user.test.ts +158 -0
- package/vitest.config.ts +26 -0
- package/API_SPECIFICATION.md +0 -1597
- package/BASE64_REMOVAL_SUMMARY.md +0 -164
- package/CHAT_API_SPEC.md +0 -579
- package/LAB_CHAT_API_SPEC.md +0 -518
- package/dist/routers/school.d.ts +0 -208
- package/dist/routers/school.d.ts.map +0 -1
- package/dist/routers/school.js +0 -483
package/dist/routers/user.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
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]="
|
|
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]="0dff2490-6903-5dec-aa0c-7d8bd2ac7c23")}catch(e){}}();
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { createTRPCRouter, protectedProcedure } from "../trpc.js";
|
|
5
5
|
import { TRPCError } from "@trpc/server";
|
|
6
6
|
import { prisma } from "../lib/prisma.js";
|
|
7
7
|
import { logger } from "../utils/logger.js";
|
|
8
|
+
import { env } from "../lib/config/env.js";
|
|
8
9
|
// Helper function to convert file path to backend proxy URL
|
|
9
10
|
function getFileUrl(filePath) {
|
|
10
11
|
if (!filePath)
|
|
@@ -14,7 +15,7 @@ function getFileUrl(filePath) {
|
|
|
14
15
|
return filePath;
|
|
15
16
|
}
|
|
16
17
|
// Convert GCS path to full backend proxy URL
|
|
17
|
-
const backendUrl =
|
|
18
|
+
const backendUrl = env.BACKEND_URL || 'http://localhost:3001';
|
|
18
19
|
return `${backendUrl}/api/files/${encodeURIComponent(filePath)}`;
|
|
19
20
|
}
|
|
20
21
|
// For direct file uploads (file already uploaded to GCS)
|
|
@@ -205,7 +206,7 @@ export const userRouter = createTRPCRouter({
|
|
|
205
206
|
const uniqueFilename = `${ctx.user.id}-${Date.now()}.${fileExtension}`;
|
|
206
207
|
const filePath = `users/${ctx.user.id}/profile/${uniqueFilename}`;
|
|
207
208
|
// Generate backend proxy upload URL instead of direct GCS signed URL
|
|
208
|
-
const backendUrl =
|
|
209
|
+
const backendUrl = env.BACKEND_URL || 'http://localhost:3001';
|
|
209
210
|
const uploadUrl = `${backendUrl}/api/upload/${encodeURIComponent(filePath)}`;
|
|
210
211
|
logger.info('Generated upload URL', {
|
|
211
212
|
userId: ctx.user.id,
|
|
@@ -233,4 +234,4 @@ export const userRouter = createTRPCRouter({
|
|
|
233
234
|
}),
|
|
234
235
|
});
|
|
235
236
|
//# sourceMappingURL=user.js.map
|
|
236
|
-
//# debugId=
|
|
237
|
+
//# debugId=0dff2490-6903-5dec-aa0c-7d8bd2ac7c23
|
package/dist/routers/user.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.js","sources":["routers/user.ts"],"sourceRoot":"/","sourcesContent":["import { z } from \"zod\";\nimport { createTRPCRouter, protectedProcedure } from \"../trpc.js\";\nimport { TRPCError } from \"@trpc/server\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { createDirectUploadFiles, type DirectUploadFile } from \"../lib/fileUpload.js\";\nimport { getSignedUrl } from \"../lib/googleCloudStorage.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { bucket } from \"../lib/googleCloudStorage.js\";\n\n// Helper function to convert file path to backend proxy URL\nfunction getFileUrl(filePath: string | null): string | null {\n if (!filePath) return null;\n \n // If it's already a full URL (DiceBear or external), return as is\n if (filePath.startsWith('http')) {\n return filePath;\n }\n \n // Convert GCS path to full backend proxy URL\n const backendUrl = process.env.BACKEND_URL || 'http://localhost:3001';\n return `${backendUrl}/api/files/${encodeURIComponent(filePath)}`;\n}\n\n// For direct file uploads (file already uploaded to GCS)\nconst fileUploadSchema = z.object({\n filePath: z.string().min(1, \"File path is required\"),\n fileName: z.string().min(1, \"File name is required\"),\n fileType: z.string().regex(/^image\\/(jpeg|jpg|png|gif|webp)$/i, \"Only image files (JPEG, PNG, GIF, WebP) are allowed\"),\n fileSize: z.number().max(5 * 1024 * 1024, \"File size must be less than 5MB\"),\n});\n\n// For DiceBear avatar URL\nconst dicebearSchema = z.object({\n url: z.string().url(\"Invalid DiceBear avatar URL\"),\n});\n\nconst profileSchema = z.object({\n displayName: z.string().nullable().optional().transform(val => val === null ? undefined : val),\n bio: z.string().nullable().optional().transform(val => val === null ? undefined : val),\n location: z.string().nullable().optional().transform(val => val === null ? undefined : val),\n website: z.union([\n z.string().url(),\n z.literal(\"\"),\n z.null().transform(() => undefined)\n ]).optional(),\n});\n\nconst updateProfileSchema = z.object({\n profile: profileSchema.optional(),\n // Support both custom file upload and DiceBear avatar\n profilePicture: fileUploadSchema.optional(),\n dicebearAvatar: dicebearSchema.optional(),\n});\n\nconst getUploadUrlSchema = z.object({\n fileName: z.string().min(1, \"File name is required\"),\n fileType: z.string().regex(/^image\\/(jpeg|jpg|png|gif|webp)$/i, \"Only image files are allowed\"),\n});\n\nexport const userRouter = createTRPCRouter({\n getProfile: protectedProcedure\n .query(async ({ ctx }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n\n const user = await prisma.user.findUnique({\n where: { id: ctx.user.id },\n select: {\n id: true,\n username: true,\n },\n });\n\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n\n // Get user profile separately\n const userProfile = await prisma.userProfile.findUnique({\n where: { userId: ctx.user.id },\n });\n\n return {\n id: user.id,\n username: user.username,\n profile: userProfile ? {\n displayName: (userProfile as any).displayName || null,\n bio: (userProfile as any).bio || null,\n location: (userProfile as any).location || null,\n website: (userProfile as any).website || null,\n profilePicture: getFileUrl((userProfile as any).profilePicture),\n profilePictureThumbnail: getFileUrl((userProfile as any).profilePictureThumbnail),\n } : {\n displayName: null,\n bio: null,\n location: null,\n website: null,\n profilePicture: null,\n profilePictureThumbnail: null,\n },\n };\n }),\n\n updateProfile: protectedProcedure\n .input(updateProfileSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n\n // Get current profile to clean up old profile picture\n const currentProfile = await prisma.userProfile.findUnique({\n where: { userId: ctx.user.id },\n });\n\n let profilePictureUrl: string | null = null;\n let profilePictureThumbnail: string | null = null;\n\n // Handle custom profile picture (already uploaded to GCS)\n if (input.profilePicture) {\n try {\n // File is already uploaded to GCS, just use the path\n profilePictureUrl = input.profilePicture.filePath;\n \n // Generate thumbnail for the uploaded file\n // TODO: Implement thumbnail generation for direct uploads\n profilePictureThumbnail = null;\n\n // Clean up old profile picture if it exists\n if ((currentProfile as any)?.profilePicture) {\n // TODO: Implement file deletion logic here\n // await deleteFile((currentProfile as any).profilePicture);\n }\n } catch (error) {\n logger.error('Profile picture processing failed', { \n userId: ctx.user.id, \n error: error instanceof Error ? error.message : 'Unknown error' \n });\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"Failed to process profile picture. Please try again.\",\n });\n }\n }\n\n // Handle DiceBear avatar URL\n if (input.dicebearAvatar) {\n profilePictureUrl = input.dicebearAvatar.url;\n // No thumbnail for DiceBear avatars since they're SVG URLs\n profilePictureThumbnail = null;\n }\n\n // Prepare update data\n const updateData: any = {};\n if (input.profile) {\n if (input.profile.displayName !== undefined && input.profile.displayName !== null) {\n updateData.displayName = input.profile.displayName;\n }\n if (input.profile.bio !== undefined && input.profile.bio !== null) {\n updateData.bio = input.profile.bio;\n }\n if (input.profile.location !== undefined && input.profile.location !== null) {\n updateData.location = input.profile.location;\n }\n if (input.profile.website !== undefined && input.profile.website !== null) {\n updateData.website = input.profile.website;\n }\n }\n if (profilePictureUrl !== null) updateData.profilePicture = profilePictureUrl;\n if (profilePictureThumbnail !== null) updateData.profilePictureThumbnail = profilePictureThumbnail;\n\n // Upsert user profile with structured data\n const updatedProfile = await prisma.userProfile.upsert({\n where: { userId: ctx.user.id },\n create: {\n userId: ctx.user.id,\n ...updateData,\n },\n update: {\n ...updateData,\n updatedAt: new Date(),\n },\n });\n\n // Get username for response\n const user = await prisma.user.findUnique({\n where: { id: ctx.user.id },\n select: { username: true },\n });\n\n return {\n id: ctx.user.id,\n username: user?.username || '',\n profile: {\n displayName: (updatedProfile as any).displayName || null,\n bio: (updatedProfile as any).bio || null,\n location: (updatedProfile as any).location || null,\n website: (updatedProfile as any).website || null,\n profilePicture: getFileUrl((updatedProfile as any).profilePicture),\n profilePictureThumbnail: getFileUrl((updatedProfile as any).profilePictureThumbnail),\n },\n };\n }),\n\n getUploadUrl: protectedProcedure\n .input(getUploadUrlSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n\n try {\n // Generate unique filename\n const fileExtension = input.fileName.split('.').pop();\n const uniqueFilename = `${ctx.user.id}-${Date.now()}.${fileExtension}`;\n const filePath = `users/${ctx.user.id}/profile/${uniqueFilename}`;\n\n // Generate backend proxy upload URL instead of direct GCS signed URL\n const backendUrl = process.env.BACKEND_URL || 'http://localhost:3001';\n const uploadUrl = `${backendUrl}/api/upload/${encodeURIComponent(filePath)}`;\n\n logger.info('Generated upload URL', {\n userId: ctx.user.id,\n filePath,\n fileName: uniqueFilename,\n fileType: input.fileType,\n uploadUrl\n });\n\n return {\n uploadUrl,\n filePath,\n fileName: uniqueFilename,\n };\n } catch (error) {\n logger.error('Failed to generate upload URL', { \n userId: ctx.user.id, \n error: error instanceof Error ? error.message : 'Unknown error' \n });\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"Failed to generate upload URL\",\n });\n }\n }),\n}); "],"names":[],"mappings":"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","debug_id":"9fd79d80-c720-5d04-af6a-a66a555d5f74"}
|
|
1
|
+
{"version":3,"file":"user.js","sources":["routers/user.ts"],"sourceRoot":"/","sourcesContent":["import { z } from \"zod\";\nimport { createTRPCRouter, protectedProcedure } from \"../trpc.js\";\nimport { TRPCError } from \"@trpc/server\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { createDirectUploadFiles, type DirectUploadFile } from \"../lib/fileUpload.js\";\nimport { getSignedUrl } from \"../lib/googleCloudStorage.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { bucket } from \"../lib/googleCloudStorage.js\";\nimport { env } from \"../lib/config/env.js\";\n\n// Helper function to convert file path to backend proxy URL\nfunction getFileUrl(filePath: string | null): string | null {\n if (!filePath) return null;\n \n // If it's already a full URL (DiceBear or external), return as is\n if (filePath.startsWith('http')) {\n return filePath;\n }\n \n // Convert GCS path to full backend proxy URL\n const backendUrl = env.BACKEND_URL || 'http://localhost:3001';\n return `${backendUrl}/api/files/${encodeURIComponent(filePath)}`;\n}\n\n// For direct file uploads (file already uploaded to GCS)\nconst fileUploadSchema = z.object({\n filePath: z.string().min(1, \"File path is required\"),\n fileName: z.string().min(1, \"File name is required\"),\n fileType: z.string().regex(/^image\\/(jpeg|jpg|png|gif|webp)$/i, \"Only image files (JPEG, PNG, GIF, WebP) are allowed\"),\n fileSize: z.number().max(5 * 1024 * 1024, \"File size must be less than 5MB\"),\n});\n\n// For DiceBear avatar URL\nconst dicebearSchema = z.object({\n url: z.string().url(\"Invalid DiceBear avatar URL\"),\n});\n\nconst profileSchema = z.object({\n displayName: z.string().nullable().optional().transform(val => val === null ? undefined : val),\n bio: z.string().nullable().optional().transform(val => val === null ? undefined : val),\n location: z.string().nullable().optional().transform(val => val === null ? undefined : val),\n website: z.union([\n z.string().url(),\n z.literal(\"\"),\n z.null().transform(() => undefined)\n ]).optional(),\n});\n\nconst updateProfileSchema = z.object({\n profile: profileSchema.optional(),\n // Support both custom file upload and DiceBear avatar\n profilePicture: fileUploadSchema.optional(),\n dicebearAvatar: dicebearSchema.optional(),\n});\n\nconst getUploadUrlSchema = z.object({\n fileName: z.string().min(1, \"File name is required\"),\n fileType: z.string().regex(/^image\\/(jpeg|jpg|png|gif|webp)$/i, \"Only image files are allowed\"),\n});\n\nexport const userRouter = createTRPCRouter({\n getProfile: protectedProcedure\n .query(async ({ ctx }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n\n const user = await prisma.user.findUnique({\n where: { id: ctx.user.id },\n select: {\n id: true,\n username: true,\n },\n });\n\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n\n // Get user profile separately\n const userProfile = await prisma.userProfile.findUnique({\n where: { userId: ctx.user.id },\n });\n\n return {\n id: user.id,\n username: user.username,\n profile: userProfile ? {\n displayName: (userProfile as any).displayName || null,\n bio: (userProfile as any).bio || null,\n location: (userProfile as any).location || null,\n website: (userProfile as any).website || null,\n profilePicture: getFileUrl((userProfile as any).profilePicture),\n profilePictureThumbnail: getFileUrl((userProfile as any).profilePictureThumbnail),\n } : {\n displayName: null,\n bio: null,\n location: null,\n website: null,\n profilePicture: null,\n profilePictureThumbnail: null,\n },\n };\n }),\n\n updateProfile: protectedProcedure\n .input(updateProfileSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n\n // Get current profile to clean up old profile picture\n const currentProfile = await prisma.userProfile.findUnique({\n where: { userId: ctx.user.id },\n });\n\n let profilePictureUrl: string | null = null;\n let profilePictureThumbnail: string | null = null;\n\n // Handle custom profile picture (already uploaded to GCS)\n if (input.profilePicture) {\n try {\n // File is already uploaded to GCS, just use the path\n profilePictureUrl = input.profilePicture.filePath;\n \n // Generate thumbnail for the uploaded file\n // TODO: Implement thumbnail generation for direct uploads\n profilePictureThumbnail = null;\n\n // Clean up old profile picture if it exists\n if ((currentProfile as any)?.profilePicture) {\n // TODO: Implement file deletion logic here\n // await deleteFile((currentProfile as any).profilePicture);\n }\n } catch (error) {\n logger.error('Profile picture processing failed', { \n userId: ctx.user.id, \n error: error instanceof Error ? error.message : 'Unknown error' \n });\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"Failed to process profile picture. Please try again.\",\n });\n }\n }\n\n // Handle DiceBear avatar URL\n if (input.dicebearAvatar) {\n profilePictureUrl = input.dicebearAvatar.url;\n // No thumbnail for DiceBear avatars since they're SVG URLs\n profilePictureThumbnail = null;\n }\n\n // Prepare update data\n const updateData: any = {};\n if (input.profile) {\n if (input.profile.displayName !== undefined && input.profile.displayName !== null) {\n updateData.displayName = input.profile.displayName;\n }\n if (input.profile.bio !== undefined && input.profile.bio !== null) {\n updateData.bio = input.profile.bio;\n }\n if (input.profile.location !== undefined && input.profile.location !== null) {\n updateData.location = input.profile.location;\n }\n if (input.profile.website !== undefined && input.profile.website !== null) {\n updateData.website = input.profile.website;\n }\n }\n if (profilePictureUrl !== null) updateData.profilePicture = profilePictureUrl;\n if (profilePictureThumbnail !== null) updateData.profilePictureThumbnail = profilePictureThumbnail;\n\n // Upsert user profile with structured data\n const updatedProfile = await prisma.userProfile.upsert({\n where: { userId: ctx.user.id },\n create: {\n userId: ctx.user.id,\n ...updateData,\n },\n update: {\n ...updateData,\n updatedAt: new Date(),\n },\n });\n\n // Get username for response\n const user = await prisma.user.findUnique({\n where: { id: ctx.user.id },\n select: { username: true },\n });\n\n return {\n id: ctx.user.id,\n username: user?.username || '',\n profile: {\n displayName: (updatedProfile as any).displayName || null,\n bio: (updatedProfile as any).bio || null,\n location: (updatedProfile as any).location || null,\n website: (updatedProfile as any).website || null,\n profilePicture: getFileUrl((updatedProfile as any).profilePicture),\n profilePictureThumbnail: getFileUrl((updatedProfile as any).profilePictureThumbnail),\n },\n };\n }),\n\n getUploadUrl: protectedProcedure\n .input(getUploadUrlSchema)\n .mutation(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"User must be authenticated\",\n });\n }\n\n try {\n // Generate unique filename\n const fileExtension = input.fileName.split('.').pop();\n const uniqueFilename = `${ctx.user.id}-${Date.now()}.${fileExtension}`;\n const filePath = `users/${ctx.user.id}/profile/${uniqueFilename}`;\n\n // Generate backend proxy upload URL instead of direct GCS signed URL\n const backendUrl = env.BACKEND_URL || 'http://localhost:3001';\n const uploadUrl = `${backendUrl}/api/upload/${encodeURIComponent(filePath)}`;\n\n logger.info('Generated upload URL', {\n userId: ctx.user.id,\n filePath,\n fileName: uniqueFilename,\n fileType: input.fileType,\n uploadUrl\n });\n\n return {\n uploadUrl,\n filePath,\n fileName: uniqueFilename,\n };\n } catch (error) {\n logger.error('Failed to generate upload URL', { \n userId: ctx.user.id, \n error: error instanceof Error ? error.message : 'Unknown error' \n });\n throw new TRPCError({\n code: \"INTERNAL_SERVER_ERROR\",\n message: \"Failed to generate upload URL\",\n });\n }\n }),\n}); "],"names":[],"mappings":"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","debug_id":"0dff2490-6903-5dec-aa0c-7d8bd2ac7c23"}
|
|
@@ -31,15 +31,15 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
31
31
|
syllabus: string | null;
|
|
32
32
|
} | null;
|
|
33
33
|
questions: {
|
|
34
|
+
options: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
34
35
|
type: import(".prisma/client").$Enums.WorksheetQuestionType;
|
|
35
36
|
id: string;
|
|
36
|
-
options: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
37
37
|
createdAt: Date;
|
|
38
38
|
order: number | null;
|
|
39
39
|
markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
40
40
|
updatedAt: Date;
|
|
41
|
-
points: number;
|
|
42
41
|
question: string;
|
|
42
|
+
points: number;
|
|
43
43
|
worksheetId: string;
|
|
44
44
|
answer: string;
|
|
45
45
|
}[];
|
|
@@ -52,6 +52,15 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
52
52
|
};
|
|
53
53
|
meta: object;
|
|
54
54
|
}>;
|
|
55
|
+
exists: import("@trpc/server").TRPCQueryProcedure<{
|
|
56
|
+
input: {
|
|
57
|
+
[x: string]: unknown;
|
|
58
|
+
classId: string;
|
|
59
|
+
id: string;
|
|
60
|
+
};
|
|
61
|
+
output: boolean;
|
|
62
|
+
meta: object;
|
|
63
|
+
}>;
|
|
55
64
|
listWorksheets: import("@trpc/server").TRPCQueryProcedure<{
|
|
56
65
|
input: {
|
|
57
66
|
classId: string;
|
|
@@ -121,15 +130,15 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
121
130
|
points?: number | undefined;
|
|
122
131
|
};
|
|
123
132
|
output: {
|
|
133
|
+
options: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
124
134
|
type: import(".prisma/client").$Enums.WorksheetQuestionType;
|
|
125
135
|
id: string;
|
|
126
|
-
options: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
127
136
|
createdAt: Date;
|
|
128
137
|
order: number | null;
|
|
129
138
|
markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
130
139
|
updatedAt: Date;
|
|
131
|
-
points: number;
|
|
132
140
|
question: string;
|
|
141
|
+
points: number;
|
|
133
142
|
worksheetId: string;
|
|
134
143
|
answer: string;
|
|
135
144
|
};
|
|
@@ -137,10 +146,10 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
137
146
|
}>;
|
|
138
147
|
reorderQuestions: import("@trpc/server").TRPCMutationProcedure<{
|
|
139
148
|
input: {
|
|
149
|
+
worksheetId: string;
|
|
140
150
|
movedId: string;
|
|
141
151
|
position: "before" | "after";
|
|
142
152
|
targetId: string;
|
|
143
|
-
worksheetId: string;
|
|
144
153
|
};
|
|
145
154
|
output: {
|
|
146
155
|
id: string;
|
|
@@ -149,25 +158,25 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
149
158
|
}>;
|
|
150
159
|
updateQuestion: import("@trpc/server").TRPCMutationProcedure<{
|
|
151
160
|
input: {
|
|
152
|
-
worksheetId: string;
|
|
153
161
|
questionId: string;
|
|
154
|
-
|
|
162
|
+
worksheetId: string;
|
|
155
163
|
options?: any;
|
|
164
|
+
type?: "ESSAY" | "MULTIPLE_CHOICE" | "TRUE_FALSE" | "SHORT_ANSWER" | "LONG_ANSWER" | "MATH_EXPRESSION" | undefined;
|
|
156
165
|
markScheme?: any;
|
|
157
|
-
points?: number | undefined;
|
|
158
166
|
question?: string | undefined;
|
|
167
|
+
points?: number | undefined;
|
|
159
168
|
answer?: string | undefined;
|
|
160
169
|
};
|
|
161
170
|
output: {
|
|
171
|
+
options: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
162
172
|
type: import(".prisma/client").$Enums.WorksheetQuestionType;
|
|
163
173
|
id: string;
|
|
164
|
-
options: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
165
174
|
createdAt: Date;
|
|
166
175
|
order: number | null;
|
|
167
176
|
markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
168
177
|
updatedAt: Date;
|
|
169
|
-
points: number;
|
|
170
178
|
question: string;
|
|
179
|
+
points: number;
|
|
171
180
|
worksheetId: string;
|
|
172
181
|
answer: string;
|
|
173
182
|
};
|
|
@@ -175,19 +184,19 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
175
184
|
}>;
|
|
176
185
|
deleteQuestion: import("@trpc/server").TRPCMutationProcedure<{
|
|
177
186
|
input: {
|
|
178
|
-
worksheetId: string;
|
|
179
187
|
questionId: string;
|
|
188
|
+
worksheetId: string;
|
|
180
189
|
};
|
|
181
190
|
output: {
|
|
191
|
+
options: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
182
192
|
type: import(".prisma/client").$Enums.WorksheetQuestionType;
|
|
183
193
|
id: string;
|
|
184
|
-
options: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
185
194
|
createdAt: Date;
|
|
186
195
|
order: number | null;
|
|
187
196
|
markScheme: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
188
197
|
updatedAt: Date;
|
|
189
|
-
points: number;
|
|
190
198
|
question: string;
|
|
199
|
+
points: number;
|
|
191
200
|
worksheetId: string;
|
|
192
201
|
answer: string;
|
|
193
202
|
};
|
|
@@ -204,17 +213,18 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
204
213
|
id: string;
|
|
205
214
|
}[];
|
|
206
215
|
} & {
|
|
216
|
+
status: import(".prisma/client").$Enums.GenerationStatus | null;
|
|
207
217
|
id: string;
|
|
208
218
|
feedback: string | null;
|
|
209
219
|
studentId: string;
|
|
210
220
|
createdAt: Date;
|
|
211
221
|
updatedAt: Date | null;
|
|
212
|
-
points: number;
|
|
213
222
|
questionId: string;
|
|
214
223
|
response: string;
|
|
215
|
-
studentWorksheetResponseId: string | null;
|
|
216
224
|
isCorrect: boolean;
|
|
217
225
|
markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
226
|
+
points: number;
|
|
227
|
+
studentWorksheetResponseId: string | null;
|
|
218
228
|
})[];
|
|
219
229
|
} & {
|
|
220
230
|
id: string;
|
|
@@ -231,22 +241,23 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
231
241
|
answerQuestion: import("@trpc/server").TRPCMutationProcedure<{
|
|
232
242
|
input: {
|
|
233
243
|
questionId: string;
|
|
234
|
-
worksheetResponseId: string;
|
|
235
244
|
response: string;
|
|
245
|
+
worksheetResponseId: string;
|
|
236
246
|
};
|
|
237
247
|
output: ({
|
|
238
248
|
responses: {
|
|
249
|
+
status: import(".prisma/client").$Enums.GenerationStatus | null;
|
|
239
250
|
id: string;
|
|
240
251
|
feedback: string | null;
|
|
241
252
|
studentId: string;
|
|
242
253
|
createdAt: Date;
|
|
243
254
|
updatedAt: Date | null;
|
|
244
|
-
points: number;
|
|
245
255
|
questionId: string;
|
|
246
256
|
response: string;
|
|
247
|
-
studentWorksheetResponseId: string | null;
|
|
248
257
|
isCorrect: boolean;
|
|
249
258
|
markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
259
|
+
points: number;
|
|
260
|
+
studentWorksheetResponseId: string | null;
|
|
250
261
|
}[];
|
|
251
262
|
} & {
|
|
252
263
|
id: string;
|
|
@@ -260,46 +271,37 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
260
271
|
}) | null;
|
|
261
272
|
meta: object;
|
|
262
273
|
}>;
|
|
263
|
-
|
|
274
|
+
cancelAutoGrading: import("@trpc/server").TRPCMutationProcedure<{
|
|
264
275
|
input: {
|
|
276
|
+
questionId: string;
|
|
265
277
|
worksheetResponseId: string;
|
|
266
278
|
};
|
|
267
279
|
output: {
|
|
268
|
-
|
|
269
|
-
id: string;
|
|
270
|
-
feedback: string | null;
|
|
271
|
-
studentId: string;
|
|
272
|
-
createdAt: Date;
|
|
273
|
-
updatedAt: Date | null;
|
|
274
|
-
points: number;
|
|
275
|
-
questionId: string;
|
|
276
|
-
response: string;
|
|
277
|
-
studentWorksheetResponseId: string | null;
|
|
278
|
-
isCorrect: boolean;
|
|
279
|
-
markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
280
|
-
}[];
|
|
281
|
-
} & {
|
|
280
|
+
status: import(".prisma/client").$Enums.GenerationStatus | null;
|
|
282
281
|
id: string;
|
|
283
|
-
|
|
282
|
+
feedback: string | null;
|
|
284
283
|
studentId: string;
|
|
285
284
|
createdAt: Date;
|
|
286
|
-
updatedAt: Date;
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
285
|
+
updatedAt: Date | null;
|
|
286
|
+
questionId: string;
|
|
287
|
+
response: string;
|
|
288
|
+
isCorrect: boolean;
|
|
289
|
+
markschemeState: import("@prisma/client/runtime/library.js").JsonValue | null;
|
|
290
|
+
points: number;
|
|
291
|
+
studentWorksheetResponseId: string | null;
|
|
290
292
|
};
|
|
291
293
|
meta: object;
|
|
292
294
|
}>;
|
|
293
295
|
gradeAnswer: import("@trpc/server").TRPCMutationProcedure<{
|
|
294
296
|
input: {
|
|
295
297
|
questionId: string;
|
|
296
|
-
studentWorksheetResponseId: string;
|
|
297
298
|
isCorrect: boolean;
|
|
299
|
+
studentWorksheetResponseId: string;
|
|
298
300
|
feedback?: string | undefined;
|
|
299
|
-
points?: number | undefined;
|
|
300
301
|
response?: string | undefined;
|
|
301
|
-
responseId?: string | undefined;
|
|
302
302
|
markschemeState?: any;
|
|
303
|
+
points?: number | undefined;
|
|
304
|
+
responseId?: string | undefined;
|
|
303
305
|
};
|
|
304
306
|
output: any;
|
|
305
307
|
meta: object;
|
|
@@ -310,6 +312,7 @@ export declare const worksheetRouter: import("@trpc/server").TRPCBuiltRouter<{
|
|
|
310
312
|
responseId: string;
|
|
311
313
|
};
|
|
312
314
|
output: {
|
|
315
|
+
status: import(".prisma/client").$Enums.GenerationStatus | null;
|
|
313
316
|
id: string;
|
|
314
317
|
content: string;
|
|
315
318
|
createdAt: Date;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["routers/worksheet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"worksheet.d.ts","sourceRoot":"/","sources":["routers/worksheet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA8LA,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6UhC,CAAC"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
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]="
|
|
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]="2c030eda-ac5e-571a-992d-93eceb0062bc")}catch(e){}}();
|
|
3
3
|
import { TRPCError } from "@trpc/server";
|
|
4
|
-
import { createTRPCRouter, protectedProcedure } from "../trpc.js";
|
|
4
|
+
import { createTRPCRouter, protectedClassMemberProcedure, protectedProcedure } from "../trpc.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { prisma } from "../lib/prisma.js";
|
|
7
|
+
import { GenerationStatus } from "@prisma/client";
|
|
7
8
|
export const worksheetRouter = createTRPCRouter({
|
|
8
9
|
// Get a single worksheet with all questions
|
|
9
10
|
getWorksheet: protectedProcedure
|
|
@@ -27,6 +28,19 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
27
28
|
}
|
|
28
29
|
return worksheet;
|
|
29
30
|
}),
|
|
31
|
+
exists: protectedClassMemberProcedure
|
|
32
|
+
.input(z.object({
|
|
33
|
+
id: z.string(),
|
|
34
|
+
}))
|
|
35
|
+
.query(async ({ ctx, input }) => {
|
|
36
|
+
if (!ctx.user) {
|
|
37
|
+
throw new TRPCError({ code: 'UNAUTHORIZED', message: 'User must be authenticated' });
|
|
38
|
+
}
|
|
39
|
+
const worksheet = await prisma.worksheet.findUnique({
|
|
40
|
+
where: { id: input.id },
|
|
41
|
+
});
|
|
42
|
+
return worksheet ? true : false;
|
|
43
|
+
}),
|
|
30
44
|
// List all worksheets for a class
|
|
31
45
|
listWorksheets: protectedProcedure
|
|
32
46
|
.input(z.object({
|
|
@@ -309,6 +323,7 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
309
323
|
data: { response,
|
|
310
324
|
...(isMarkableByAlgo && { isCorrect: response === correctAnswer }),
|
|
311
325
|
...(isMarkableByAlgo && { points: response === correctAnswer ? marksAwardedIfCorrect : 0 }),
|
|
326
|
+
status: GenerationStatus.NOT_STARTED,
|
|
312
327
|
},
|
|
313
328
|
});
|
|
314
329
|
}
|
|
@@ -334,44 +349,20 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
334
349
|
});
|
|
335
350
|
return updatedWorksheetResponse;
|
|
336
351
|
}),
|
|
337
|
-
|
|
352
|
+
cancelAutoGrading: protectedProcedure
|
|
338
353
|
.input(z.object({
|
|
339
354
|
worksheetResponseId: z.string(),
|
|
355
|
+
questionId: z.string(),
|
|
340
356
|
}))
|
|
341
357
|
.mutation(async ({ ctx, input }) => {
|
|
342
|
-
const { worksheetResponseId } = input;
|
|
343
|
-
const
|
|
344
|
-
where: { id: worksheetResponseId },
|
|
345
|
-
include: {
|
|
346
|
-
worksheet: {
|
|
347
|
-
include: {
|
|
348
|
-
questions: true,
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
responses: true,
|
|
352
|
-
},
|
|
353
|
-
});
|
|
354
|
-
if (!worksheetResponse) {
|
|
355
|
-
throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet response not found' });
|
|
356
|
-
}
|
|
357
|
-
if (worksheetResponse.submitted) {
|
|
358
|
-
throw new TRPCError({ code: 'BAD_REQUEST', message: 'Worksheet already submitted' });
|
|
359
|
-
}
|
|
360
|
-
// Mark worksheet as submitted
|
|
361
|
-
const submittedWorksheet = await prisma.studentWorksheetResponse.update({
|
|
362
|
-
where: { id: worksheetResponseId },
|
|
358
|
+
const { worksheetResponseId, questionId } = input;
|
|
359
|
+
const updatedQuestion = await prisma.studentQuestionProgress.update({
|
|
360
|
+
where: { id: questionId, studentWorksheetResponseId: worksheetResponseId },
|
|
363
361
|
data: {
|
|
364
|
-
|
|
365
|
-
submittedAt: new Date(),
|
|
366
|
-
},
|
|
367
|
-
include: {
|
|
368
|
-
responses: true,
|
|
362
|
+
status: GenerationStatus.CANCELLED,
|
|
369
363
|
},
|
|
370
364
|
});
|
|
371
|
-
|
|
372
|
-
// For now, we'll just mark all answers as pending review
|
|
373
|
-
// You could integrate with an AI service to auto-grade certain question types
|
|
374
|
-
return submittedWorksheet;
|
|
365
|
+
return updatedQuestion;
|
|
375
366
|
}),
|
|
376
367
|
// Grade a student's answer
|
|
377
368
|
gradeAnswer: protectedProcedure
|
|
@@ -470,4 +461,4 @@ export const worksheetRouter = createTRPCRouter({
|
|
|
470
461
|
}),
|
|
471
462
|
});
|
|
472
463
|
//# sourceMappingURL=worksheet.js.map
|
|
473
|
-
//# debugId=
|
|
464
|
+
//# debugId=2c030eda-ac5e-571a-992d-93eceb0062bc
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worksheet.js","sources":["routers/worksheet.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from \"@trpc/server\";\nimport { createTRPCRouter, protectedProcedure } from \"../trpc.js\";\nimport { z } from \"zod\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { WorksheetQuestionType } from \"@prisma/client\";\nimport { commentSelect } from \"./comment.js\";\n\ntype MCQOptions = {\n id: string;\n text: string;\n isCorrect: boolean;\n}[];\n\nexport const worksheetRouter = createTRPCRouter({\n // Get a single worksheet with all questions\n getWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { worksheetId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n include: {\n questions: {\n orderBy: { createdAt: 'asc' },\n // select: { id: true, type: true, question: true, answer: true, points: true },\n },\n class: true,\n },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n return worksheet;\n }),\n\n // List all worksheets for a class\n listWorksheets: protectedProcedure\n .input(z.object({\n classId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { classId } = input;\n\n const worksheets = await prisma.worksheet.findMany({\n where: { classId },\n include: {\n questions: {\n select: { id: true },\n },\n },\n orderBy: { createdAt: 'desc' },\n });\n\n return worksheets.map(worksheet => ({\n ...worksheet,\n questionCount: worksheet.questions.length,\n }));\n }),\n\n // Update worksheet metadata\n updateWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n name: z.string().optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, name } = input;\n\n const worksheet = await prisma.worksheet.update({\n where: { id: worksheetId },\n data: {\n ...(name !== undefined && { name }),\n },\n });\n\n return worksheet;\n }),\n\n // Delete a worksheet\n deleteWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId } = input;\n\n // This will cascade delete all questions and responses\n const deletedWorksheet = await prisma.worksheet.delete({\n where: { id: worksheetId },\n });\n\n return deletedWorksheet;\n }),\n\n create: protectedProcedure\n .input(z.object({\n classId: z.string(),\n name: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { classId, name } = input;\n\n // Create the worksheet\n const worksheet = await prisma.worksheet.create({\n data: {\n name,\n classId,\n },\n });\n\n return worksheet;\n }),\n addQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n question: z.string(),\n answer: z.string(),\n points: z.number().optional(),\n options: z.any().optional(), // JSON field\n markScheme: z.any().optional(), // JSON field\n type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, question, points, answer, options, markScheme, type } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const newQuestion = await prisma.worksheetQuestion.create({\n data: {\n worksheetId,\n type,\n points,\n question,\n answer,\n options,\n markScheme,\n },\n });\n\n return newQuestion;\n }),\n reorderQuestions: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n movedId: z.string(),\n position: z.enum(['before', 'after']),\n targetId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, movedId, position, targetId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const questions = await prisma.worksheetQuestion.findMany({\n where: { worksheetId },\n orderBy: { order: 'asc' },\n });\n\n const movedIdx = questions.findIndex(question => question.id === movedId);\n if (movedIdx === -1) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Moved question not found' });\n }\n\n const targetIdx = questions.findIndex(question => question.id === targetId);\n if (targetIdx === -1) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Target question not found' });\n }\n\n const withoutMoved = questions.filter(question => question.id !== movedId);\n\n let next: Array<{ id: string }> = [];\n\n if (position === 'before') {\n next = [...withoutMoved.slice(0, targetIdx).map(item => ({ id: item.id })), { id: movedId }, ...withoutMoved.slice(targetIdx).map(item => ({ id: item.id }))];\n } else {\n next = [...withoutMoved.slice(0, targetIdx + 1).map(item => ({ id: item.id })), { id: movedId }, ...withoutMoved.slice(targetIdx + 1).map(item => ({ id: item.id }))];\n }\n\n // Update the order of each question\n await prisma.$transaction(\n next.map((item, index) =>\n prisma.worksheetQuestion.update({\n where: { id: item.id },\n data: { order: index },\n })\n )\n );\n\n return next;\n }),\n updateQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n question: z.string().optional(),\n answer: z.string().optional(),\n points: z.number().optional(),\n options: z.any().optional(), // JSON field\n markScheme: z.any().optional(), // JSON field\n type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']).optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, questionId, points, question, answer, options, markScheme, type } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const updatedQuestion = await prisma.worksheetQuestion.update({\n where: { id: questionId },\n data: {\n ...(question !== undefined && { question }),\n ...(answer !== undefined && { answer }),\n ...(markScheme !== undefined && { markScheme }),\n ...(type !== undefined && { type }),\n ...(options !== undefined && { options }),\n ...(points !== undefined && { points }),\n },\n });\n\n return updatedQuestion;\n }),\n deleteQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, questionId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const deletedQuestion = await prisma.worksheetQuestion.delete({\n where: { id: questionId },\n });\n\n return deletedQuestion;\n }),\n\n getWorksheetSubmission: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n submissionId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { worksheetId, submissionId } = input;\n\n const submission = await prisma.submission.findUnique({\n where: { id: submissionId },\n });\n\n if (!submission) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Submission not found' });\n }\n\n // Find or create worksheet response for this submission\n const worksheetResponse = await prisma.$transaction(async (tx) => {\n // First check if a response exists\n const existing = await tx.studentWorksheetResponse.findFirst({\n where: { \n submissionId,\n worksheetId \n },\n include: {\n responses: {\n include: {\n comments: {\n select: {\n id: true,\n },\n },\n },\n },\n },\n });\n\n if (existing) {\n return existing;\n }\n\n // Create new response if it doesn't exist\n const created = await tx.studentWorksheetResponse.create({\n data: {\n worksheetId,\n submissionId,\n studentId: submission.studentId,\n },\n include: {\n responses: {\n include: {\n comments: {\n select: {\n id: true,\n },\n },\n },\n },\n },\n });\n\n return created;\n });\n\n\n return worksheetResponse;\n }),\n answerQuestion: protectedProcedure\n .input(z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n response: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetResponseId, questionId, response } = input;\n\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n responses: {\n where: { questionId },\n },\n },\n });\n\n if (!worksheetResponse) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet response not found' });\n }\n\n const question = await prisma.worksheetQuestion.findUnique({\n where: { id: questionId },\n });\n\n const isMarkableByAlgo = question?.type === 'MULTIPLE_CHOICE' || question?.type === 'TRUE_FALSE';\n const marksAwardedIfCorrect = question?.points || 0;\n \n const correctAnswer = isMarkableByAlgo ? (question?.type === 'MULTIPLE_CHOICE' ? (question?.options as MCQOptions).find((option) => option.isCorrect)?.id : question?.answer.toString()) : null;\n\n // Check if a response already exists for this question\n const existingResponse = worksheetResponse.responses[0];\n\n if (existingResponse) {\n // Update existing response\n await prisma.studentQuestionProgress.update({\n where: { id: existingResponse.id },\n data: { response, \n ...(isMarkableByAlgo && { isCorrect: response === correctAnswer }),\n ...(isMarkableByAlgo && { points: response === correctAnswer ? marksAwardedIfCorrect : 0 }),\n },\n });\n } else {\n // Create new response\n await prisma.studentQuestionProgress.create({\n data: {\n studentId: worksheetResponse.studentId,\n questionId,\n response,\n studentWorksheetResponseId: worksheetResponseId,\n ...(isMarkableByAlgo && { isCorrect: response === correctAnswer }),\n ...(isMarkableByAlgo && { points: response === correctAnswer ? marksAwardedIfCorrect : 0 }),\n },\n });\n }\n\n // Return the updated worksheet response with all responses\n const updatedWorksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n responses: true,\n },\n });\n\n return updatedWorksheetResponse;\n }),\n submitWorksheet: protectedProcedure\n .input(z.object({\n worksheetResponseId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetResponseId } = input;\n\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n worksheet: {\n include: {\n questions: true,\n },\n },\n responses: true,\n },\n });\n\n if (!worksheetResponse) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet response not found' });\n }\n\n if (worksheetResponse.submitted) {\n throw new TRPCError({ code: 'BAD_REQUEST', message: 'Worksheet already submitted' });\n }\n\n // Mark worksheet as submitted\n const submittedWorksheet = await prisma.studentWorksheetResponse.update({\n where: { id: worksheetResponseId },\n data: {\n submitted: true,\n submittedAt: new Date(),\n },\n include: {\n responses: true,\n },\n });\n\n // TODO: Implement AI grading here\n // For now, we'll just mark all answers as pending review\n // You could integrate with an AI service to auto-grade certain question types\n \n return submittedWorksheet;\n }),\n\n // Grade a student's answer\n gradeAnswer: protectedProcedure\n .input(z.object({\n questionId: z.string(),\n responseId: z.string().optional(), // StudentQuestionProgress ID (optional for upsert)\n studentWorksheetResponseId: z.string(), // Required for linking to worksheet response\n response: z.string().optional(), // The actual response text (needed if creating new)\n isCorrect: z.boolean(),\n feedback: z.string().optional(),\n markschemeState: z.any().optional(),\n points: z.number().optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { responseId, questionId, studentWorksheetResponseId, response, isCorrect, feedback, markschemeState, points } = input;\n\n let gradedResponse;\n \n if (responseId) {\n // Update existing progress by ID\n gradedResponse = await prisma.studentQuestionProgress.update({\n where: { id: responseId },\n data: {\n isCorrect,\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points }),\n },\n });\n } else {\n // Get the studentId from the worksheet response\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: studentWorksheetResponseId },\n select: { studentId: true },\n });\n\n if (!worksheetResponse) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Student worksheet response not found',\n });\n }\n\n const { studentId } = worksheetResponse;\n\n // Upsert - find or create the progress record\n const existing = await prisma.studentQuestionProgress.findFirst({\n where: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n },\n });\n\n if (existing) {\n // Update existing\n gradedResponse = await prisma.studentQuestionProgress.update({\n where: { id: existing.id },\n data: {\n isCorrect,\n ...(response !== undefined && { response }),\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points }),\n },\n });\n } else {\n // Create new\n gradedResponse = await prisma.studentQuestionProgress.create({\n data: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n response: response || '',\n isCorrect,\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points: points || 0 }),\n },\n });\n }\n }\n\n return gradedResponse;\n }),\n addComment: protectedProcedure\n .input(z.object({\n responseId: z.string(),\n comment: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { responseId, comment } = input;\n\n const newComment = await prisma.comment.create({\n data: {\n studentQuestionProgressId: responseId,\n content: comment,\n authorId: ctx.user!.id,\n },\n });\n\n return newComment;\n }),\n});"],"names":[],"mappings":"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","debug_id":"3cc2db02-83f1-58c4-86e4-295f862282b9"}
|
|
1
|
+
{"version":3,"file":"worksheet.js","sources":["routers/worksheet.ts"],"sourceRoot":"/","sourcesContent":["import { TRPCError } from \"@trpc/server\";\nimport { createTRPCRouter, protectedClassMemberProcedure, protectedProcedure } from \"../trpc.js\";\nimport { z } from \"zod\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { GenerationStatus, WorksheetQuestionType } from \"@prisma/client\";\nimport { commentSelect } from \"./comment.js\";\n\ntype MCQOptions = {\n id: string;\n text: string;\n isCorrect: boolean;\n}[];\n\nexport const worksheetRouter = createTRPCRouter({\n // Get a single worksheet with all questions\n getWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { worksheetId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n include: {\n questions: {\n orderBy: { createdAt: 'asc' },\n // select: { id: true, type: true, question: true, answer: true, points: true },\n },\n class: true,\n },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n return worksheet;\n }),\n\n exists: protectedClassMemberProcedure\n .input(z.object({\n id: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n if (!ctx.user) {\n throw new TRPCError({ code: 'UNAUTHORIZED', message: 'User must be authenticated' });\n }\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: input.id },\n });\n\n return worksheet ? true : false;\n }),\n\n // List all worksheets for a class\n listWorksheets: protectedProcedure\n .input(z.object({\n classId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { classId } = input;\n\n const worksheets = await prisma.worksheet.findMany({\n where: { classId },\n include: {\n questions: {\n select: { id: true },\n },\n },\n orderBy: { createdAt: 'desc' },\n });\n\n return worksheets.map(worksheet => ({\n ...worksheet,\n questionCount: worksheet.questions.length,\n }));\n }),\n\n // Update worksheet metadata\n updateWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n name: z.string().optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, name } = input;\n\n const worksheet = await prisma.worksheet.update({\n where: { id: worksheetId },\n data: {\n ...(name !== undefined && { name }),\n },\n });\n\n return worksheet;\n }),\n\n // Delete a worksheet\n deleteWorksheet: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId } = input;\n\n // This will cascade delete all questions and responses\n const deletedWorksheet = await prisma.worksheet.delete({\n where: { id: worksheetId },\n });\n\n return deletedWorksheet;\n }),\n\n create: protectedProcedure\n .input(z.object({\n classId: z.string(),\n name: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { classId, name } = input;\n\n // Create the worksheet\n const worksheet = await prisma.worksheet.create({\n data: {\n name,\n classId,\n },\n });\n\n return worksheet;\n }),\n addQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n question: z.string(),\n answer: z.string(),\n points: z.number().optional(),\n options: z.any().optional(), // JSON field\n markScheme: z.any().optional(), // JSON field\n type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, question, points, answer, options, markScheme, type } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const newQuestion = await prisma.worksheetQuestion.create({\n data: {\n worksheetId,\n type,\n points,\n question,\n answer,\n options,\n markScheme,\n },\n });\n\n return newQuestion;\n }),\n reorderQuestions: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n movedId: z.string(),\n position: z.enum(['before', 'after']),\n targetId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, movedId, position, targetId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const questions = await prisma.worksheetQuestion.findMany({\n where: { worksheetId },\n orderBy: { order: 'asc' },\n });\n\n const movedIdx = questions.findIndex(question => question.id === movedId);\n if (movedIdx === -1) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Moved question not found' });\n }\n\n const targetIdx = questions.findIndex(question => question.id === targetId);\n if (targetIdx === -1) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Target question not found' });\n }\n\n const withoutMoved = questions.filter(question => question.id !== movedId);\n\n let next: Array<{ id: string }> = [];\n\n if (position === 'before') {\n next = [...withoutMoved.slice(0, targetIdx).map(item => ({ id: item.id })), { id: movedId }, ...withoutMoved.slice(targetIdx).map(item => ({ id: item.id }))];\n } else {\n next = [...withoutMoved.slice(0, targetIdx + 1).map(item => ({ id: item.id })), { id: movedId }, ...withoutMoved.slice(targetIdx + 1).map(item => ({ id: item.id }))];\n }\n\n // Update the order of each question\n await prisma.$transaction(\n next.map((item, index) =>\n prisma.worksheetQuestion.update({\n where: { id: item.id },\n data: { order: index },\n })\n )\n );\n\n return next;\n }),\n updateQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n question: z.string().optional(),\n answer: z.string().optional(),\n points: z.number().optional(),\n options: z.any().optional(), // JSON field\n markScheme: z.any().optional(), // JSON field\n type: z.enum(['MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY']).optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, questionId, points, question, answer, options, markScheme, type } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const updatedQuestion = await prisma.worksheetQuestion.update({\n where: { id: questionId },\n data: {\n ...(question !== undefined && { question }),\n ...(answer !== undefined && { answer }),\n ...(markScheme !== undefined && { markScheme }),\n ...(type !== undefined && { type }),\n ...(options !== undefined && { options }),\n ...(points !== undefined && { points }),\n },\n });\n\n return updatedQuestion;\n }),\n deleteQuestion: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n questionId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetId, questionId } = input;\n\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId },\n });\n\n if (!worksheet) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet not found' });\n }\n\n const deletedQuestion = await prisma.worksheetQuestion.delete({\n where: { id: questionId },\n });\n\n return deletedQuestion;\n }),\n\n getWorksheetSubmission: protectedProcedure\n .input(z.object({\n worksheetId: z.string(),\n submissionId: z.string(),\n }))\n .query(async ({ ctx, input }) => {\n const { worksheetId, submissionId } = input;\n\n const submission = await prisma.submission.findUnique({\n where: { id: submissionId },\n });\n\n if (!submission) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Submission not found' });\n }\n\n // Find or create worksheet response for this submission\n const worksheetResponse = await prisma.$transaction(async (tx) => {\n // First check if a response exists\n const existing = await tx.studentWorksheetResponse.findFirst({\n where: { \n submissionId,\n worksheetId \n },\n include: {\n responses: {\n include: {\n comments: {\n select: {\n id: true,\n },\n },\n },\n },\n },\n });\n\n if (existing) {\n return existing;\n }\n\n // Create new response if it doesn't exist\n const created = await tx.studentWorksheetResponse.create({\n data: {\n worksheetId,\n submissionId,\n studentId: submission.studentId,\n },\n include: {\n responses: {\n include: {\n comments: {\n select: {\n id: true,\n },\n },\n },\n },\n },\n });\n\n return created;\n });\n\n\n return worksheetResponse;\n }),\n answerQuestion: protectedProcedure\n .input(z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n response: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetResponseId, questionId, response } = input;\n\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n responses: {\n where: { questionId },\n },\n },\n });\n\n if (!worksheetResponse) {\n throw new TRPCError({ code: 'NOT_FOUND', message: 'Worksheet response not found' });\n }\n\n const question = await prisma.worksheetQuestion.findUnique({\n where: { id: questionId },\n });\n\n const isMarkableByAlgo = question?.type === 'MULTIPLE_CHOICE' || question?.type === 'TRUE_FALSE';\n const marksAwardedIfCorrect = question?.points || 0;\n \n const correctAnswer = isMarkableByAlgo ? (question?.type === 'MULTIPLE_CHOICE' ? (question?.options as MCQOptions).find((option) => option.isCorrect)?.id : question?.answer.toString()) : null;\n\n // Check if a response already exists for this question\n const existingResponse = worksheetResponse.responses[0];\n\n if (existingResponse) {\n // Update existing response\n await prisma.studentQuestionProgress.update({\n where: { id: existingResponse.id },\n data: { response, \n ...(isMarkableByAlgo && { isCorrect: response === correctAnswer }),\n ...(isMarkableByAlgo && { points: response === correctAnswer ? marksAwardedIfCorrect : 0 }),\n status: GenerationStatus.NOT_STARTED,\n },\n });\n } else {\n // Create new response\n await prisma.studentQuestionProgress.create({\n data: {\n studentId: worksheetResponse.studentId,\n questionId,\n response,\n studentWorksheetResponseId: worksheetResponseId,\n ...(isMarkableByAlgo && { isCorrect: response === correctAnswer }),\n ...(isMarkableByAlgo && { points: response === correctAnswer ? marksAwardedIfCorrect : 0 }),\n },\n });\n }\n\n // Return the updated worksheet response with all responses\n const updatedWorksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: worksheetResponseId },\n include: {\n responses: true,\n },\n });\n\n return updatedWorksheetResponse;\n }),\n cancelAutoGrading: protectedProcedure\n .input(z.object({\n worksheetResponseId: z.string(),\n questionId: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { worksheetResponseId, questionId } = input;\n\n const updatedQuestion = await prisma.studentQuestionProgress.update({\n where: { id: questionId, studentWorksheetResponseId: worksheetResponseId },\n data: {\n status: GenerationStatus.CANCELLED,\n },\n });\n\n return updatedQuestion;\n }),\n // Grade a student's answer\n gradeAnswer: protectedProcedure\n .input(z.object({\n questionId: z.string(),\n responseId: z.string().optional(), // StudentQuestionProgress ID (optional for upsert)\n studentWorksheetResponseId: z.string(), // Required for linking to worksheet response\n response: z.string().optional(), // The actual response text (needed if creating new)\n isCorrect: z.boolean(),\n feedback: z.string().optional(),\n markschemeState: z.any().optional(),\n points: z.number().optional(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { responseId, questionId, studentWorksheetResponseId, response, isCorrect, feedback, markschemeState, points } = input;\n\n let gradedResponse;\n \n if (responseId) {\n // Update existing progress by ID\n gradedResponse = await prisma.studentQuestionProgress.update({\n where: { id: responseId },\n data: {\n isCorrect,\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points }),\n },\n });\n } else {\n // Get the studentId from the worksheet response\n const worksheetResponse = await prisma.studentWorksheetResponse.findUnique({\n where: { id: studentWorksheetResponseId },\n select: { studentId: true },\n });\n\n if (!worksheetResponse) {\n throw new TRPCError({\n code: 'NOT_FOUND',\n message: 'Student worksheet response not found',\n });\n }\n\n const { studentId } = worksheetResponse;\n\n // Upsert - find or create the progress record\n const existing = await prisma.studentQuestionProgress.findFirst({\n where: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n },\n });\n\n if (existing) {\n // Update existing\n gradedResponse = await prisma.studentQuestionProgress.update({\n where: { id: existing.id },\n data: {\n isCorrect,\n ...(response !== undefined && { response }),\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points }),\n },\n });\n } else {\n // Create new\n gradedResponse = await prisma.studentQuestionProgress.create({\n data: {\n studentId,\n questionId,\n studentWorksheetResponseId,\n response: response || '',\n isCorrect,\n ...(feedback !== undefined && { feedback }),\n ...(markschemeState !== undefined && { markschemeState }),\n ...(points !== undefined && { points: points || 0 }),\n },\n });\n }\n }\n\n return gradedResponse;\n }),\n addComment: protectedProcedure\n .input(z.object({\n responseId: z.string(),\n comment: z.string(),\n }))\n .mutation(async ({ ctx, input }) => {\n const { responseId, comment } = input;\n\n const newComment = await prisma.comment.create({\n data: {\n studentQuestionProgressId: responseId,\n content: comment,\n authorId: ctx.user!.id,\n },\n });\n\n return newComment;\n }),\n});"],"names":[],"mappings":"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","debug_id":"2c030eda-ac5e-571a-992d-93eceb0062bc"}
|
package/dist/seedDatabase.d.ts
CHANGED
|
@@ -13,9 +13,9 @@ export declare function addNotification(userId: string, title: string, content:
|
|
|
13
13
|
title: string;
|
|
14
14
|
content: string;
|
|
15
15
|
createdAt: Date;
|
|
16
|
+
read: boolean;
|
|
16
17
|
senderId: string | null;
|
|
17
18
|
receiverId: string;
|
|
18
|
-
read: boolean;
|
|
19
19
|
}>;
|
|
20
20
|
export declare const seedDatabase: () => Promise<void>;
|
|
21
21
|
//# sourceMappingURL=seedDatabase.d.ts.map
|