@studious-lms/server 1.11.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +3 -0
- package/dist/index.js +40 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/config/cors.d.ts.map +1 -1
- package/dist/lib/config/cors.js +7 -2
- package/dist/lib/config/cors.js.map +1 -1
- package/dist/lib/config/env.d.ts +8 -0
- package/dist/lib/config/env.d.ts.map +1 -1
- package/dist/lib/config/env.js +5 -2
- package/dist/lib/config/env.js.map +1 -1
- package/dist/lib/pusher.d.ts +2 -1
- package/dist/lib/pusher.d.ts.map +1 -1
- package/dist/lib/pusher.js +4 -3
- package/dist/lib/pusher.js.map +1 -1
- package/dist/models/agenda.d.ts +6 -0
- package/dist/models/agenda.d.ts.map +1 -1
- package/dist/models/announcement.d.ts +3 -0
- package/dist/models/announcement.d.ts.map +1 -1
- package/dist/models/assignment.d.ts +61 -0
- package/dist/models/assignment.d.ts.map +1 -1
- package/dist/models/auth.d.ts +6 -0
- package/dist/models/auth.d.ts.map +1 -1
- package/dist/models/class.d.ts +18 -0
- package/dist/models/class.d.ts.map +1 -1
- package/dist/models/class.js +5 -2
- package/dist/models/class.js.map +1 -1
- package/dist/models/comment.d.ts +6 -0
- package/dist/models/comment.d.ts.map +1 -1
- package/dist/models/event.d.ts +12 -0
- package/dist/models/event.d.ts.map +1 -1
- package/dist/models/file.d.ts +38 -0
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/folder.d.ts +6 -0
- package/dist/models/folder.d.ts.map +1 -1
- package/dist/models/labChat.d.ts +6 -0
- package/dist/models/labChat.d.ts.map +1 -1
- package/dist/models/newtonChat.d.ts +3 -0
- package/dist/models/newtonChat.d.ts.map +1 -1
- package/dist/models/school.d.ts +3 -0
- package/dist/models/school.d.ts.map +1 -1
- package/dist/models/section.d.ts +3 -0
- package/dist/models/section.d.ts.map +1 -1
- package/dist/models/worksheet.d.ts +58 -0
- package/dist/models/worksheet.d.ts.map +1 -1
- package/dist/models/worksheet.js +26 -2
- package/dist/models/worksheet.js.map +1 -1
- package/dist/routers/_app.d.ts +4055 -1823
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/_app.js +6 -2
- package/dist/routers/_app.js.map +1 -1
- package/dist/routers/admin.d.ts +190 -0
- package/dist/routers/admin.d.ts.map +1 -0
- package/dist/routers/admin.js +50 -0
- package/dist/routers/admin.js.map +1 -0
- package/dist/routers/agenda.d.ts +6 -0
- package/dist/routers/agenda.d.ts.map +1 -1
- package/dist/routers/announcement.d.ts +2 -0
- package/dist/routers/announcement.d.ts.map +1 -1
- package/dist/routers/assignment.d.ts +50 -0
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/class.d.ts +31 -0
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/class.js +5 -2
- 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/discussion.d.ts +823 -0
- package/dist/routers/discussion.d.ts.map +1 -0
- package/dist/routers/discussion.js +151 -0
- package/dist/routers/discussion.js.map +1 -0
- package/dist/routers/event.d.ts +3 -0
- package/dist/routers/event.d.ts.map +1 -1
- package/dist/routers/file.d.ts +4 -0
- package/dist/routers/file.d.ts.map +1 -1
- package/dist/routers/school.d.ts +6 -0
- package/dist/routers/school.d.ts.map +1 -1
- package/dist/routers/worksheet.d.ts +3 -0
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/seedDatabase.d.ts.map +1 -1
- package/dist/seedDatabase.js +1490 -1307
- package/dist/seedDatabase.js.map +1 -1
- package/dist/services/adminInstitution.d.ts +102 -0
- package/dist/services/adminInstitution.d.ts.map +1 -0
- package/dist/services/adminInstitution.js +117 -0
- package/dist/services/adminInstitution.js.map +1 -0
- package/dist/services/adminRunJob.d.ts +45 -0
- package/dist/services/adminRunJob.d.ts.map +1 -0
- package/dist/services/adminRunJob.js +41 -0
- package/dist/services/adminRunJob.js.map +1 -0
- package/dist/services/agenda.d.ts +6 -0
- package/dist/services/agenda.d.ts.map +1 -1
- package/dist/services/assignment.d.ts +50 -0
- package/dist/services/assignment.d.ts.map +1 -1
- package/dist/services/assignment.js +8 -3
- package/dist/services/assignment.js.map +1 -1
- package/dist/services/class.d.ts +31 -0
- package/dist/services/class.d.ts.map +1 -1
- package/dist/services/class.js +14 -2
- package/dist/services/class.js.map +1 -1
- package/dist/services/comment.d.ts +2 -0
- package/dist/services/comment.d.ts.map +1 -1
- package/dist/services/discussion.d.ts +762 -0
- package/dist/services/discussion.d.ts.map +1 -0
- package/dist/services/discussion.js +625 -0
- package/dist/services/discussion.js.map +1 -0
- package/dist/services/event.d.ts +3 -0
- package/dist/services/event.d.ts.map +1 -1
- package/dist/services/file.d.ts +8 -0
- package/dist/services/file.d.ts.map +1 -1
- package/dist/services/school.d.ts +6 -0
- package/dist/services/school.d.ts.map +1 -1
- package/dist/services/studentProgress.d.ts.map +1 -1
- package/dist/services/studentProgress.js +27 -5
- package/dist/services/studentProgress.js.map +1 -1
- package/dist/services/studentProgressInferenceCache.d.ts +16 -0
- package/dist/services/studentProgressInferenceCache.d.ts.map +1 -0
- package/dist/services/studentProgressInferenceCache.js +43 -0
- package/dist/services/studentProgressInferenceCache.js.map +1 -0
- package/dist/services/worksheet.d.ts +3 -0
- package/dist/services/worksheet.d.ts.map +1 -1
- package/dist/services/worksheet.js +5 -5
- package/dist/services/worksheet.js.map +1 -1
- package/dist/trpc.d.ts +12 -0
- package/dist/trpc.d.ts.map +1 -1
- package/dist/trpc.js +16 -3
- package/dist/trpc.js.map +1 -1
- package/dist/utils/adminPanelAccess.d.ts +8 -0
- package/dist/utils/adminPanelAccess.d.ts.map +1 -0
- package/dist/utils/adminPanelAccess.js +44 -0
- package/dist/utils/adminPanelAccess.js.map +1 -0
- package/package.json +1 -1
- package/prisma/migrations/20260510183000_add_discussions/migration.sql +151 -0
- package/prisma/schema.prisma +97 -0
- package/src/index.ts +39 -2
- package/src/lib/config/cors.ts +5 -0
- package/src/lib/config/env.ts +3 -0
- package/src/lib/pusher.ts +2 -1
- package/src/models/class.ts +3 -0
- package/src/models/worksheet.ts +28 -0
- package/src/routers/_app.ts +4 -0
- package/src/routers/admin.ts +70 -0
- package/src/routers/class.ts +3 -0
- package/src/routers/discussion.ts +205 -0
- package/src/seedDatabase.ts +1713 -1361
- package/src/services/adminInstitution.ts +140 -0
- package/src/services/adminRunJob.ts +46 -0
- package/src/services/assignment.ts +11 -1
- package/src/services/class.ts +18 -0
- package/src/services/discussion.ts +701 -0
- package/src/services/studentProgress.ts +80 -3
- package/src/services/studentProgressInferenceCache.ts +64 -0
- package/src/services/worksheet.ts +4 -2
- package/src/trpc.ts +15 -0
- package/src/utils/adminPanelAccess.ts +46 -0
- package/tests/integration/routers/discussion.test.ts +253 -0
- package/tests/unit/services/discussion.test.ts +356 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discussion.js","sources":["services/discussion.ts"],"sourceRoot":"/","sourcesContent":["import type { DiscussionType, Prisma, ReactionType } from \"@prisma/client\";\nimport { TRPCError } from \"@trpc/server\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { discussionChannel, pusher } from \"../lib/pusher.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { classMemberOrSchoolAdminWhere, classTeacherOrSchoolAdminWhere } from \"../models/access.js\";\nimport { sendNotification } from \"./notification.js\";\n\nconst authorSelect = {\n id: true,\n username: true,\n profile: {\n select: {\n displayName: true,\n profilePicture: true,\n profilePictureThumbnail: true,\n },\n },\n} as const;\n\nconst attachmentSelect = {\n id: true,\n name: true,\n type: true,\n size: true,\n path: true,\n uploadedAt: true,\n uploadStatus: true,\n thumbnailId: true,\n thumbnail: { select: { id: true, path: true } },\n} as const;\n\nconst reactionCounts = {\n THUMBSUP: 0,\n CELEBRATE: 0,\n CARE: 0,\n HEART: 0,\n IDEA: 0,\n HAPPY: 0,\n} satisfies Record<ReactionType, number>;\n\nconst discussionInclude = {\n author: { select: authorSelect },\n attachments: { select: attachmentSelect },\n tags: { select: { id: true, name: true, color: true } },\n reactions: { select: { type: true, userId: true } },\n _count: { select: { replies: { where: { deletedAt: null } } } },\n} as const;\n\nconst replyInclude = {\n author: { select: authorSelect },\n attachments: { select: attachmentSelect },\n reactions: { select: { type: true, userId: true } },\n} as const;\n\nconst unclaimedAttachmentWhere = {\n assignmentId: null,\n submissionId: null,\n annotationId: null,\n classDraftId: null,\n folderId: null,\n messageId: null,\n announcementId: null,\n discussionId: null,\n discussionReplyId: null,\n} satisfies Prisma.FileWhereInput;\n\ntype DiscussionWithInclude = Prisma.DiscussionGetPayload<{ include: typeof discussionInclude }>;\ntype ReplyWithInclude = Prisma.DiscussionReplyGetPayload<{ include: typeof replyInclude }>;\n\nexport type DiscussionReplyTree = ReturnType<typeof serializeReply> & {\n children: DiscussionReplyTree[];\n};\n\nfunction summarizeReactions(reactions: { type: ReactionType; userId: string }[], userId: string) {\n const counts = { ...reactionCounts };\n for (const reaction of reactions) {\n counts[reaction.type] += 1;\n }\n return {\n counts,\n userReaction: reactions.find((reaction) => reaction.userId === userId)?.type ?? null,\n total: reactions.length,\n };\n}\n\nfunction serializeDiscussion(discussion: DiscussionWithInclude, userId: string, unreadCount = 0) {\n return {\n id: discussion.id,\n classId: discussion.classId,\n authorId: discussion.authorId,\n title: discussion.title,\n body: discussion.body,\n type: discussion.type,\n isPinned: discussion.isPinned,\n isLocked: discussion.isLocked,\n allowReplies: discussion.allowReplies,\n createdAt: discussion.createdAt,\n updatedAt: discussion.updatedAt,\n lastActivityAt: discussion.lastActivityAt,\n author: discussion.author,\n attachments: discussion.attachments,\n tags: discussion.tags,\n replyCount: discussion._count.replies,\n hasAcceptedAnswer: false,\n reactions: summarizeReactions(discussion.reactions, userId),\n unreadCount,\n };\n}\n\nfunction serializeReply(reply: ReplyWithInclude, userId: string) {\n return {\n id: reply.id,\n discussionId: reply.discussionId,\n authorId: reply.authorId,\n parentId: reply.parentId,\n body: reply.deletedAt ? \"[deleted]\" : reply.body,\n deletedAt: reply.deletedAt,\n isAcceptedAnswer: reply.isAcceptedAnswer,\n createdAt: reply.createdAt,\n modifiedAt: reply.modifiedAt,\n author: reply.author,\n attachments: reply.deletedAt ? [] : reply.attachments,\n reactions: summarizeReactions(reply.reactions, userId),\n };\n}\n\nexport function buildReplyTree(replies: ReplyWithInclude[], userId: string): DiscussionReplyTree[] {\n const byId = new Map<string, DiscussionReplyTree>();\n const roots: DiscussionReplyTree[] = [];\n\n for (const reply of replies) {\n byId.set(reply.id, { ...serializeReply(reply, userId), children: [] });\n }\n\n for (const reply of replies) {\n const node = byId.get(reply.id)!;\n if (reply.parentId && byId.has(reply.parentId)) {\n byId.get(reply.parentId)!.children.push(node);\n } else {\n roots.push(node);\n }\n }\n\n return roots;\n}\n\nfunction isWithinAuthorEditWindow(createdAt: Date) {\n return Date.now() - createdAt.getTime() <= 24 * 60 * 60 * 1000;\n}\n\nexport async function getDiscussionClassAccess(classId: string, userId: string) {\n const classData = await prisma.class.findFirst({\n where: { id: classId, ...classMemberOrSchoolAdminWhere(userId) },\n select: {\n id: true,\n name: true,\n discussionsEnabled: true,\n studentsCanCreateDiscussions: true,\n studentsCanReply: true,\n students: { where: { id: userId }, select: { id: true } },\n teachers: { where: { id: userId }, select: { id: true } },\n school: {\n select: {\n memberships: {\n where: { userId, role: \"ADMIN\", status: \"ACTIVE\" },\n select: { userId: true },\n },\n },\n },\n },\n });\n\n if (!classData) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Not a member in this class\" });\n }\n if (!classData.discussionsEnabled) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Discussions are disabled for this class\" });\n }\n\n const isTeacher = classData.teachers.length > 0 || Boolean(classData.school?.memberships.length);\n const isStudent = classData.students.length > 0;\n\n return { ...classData, isTeacher, isStudent };\n}\n\nasync function getDiscussionForUser(discussionId: string, userId: string) {\n const discussion = await prisma.discussion.findUnique({\n where: { id: discussionId },\n include: {\n class: {\n select: {\n id: true,\n discussionsEnabled: true,\n studentsCanReply: true,\n teachers: { where: { id: userId }, select: { id: true } },\n students: { where: { id: userId }, select: { id: true } },\n school: {\n select: {\n memberships: {\n where: { userId, role: \"ADMIN\", status: \"ACTIVE\" },\n select: { userId: true },\n },\n },\n },\n },\n },\n },\n });\n\n if (!discussion) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Discussion not found\" });\n }\n\n const isTeacher = discussion.class.teachers.length > 0 || Boolean(discussion.class.school?.memberships.length);\n const isStudent = discussion.class.students.length > 0;\n if (!isTeacher && !isStudent) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Not a member in this class\" });\n }\n if (!discussion.class.discussionsEnabled) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Discussions are disabled for this class\" });\n }\n\n return { discussion, isTeacher, isStudent };\n}\n\nasync function claimDiscussionAttachments(\n tx: Prisma.TransactionClient,\n userId: string,\n discussionId: string,\n attachmentIds: string[] = []\n) {\n const uniqueIds = [...new Set(attachmentIds)];\n if (!uniqueIds.length) return;\n const { count } = await tx.file.updateMany({\n where: { id: { in: uniqueIds }, userId, uploadStatus: \"COMPLETED\", ...unclaimedAttachmentWhere },\n data: { discussionId },\n });\n if (count !== uniqueIds.length) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"Some attachments are missing, unfinished, or unavailable\" });\n }\n}\n\nasync function claimReplyAttachments(\n tx: Prisma.TransactionClient,\n userId: string,\n replyId: string,\n attachmentIds: string[] = []\n) {\n const uniqueIds = [...new Set(attachmentIds)];\n if (!uniqueIds.length) return;\n const { count } = await tx.file.updateMany({\n where: { id: { in: uniqueIds }, userId, uploadStatus: \"COMPLETED\", ...unclaimedAttachmentWhere },\n data: { discussionReplyId: replyId },\n });\n if (count !== uniqueIds.length) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"Some attachments are missing, unfinished, or unavailable\" });\n }\n}\n\nfunction triggerDiscussionEvent(classId: string, event: string, payload: unknown) {\n pusher.trigger(discussionChannel(classId), event, payload).catch((error) => {\n logger.error(\"Failed to trigger discussion pusher event\", { event, classId, error });\n });\n}\n\nasync function notify(receiverId: string | null | undefined, senderId: string, title: string, content: string) {\n if (!receiverId || receiverId === senderId) return;\n await sendNotification({ receiverId, title, content }).catch((error) => {\n logger.error(\"Failed to send discussion notification\", { receiverId, error });\n });\n}\n\nasync function notifyMentionedUsers(classId: string, senderId: string, body: string, link: string) {\n const usernames = [...new Set(Array.from(body.matchAll(/(^|\\s)@([a-zA-Z0-9_.-]{2,32})/g)).map((match) => match[2]))];\n if (!usernames.length) return;\n const members = await prisma.user.findMany({\n where: {\n username: { in: usernames },\n OR: [\n { teacherIn: { some: { id: classId } } },\n { studentIn: { some: { id: classId } } },\n { schoolMemberships: { some: { status: \"ACTIVE\", school: { classes: { some: { id: classId } } } } } },\n ],\n },\n select: { id: true },\n });\n await Promise.all(members.map((member) => notify(member.id, senderId, \"You were mentioned in a discussion\", link)));\n}\n\nasync function unreadCountsForDiscussions(userId: string, discussionIds: string[]) {\n if (!discussionIds.length) return new Map<string, number>();\n const reads = await prisma.discussionRead.findMany({\n where: { userId, discussionId: { in: discussionIds } },\n select: { discussionId: true, lastReadAt: true },\n });\n const readMap = new Map(reads.map((read) => [read.discussionId, read.lastReadAt]));\n const neverRead = discussionIds.filter((discussionId) => !readMap.has(discussionId));\n const readPredicates = Array.from(readMap.entries()).map(([discussionId, lastReadAt]) => ({\n discussionId,\n createdAt: { gt: lastReadAt },\n }));\n const counts = new Map<string, number>();\n\n const [neverReadCounts, readCounts] = await Promise.all([\n neverRead.length\n ? prisma.discussionReply.groupBy({\n by: [\"discussionId\"],\n where: { discussionId: { in: neverRead }, deletedAt: null, authorId: { not: userId } },\n _count: true,\n })\n : Promise.resolve([]),\n readPredicates.length\n ? prisma.discussionReply.groupBy({\n by: [\"discussionId\"],\n where: { deletedAt: null, authorId: { not: userId }, OR: readPredicates },\n _count: true,\n })\n : Promise.resolve([]),\n ]);\n\n for (const item of [...neverReadCounts, ...readCounts]) {\n counts.set(item.discussionId, item._count);\n }\n return counts;\n}\n\nexport async function listDiscussions(userId: string, input: {\n classId: string;\n tagId?: string;\n type?: DiscussionType;\n search?: string;\n sort: \"recent\" | \"activity\" | \"top\";\n cursor?: string;\n limit: number;\n}) {\n await getDiscussionClassAccess(input.classId, userId);\n const where: Prisma.DiscussionWhereInput = {\n classId: input.classId,\n ...(input.tagId ? { tags: { some: { id: input.tagId } } } : {}),\n ...(input.type ? { type: input.type } : {}),\n ...(input.search?.trim()\n ? {\n OR: [\n { title: { contains: input.search.trim(), mode: \"insensitive\" } },\n { body: { contains: input.search.trim(), mode: \"insensitive\" } },\n ],\n }\n : {}),\n };\n const orderBy: Prisma.DiscussionOrderByWithRelationInput[] =\n input.sort === \"recent\"\n ? [{ isPinned: \"desc\" }, { createdAt: \"desc\" }]\n : input.sort === \"top\"\n ? [{ isPinned: \"desc\" }, { replies: { _count: \"desc\" } }, { lastActivityAt: \"desc\" }]\n : [{ isPinned: \"desc\" }, { lastActivityAt: \"desc\" }];\n\n const items = await prisma.discussion.findMany({\n where,\n include: discussionInclude,\n orderBy,\n cursor: input.cursor ? { id: input.cursor } : undefined,\n skip: input.cursor ? 1 : 0,\n take: input.limit + 1,\n });\n const next = items.length > input.limit ? items.pop() : undefined;\n const unreadMap = await unreadCountsForDiscussions(userId, items.map((item) => item.id));\n const accepted = await prisma.discussionReply.groupBy({\n by: [\"discussionId\"],\n where: { discussionId: { in: items.map((item) => item.id) }, isAcceptedAnswer: true, deletedAt: null },\n });\n const acceptedIds = new Set(accepted.map((item) => item.discussionId));\n\n return {\n items: items.map((item) => ({\n ...serializeDiscussion(item, userId, unreadMap.get(item.id) ?? 0),\n hasAcceptedAnswer: acceptedIds.has(item.id),\n })),\n nextCursor: next?.id,\n };\n}\n\nexport async function getDiscussion(userId: string, discussionId: string) {\n const { discussion: accessDiscussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n const [discussion, replies, myReaction] = await Promise.all([\n prisma.discussion.findUniqueOrThrow({ where: { id: discussionId }, include: discussionInclude }),\n prisma.discussionReply.findMany({ where: { discussionId }, include: replyInclude, orderBy: { createdAt: \"asc\" } }),\n prisma.reaction.findUnique({ where: { userId_discussionId: { userId, discussionId } }, select: { type: true } }),\n prisma.discussionRead.upsert({\n where: { userId_discussionId: { userId, discussionId } },\n update: { lastReadAt: new Date() },\n create: { userId, discussionId },\n }),\n ]);\n const canAuthorEdit = accessDiscussion.authorId === userId && isWithinAuthorEditWindow(accessDiscussion.createdAt);\n const canReply = isTeacher || (accessDiscussion.class.studentsCanReply && !accessDiscussion.isLocked && accessDiscussion.allowReplies);\n return {\n discussion: serializeDiscussion(discussion, userId),\n replies: buildReplyTree(replies, userId),\n myReaction: myReaction?.type ?? null,\n canEdit: isTeacher || canAuthorEdit,\n canPin: isTeacher,\n canLock: isTeacher,\n canDelete: isTeacher || accessDiscussion.authorId === userId,\n canReply,\n };\n}\n\nexport async function createDiscussion(userId: string, input: {\n classId: string;\n title: string;\n body: string;\n type: DiscussionType;\n tagIds?: string[];\n attachmentIds?: string[];\n}) {\n const classData = await getDiscussionClassAccess(input.classId, userId);\n if (!classData.isTeacher && !classData.studentsCanCreateDiscussions) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Students cannot create discussions in this class\" });\n }\n if (input.type === \"ANNOUNCEMENT\" && !classData.isTeacher) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can create announcement discussions\" });\n }\n\n const discussion = await prisma.$transaction(async (tx) => {\n const created = await tx.discussion.create({\n data: {\n classId: input.classId,\n authorId: userId,\n title: input.title.trim(),\n body: input.body.trim(),\n type: input.type,\n allowReplies: input.type !== \"ANNOUNCEMENT\",\n tags: input.tagIds?.length ? { connect: input.tagIds.map((id) => ({ id })) } : undefined,\n },\n });\n await claimDiscussionAttachments(tx, userId, created.id, input.attachmentIds);\n return tx.discussion.findUniqueOrThrow({ where: { id: created.id }, include: discussionInclude });\n });\n\n triggerDiscussionEvent(input.classId, \"discussion-created\", { discussion: serializeDiscussion(discussion, userId) });\n await notifyMentionedUsers(input.classId, userId, input.body, `/class/${input.classId}/discussions/${discussion.id}`);\n return { discussion: serializeDiscussion(discussion, userId) };\n}\n\nexport async function updateDiscussion(userId: string, input: {\n discussionId: string;\n title?: string;\n body?: string;\n type?: DiscussionType;\n tagIds?: string[];\n allowReplies?: boolean;\n}) {\n const { discussion, isTeacher } = await getDiscussionForUser(input.discussionId, userId);\n if (!isTeacher && !(discussion.authorId === userId && isWithinAuthorEditWindow(discussion.createdAt))) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot edit this discussion\" });\n }\n if (input.type === \"ANNOUNCEMENT\" && !isTeacher) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can create announcement discussions\" });\n }\n const updated = await prisma.discussion.update({\n where: { id: input.discussionId },\n data: {\n ...(input.title !== undefined ? { title: input.title.trim() } : {}),\n ...(input.body !== undefined ? { body: input.body.trim() } : {}),\n ...(input.type !== undefined ? { type: input.type } : {}),\n ...(input.allowReplies !== undefined ? { allowReplies: input.allowReplies } : {}),\n ...(input.tagIds ? { tags: { set: input.tagIds.map((id) => ({ id })) } } : {}),\n },\n include: discussionInclude,\n });\n triggerDiscussionEvent(updated.classId, \"discussion-updated\", { discussion: serializeDiscussion(updated, userId) });\n return { discussion: serializeDiscussion(updated, userId) };\n}\n\nexport async function deleteDiscussion(userId: string, discussionId: string) {\n const { discussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n if (!isTeacher && discussion.authorId !== userId) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot delete this discussion\" });\n }\n await prisma.discussion.delete({ where: { id: discussionId } });\n triggerDiscussionEvent(discussion.classId, \"discussion-deleted\", { discussionId });\n return { success: true };\n}\n\nexport async function replyToDiscussion(userId: string, input: {\n discussionId: string;\n parentReplyId?: string;\n body: string;\n attachmentIds?: string[];\n}) {\n const { discussion, isTeacher } = await getDiscussionForUser(input.discussionId, userId);\n const canReply = isTeacher || (discussion.class.studentsCanReply && !discussion.isLocked && discussion.allowReplies);\n if (!canReply) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot reply to this discussion\" });\n }\n let parent: { id: string; authorId: string } | null = null;\n if (input.parentReplyId) {\n parent = await prisma.discussionReply.findFirst({\n where: { id: input.parentReplyId, discussionId: input.discussionId },\n select: { id: true, authorId: true },\n });\n if (!parent) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Parent reply not found\" });\n }\n const reply = await prisma.$transaction(async (tx) => {\n const created = await tx.discussionReply.create({\n data: {\n discussionId: input.discussionId,\n authorId: userId,\n parentId: input.parentReplyId,\n body: input.body.trim(),\n },\n });\n await claimReplyAttachments(tx, userId, created.id, input.attachmentIds);\n await tx.discussion.update({\n where: { id: input.discussionId },\n data: { lastActivityAt: new Date() },\n });\n return tx.discussionReply.findUniqueOrThrow({ where: { id: created.id }, include: replyInclude });\n });\n const link = `/class/${discussion.classId}/discussions/${discussion.id}#${reply.id}`;\n await Promise.all([\n notify(discussion.authorId, userId, \"New reply to your discussion\", link),\n notify(parent?.authorId, userId, \"New reply in a discussion thread\", link),\n notifyMentionedUsers(discussion.classId, userId, input.body, link),\n ]);\n triggerDiscussionEvent(discussion.classId, \"reply-created\", { discussionId: discussion.id, reply: serializeReply(reply, userId) });\n return { reply: serializeReply(reply, userId) };\n}\n\nexport async function updateDiscussionReply(userId: string, input: { replyId: string; body: string; attachmentIds?: string[] }) {\n const existing = await prisma.discussionReply.findUnique({ where: { id: input.replyId }, include: { discussion: true } });\n if (!existing) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n const { isTeacher } = await getDiscussionForUser(existing.discussionId, userId);\n if (!isTeacher && !(existing.authorId === userId && isWithinAuthorEditWindow(existing.createdAt))) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot edit this reply\" });\n }\n const reply = await prisma.$transaction(async (tx) => {\n await tx.file.updateMany({ where: { discussionReplyId: input.replyId }, data: { discussionReplyId: null } });\n await claimReplyAttachments(tx, userId, input.replyId, input.attachmentIds);\n return tx.discussionReply.update({\n where: { id: input.replyId },\n data: { body: input.body.trim(), deletedAt: null },\n include: replyInclude,\n });\n });\n triggerDiscussionEvent(existing.discussion.classId, \"reply-updated\", { discussionId: existing.discussionId, reply: serializeReply(reply, userId) });\n return { reply: serializeReply(reply, userId) };\n}\n\nexport async function deleteDiscussionReply(userId: string, replyId: string) {\n const existing = await prisma.discussionReply.findUnique({ where: { id: replyId }, include: { discussion: true } });\n if (!existing) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n const { isTeacher } = await getDiscussionForUser(existing.discussionId, userId);\n if (!isTeacher && existing.authorId !== userId) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"You cannot delete this reply\" });\n }\n const reply = await prisma.discussionReply.update({\n where: { id: replyId },\n data: { body: \"[deleted]\", deletedAt: new Date(), isAcceptedAnswer: false },\n include: replyInclude,\n });\n triggerDiscussionEvent(existing.discussion.classId, \"reply-deleted\", { discussionId: existing.discussionId, reply: serializeReply(reply, userId) });\n return { reply: serializeReply(reply, userId) };\n}\n\nexport async function pinDiscussion(userId: string, discussionId: string, isPinned: boolean) {\n const { discussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n if (!isTeacher) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can pin discussions\" });\n const updated = await prisma.discussion.update({ where: { id: discussionId }, data: { isPinned }, include: discussionInclude });\n await notify(discussion.authorId, userId, isPinned ? \"Your discussion was pinned\" : \"Your discussion was unpinned\", `/class/${discussion.classId}/discussions/${discussionId}`);\n triggerDiscussionEvent(discussion.classId, \"discussion-updated\", { discussion: serializeDiscussion(updated, userId) });\n return { discussion: serializeDiscussion(updated, userId) };\n}\n\nexport async function lockDiscussion(userId: string, discussionId: string, isLocked: boolean) {\n const { discussion, isTeacher } = await getDiscussionForUser(discussionId, userId);\n if (!isTeacher) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can lock discussions\" });\n const updated = await prisma.discussion.update({ where: { id: discussionId }, data: { isLocked }, include: discussionInclude });\n triggerDiscussionEvent(discussion.classId, \"discussion-updated\", { discussion: serializeDiscussion(updated, userId) });\n return { discussion: serializeDiscussion(updated, userId) };\n}\n\nexport async function markAcceptedAnswer(userId: string, replyId: string, accepted: boolean) {\n const reply = await prisma.discussionReply.findUnique({ where: { id: replyId }, include: { discussion: true } });\n if (!reply) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n const { isTeacher } = await getDiscussionForUser(reply.discussionId, userId);\n if (reply.discussion.type !== \"QUESTION\") {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"Only question discussions can have accepted answers\" });\n }\n if (!isTeacher && reply.discussion.authorId !== userId) {\n throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only the discussion author or a teacher can mark an accepted answer\" });\n }\n const updated = await prisma.$transaction(async (tx) => {\n if (accepted) {\n await tx.discussionReply.updateMany({ where: { discussionId: reply.discussionId, isAcceptedAnswer: true }, data: { isAcceptedAnswer: false } });\n }\n return tx.discussionReply.update({ where: { id: replyId }, data: { isAcceptedAnswer: accepted }, include: replyInclude });\n });\n await notify(reply.authorId, userId, accepted ? \"Your answer was accepted\" : \"Your answer was unmarked\", `/class/${reply.discussion.classId}/discussions/${reply.discussionId}#${replyId}`);\n triggerDiscussionEvent(reply.discussion.classId, \"reply-updated\", { discussionId: reply.discussionId, reply: serializeReply(updated, userId) });\n return { reply: serializeReply(updated, userId) };\n}\n\nexport async function markDiscussionRead(userId: string, discussionId: string) {\n await getDiscussionForUser(discussionId, userId);\n return prisma.discussionRead.upsert({\n where: { userId_discussionId: { userId, discussionId } },\n update: { lastReadAt: new Date() },\n create: { userId, discussionId },\n });\n}\n\nexport async function getUnreadCounts(userId: string, classIds: string[]) {\n const allowedClasses = await prisma.class.findMany({\n where: { id: { in: classIds }, discussionsEnabled: true, ...classMemberOrSchoolAdminWhere(userId) },\n select: { id: true },\n });\n const result: Record<string, { total: number; perDiscussion: { discussionId: string; count: number }[] }> = {};\n for (const cls of allowedClasses) {\n const discussions = await prisma.discussion.findMany({\n where: { classId: cls.id },\n select: { id: true },\n });\n const countMap = await unreadCountsForDiscussions(userId, discussions.map((discussion) => discussion.id));\n const perDiscussion = Array.from(countMap.entries())\n .map(([discussionId, count]) => ({ discussionId, count }))\n .filter((item) => item.count > 0);\n result[cls.id] = {\n total: perDiscussion.reduce((sum, item) => sum + item.count, 0),\n perDiscussion,\n };\n }\n return result;\n}\n\nexport async function toggleDiscussionReaction(userId: string, input: { discussionId?: string; discussionReplyId?: string; type: ReactionType }) {\n if (!input.discussionId && !input.discussionReplyId) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"A discussion or reply is required\" });\n }\n if (input.discussionId && input.discussionReplyId) {\n throw new TRPCError({ code: \"BAD_REQUEST\", message: \"React to either a discussion or a reply\" });\n }\n const target = input.discussionId\n ? await getDiscussionForUser(input.discussionId, userId).then(({ discussion }) => ({ classId: discussion.classId, discussionId: discussion.id }))\n : await prisma.discussionReply.findUnique({ where: { id: input.discussionReplyId }, include: { discussion: true } }).then(async (reply) => {\n if (!reply) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Reply not found\" });\n await getDiscussionForUser(reply.discussionId, userId);\n return { classId: reply.discussion.classId, discussionId: reply.discussionId };\n });\n const where = input.discussionId\n ? { userId_discussionId: { userId, discussionId: input.discussionId } }\n : { userId_discussionReplyId: { userId, discussionReplyId: input.discussionReplyId! } };\n const existing = await prisma.reaction.findUnique({ where });\n if (existing?.type === input.type) {\n await prisma.reaction.delete({ where: { id: existing.id } });\n triggerDiscussionEvent(target.classId, \"reaction-removed\", { discussionId: target.discussionId, discussionReplyId: input.discussionReplyId, userId });\n return { reaction: null };\n }\n const reaction = input.discussionId\n ? await prisma.reaction.upsert({\n where: { userId_discussionId: { userId, discussionId: input.discussionId } },\n update: { type: input.type },\n create: { userId, discussionId: input.discussionId, type: input.type },\n })\n : await prisma.reaction.upsert({\n where: { userId_discussionReplyId: { userId, discussionReplyId: input.discussionReplyId! } },\n update: { type: input.type },\n create: { userId, discussionReplyId: input.discussionReplyId!, type: input.type },\n });\n triggerDiscussionEvent(target.classId, \"reaction-added\", { discussionId: target.discussionId, discussionReplyId: input.discussionReplyId, reaction });\n return { reaction };\n}\n\nexport async function listDiscussionTags(userId: string, classId: string) {\n await getDiscussionClassAccess(classId, userId);\n return prisma.discussionTag.findMany({ where: { classId }, orderBy: { name: \"asc\" } });\n}\n\nexport async function createDiscussionTag(userId: string, input: { classId: string; name: string; color: string }) {\n const isTeacher = await prisma.class.findFirst({ where: { id: input.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });\n if (!isTeacher?.discussionsEnabled) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can manage discussion tags\" });\n return prisma.discussionTag.create({ data: { classId: input.classId, name: input.name.trim(), color: input.color } });\n}\n\nexport async function updateDiscussionTag(userId: string, input: { tagId: string; name?: string; color?: string }) {\n const tag = await prisma.discussionTag.findUnique({ where: { id: input.tagId }, select: { classId: true } });\n if (!tag) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Tag not found\" });\n const isTeacher = await prisma.class.findFirst({ where: { id: tag.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });\n if (!isTeacher?.discussionsEnabled) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can manage discussion tags\" });\n return prisma.discussionTag.update({ where: { id: input.tagId }, data: { name: input.name?.trim(), color: input.color } });\n}\n\nexport async function deleteDiscussionTag(userId: string, tagId: string) {\n const tag = await prisma.discussionTag.findUnique({ where: { id: tagId }, select: { classId: true } });\n if (!tag) throw new TRPCError({ code: \"NOT_FOUND\", message: \"Tag not found\" });\n const isTeacher = await prisma.class.findFirst({ where: { id: tag.classId, ...classTeacherOrSchoolAdminWhere(userId) }, select: { id: true, discussionsEnabled: true } });\n if (!isTeacher?.discussionsEnabled) throw new TRPCError({ code: \"FORBIDDEN\", message: \"Only teachers can manage discussion tags\" });\n await prisma.discussionTag.delete({ where: { id: tagId } });\n return { success: true };\n}\n"],"names":[],"mappings":"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","debug_id":"b10e68f8-0106-57a7-be41-a32938701565"}
|
package/dist/services/event.d.ts
CHANGED
|
@@ -38,6 +38,9 @@ export declare function getEvent(userId: string, id: string): Promise<{
|
|
|
38
38
|
section: string;
|
|
39
39
|
syllabus: string | null;
|
|
40
40
|
departmentId: string | null;
|
|
41
|
+
discussionsEnabled: boolean;
|
|
42
|
+
studentsCanCreateDiscussions: boolean;
|
|
43
|
+
studentsCanReply: boolean;
|
|
41
44
|
}) | null;
|
|
42
45
|
assignmentsAttached: {
|
|
43
46
|
type: import(".prisma/client").$Enums.AssignmentType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event.d.ts","sourceRoot":"/","sources":["services/event.ts"],"names":[],"mappings":"AAmBA,6DAA6D;AAC7D,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"/","sources":["services/event.ts"],"names":[],"mappings":"AAmBA,6DAA6D;AAC7D,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAexD;AAED,wCAAwC;AACxC,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;;;;;;;;;;;;;;;GAwBF;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,IAAI,EAAE;IACJ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;;;;;;;;;;;;GA2BF;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;;GAiBjE;AAuBD,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CrB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBrB;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;GAkBhB"}
|
package/dist/services/file.d.ts
CHANGED
|
@@ -50,6 +50,8 @@ export declare function moveFile(fileId: string, targetFolderId: string): Promis
|
|
|
50
50
|
conversationId: string | null;
|
|
51
51
|
messageId: string | null;
|
|
52
52
|
announcementId: string | null;
|
|
53
|
+
discussionId: string | null;
|
|
54
|
+
discussionReplyId: string | null;
|
|
53
55
|
schoolDevelopementProgramId: string | null;
|
|
54
56
|
}>;
|
|
55
57
|
export declare function renameFile(fileId: string, newName: string): Promise<{
|
|
@@ -83,6 +85,8 @@ export declare function renameFile(fileId: string, newName: string): Promise<{
|
|
|
83
85
|
conversationId: string | null;
|
|
84
86
|
messageId: string | null;
|
|
85
87
|
announcementId: string | null;
|
|
88
|
+
discussionId: string | null;
|
|
89
|
+
discussionReplyId: string | null;
|
|
86
90
|
schoolDevelopementProgramId: string | null;
|
|
87
91
|
}>;
|
|
88
92
|
export declare function deleteFileRecord(fileId: string, classId: string): Promise<{
|
|
@@ -126,6 +130,8 @@ export declare function moveFileScoped(userId: string, input: {
|
|
|
126
130
|
conversationId: string | null;
|
|
127
131
|
messageId: string | null;
|
|
128
132
|
announcementId: string | null;
|
|
133
|
+
discussionId: string | null;
|
|
134
|
+
discussionReplyId: string | null;
|
|
129
135
|
schoolDevelopementProgramId: string | null;
|
|
130
136
|
}>;
|
|
131
137
|
/** Scope-aware rename. */
|
|
@@ -163,6 +169,8 @@ export declare function renameFileScoped(userId: string, input: {
|
|
|
163
169
|
conversationId: string | null;
|
|
164
170
|
messageId: string | null;
|
|
165
171
|
announcementId: string | null;
|
|
172
|
+
discussionId: string | null;
|
|
173
|
+
discussionReplyId: string | null;
|
|
166
174
|
schoolDevelopementProgramId: string | null;
|
|
167
175
|
}>;
|
|
168
176
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.d.ts","sourceRoot":"/","sources":["services/file.ts"],"names":[],"mappings":"AA+CA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;GAkFpE;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"/","sources":["services/file.ts"],"names":[],"mappings":"AA+CA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;GAkFpE;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmBvB;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkBhB;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;GA6BrE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsBlD;AAED,0BAA0B;AAC1B,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsB3C;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;GA4BrE"}
|
|
@@ -140,6 +140,9 @@ export declare function listClasses(userId: string, schoolId: string): Promise<{
|
|
|
140
140
|
section: string;
|
|
141
141
|
syllabus: string | null;
|
|
142
142
|
departmentId: string | null;
|
|
143
|
+
discussionsEnabled: boolean;
|
|
144
|
+
studentsCanCreateDiscussions: boolean;
|
|
145
|
+
studentsCanReply: boolean;
|
|
143
146
|
})[];
|
|
144
147
|
}>;
|
|
145
148
|
export declare function createSchoolClass(userId: string, input: {
|
|
@@ -178,6 +181,9 @@ export declare function createSchoolClass(userId: string, input: {
|
|
|
178
181
|
section: string;
|
|
179
182
|
syllabus: string | null;
|
|
180
183
|
departmentId: string | null;
|
|
184
|
+
discussionsEnabled: boolean;
|
|
185
|
+
studentsCanCreateDiscussions: boolean;
|
|
186
|
+
studentsCanReply: boolean;
|
|
181
187
|
};
|
|
182
188
|
}>;
|
|
183
189
|
export declare function listMembers(userId: string, schoolId: string): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"school.d.ts","sourceRoot":"/","sources":["services/school.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,oBAAoB,EAAe,MAAM,gBAAgB,CAAC;AA4DnE,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyBvE;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;;;;;;;;;;;;;;;;;;;;GAcF;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;;;;;;;;GAUF;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BtE;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"school.d.ts","sourceRoot":"/","sources":["services/school.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studentProgress.d.ts","sourceRoot":"/","sources":["services/studentProgress.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"studentProgress.d.ts","sourceRoot":"/","sources":["services/studentProgress.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAgCF,QAAA,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKjC,CAAC;AAEH,QAAA,MAAM,6BAA6B;;;;;;;;;;;;;;;EAKjC,CAAC;AAEH,QAAA,MAAM,0BAA0B;;;;;;EAE9B,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAC3C,OAAO,6BAA6B,CACrC,CAAC;AACF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,KAAK,kBAAkB,GAAG,SAAS,GAAG,WAAW,GAAG,mBAAmB,CAAC;AAwXxE,wBAAsB,iCAAiC,CACrD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsBlB;AAED,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2FhB;AAED,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;;GAqCF;AAyFD,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM;;;;;;;;;;;GA+ClB;AAED,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM;;;;;GA0ClB;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM;;GA0ClB;AAED,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE;IACL,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACjC;;;GAiGF"}
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* Student progress service - assignment recommendations and progress chat.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
5
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="159c0157-8d54-553a-84a9-e84c0b152f43")}catch(e){}}();
|
|
6
6
|
import { TRPCError } from "@trpc/server";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { prisma } from "../lib/prisma.js";
|
|
9
9
|
import { isTeacherInClass } from "../models/class.js";
|
|
10
10
|
import { inference } from "../utils/inference.js";
|
|
11
11
|
import { logger } from "../utils/logger.js";
|
|
12
|
+
import { getStudentProgressInferenceCacheHit, setStudentProgressInferenceCache, } from "./studentProgressInferenceCache.js";
|
|
12
13
|
const insightItemSchema = z.object({
|
|
13
14
|
label: z.string(),
|
|
14
15
|
evidence: z.string(),
|
|
@@ -465,10 +466,17 @@ function buildStructuredInferenceMessages(instruction, context) {
|
|
|
465
466
|
},
|
|
466
467
|
];
|
|
467
468
|
}
|
|
469
|
+
const studentProgressInsightsCache = new Map();
|
|
470
|
+
const studentProgressForecastCache = new Map();
|
|
471
|
+
const studentProgressFocusCache = new Map();
|
|
468
472
|
export async function getStudentProgressInsights(viewerId, classId, studentId) {
|
|
473
|
+
const cached = getStudentProgressInferenceCacheHit(studentProgressInsightsCache, classId, studentId);
|
|
469
474
|
const { classData, student, submissions } = await loadStudentProgressContext(viewerId, classId, studentId);
|
|
475
|
+
if (cached !== undefined) {
|
|
476
|
+
return cached;
|
|
477
|
+
}
|
|
470
478
|
const context = buildStructuredProgressContext(classData, student, submissions);
|
|
471
|
-
|
|
479
|
+
const value = await inference(buildStructuredInferenceMessages([
|
|
472
480
|
"Generate an AI analytics summary for this one student's dashboard.",
|
|
473
481
|
"The summary must be 2-4 plain-prose sentences: lead with overall grade and trajectory, then call out one strength and one concern with assignment titles.",
|
|
474
482
|
"Strengths and growth items need 2-6 word labels and one-line evidence grounded in assignment titles or sections.",
|
|
@@ -477,22 +485,36 @@ export async function getStudentProgressInsights(viewerId, classId, studentId) {
|
|
|
477
485
|
reason: "student_progress_insights",
|
|
478
486
|
metadata: { viewerId, classId, studentId },
|
|
479
487
|
});
|
|
488
|
+
setStudentProgressInferenceCache(studentProgressInsightsCache, classId, studentId, value);
|
|
489
|
+
return value;
|
|
480
490
|
}
|
|
481
491
|
export async function getStudentProgressForecast(viewerId, classId, studentId) {
|
|
492
|
+
const cached = getStudentProgressInferenceCacheHit(studentProgressForecastCache, classId, studentId);
|
|
482
493
|
const { classData, student, submissions } = await loadStudentProgressContext(viewerId, classId, studentId);
|
|
494
|
+
if (cached !== undefined) {
|
|
495
|
+
return cached;
|
|
496
|
+
}
|
|
483
497
|
const context = buildStructuredProgressContext(classData, student, submissions);
|
|
484
|
-
|
|
498
|
+
const value = await inference(buildStructuredInferenceMessages("Predict the student's next graded assignment percentage band and risk status. Base the forecast on trajectory, missing work, low scores, and assignment recency. Keep the reason to one sentence.", context), studentProgressForecastSchema, {
|
|
485
499
|
reason: "student_progress_forecast",
|
|
486
500
|
metadata: { viewerId, classId, studentId },
|
|
487
501
|
});
|
|
502
|
+
setStudentProgressInferenceCache(studentProgressForecastCache, classId, studentId, value);
|
|
503
|
+
return value;
|
|
488
504
|
}
|
|
489
505
|
export async function getStudentProgressFocus(viewerId, classId, studentId) {
|
|
506
|
+
const cached = getStudentProgressInferenceCacheHit(studentProgressFocusCache, classId, studentId);
|
|
490
507
|
const { classData, student, submissions } = await loadStudentProgressContext(viewerId, classId, studentId);
|
|
508
|
+
if (cached !== undefined) {
|
|
509
|
+
return cached;
|
|
510
|
+
}
|
|
491
511
|
const context = buildStructuredProgressContext(classData, student, submissions);
|
|
492
|
-
|
|
512
|
+
const value = await inference(buildStructuredInferenceMessages("Generate 3-5 student-facing weekly focus items. Each item should be specific, actionable, and grounded in the student's grade pattern or assignment titles. No numbering in the strings.", context), studentProgressFocusSchema, {
|
|
493
513
|
reason: "student_progress_focus",
|
|
494
514
|
metadata: { viewerId, classId, studentId },
|
|
495
515
|
});
|
|
516
|
+
setStudentProgressInferenceCache(studentProgressFocusCache, classId, studentId, value);
|
|
517
|
+
return value;
|
|
496
518
|
}
|
|
497
519
|
export async function chatAboutStudentProgress(viewerId, input) {
|
|
498
520
|
const { classData, student, submissions } = await loadStudentProgressContext(viewerId, input.classId, input.studentId);
|
|
@@ -572,4 +594,4 @@ export async function chatAboutStudentProgress(viewerId, input) {
|
|
|
572
594
|
}
|
|
573
595
|
}
|
|
574
596
|
//# sourceMappingURL=studentProgress.js.map
|
|
575
|
-
//# debugId=
|
|
597
|
+
//# debugId=159c0157-8d54-553a-84a9-e84c0b152f43
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"studentProgress.js","sources":["services/studentProgress.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Student progress service - assignment recommendations and progress chat.\n */\nimport { TRPCError } from \"@trpc/server\";\nimport type { AssignmentType } from \"@prisma/client\";\nimport { z } from \"zod\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { isTeacherInClass } from \"../models/class.js\";\nimport { inference } from \"../utils/inference.js\";\nimport { logger } from \"../utils/logger.js\";\n\ntype ProgressChatMessage = {\n role: \"user\" | \"assistant\";\n content: string;\n};\n\ntype GradeSubmission = {\n id: string;\n gradeReceived: number | null;\n submitted: boolean | null;\n returned: boolean | null;\n submittedAt: Date | null;\n recommendationState: \"NONE\" | \"OPEN\" | \"ASSIGNED\" | \"DISMISSED\";\n targetedAssignmentId: string | null;\n assignment: {\n id: string;\n title: string;\n dueDate: Date;\n maxGrade: number | null;\n weight: number;\n type: AssignmentType;\n section: { id: string; name: string } | null;\n };\n};\n\ntype ProgressStudent = {\n id: string;\n username: string;\n profile: { displayName: string | null } | null;\n};\n\nconst insightItemSchema = z.object({\n label: z.string(),\n evidence: z.string(),\n});\n\nconst studentProgressInsightsSchema = z.object({\n summary: z.string(),\n strengths: z.array(insightItemSchema).min(2).max(4),\n growth: z.array(insightItemSchema).min(2).max(4),\n talkingPoints: z.array(z.string()).min(3).max(5),\n});\n\nconst studentProgressForecastSchema = z.object({\n forecastLow: z.number().min(0).max(100),\n forecastHigh: z.number().min(0).max(100),\n risk: z.enum([\"on_track\", \"watch\", \"at_risk\"]),\n reason: z.string(),\n});\n\nconst studentProgressFocusSchema = z.object({\n focusItems: z.array(z.string()).min(3).max(5),\n});\n\nexport type StudentProgressInsights = z.infer<\n typeof studentProgressInsightsSchema\n>;\nexport type StudentProgressForecast = z.infer<\n typeof studentProgressForecastSchema\n>;\nexport type StudentProgressFocus = z.infer<typeof studentProgressFocusSchema>;\n\ntype RecommendationType = \"missing\" | \"low_score\" | \"awaiting_feedback\";\n\nfunction calculatePercentage(submission: GradeSubmission) {\n if (submission.gradeReceived == null || !submission.assignment.maxGrade) {\n return null;\n }\n\n return (\n Math.round(\n (submission.gradeReceived / submission.assignment.maxGrade) * 1000,\n ) / 10\n );\n}\n\nfunction calculateTrend(submissions: GradeSubmission[]) {\n const graded = submissions\n .filter(\n (submission) =>\n submission.gradeReceived != null && submission.assignment.maxGrade,\n )\n .sort((a, b) => {\n const aTime = a.submittedAt?.getTime() ?? a.assignment.dueDate.getTime();\n const bTime = b.submittedAt?.getTime() ?? b.assignment.dueDate.getTime();\n return aTime - bTime;\n })\n .map((submission) => calculatePercentage(submission))\n .filter((value): value is number => value != null);\n\n if (graded.length < 2) return 0;\n\n const midpoint = Math.floor(graded.length / 2);\n const first = graded.slice(0, midpoint);\n const second = graded.slice(midpoint);\n const average = (values: number[]) =>\n values.reduce((sum, value) => sum + value, 0) / values.length;\n\n return Math.round((average(second) - average(first)) * 10) / 10;\n}\n\nfunction getOverallGrade(submissions: GradeSubmission[]) {\n let totalWeighted = 0;\n let totalWeight = 0;\n\n for (const submission of submissions) {\n if (\n submission.gradeReceived != null &&\n submission.assignment.maxGrade &&\n submission.assignment.weight\n ) {\n totalWeighted +=\n (submission.gradeReceived / submission.assignment.maxGrade) *\n submission.assignment.weight;\n totalWeight += submission.assignment.weight;\n }\n }\n\n return totalWeight > 0\n ? Math.round((totalWeighted / totalWeight) * 1000) / 10\n : null;\n}\n\nfunction normalizeAssignmentType(\n assignmentType: AssignmentType,\n): AssignmentType {\n if (assignmentType === \"TEST\" || assignmentType === \"QUIZ\") {\n return \"HOMEWORK\";\n }\n\n return assignmentType;\n}\n\nfunction buildSuggestedAssignment(\n recommendationType: RecommendationType,\n submission: GradeSubmission,\n displayName: string,\n percentage: number | null,\n) {\n const sourceTitle = submission.assignment.title;\n const section = submission.assignment.section?.name;\n const titleByType: Record<RecommendationType, string> = {\n missing: `Make-up: ${sourceTitle}`,\n low_score: `Targeted practice: ${sourceTitle}`,\n awaiting_feedback: `Revision follow-up: ${sourceTitle}`,\n };\n const leadByType: Record<RecommendationType, string> = {\n missing: `${displayName} missed the original assignment and needs a focused make-up task on the same material.`,\n low_score:\n percentage != null\n ? `${displayName} scored ${percentage}% and needs targeted reinforcement on the underlying concepts.`\n : `${displayName} needs targeted reinforcement on the underlying concepts.`,\n awaiting_feedback: `${displayName} has work in progress here, so a short follow-up can keep momentum once feedback lands.`,\n };\n\n return {\n title: titleByType[recommendationType],\n instructions: [\n leadByType[recommendationType],\n `Source assignment: ${sourceTitle}.`,\n section ? `Section: ${section}.` : null,\n \"Keep the work concise and focused on the specific area of concern.\",\n ]\n .filter((line): line is string => Boolean(line))\n .join(\"\\n\\n\"),\n type: normalizeAssignmentType(submission.assignment.type),\n maxGrade: submission.assignment.maxGrade ?? 100,\n weight: submission.assignment.weight || 1,\n graded: true,\n sectionId: submission.assignment.section?.id ?? null,\n sourceAssignmentId: submission.assignment.id,\n };\n}\n\nfunction buildRecommendationCandidate(\n submission: GradeSubmission,\n displayName: string,\n now: Date,\n) {\n if (\n submission.recommendationState === \"ASSIGNED\" ||\n submission.recommendationState === \"DISMISSED\"\n ) {\n return null;\n }\n\n const percentage = calculatePercentage(submission);\n const isMissing =\n !submission.submitted &&\n submission.assignment.dueDate.getTime() < now.getTime();\n const isLowScore = percentage != null && percentage < 70;\n const isUnreturned =\n Boolean(submission.submitted) &&\n submission.gradeReceived == null &&\n !submission.returned;\n const reasons: string[] = [];\n let priorityScore = 0;\n let recommendationType: RecommendationType | null = null;\n\n if (isMissing) {\n reasons.push(\"Missing past-due work\");\n priorityScore += 100;\n recommendationType = \"missing\";\n }\n if (isLowScore) {\n reasons.push(`Scored ${percentage}%`);\n priorityScore += 85 - (percentage ?? 0);\n recommendationType ??= \"low_score\";\n }\n if (isUnreturned) {\n reasons.push(\"Awaiting grade or feedback\");\n priorityScore += 15;\n recommendationType ??= \"awaiting_feedback\";\n }\n\n if (priorityScore <= 0 || !recommendationType) {\n return null;\n }\n\n return {\n assignmentId: submission.assignment.id,\n submissionId: submission.id,\n title: submission.assignment.title,\n type: submission.assignment.type,\n sectionId: submission.assignment.section?.id ?? null,\n sectionName: submission.assignment.section?.name ?? null,\n dueDate: submission.assignment.dueDate,\n gradeReceived: submission.gradeReceived,\n maxGrade: submission.assignment.maxGrade,\n percentage,\n submitted: Boolean(submission.submitted),\n returned: Boolean(submission.returned),\n recommendationType,\n reasons,\n priorityScore,\n suggestedAssignment: buildSuggestedAssignment(\n recommendationType,\n submission,\n displayName,\n percentage,\n ),\n };\n}\n\nfunction summarizeStudentRecommendations(\n student: ProgressStudent,\n submissions: GradeSubmission[],\n) {\n const now = new Date();\n const displayName = student.profile?.displayName ?? student.username;\n const recommendationCandidates = submissions\n .map((submission) =>\n buildRecommendationCandidate(submission, displayName, now),\n )\n .filter(\n (\n candidate,\n ): candidate is NonNullable<\n ReturnType<typeof buildRecommendationCandidate>\n > => candidate != null,\n )\n .sort((a, b) => b.priorityScore - a.priorityScore);\n\n const recommendations = recommendationCandidates\n .slice(0, 5)\n .map(({ priorityScore, ...candidate }) => candidate);\n\n const gradedPercentages = submissions\n .map(calculatePercentage)\n .filter((value): value is number => value != null);\n const lowScoreCount = gradedPercentages.filter(\n (percentage) => percentage < 70,\n ).length;\n const missingCount = submissions.filter(\n (submission) =>\n !submission.submitted &&\n submission.assignment.dueDate.getTime() < now.getTime(),\n ).length;\n const trend = calculateTrend(submissions);\n const overallGrade = getOverallGrade(submissions);\n\n const nextSteps = [\n missingCount > 0\n ? `Prioritize ${missingCount} missing assignment${missingCount === 1 ? \"\" : \"s\"}.`\n : null,\n lowScoreCount > 0\n ? `Review ${lowScoreCount} low-scoring assignment${lowScoreCount === 1 ? \"\" : \"s\"} before introducing new material.`\n : null,\n trend < -5\n ? \"Schedule a check-in because recent performance is trending down.\"\n : null,\n recommendationCandidates.length === 0\n ? \"No urgent assignment issues detected from the available grades.\"\n : null,\n ].filter((step): step is string => Boolean(step));\n\n return {\n student: {\n id: student.id,\n username: student.username,\n displayName,\n },\n summary: {\n overallGrade,\n trend,\n completedAssignments: submissions.filter((submission) =>\n Boolean(submission.submitted),\n ).length,\n totalAssignments: submissions.length,\n missingCount,\n lowScoreCount,\n },\n recommendations,\n recommendationCandidates,\n nextSteps,\n priorityScore: recommendationCandidates[0]?.priorityScore ?? 0,\n };\n}\n\nasync function syncRecommendationStates(\n submissions: GradeSubmission[],\n recommendationCandidates: Array<\n NonNullable<ReturnType<typeof buildRecommendationCandidate>>\n >,\n) {\n const candidateSubmissionIds = new Set(\n recommendationCandidates.map((candidate) => candidate.submissionId),\n );\n const updates: Promise<unknown>[] = [];\n\n for (const submission of submissions) {\n const shouldBeOpen = candidateSubmissionIds.has(submission.id);\n\n if (shouldBeOpen && submission.recommendationState === \"NONE\") {\n updates.push(\n prisma.submission.update({\n where: { id: submission.id },\n data: {\n recommendationState: \"OPEN\",\n recommendationUpdatedAt: new Date(),\n },\n }),\n );\n continue;\n }\n\n if (!shouldBeOpen && submission.recommendationState === \"OPEN\") {\n updates.push(\n prisma.submission.update({\n where: { id: submission.id },\n data: {\n recommendationState: \"NONE\",\n recommendationUpdatedAt: new Date(),\n },\n }),\n );\n }\n }\n\n if (updates.length) {\n await Promise.all(updates);\n }\n}\n\nasync function summarizeStudentRecommendationsWithCases(\n student: ProgressStudent,\n submissions: GradeSubmission[],\n) {\n const summary = summarizeStudentRecommendations(student, submissions);\n await syncRecommendationStates(submissions, summary.recommendationCandidates);\n return summary;\n}\n\nasync function loadStudentProgressContext(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const isTeacher = await isTeacherInClass(classId, viewerId);\n if (viewerId !== studentId && !isTeacher) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You can only view your own progress\",\n });\n }\n\n const [classData, student, submissions] = await Promise.all([\n prisma.class.findUnique({\n where: { id: classId },\n select: { id: true, name: true, subject: true },\n }),\n prisma.user.findFirst({\n where: {\n id: studentId,\n studentIn: { some: { id: classId } },\n },\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n },\n }),\n prisma.submission.findMany({\n where: {\n studentId,\n assignment: { classId, graded: true },\n },\n include: {\n assignment: {\n select: {\n id: true,\n title: true,\n dueDate: true,\n maxGrade: true,\n weight: true,\n type: true,\n section: { select: { id: true, name: true } },\n },\n },\n },\n orderBy: { assignment: { dueDate: \"asc\" } },\n }),\n ]);\n\n if (!classData) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Class not found\" });\n }\n\n if (!student) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Student not found in this class\",\n });\n }\n\n return { classData, student, submissions };\n}\n\nexport async function getStudentProgressRecommendations(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const { student, submissions } = await loadStudentProgressContext(\n viewerId,\n classId,\n studentId,\n );\n\n const summary = await summarizeStudentRecommendationsWithCases(\n student,\n submissions,\n );\n const {\n recommendationCandidates: _recommendationCandidates,\n ...summaryResponse\n } = summary;\n return {\n student: summaryResponse.student,\n summary: summaryResponse.summary,\n recommendations: summaryResponse.recommendations,\n nextSteps: summaryResponse.nextSteps,\n };\n}\n\nexport async function getClassProgressRecommendations(\n viewerId: string,\n classId: string,\n) {\n const teacherInClass = await isTeacherInClass(classId, viewerId);\n if (!teacherInClass) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Only teachers can view class-wide recommendations\",\n });\n }\n\n const classData = await prisma.class.findUnique({\n where: { id: classId },\n select: {\n id: true,\n name: true,\n subject: true,\n students: {\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n submissions: {\n where: {\n assignment: { classId, graded: true },\n },\n include: {\n assignment: {\n select: {\n id: true,\n title: true,\n dueDate: true,\n maxGrade: true,\n weight: true,\n type: true,\n section: { select: { id: true, name: true } },\n },\n },\n },\n orderBy: { assignment: { dueDate: \"asc\" } },\n },\n },\n },\n },\n });\n\n if (!classData) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Class not found\" });\n }\n\n const students = (\n await Promise.all(\n classData.students.map((student) =>\n summarizeStudentRecommendationsWithCases(student, student.submissions),\n ),\n )\n )\n .map(\n ({ recommendationCandidates: _recommendationCandidates, ...student }) =>\n student,\n )\n .filter((student) => student.recommendations.length > 0)\n .sort((a, b) => b.priorityScore - a.priorityScore);\n\n const totalRecommendations = students.reduce(\n (sum, student) => sum + student.recommendations.length,\n 0,\n );\n const studentsWithConcerns = students.length;\n const totalMissingAssignments = students.reduce(\n (sum, student) => sum + student.summary.missingCount,\n 0,\n );\n const totalLowScoreAssignments = students.reduce(\n (sum, student) => sum + student.summary.lowScoreCount,\n 0,\n );\n\n return {\n class: {\n id: classData.id,\n name: classData.name,\n subject: classData.subject,\n },\n summary: {\n studentsWithConcerns,\n totalRecommendations,\n totalMissingAssignments,\n totalLowScoreAssignments,\n },\n students: students.map(({ priorityScore, ...student }) => student),\n };\n}\n\nexport async function dismissStudentRecommendation(\n viewerId: string,\n input: {\n classId: string;\n studentId: string;\n submissionId: string;\n },\n) {\n const teacherInClass = await isTeacherInClass(input.classId, viewerId);\n if (!teacherInClass) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Only teachers can dismiss recommendations\",\n });\n }\n\n const submission = await prisma.submission.findFirst({\n where: {\n id: input.submissionId,\n studentId: input.studentId,\n assignment: {\n classId: input.classId,\n },\n },\n select: { id: true },\n });\n\n if (!submission) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Submission not found for this student in this class\",\n });\n }\n\n await prisma.submission.update({\n where: { id: input.submissionId },\n data: {\n recommendationState: \"DISMISSED\",\n recommendationUpdatedAt: new Date(),\n },\n });\n\n return { success: true };\n}\n\nfunction buildProgressSummary(submissions: GradeSubmission[]) {\n return submissions.map((submission) => ({\n title: submission.assignment.title,\n type: submission.assignment.type,\n dueDate: submission.assignment.dueDate.toISOString(),\n submitted: Boolean(submission.submitted),\n returned: Boolean(submission.returned),\n gradeReceived: submission.gradeReceived,\n maxGrade: submission.assignment.maxGrade,\n percentage: calculatePercentage(submission),\n section: submission.assignment.section?.name ?? null,\n }));\n}\n\nfunction buildStructuredProgressContext(\n classData: { id: string; name: string; subject: string | null },\n student: ProgressStudent,\n submissions: GradeSubmission[],\n) {\n const displayName = student.profile?.displayName ?? student.username;\n const recommendationSummary = summarizeStudentRecommendations(\n student,\n submissions,\n );\n\n return {\n class: classData,\n student: { id: student.id, username: student.username, displayName },\n progress: {\n overallGrade: getOverallGrade(submissions),\n trend: calculateTrend(submissions),\n summary: recommendationSummary.summary,\n assignments: buildProgressSummary(submissions),\n recommendations: recommendationSummary.recommendations.map(\n (recommendation) => ({\n title: recommendation.title,\n recommendationType: recommendation.recommendationType,\n percentage: recommendation.percentage,\n submitted: recommendation.submitted,\n reasons: recommendation.reasons,\n sectionName: recommendation.sectionName,\n }),\n ),\n },\n };\n}\n\nfunction buildStructuredInferenceMessages(\n instruction: string,\n context: ReturnType<typeof buildStructuredProgressContext>,\n) {\n return [\n {\n role: \"system\" as const,\n content:\n \"You are an educational progress analyst. Use only the provided class and grade context. Be specific, concise, supportive, and do not fabricate assignments, grades, or sections.\",\n },\n {\n role: \"user\" as const,\n content: JSON.stringify(context),\n },\n {\n role: \"user\" as const,\n content: instruction,\n },\n ];\n}\n\nexport async function getStudentProgressInsights(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const { classData, student, submissions } = await loadStudentProgressContext(\n viewerId,\n classId,\n studentId,\n );\n const context = buildStructuredProgressContext(\n classData,\n student,\n submissions,\n );\n\n return inference<StudentProgressInsights>(\n buildStructuredInferenceMessages(\n [\n \"Generate an AI analytics summary for this one student's dashboard.\",\n \"The summary must be 2-4 plain-prose sentences: lead with overall grade and trajectory, then call out one strength and one concern with assignment titles.\",\n \"Strengths and growth items need 2-6 word labels and one-line evidence grounded in assignment titles or sections.\",\n \"Talking points must be 3-5 specific teacher check-in prompts with no numbering.\",\n ].join(\" \"),\n context,\n ),\n studentProgressInsightsSchema,\n {\n reason: \"student_progress_insights\",\n metadata: { viewerId, classId, studentId },\n },\n );\n}\n\nexport async function getStudentProgressForecast(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const { classData, student, submissions } = await loadStudentProgressContext(\n viewerId,\n classId,\n studentId,\n );\n const context = buildStructuredProgressContext(\n classData,\n student,\n submissions,\n );\n\n return inference<StudentProgressForecast>(\n buildStructuredInferenceMessages(\n \"Predict the student's next graded assignment percentage band and risk status. Base the forecast on trajectory, missing work, low scores, and assignment recency. Keep the reason to one sentence.\",\n context,\n ),\n studentProgressForecastSchema,\n {\n reason: \"student_progress_forecast\",\n metadata: { viewerId, classId, studentId },\n },\n );\n}\n\nexport async function getStudentProgressFocus(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const { classData, student, submissions } = await loadStudentProgressContext(\n viewerId,\n classId,\n studentId,\n );\n const context = buildStructuredProgressContext(\n classData,\n student,\n submissions,\n );\n\n return inference<StudentProgressFocus>(\n buildStructuredInferenceMessages(\n \"Generate 3-5 student-facing weekly focus items. Each item should be specific, actionable, and grounded in the student's grade pattern or assignment titles. No numbering in the strings.\",\n context,\n ),\n studentProgressFocusSchema,\n {\n reason: \"student_progress_focus\",\n metadata: { viewerId, classId, studentId },\n },\n );\n}\n\nexport async function chatAboutStudentProgress(\n viewerId: string,\n input: {\n classId: string;\n studentId: string;\n message: string;\n history?: ProgressChatMessage[];\n },\n) {\n const { classData, student, submissions } = await loadStudentProgressContext(\n viewerId,\n input.classId,\n input.studentId,\n );\n\n const displayName = student.profile?.displayName ?? student.username;\n const summary = {\n overallGrade: getOverallGrade(submissions),\n trend: calculateTrend(submissions),\n assignments: buildProgressSummary(submissions),\n };\n\n const messages = [\n {\n role: \"system\" as const,\n content:\n \"You are an educational progress assistant for teachers and students. Use only the provided class and grade context. Be concise, specific, supportive, and avoid fabricating grades or assignments.\",\n },\n {\n role: \"user\" as const,\n content: JSON.stringify({\n class: classData,\n student: { id: student.id, username: student.username, displayName },\n progress: summary,\n }),\n },\n ...(input.history ?? []).slice(-8).map((message) => ({\n role: message.role,\n content: message.content,\n })),\n { role: \"user\" as const, content: input.message },\n ];\n\n try {\n const response = await inference<string>(messages, undefined, {\n reason: \"student_progress_chat\",\n metadata: {\n viewerId,\n classId: input.classId,\n studentId: input.studentId,\n },\n });\n if (typeof response !== \"string\" || response.trim().length === 0) {\n throw new Error(\"Student progress chat returned an empty response\");\n }\n return { message: response, isFallback: false };\n } catch (error) {\n logger.error(\"Failed to generate student progress chat response\", {\n error,\n classId: input.classId,\n studentId: input.studentId,\n });\n\n const overall =\n summary.overallGrade == null\n ? \"not enough graded work\"\n : `${summary.overallGrade}%`;\n const missingItems = summary.assignments.filter(\n (assignment) =>\n !assignment.submitted &&\n new Date(assignment.dueDate).getTime() < Date.now(),\n ).length;\n const lowScores = summary.assignments.filter(\n (assignment) =>\n assignment.percentage != null && assignment.percentage < 70,\n ).length;\n const awaitingFeedback = summary.assignments.filter(\n (assignment) =>\n assignment.submitted &&\n assignment.gradeReceived == null &&\n !assignment.returned,\n ).length;\n\n const fallbackParts = [\n `${displayName}'s current overall grade is ${overall}.`,\n missingItems > 0\n ? `${missingItems} assignment${missingItems === 1 ? \"\" : \"s\"} ${missingItems === 1 ? \"appears\" : \"appear\"} overdue.`\n : null,\n lowScores > 0\n ? `${lowScores} graded assignment${lowScores === 1 ? \" is\" : \"s are\"} below 70%.`\n : null,\n awaitingFeedback > 0\n ? `${awaitingFeedback} assignment${awaitingFeedback === 1 ? \" is\" : \"s are\"} still awaiting feedback.`\n : null,\n summary.trend < -5\n ? \"Recent performance is trending down, so a check-in would be reasonable.\"\n : \"Performance looks relatively steady from the available data.\",\n ].filter((part): part is string => Boolean(part));\n\n return {\n message: fallbackParts.join(\" \"),\n isFallback: true,\n };\n }\n}\n"],"names":[],"mappings":"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","debug_id":"c49fe091-24d9-53b6-95ef-ab6f370623cd"}
|
|
1
|
+
{"version":3,"file":"studentProgress.js","sources":["services/studentProgress.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Student progress service - assignment recommendations and progress chat.\n */\nimport { TRPCError } from \"@trpc/server\";\nimport type { AssignmentType } from \"@prisma/client\";\nimport { z } from \"zod\";\nimport { prisma } from \"../lib/prisma.js\";\nimport { isTeacherInClass } from \"../models/class.js\";\nimport { inference } from \"../utils/inference.js\";\nimport { logger } from \"../utils/logger.js\";\nimport {\n getStudentProgressInferenceCacheHit,\n setStudentProgressInferenceCache,\n} from \"./studentProgressInferenceCache.js\";\n\ntype ProgressChatMessage = {\n role: \"user\" | \"assistant\";\n content: string;\n};\n\ntype GradeSubmission = {\n id: string;\n gradeReceived: number | null;\n submitted: boolean | null;\n returned: boolean | null;\n submittedAt: Date | null;\n recommendationState: \"NONE\" | \"OPEN\" | \"ASSIGNED\" | \"DISMISSED\";\n targetedAssignmentId: string | null;\n assignment: {\n id: string;\n title: string;\n dueDate: Date;\n maxGrade: number | null;\n weight: number;\n type: AssignmentType;\n section: { id: string; name: string } | null;\n };\n};\n\ntype ProgressStudent = {\n id: string;\n username: string;\n profile: { displayName: string | null } | null;\n};\n\nconst insightItemSchema = z.object({\n label: z.string(),\n evidence: z.string(),\n});\n\nconst studentProgressInsightsSchema = z.object({\n summary: z.string(),\n strengths: z.array(insightItemSchema).min(2).max(4),\n growth: z.array(insightItemSchema).min(2).max(4),\n talkingPoints: z.array(z.string()).min(3).max(5),\n});\n\nconst studentProgressForecastSchema = z.object({\n forecastLow: z.number().min(0).max(100),\n forecastHigh: z.number().min(0).max(100),\n risk: z.enum([\"on_track\", \"watch\", \"at_risk\"]),\n reason: z.string(),\n});\n\nconst studentProgressFocusSchema = z.object({\n focusItems: z.array(z.string()).min(3).max(5),\n});\n\nexport type StudentProgressInsights = z.infer<\n typeof studentProgressInsightsSchema\n>;\nexport type StudentProgressForecast = z.infer<\n typeof studentProgressForecastSchema\n>;\nexport type StudentProgressFocus = z.infer<typeof studentProgressFocusSchema>;\n\ntype RecommendationType = \"missing\" | \"low_score\" | \"awaiting_feedback\";\n\nfunction calculatePercentage(submission: GradeSubmission) {\n if (submission.gradeReceived == null || !submission.assignment.maxGrade) {\n return null;\n }\n\n return (\n Math.round(\n (submission.gradeReceived / submission.assignment.maxGrade) * 1000,\n ) / 10\n );\n}\n\nfunction calculateTrend(submissions: GradeSubmission[]) {\n const graded = submissions\n .filter(\n (submission) =>\n submission.gradeReceived != null && submission.assignment.maxGrade,\n )\n .sort((a, b) => {\n const aTime = a.submittedAt?.getTime() ?? a.assignment.dueDate.getTime();\n const bTime = b.submittedAt?.getTime() ?? b.assignment.dueDate.getTime();\n return aTime - bTime;\n })\n .map((submission) => calculatePercentage(submission))\n .filter((value): value is number => value != null);\n\n if (graded.length < 2) return 0;\n\n const midpoint = Math.floor(graded.length / 2);\n const first = graded.slice(0, midpoint);\n const second = graded.slice(midpoint);\n const average = (values: number[]) =>\n values.reduce((sum, value) => sum + value, 0) / values.length;\n\n return Math.round((average(second) - average(first)) * 10) / 10;\n}\n\nfunction getOverallGrade(submissions: GradeSubmission[]) {\n let totalWeighted = 0;\n let totalWeight = 0;\n\n for (const submission of submissions) {\n if (\n submission.gradeReceived != null &&\n submission.assignment.maxGrade &&\n submission.assignment.weight\n ) {\n totalWeighted +=\n (submission.gradeReceived / submission.assignment.maxGrade) *\n submission.assignment.weight;\n totalWeight += submission.assignment.weight;\n }\n }\n\n return totalWeight > 0\n ? Math.round((totalWeighted / totalWeight) * 1000) / 10\n : null;\n}\n\nfunction normalizeAssignmentType(\n assignmentType: AssignmentType,\n): AssignmentType {\n if (assignmentType === \"TEST\" || assignmentType === \"QUIZ\") {\n return \"HOMEWORK\";\n }\n\n return assignmentType;\n}\n\nfunction buildSuggestedAssignment(\n recommendationType: RecommendationType,\n submission: GradeSubmission,\n displayName: string,\n percentage: number | null,\n) {\n const sourceTitle = submission.assignment.title;\n const section = submission.assignment.section?.name;\n const titleByType: Record<RecommendationType, string> = {\n missing: `Make-up: ${sourceTitle}`,\n low_score: `Targeted practice: ${sourceTitle}`,\n awaiting_feedback: `Revision follow-up: ${sourceTitle}`,\n };\n const leadByType: Record<RecommendationType, string> = {\n missing: `${displayName} missed the original assignment and needs a focused make-up task on the same material.`,\n low_score:\n percentage != null\n ? `${displayName} scored ${percentage}% and needs targeted reinforcement on the underlying concepts.`\n : `${displayName} needs targeted reinforcement on the underlying concepts.`,\n awaiting_feedback: `${displayName} has work in progress here, so a short follow-up can keep momentum once feedback lands.`,\n };\n\n return {\n title: titleByType[recommendationType],\n instructions: [\n leadByType[recommendationType],\n `Source assignment: ${sourceTitle}.`,\n section ? `Section: ${section}.` : null,\n \"Keep the work concise and focused on the specific area of concern.\",\n ]\n .filter((line): line is string => Boolean(line))\n .join(\"\\n\\n\"),\n type: normalizeAssignmentType(submission.assignment.type),\n maxGrade: submission.assignment.maxGrade ?? 100,\n weight: submission.assignment.weight || 1,\n graded: true,\n sectionId: submission.assignment.section?.id ?? null,\n sourceAssignmentId: submission.assignment.id,\n };\n}\n\nfunction buildRecommendationCandidate(\n submission: GradeSubmission,\n displayName: string,\n now: Date,\n) {\n if (\n submission.recommendationState === \"ASSIGNED\" ||\n submission.recommendationState === \"DISMISSED\"\n ) {\n return null;\n }\n\n const percentage = calculatePercentage(submission);\n const isMissing =\n !submission.submitted &&\n submission.assignment.dueDate.getTime() < now.getTime();\n const isLowScore = percentage != null && percentage < 70;\n const isUnreturned =\n Boolean(submission.submitted) &&\n submission.gradeReceived == null &&\n !submission.returned;\n const reasons: string[] = [];\n let priorityScore = 0;\n let recommendationType: RecommendationType | null = null;\n\n if (isMissing) {\n reasons.push(\"Missing past-due work\");\n priorityScore += 100;\n recommendationType = \"missing\";\n }\n if (isLowScore) {\n reasons.push(`Scored ${percentage}%`);\n priorityScore += 85 - (percentage ?? 0);\n recommendationType ??= \"low_score\";\n }\n if (isUnreturned) {\n reasons.push(\"Awaiting grade or feedback\");\n priorityScore += 15;\n recommendationType ??= \"awaiting_feedback\";\n }\n\n if (priorityScore <= 0 || !recommendationType) {\n return null;\n }\n\n return {\n assignmentId: submission.assignment.id,\n submissionId: submission.id,\n title: submission.assignment.title,\n type: submission.assignment.type,\n sectionId: submission.assignment.section?.id ?? null,\n sectionName: submission.assignment.section?.name ?? null,\n dueDate: submission.assignment.dueDate,\n gradeReceived: submission.gradeReceived,\n maxGrade: submission.assignment.maxGrade,\n percentage,\n submitted: Boolean(submission.submitted),\n returned: Boolean(submission.returned),\n recommendationType,\n reasons,\n priorityScore,\n suggestedAssignment: buildSuggestedAssignment(\n recommendationType,\n submission,\n displayName,\n percentage,\n ),\n };\n}\n\nfunction summarizeStudentRecommendations(\n student: ProgressStudent,\n submissions: GradeSubmission[],\n) {\n const now = new Date();\n const displayName = student.profile?.displayName ?? student.username;\n const recommendationCandidates = submissions\n .map((submission) =>\n buildRecommendationCandidate(submission, displayName, now),\n )\n .filter(\n (\n candidate,\n ): candidate is NonNullable<\n ReturnType<typeof buildRecommendationCandidate>\n > => candidate != null,\n )\n .sort((a, b) => b.priorityScore - a.priorityScore);\n\n const recommendations = recommendationCandidates\n .slice(0, 5)\n .map(({ priorityScore, ...candidate }) => candidate);\n\n const gradedPercentages = submissions\n .map(calculatePercentage)\n .filter((value): value is number => value != null);\n const lowScoreCount = gradedPercentages.filter(\n (percentage) => percentage < 70,\n ).length;\n const missingCount = submissions.filter(\n (submission) =>\n !submission.submitted &&\n submission.assignment.dueDate.getTime() < now.getTime(),\n ).length;\n const trend = calculateTrend(submissions);\n const overallGrade = getOverallGrade(submissions);\n\n const nextSteps = [\n missingCount > 0\n ? `Prioritize ${missingCount} missing assignment${missingCount === 1 ? \"\" : \"s\"}.`\n : null,\n lowScoreCount > 0\n ? `Review ${lowScoreCount} low-scoring assignment${lowScoreCount === 1 ? \"\" : \"s\"} before introducing new material.`\n : null,\n trend < -5\n ? \"Schedule a check-in because recent performance is trending down.\"\n : null,\n recommendationCandidates.length === 0\n ? \"No urgent assignment issues detected from the available grades.\"\n : null,\n ].filter((step): step is string => Boolean(step));\n\n return {\n student: {\n id: student.id,\n username: student.username,\n displayName,\n },\n summary: {\n overallGrade,\n trend,\n completedAssignments: submissions.filter((submission) =>\n Boolean(submission.submitted),\n ).length,\n totalAssignments: submissions.length,\n missingCount,\n lowScoreCount,\n },\n recommendations,\n recommendationCandidates,\n nextSteps,\n priorityScore: recommendationCandidates[0]?.priorityScore ?? 0,\n };\n}\n\nasync function syncRecommendationStates(\n submissions: GradeSubmission[],\n recommendationCandidates: Array<\n NonNullable<ReturnType<typeof buildRecommendationCandidate>>\n >,\n) {\n const candidateSubmissionIds = new Set(\n recommendationCandidates.map((candidate) => candidate.submissionId),\n );\n const updates: Promise<unknown>[] = [];\n\n for (const submission of submissions) {\n const shouldBeOpen = candidateSubmissionIds.has(submission.id);\n\n if (shouldBeOpen && submission.recommendationState === \"NONE\") {\n updates.push(\n prisma.submission.update({\n where: { id: submission.id },\n data: {\n recommendationState: \"OPEN\",\n recommendationUpdatedAt: new Date(),\n },\n }),\n );\n continue;\n }\n\n if (!shouldBeOpen && submission.recommendationState === \"OPEN\") {\n updates.push(\n prisma.submission.update({\n where: { id: submission.id },\n data: {\n recommendationState: \"NONE\",\n recommendationUpdatedAt: new Date(),\n },\n }),\n );\n }\n }\n\n if (updates.length) {\n await Promise.all(updates);\n }\n}\n\nasync function summarizeStudentRecommendationsWithCases(\n student: ProgressStudent,\n submissions: GradeSubmission[],\n) {\n const summary = summarizeStudentRecommendations(student, submissions);\n await syncRecommendationStates(submissions, summary.recommendationCandidates);\n return summary;\n}\n\nasync function loadStudentProgressContext(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const isTeacher = await isTeacherInClass(classId, viewerId);\n if (viewerId !== studentId && !isTeacher) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"You can only view your own progress\",\n });\n }\n\n const [classData, student, submissions] = await Promise.all([\n prisma.class.findUnique({\n where: { id: classId },\n select: { id: true, name: true, subject: true },\n }),\n prisma.user.findFirst({\n where: {\n id: studentId,\n studentIn: { some: { id: classId } },\n },\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n },\n }),\n prisma.submission.findMany({\n where: {\n studentId,\n assignment: { classId, graded: true },\n },\n include: {\n assignment: {\n select: {\n id: true,\n title: true,\n dueDate: true,\n maxGrade: true,\n weight: true,\n type: true,\n section: { select: { id: true, name: true } },\n },\n },\n },\n orderBy: { assignment: { dueDate: \"asc\" } },\n }),\n ]);\n\n if (!classData) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Class not found\" });\n }\n\n if (!student) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Student not found in this class\",\n });\n }\n\n return { classData, student, submissions };\n}\n\nexport async function getStudentProgressRecommendations(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const { student, submissions } = await loadStudentProgressContext(\n viewerId,\n classId,\n studentId,\n );\n\n const summary = await summarizeStudentRecommendationsWithCases(\n student,\n submissions,\n );\n const {\n recommendationCandidates: _recommendationCandidates,\n ...summaryResponse\n } = summary;\n return {\n student: summaryResponse.student,\n summary: summaryResponse.summary,\n recommendations: summaryResponse.recommendations,\n nextSteps: summaryResponse.nextSteps,\n };\n}\n\nexport async function getClassProgressRecommendations(\n viewerId: string,\n classId: string,\n) {\n const teacherInClass = await isTeacherInClass(classId, viewerId);\n if (!teacherInClass) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Only teachers can view class-wide recommendations\",\n });\n }\n\n const classData = await prisma.class.findUnique({\n where: { id: classId },\n select: {\n id: true,\n name: true,\n subject: true,\n students: {\n select: {\n id: true,\n username: true,\n profile: { select: { displayName: true } },\n submissions: {\n where: {\n assignment: { classId, graded: true },\n },\n include: {\n assignment: {\n select: {\n id: true,\n title: true,\n dueDate: true,\n maxGrade: true,\n weight: true,\n type: true,\n section: { select: { id: true, name: true } },\n },\n },\n },\n orderBy: { assignment: { dueDate: \"asc\" } },\n },\n },\n },\n },\n });\n\n if (!classData) {\n throw new TRPCError({ code: \"NOT_FOUND\", message: \"Class not found\" });\n }\n\n const students = (\n await Promise.all(\n classData.students.map((student) =>\n summarizeStudentRecommendationsWithCases(student, student.submissions),\n ),\n )\n )\n .map(\n ({ recommendationCandidates: _recommendationCandidates, ...student }) =>\n student,\n )\n .filter((student) => student.recommendations.length > 0)\n .sort((a, b) => b.priorityScore - a.priorityScore);\n\n const totalRecommendations = students.reduce(\n (sum, student) => sum + student.recommendations.length,\n 0,\n );\n const studentsWithConcerns = students.length;\n const totalMissingAssignments = students.reduce(\n (sum, student) => sum + student.summary.missingCount,\n 0,\n );\n const totalLowScoreAssignments = students.reduce(\n (sum, student) => sum + student.summary.lowScoreCount,\n 0,\n );\n\n return {\n class: {\n id: classData.id,\n name: classData.name,\n subject: classData.subject,\n },\n summary: {\n studentsWithConcerns,\n totalRecommendations,\n totalMissingAssignments,\n totalLowScoreAssignments,\n },\n students: students.map(({ priorityScore, ...student }) => student),\n };\n}\n\nexport async function dismissStudentRecommendation(\n viewerId: string,\n input: {\n classId: string;\n studentId: string;\n submissionId: string;\n },\n) {\n const teacherInClass = await isTeacherInClass(input.classId, viewerId);\n if (!teacherInClass) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Only teachers can dismiss recommendations\",\n });\n }\n\n const submission = await prisma.submission.findFirst({\n where: {\n id: input.submissionId,\n studentId: input.studentId,\n assignment: {\n classId: input.classId,\n },\n },\n select: { id: true },\n });\n\n if (!submission) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Submission not found for this student in this class\",\n });\n }\n\n await prisma.submission.update({\n where: { id: input.submissionId },\n data: {\n recommendationState: \"DISMISSED\",\n recommendationUpdatedAt: new Date(),\n },\n });\n\n return { success: true };\n}\n\nfunction buildProgressSummary(submissions: GradeSubmission[]) {\n return submissions.map((submission) => ({\n title: submission.assignment.title,\n type: submission.assignment.type,\n dueDate: submission.assignment.dueDate.toISOString(),\n submitted: Boolean(submission.submitted),\n returned: Boolean(submission.returned),\n gradeReceived: submission.gradeReceived,\n maxGrade: submission.assignment.maxGrade,\n percentage: calculatePercentage(submission),\n section: submission.assignment.section?.name ?? null,\n }));\n}\n\nfunction buildStructuredProgressContext(\n classData: { id: string; name: string; subject: string | null },\n student: ProgressStudent,\n submissions: GradeSubmission[],\n) {\n const displayName = student.profile?.displayName ?? student.username;\n const recommendationSummary = summarizeStudentRecommendations(\n student,\n submissions,\n );\n\n return {\n class: classData,\n student: { id: student.id, username: student.username, displayName },\n progress: {\n overallGrade: getOverallGrade(submissions),\n trend: calculateTrend(submissions),\n summary: recommendationSummary.summary,\n assignments: buildProgressSummary(submissions),\n recommendations: recommendationSummary.recommendations.map(\n (recommendation) => ({\n title: recommendation.title,\n recommendationType: recommendation.recommendationType,\n percentage: recommendation.percentage,\n submitted: recommendation.submitted,\n reasons: recommendation.reasons,\n sectionName: recommendation.sectionName,\n }),\n ),\n },\n };\n}\n\nfunction buildStructuredInferenceMessages(\n instruction: string,\n context: ReturnType<typeof buildStructuredProgressContext>,\n) {\n return [\n {\n role: \"system\" as const,\n content:\n \"You are an educational progress analyst. Use only the provided class and grade context. Be specific, concise, supportive, and do not fabricate assignments, grades, or sections.\",\n },\n {\n role: \"user\" as const,\n content: JSON.stringify(context),\n },\n {\n role: \"user\" as const,\n content: instruction,\n },\n ];\n}\n\ntype ProgressInferenceCacheRow<T> = {\n epoch: number;\n cachedAt: number;\n value: T;\n};\n\nconst studentProgressInsightsCache = new Map<\n string,\n ProgressInferenceCacheRow<StudentProgressInsights>\n>();\nconst studentProgressForecastCache = new Map<\n string,\n ProgressInferenceCacheRow<StudentProgressForecast>\n>();\nconst studentProgressFocusCache = new Map<\n string,\n ProgressInferenceCacheRow<StudentProgressFocus>\n>();\n\nexport async function getStudentProgressInsights(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const cached = getStudentProgressInferenceCacheHit(\n studentProgressInsightsCache,\n classId,\n studentId,\n );\n\n const { classData, student, submissions } = await loadStudentProgressContext(\n viewerId,\n classId,\n studentId,\n );\n\n if (cached !== undefined) {\n return cached;\n }\n\n const context = buildStructuredProgressContext(\n classData,\n student,\n submissions,\n );\n\n const value = await inference<StudentProgressInsights>(\n buildStructuredInferenceMessages(\n [\n \"Generate an AI analytics summary for this one student's dashboard.\",\n \"The summary must be 2-4 plain-prose sentences: lead with overall grade and trajectory, then call out one strength and one concern with assignment titles.\",\n \"Strengths and growth items need 2-6 word labels and one-line evidence grounded in assignment titles or sections.\",\n \"Talking points must be 3-5 specific teacher check-in prompts with no numbering.\",\n ].join(\" \"),\n context,\n ),\n studentProgressInsightsSchema,\n {\n reason: \"student_progress_insights\",\n metadata: { viewerId, classId, studentId },\n },\n );\n setStudentProgressInferenceCache(\n studentProgressInsightsCache,\n classId,\n studentId,\n value,\n );\n return value;\n}\n\nexport async function getStudentProgressForecast(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const cached = getStudentProgressInferenceCacheHit(\n studentProgressForecastCache,\n classId,\n studentId,\n );\n\n const { classData, student, submissions } = await loadStudentProgressContext(\n viewerId,\n classId,\n studentId,\n );\n\n if (cached !== undefined) {\n return cached;\n }\n\n const context = buildStructuredProgressContext(\n classData,\n student,\n submissions,\n );\n\n const value = await inference<StudentProgressForecast>(\n buildStructuredInferenceMessages(\n \"Predict the student's next graded assignment percentage band and risk status. Base the forecast on trajectory, missing work, low scores, and assignment recency. Keep the reason to one sentence.\",\n context,\n ),\n studentProgressForecastSchema,\n {\n reason: \"student_progress_forecast\",\n metadata: { viewerId, classId, studentId },\n },\n );\n setStudentProgressInferenceCache(\n studentProgressForecastCache,\n classId,\n studentId,\n value,\n );\n return value;\n}\n\nexport async function getStudentProgressFocus(\n viewerId: string,\n classId: string,\n studentId: string,\n) {\n const cached = getStudentProgressInferenceCacheHit(\n studentProgressFocusCache,\n classId,\n studentId,\n );\n\n const { classData, student, submissions } = await loadStudentProgressContext(\n viewerId,\n classId,\n studentId,\n );\n\n if (cached !== undefined) {\n return cached;\n }\n \n const context = buildStructuredProgressContext(\n classData,\n student,\n submissions,\n );\n\n const value = await inference<StudentProgressFocus>(\n buildStructuredInferenceMessages(\n \"Generate 3-5 student-facing weekly focus items. Each item should be specific, actionable, and grounded in the student's grade pattern or assignment titles. No numbering in the strings.\",\n context,\n ),\n studentProgressFocusSchema,\n {\n reason: \"student_progress_focus\",\n metadata: { viewerId, classId, studentId },\n },\n );\n setStudentProgressInferenceCache(\n studentProgressFocusCache,\n classId,\n studentId,\n value,\n );\n return value;\n}\n\nexport async function chatAboutStudentProgress(\n viewerId: string,\n input: {\n classId: string;\n studentId: string;\n message: string;\n history?: ProgressChatMessage[];\n },\n) {\n const { classData, student, submissions } = await loadStudentProgressContext(\n viewerId,\n input.classId,\n input.studentId,\n );\n\n const displayName = student.profile?.displayName ?? student.username;\n const summary = {\n overallGrade: getOverallGrade(submissions),\n trend: calculateTrend(submissions),\n assignments: buildProgressSummary(submissions),\n };\n\n const messages = [\n {\n role: \"system\" as const,\n content:\n \"You are an educational progress assistant for teachers and students. Use only the provided class and grade context. Be concise, specific, supportive, and avoid fabricating grades or assignments.\",\n },\n {\n role: \"user\" as const,\n content: JSON.stringify({\n class: classData,\n student: { id: student.id, username: student.username, displayName },\n progress: summary,\n }),\n },\n ...(input.history ?? []).slice(-8).map((message) => ({\n role: message.role,\n content: message.content,\n })),\n { role: \"user\" as const, content: input.message },\n ];\n\n try {\n const response = await inference<string>(messages, undefined, {\n reason: \"student_progress_chat\",\n metadata: {\n viewerId,\n classId: input.classId,\n studentId: input.studentId,\n },\n });\n if (typeof response !== \"string\" || response.trim().length === 0) {\n throw new Error(\"Student progress chat returned an empty response\");\n }\n return { message: response, isFallback: false };\n } catch (error) {\n logger.error(\"Failed to generate student progress chat response\", {\n error,\n classId: input.classId,\n studentId: input.studentId,\n });\n\n const overall =\n summary.overallGrade == null\n ? \"not enough graded work\"\n : `${summary.overallGrade}%`;\n const missingItems = summary.assignments.filter(\n (assignment) =>\n !assignment.submitted &&\n new Date(assignment.dueDate).getTime() < Date.now(),\n ).length;\n const lowScores = summary.assignments.filter(\n (assignment) =>\n assignment.percentage != null && assignment.percentage < 70,\n ).length;\n const awaitingFeedback = summary.assignments.filter(\n (assignment) =>\n assignment.submitted &&\n assignment.gradeReceived == null &&\n !assignment.returned,\n ).length;\n\n const fallbackParts = [\n `${displayName}'s current overall grade is ${overall}.`,\n missingItems > 0\n ? `${missingItems} assignment${missingItems === 1 ? \"\" : \"s\"} ${missingItems === 1 ? \"appears\" : \"appear\"} overdue.`\n : null,\n lowScores > 0\n ? `${lowScores} graded assignment${lowScores === 1 ? \" is\" : \"s are\"} below 70%.`\n : null,\n awaitingFeedback > 0\n ? `${awaitingFeedback} assignment${awaitingFeedback === 1 ? \" is\" : \"s are\"} still awaiting feedback.`\n : null,\n summary.trend < -5\n ? \"Recent performance is trending down, so a check-in would be reasonable.\"\n : \"Performance looks relatively steady from the available data.\",\n ].filter((part): part is string => Boolean(part));\n\n return {\n message: fallbackParts.join(\" \"),\n isFallback: true,\n };\n }\n}\n"],"names":[],"mappings":"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","debug_id":"159c0157-8d54-553a-84a9-e84c0b152f43"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process cache for student progress AI panels (insights / forecast / focus).
|
|
3
|
+
* Epoch bumps invalidate all three for a given class + student (e.g. after a grade update).
|
|
4
|
+
* Entries also expire after one week so stale AI summaries eventually refresh.
|
|
5
|
+
*/
|
|
6
|
+
/** Call when a teacher updates `gradeReceived` for that student's work in this class. */
|
|
7
|
+
export declare function invalidateStudentProgressInferenceCache(classId: string, studentId: string): void;
|
|
8
|
+
type CacheRow<T> = {
|
|
9
|
+
epoch: number;
|
|
10
|
+
cachedAt: number;
|
|
11
|
+
value: T;
|
|
12
|
+
};
|
|
13
|
+
export declare function getStudentProgressInferenceCacheHit<T>(store: Map<string, CacheRow<T>>, classId: string, studentId: string): T | undefined;
|
|
14
|
+
export declare function setStudentProgressInferenceCache<T>(store: Map<string, CacheRow<T>>, classId: string, studentId: string, value: T): void;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=studentProgressInferenceCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"studentProgressInferenceCache.d.ts","sourceRoot":"/","sources":["services/studentProgressInferenceCache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH,yFAAyF;AACzF,wBAAgB,uCAAuC,CACrD,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,QAIlB;AAED,KAAK,QAAQ,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAEjE,wBAAgB,mCAAmC,CAAC,CAAC,EACnD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAC/B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,CAAC,GAAG,SAAS,CAcf;AAED,wBAAgB,gCAAgC,CAAC,CAAC,EAChD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAC/B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,CAAC,QAOT"}
|