@studious-lms/server 1.16.0 → 1.17.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/.github/workflows/deploy.yml +1 -1
- package/dist/instrument.js +3 -3
- package/dist/instrument.js.map +1 -1
- package/dist/lib/chatAttachmentPrompt.d.ts +47 -0
- package/dist/lib/chatAttachmentPrompt.d.ts.map +1 -0
- package/dist/lib/chatAttachmentPrompt.js +190 -0
- package/dist/lib/chatAttachmentPrompt.js.map +1 -0
- package/dist/lib/inferDocumentFormat.js +3 -3
- package/dist/lib/inferDocumentFormat.js.map +1 -1
- package/dist/lib/legal.d.ts +3 -0
- package/dist/lib/legal.d.ts.map +1 -0
- package/dist/lib/legal.js +6 -0
- package/dist/lib/legal.js.map +1 -0
- package/dist/models/announcement.d.ts +2 -0
- package/dist/models/announcement.d.ts.map +1 -1
- package/dist/models/auth.d.ts +8 -0
- package/dist/models/auth.d.ts.map +1 -1
- package/dist/models/auth.js +4 -2
- package/dist/models/auth.js.map +1 -1
- package/dist/models/event.d.ts +2 -0
- package/dist/models/event.d.ts.map +1 -1
- package/dist/models/file.d.ts +24 -0
- package/dist/models/file.d.ts.map +1 -1
- package/dist/models/marketing.d.ts +2 -15
- package/dist/models/marketing.d.ts.map +1 -1
- package/dist/models/marketing.js +12 -4
- package/dist/models/marketing.js.map +1 -1
- package/dist/pipelines/aiLabChat.d.ts.map +1 -1
- package/dist/pipelines/aiLabChat.js +39 -59
- package/dist/pipelines/aiLabChat.js.map +1 -1
- package/dist/pipelines/aiLabChatContract.d.ts +2 -2
- package/dist/pipelines/aiNewtonChat.d.ts +1 -1
- package/dist/pipelines/aiNewtonChat.d.ts.map +1 -1
- package/dist/pipelines/aiNewtonChat.js +20 -19
- package/dist/pipelines/aiNewtonChat.js.map +1 -1
- package/dist/pipelines/gradeWorksheet.d.ts +1 -0
- package/dist/pipelines/gradeWorksheet.d.ts.map +1 -1
- package/dist/pipelines/gradeWorksheet.js +84 -13
- package/dist/pipelines/gradeWorksheet.js.map +1 -1
- package/dist/pipelines/labChatPrompt.d.ts +4 -20
- package/dist/pipelines/labChatPrompt.d.ts.map +1 -1
- package/dist/pipelines/labChatPrompt.js +24 -64
- package/dist/pipelines/labChatPrompt.js.map +1 -1
- package/dist/routers/_app.d.ts +440 -26
- package/dist/routers/_app.d.ts.map +1 -1
- package/dist/routers/assignment.d.ts +10 -0
- package/dist/routers/assignment.d.ts.map +1 -1
- package/dist/routers/auth.d.ts +2 -0
- package/dist/routers/auth.d.ts.map +1 -1
- package/dist/routers/auth.js +15 -2
- package/dist/routers/auth.js.map +1 -1
- package/dist/routers/class.d.ts +4 -0
- package/dist/routers/class.d.ts.map +1 -1
- package/dist/routers/event.d.ts +2 -0
- package/dist/routers/event.d.ts.map +1 -1
- package/dist/routers/marketing.d.ts +0 -13
- package/dist/routers/marketing.d.ts.map +1 -1
- package/dist/routers/school.d.ts +106 -0
- package/dist/routers/school.d.ts.map +1 -1
- package/dist/routers/school.js +11 -3
- package/dist/routers/school.js.map +1 -1
- package/dist/routers/user.d.ts +89 -0
- package/dist/routers/user.d.ts.map +1 -1
- package/dist/routers/user.js +19 -2
- package/dist/routers/user.js.map +1 -1
- package/dist/routers/worksheet.d.ts +7 -0
- package/dist/routers/worksheet.d.ts.map +1 -1
- package/dist/routers/worksheet.js +8 -3
- package/dist/routers/worksheet.js.map +1 -1
- package/dist/seedDatabase.d.ts +2 -0
- package/dist/seedDatabase.d.ts.map +1 -1
- package/dist/services/aiChatStream.d.ts +2 -0
- package/dist/services/aiChatStream.d.ts.map +1 -1
- package/dist/services/aiChatStream.js +31 -4
- package/dist/services/aiChatStream.js.map +1 -1
- package/dist/services/aiProposalTools.d.ts.map +1 -1
- package/dist/services/aiProposalTools.js +9 -9
- package/dist/services/aiProposalTools.js.map +1 -1
- package/dist/services/aiTools.js +3 -3
- package/dist/services/aiTools.js.map +1 -1
- package/dist/services/assignment.d.ts +10 -0
- package/dist/services/assignment.d.ts.map +1 -1
- package/dist/services/auth.d.ts +2 -0
- package/dist/services/auth.d.ts.map +1 -1
- package/dist/services/auth.js +13 -4
- package/dist/services/auth.js.map +1 -1
- package/dist/services/class.d.ts +4 -0
- package/dist/services/class.d.ts.map +1 -1
- package/dist/services/event.d.ts +2 -0
- package/dist/services/event.d.ts.map +1 -1
- package/dist/services/marketing.d.ts +1 -14
- package/dist/services/marketing.d.ts.map +1 -1
- package/dist/services/marketing.js +5 -5
- package/dist/services/marketing.js.map +1 -1
- package/dist/services/newtonChat.d.ts.map +1 -1
- package/dist/services/newtonChat.js +2 -8
- package/dist/services/newtonChat.js.map +1 -1
- package/dist/services/openaiDocumentGen.d.ts +12 -0
- package/dist/services/openaiDocumentGen.d.ts.map +1 -1
- package/dist/services/openaiDocumentGen.js +173 -65
- package/dist/services/openaiDocumentGen.js.map +1 -1
- package/dist/services/school.d.ts +116 -0
- package/dist/services/school.d.ts.map +1 -1
- package/dist/services/school.js +213 -2
- package/dist/services/school.js.map +1 -1
- package/dist/services/userPrivacy.d.ts +86 -0
- package/dist/services/userPrivacy.d.ts.map +1 -0
- package/dist/services/userPrivacy.js +184 -0
- package/dist/services/userPrivacy.js.map +1 -0
- package/dist/services/worksheet.d.ts +1 -0
- package/dist/services/worksheet.d.ts.map +1 -1
- package/dist/services/worksheet.js +13 -3
- package/dist/services/worksheet.js.map +1 -1
- package/dist/utils/email.d.ts.map +1 -1
- package/dist/utils/email.js +7 -3
- package/dist/utils/email.js.map +1 -1
- package/dist/workers/processors/aiNewtonChat.d.ts.map +1 -1
- package/dist/workers/processors/aiNewtonChat.js +3 -3
- package/dist/workers/processors/aiNewtonChat.js.map +1 -1
- package/package.json +2 -1
- package/prisma/migrations/20260611120000_add_user_terms_acceptance/migration.sql +3 -0
- package/prisma/schema.prisma +3 -0
- package/src/instrument.ts +1 -1
- package/src/lib/chatAttachmentPrompt.ts +270 -0
- package/src/lib/inferDocumentFormat.ts +1 -1
- package/src/lib/legal.ts +2 -0
- package/src/models/auth.ts +4 -0
- package/src/models/marketing.ts +10 -2
- package/src/pipelines/aiLabChat.ts +46 -71
- package/src/pipelines/aiNewtonChat.ts +20 -23
- package/src/pipelines/gradeWorksheet.ts +87 -11
- package/src/pipelines/labChatPrompt.ts +29 -98
- package/src/routers/auth.ts +13 -0
- package/src/routers/school.ts +12 -0
- package/src/routers/user.ts +26 -0
- package/src/routers/worksheet.ts +11 -0
- package/src/services/aiChatStream.ts +30 -3
- package/src/services/aiProposalTools.ts +8 -7
- package/src/services/aiTools.ts +1 -1
- package/src/services/auth.ts +14 -2
- package/src/services/marketing.ts +3 -3
- package/src/services/newtonChat.ts +0 -7
- package/src/services/openaiDocumentGen.ts +190 -66
- package/src/services/school.ts +231 -0
- package/src/services/userPrivacy.ts +196 -0
- package/src/services/worksheet.ts +20 -1
- package/src/utils/email.ts +5 -1
- package/src/workers/processors/aiNewtonChat.ts +0 -1
- package/tests/helpers/registerInput.ts +20 -0
- package/tests/integration/globalSetup.ts +10 -18
- package/tests/integration/routers/auth.test.ts +13 -18
- package/tests/integration/routers/newtonChat.test.ts +9 -8
- package/tests/unit/lib/chatAttachmentPrompt.test.ts +135 -0
- package/tests/unit/lib/inferDocumentFormat.test.ts +10 -0
- package/tests/unit/pipelines/labChatPrompt.test.ts +6 -6
- package/tests/unit/services/aiChatStream.test.ts +92 -0
- package/tests/unit/services/openaiDocumentGen.test.ts +65 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiProposalTools.js","sources":["services/aiProposalTools.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Lab-chat \"proposal\" tools.\n *\n * In the agentic Lab pipeline the model produces create-actions by *calling\n * tools* (e.g. `propose_assignment`) instead of returning a JSON blob. Each\n * tool records a structured payload into a shared accumulator and returns a\n * short confirmation so the model can keep narrating. After the stream ends\n * the pipeline turns the accumulator into the `message.meta.*ToCreate` shape\n * the frontend accept-cards already consume — so the data contract is\n * preserved while the generation becomes genuine inline tool calls.\n *\n * NOTE: these tools intentionally use `jsonSchema()` rather than the zod\n * `tool()` helper. Zod-typed `tool()` definitions with deeply nested schemas\n * make the TS compiler instantiate excessively deep types (TS2589) and OOM,\n * so we mirror the existing `aiTools.ts` pattern (plain JSON Schema + manually\n * typed execute args).\n */\nimport { jsonSchema, type ToolSet } from 'ai';\nimport { v4 } from 'uuid';\nimport type {\n AssignmentToCreate,\n WorksheetToCreate,\n SectionToCreate,\n DocToCreate,\n} from '../pipelines/aiLabChatContract.js';\n\nexport interface LabProposals {\n assignments: AssignmentToCreate[];\n worksheets: WorksheetToCreate[];\n sections: SectionToCreate[];\n docs: DocToCreate[];\n}\n\nexport function createLabProposals(): LabProposals {\n return { assignments: [], worksheets: [], sections: [], docs: [] };\n}\n\nfunction normalizeDueDate(input?: string | null): string {\n if (input) {\n const parsed = new Date(input);\n if (!Number.isNaN(parsed.getTime())) return parsed.toISOString();\n }\n // Default: one week out.\n return new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString();\n}\n\nconst ASSIGNMENT_TYPES = [\n 'HOMEWORK', 'QUIZ', 'TEST', 'PROJECT', 'ESSAY', 'DISCUSSION', 'PRESENTATION', 'LAB', 'OTHER',\n] as const;\ntype AssignmentType = (typeof ASSIGNMENT_TYPES)[number];\n\nconst QUESTION_TYPES = [\n 'MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY',\n] as const;\ntype QuestionType = (typeof QUESTION_TYPES)[number];\n\ninterface ProposeSectionArgs {\n name: string;\n color?: string | null;\n}\n\ninterface ProposeWorksheetArgs {\n title: string;\n questions: Array<{\n type: QuestionType;\n question: string;\n answer?: string;\n options?: Array<{ text: string; isCorrect: boolean }>;\n markScheme?: Array<{ points: number; description: string }>;\n points?: number;\n }>;\n}\n\ninterface ProposeAssignmentArgs {\n title: string;\n instructions: string;\n dueDate?: string;\n type?: AssignmentType;\n maxGrade?: number;\n acceptFiles?: boolean;\n acceptExtendedResponse?: boolean;\n acceptWorksheet?: boolean;\n}\n\ninterface GenerateDocumentArgs {\n title: string;\n content: string;\n format?: string;\n}\n\n/**\n * Build the set of proposal tools backed by the given accumulator.\n * Merge these with the read-only RAG tools from `aiTools(classId)`.\n */\nexport function labProposalTools(proposals: LabProposals): ToolSet {\n return {\n propose_section: {\n description:\n 'Propose a new section (folder) to organise class content. Call once per section you want to create.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Section name' },\n color: { type: 'string', description: 'Optional hex color like #3b82f6' },\n },\n required: ['name'],\n }),\n execute: async ({ name, color }: ProposeSectionArgs) => {\n proposals.sections.push({ name, color: color ?? null });\n return `Section \"${name}\" proposed.`;\n },\n },\n\n propose_worksheet: {\n description:\n 'Propose a worksheet of questions for the teacher to review and create. Include all questions in a single call.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n title: { type: 'string', description: 'Worksheet title' },\n questions: {\n type: 'array',\n description: 'The list of questions',\n items: {\n type: 'object',\n properties: {\n type: { type: 'string', enum: QUESTION_TYPES as unknown as string[] },\n question: { type: 'string' },\n answer: { type: 'string' },\n options: {\n type: 'array',\n description: 'For MULTIPLE_CHOICE/TRUE_FALSE questions',\n items: {\n type: 'object',\n properties: {\n text: { type: 'string' },\n isCorrect: { type: 'boolean' },\n },\n required: ['text', 'isCorrect'],\n },\n },\n markScheme: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n points: { type: 'number' },\n description: { type: 'string' },\n },\n required: ['points', 'description'],\n },\n },\n points: { type: 'number' },\n },\n required: ['type', 'question'],\n },\n },\n },\n required: ['title', 'questions'],\n }),\n execute: async ({ title, questions }: ProposeWorksheetArgs) => {\n const worksheet: WorksheetToCreate = {\n title,\n questions: (questions ?? []).map((q, index) => ({\n type: q.type,\n question: q.question,\n answer: q.answer ?? '',\n options: (q.options ?? []).map((o) => ({\n id: v4(),\n text: o.text,\n isCorrect: o.isCorrect,\n })),\n markScheme: (q.markScheme ?? []).map((m) => ({\n id: v4(),\n points: m.points,\n description: m.description,\n })),\n points: q.points ?? 0,\n order: index,\n })),\n };\n proposals.worksheets.push(worksheet);\n return `Worksheet \"${title}\" with ${worksheet.questions.length} question(s) proposed.`;\n },\n },\n\n propose_assignment: {\n description:\n 'Propose an assignment for the teacher to review and create. Call once per assignment.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n title: { type: 'string' },\n instructions: { type: 'string' },\n dueDate: {\n type: 'string',\n description: 'ISO 8601 datetime. Defaults to one week from now if omitted.',\n },\n type: { type: 'string', enum: ASSIGNMENT_TYPES as unknown as string[] },\n maxGrade: { type: 'number' },\n acceptFiles: { type: 'boolean' },\n acceptExtendedResponse: { type: 'boolean' },\n acceptWorksheet: { type: 'boolean' },\n },\n required: ['title', 'instructions'],\n }),\n execute: async ({\n title,\n instructions,\n dueDate,\n type,\n maxGrade,\n acceptFiles,\n acceptExtendedResponse,\n acceptWorksheet,\n }: ProposeAssignmentArgs) => {\n const assignment: AssignmentToCreate = {\n title,\n instructions,\n dueDate: normalizeDueDate(dueDate),\n type: type ?? 'HOMEWORK',\n maxGrade: maxGrade ?? 100,\n acceptFiles: acceptFiles ?? true,\n acceptExtendedResponse: acceptExtendedResponse ?? false,\n acceptWorksheet: acceptWorksheet ?? false,\n gradingBoundaryId: null,\n markSchemeId: null,\n worksheetIds: [],\n studentIds: [],\n sectionId: null,\n attachments: [],\n };\n proposals.assignments.push(assignment);\n return `Assignment \"${title}\" proposed.`;\n },\n },\n\n generate_document: {\n description:\n 'Generate a downloadable file and attach it to this message. You are NOT limited to PDF — pick the best format for the request (pptx for slides/presentations, xlsx/csv for data, docx for editable handouts, pdf for print-ready docs, png for diagrams, etc.). Always set format explicitly.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n format: {\n type: 'string',\n description:\n 'Output file type. REQUIRED. pptx=slides/presentation, xlsx/csv=spreadsheet/data, docx=Word handout, pdf=printable doc, md/txt/html=text, png/jpeg/gif=image, py/js/ts=code.',\n enum: [\n 'pdf', 'docx', 'doc', 'xlsx', 'pptx', 'csv', 'md', 'html', 'txt',\n 'json', 'xml', 'tex', 'png', 'jpeg', 'jpg', 'gif', 'zip', 'tar',\n 'py', 'js', 'ts', 'css', 'sh',\n ],\n },\n title: { type: 'string', description: 'Document title' },\n content: {\n type: 'string',\n description: 'Full body — markdown or plain text with headings, lists, tables, slide notes, etc.',\n },\n },\n required: ['title', 'content', 'format'],\n }),\n execute: async ({ title, content, format }: GenerateDocumentArgs) => {\n proposals.docs.push({\n title,\n content: content.trim(),\n format: (format ?? 'pdf') as DocToCreate['format'],\n });\n const ext = (format ?? 'pdf').toUpperCase();\n return `Document \"${title}\" queued for ${ext} generation.`;\n },\n },\n };\n}\n"],"names":[],"mappings":"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","debug_id":"d31c780d-ad85-5261-92f8-54f6cf38ad3c"}
|
|
1
|
+
{"version":3,"file":"aiProposalTools.js","sources":["services/aiProposalTools.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Lab-chat \"proposal\" tools.\n *\n * In the agentic Lab pipeline the model produces create-actions by *calling\n * tools* (e.g. `propose_assignment`) instead of returning a JSON blob. Each\n * tool records a structured payload into a shared accumulator and returns a\n * short confirmation so the model can keep narrating. After the stream ends\n * the pipeline turns the accumulator into the `message.meta.*ToCreate` shape\n * the frontend accept-cards already consume — so the data contract is\n * preserved while the generation becomes genuine inline tool calls.\n *\n * NOTE: these tools intentionally use `jsonSchema()` rather than the zod\n * `tool()` helper. Zod-typed `tool()` definitions with deeply nested schemas\n * make the TS compiler instantiate excessively deep types (TS2589) and OOM,\n * so we mirror the existing `aiTools.ts` pattern (plain JSON Schema + manually\n * typed execute args).\n */\nimport { jsonSchema, type ToolSet } from 'ai';\nimport { v4 } from 'uuid';\nimport type {\n AssignmentToCreate,\n WorksheetToCreate,\n SectionToCreate,\n DocToCreate,\n} from '../pipelines/aiLabChatContract.js';\n\nexport interface LabProposals {\n assignments: AssignmentToCreate[];\n worksheets: WorksheetToCreate[];\n sections: SectionToCreate[];\n docs: DocToCreate[];\n}\n\nexport function createLabProposals(): LabProposals {\n return { assignments: [], worksheets: [], sections: [], docs: [] };\n}\n\nfunction normalizeDueDate(input?: string | null): string {\n if (input) {\n const parsed = new Date(input);\n if (!Number.isNaN(parsed.getTime())) return parsed.toISOString();\n }\n // Default: one week out.\n return new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString();\n}\n\nconst ASSIGNMENT_TYPES = [\n 'HOMEWORK', 'QUIZ', 'TEST', 'PROJECT', 'ESSAY', 'DISCUSSION', 'PRESENTATION', 'LAB', 'OTHER',\n] as const;\ntype AssignmentType = (typeof ASSIGNMENT_TYPES)[number];\n\nconst QUESTION_TYPES = [\n 'MULTIPLE_CHOICE', 'TRUE_FALSE', 'SHORT_ANSWER', 'LONG_ANSWER', 'MATH_EXPRESSION', 'ESSAY',\n] as const;\ntype QuestionType = (typeof QUESTION_TYPES)[number];\n\ninterface ProposeSectionArgs {\n name: string;\n color?: string | null;\n}\n\ninterface ProposeWorksheetArgs {\n title: string;\n questions: Array<{\n type: QuestionType;\n question: string;\n answer?: string;\n options?: Array<{ text: string; isCorrect: boolean }>;\n markScheme?: Array<{ points: number; description: string }>;\n points?: number;\n }>;\n}\n\ninterface ProposeAssignmentArgs {\n title: string;\n instructions: string;\n dueDate?: string;\n type?: AssignmentType;\n maxGrade?: number;\n acceptFiles?: boolean;\n acceptExtendedResponse?: boolean;\n acceptWorksheet?: boolean;\n}\n\ninterface GenerateDocumentArgs {\n title: string;\n content: string;\n format?: string;\n}\n\n/**\n * Build the set of proposal tools backed by the given accumulator.\n * Merge these with the read-only RAG tools from `aiTools(classId)`.\n */\nexport function labProposalTools(proposals: LabProposals): ToolSet {\n return {\n propose_section: {\n description:\n 'Propose a new section (folder) to organise class content. Call once per section you want to create.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n name: { type: 'string', description: 'Section name' },\n color: { type: 'string', description: 'Optional hex color like #3b82f6' },\n },\n required: ['name'],\n }),\n execute: async ({ name, color }: ProposeSectionArgs) => {\n proposals.sections.push({ name, color: color ?? null });\n return `Section \"${name}\" proposed.`;\n },\n },\n\n propose_worksheet: {\n description:\n 'Propose a worksheet of questions for the teacher to review and create. Include all questions in a single call.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n title: { type: 'string', description: 'Worksheet title' },\n questions: {\n type: 'array',\n description: 'The list of questions',\n items: {\n type: 'object',\n properties: {\n type: { type: 'string', enum: QUESTION_TYPES as unknown as string[] },\n question: { type: 'string' },\n answer: { type: 'string' },\n options: {\n type: 'array',\n description: 'For MULTIPLE_CHOICE/TRUE_FALSE questions',\n items: {\n type: 'object',\n properties: {\n text: { type: 'string' },\n isCorrect: { type: 'boolean' },\n },\n required: ['text', 'isCorrect'],\n },\n },\n markScheme: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n points: { type: 'number' },\n description: { type: 'string' },\n },\n required: ['points', 'description'],\n },\n },\n points: { type: 'number' },\n },\n required: ['type', 'question'],\n },\n },\n },\n required: ['title', 'questions'],\n }),\n execute: async ({ title, questions }: ProposeWorksheetArgs) => {\n const worksheet: WorksheetToCreate = {\n title,\n questions: (questions ?? []).map((q, index) => ({\n type: q.type,\n question: q.question,\n answer: q.answer ?? '',\n options: (q.options ?? []).map((o) => ({\n id: v4(),\n text: o.text,\n isCorrect: o.isCorrect,\n })),\n markScheme: (q.markScheme ?? []).map((m) => ({\n id: v4(),\n points: m.points,\n description: m.description,\n })),\n points: q.points ?? 0,\n order: index,\n })),\n };\n proposals.worksheets.push(worksheet);\n return `Worksheet \"${title}\" with ${worksheet.questions.length} question(s) proposed.`;\n },\n },\n\n propose_assignment: {\n description:\n 'Propose an assignment for the teacher to review and create. Call once per assignment.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n title: { type: 'string' },\n instructions: { type: 'string' },\n dueDate: {\n type: 'string',\n description: 'ISO 8601 datetime. Defaults to one week from now if omitted.',\n },\n type: { type: 'string', enum: ASSIGNMENT_TYPES as unknown as string[] },\n maxGrade: { type: 'number' },\n acceptFiles: { type: 'boolean' },\n acceptExtendedResponse: { type: 'boolean' },\n acceptWorksheet: { type: 'boolean' },\n },\n required: ['title', 'instructions'],\n }),\n execute: async ({\n title,\n instructions,\n dueDate,\n type,\n maxGrade,\n acceptFiles,\n acceptExtendedResponse,\n acceptWorksheet,\n }: ProposeAssignmentArgs) => {\n const assignment: AssignmentToCreate = {\n title,\n instructions,\n dueDate: normalizeDueDate(dueDate),\n type: type ?? 'HOMEWORK',\n maxGrade: maxGrade ?? 100,\n acceptFiles: acceptFiles ?? true,\n acceptExtendedResponse: acceptExtendedResponse ?? false,\n acceptWorksheet: acceptWorksheet ?? false,\n gradingBoundaryId: null,\n markSchemeId: null,\n worksheetIds: [],\n studentIds: [],\n sectionId: null,\n attachments: [],\n };\n proposals.assignments.push(assignment);\n return `Assignment \"${title}\" proposed.`;\n },\n },\n\n generate_document: {\n description:\n 'Generate a downloadable file and attach it to this message. Pick the best format for the request — pptx for slides, xlsx/csv for data, docx for editable handouts, pdf for print-ready docs, png/jpeg for charts/diagrams/figures (NOT pdf for visuals). Use py/js/ts only when the teacher explicitly wants source code. Always set format explicitly.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n title: { type: 'string', description: 'Document title' },\n content: {\n type: 'string',\n description:\n 'Full body. Structure by format: pptx — separate slides with \"---\" or \"Slide N:\" headers; xlsx/csv — markdown tables or row data; png/jpeg — describe the visual in detail (shapes, labels, arrows, data points, colors); pdf/docx — headings, lists, tables; code formats — complete runnable source.',\n },\n format: {\n type: 'string',\n description:\n 'Output file type. REQUIRED. pptx=slides, xlsx/csv=spreadsheet, docx=Word, pdf=printable doc, png/jpeg/gif=chart/diagram/figure image, md/txt/html=text. py/js/ts/css/sh=source code only when requested.',\n enum: [\n 'pdf', 'docx', 'doc', 'xlsx', 'pptx', 'csv', 'md', 'html', 'txt',\n 'json', 'xml', 'tex', 'png', 'jpeg', 'jpg', 'gif', 'zip', 'tar',\n 'py', 'js', 'ts', 'css', 'sh',\n ],\n },\n },\n required: ['title', 'content', 'format'],\n }),\n execute: async ({ title, content, format }: GenerateDocumentArgs) => {\n proposals.docs.push({\n title,\n content: content.trim(),\n format: (format ?? 'pdf') as DocToCreate['format'],\n });\n const ext = (format ?? 'pdf').toUpperCase();\n return `Document \"${title}\" queued for ${ext} generation.`;\n },\n },\n };\n}\n"],"names":[],"mappings":"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","debug_id":"ee632b59-78dc-5c7c-9a1e-c59b510acb82"}
|
package/dist/services/aiTools.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* and web search tools.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
!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]="
|
|
7
|
+
!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]="92c04dcc-74fa-5dc9-90cb-1ee91299efe7")}catch(e){}}();
|
|
8
8
|
import { jsonSchema } from 'ai';
|
|
9
9
|
import OpenAI from 'openai';
|
|
10
10
|
import { searchEmbeddings } from './embedding.js';
|
|
@@ -240,7 +240,7 @@ export function aiTools(classId) {
|
|
|
240
240
|
const client = new OpenAI();
|
|
241
241
|
const response = await client.responses.create({
|
|
242
242
|
model: 'gpt-4o-mini',
|
|
243
|
-
tools: [{ type: '
|
|
243
|
+
tools: [{ type: 'web_search' }],
|
|
244
244
|
input: query,
|
|
245
245
|
});
|
|
246
246
|
const messageOutput = response.output.find((item) => item.type === 'message');
|
|
@@ -268,4 +268,4 @@ export function aiTools(classId) {
|
|
|
268
268
|
};
|
|
269
269
|
}
|
|
270
270
|
//# sourceMappingURL=aiTools.js.map
|
|
271
|
-
//# debugId=
|
|
271
|
+
//# debugId=92c04dcc-74fa-5dc9-90cb-1ee91299efe7
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aiTools.js","sources":["services/aiTools.ts"],"sourceRoot":"/","sourcesContent":["/**\n * AI Tool definitions and execution for agent tool calls.\n * Provides RAG search, assignment lookup, worksheet creation, student progress,\n * and web search tools.\n */\nimport { jsonSchema, type ToolSet } from 'ai';\nimport OpenAI from 'openai';\nimport { searchEmbeddings } from './embedding.js';\nimport { prisma } from '../lib/prisma.js';\nimport { logger } from '../utils/logger.js';\n\nexport interface ToolCallResult {\n toolName: string;\n result: unknown;\n}\n\n/**\n * Build the tool set for a given class context.\n * Tools are scoped to a specific class for security.\n */\nexport function aiTools(classId: string): ToolSet {\n return {\n search_materials: {\n description: 'Search class materials, files, assignments, worksheets, and announcements using semantic similarity. Use this to find relevant context for answering questions.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n query: { type: 'string', description: 'The search query to find relevant materials' },\n limit: { type: 'number', description: 'Maximum results (1-10)', default: 5 },\n },\n required: ['query'],\n }),\n execute: async ({ query, limit = 5 }: { query: string; limit?: number }) => {\n try {\n const results = await searchEmbeddings({ classId, query, limit });\n return results.map((r) => ({\n sourceType: r.sourceType,\n sourceId: r.sourceId,\n content: r.content.slice(0, 500),\n similarity: Math.round(r.similarity * 100) / 100,\n metadata: r.metadata,\n }));\n } catch (error) {\n logger.error('search_materials tool failed', { error, classId, query });\n return [];\n }\n },\n },\n\n search_assignments: {\n description: 'Search existing assignments by title, instructions, or type. Returns assignment details including due dates and submission types.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query for assignments' },\n limit: { type: 'number', description: 'Maximum results (1-10)', default: 5 },\n },\n required: ['query'],\n }),\n execute: async ({ query, limit = 5 }: { query: string; limit?: number }) => {\n try {\n const results = await searchEmbeddings({\n classId,\n query,\n limit,\n sourceTypes: ['ASSIGNMENT'],\n });\n\n const assignmentIds = results.map((r) => r.sourceId);\n const assignments = await prisma.assignment.findMany({\n where: { id: { in: assignmentIds } },\n select: {\n id: true,\n title: true,\n instructions: true,\n type: true,\n dueDate: true,\n maxGrade: true,\n section: { select: { name: true } },\n },\n });\n\n return assignments.map((a) => ({\n id: a.id,\n title: a.title,\n instructions: a.instructions?.slice(0, 200) ?? null,\n type: a.type,\n dueDate: a.dueDate.toISOString(),\n maxGrade: a.maxGrade,\n section: a.section?.name ?? null,\n }));\n } catch (error) {\n logger.error('search_assignments tool failed', { error, classId, query });\n return [];\n }\n },\n },\n\n get_student_progress: {\n description: 'Get progress summary for a specific student in this class, including grades and submission status.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n studentId: { type: 'string', description: 'The student user ID' },\n },\n required: ['studentId'],\n }),\n execute: async ({ studentId }: { studentId: string }) => {\n try {\n const submissions = await prisma.submission.findMany({\n where: {\n studentId,\n assignment: { classId },\n },\n select: {\n id: true,\n gradeReceived: true,\n submittedAt: true,\n assignment: {\n select: {\n title: true,\n maxGrade: true,\n type: true,\n },\n },\n },\n orderBy: { submittedAt: 'desc' },\n take: 20,\n });\n\n const totalAssignments = await prisma.assignment.count({\n where: { classId },\n });\n\n const submitted = submissions.filter((s) => s.submittedAt);\n const graded = submissions.filter((s) => s.gradeReceived !== null);\n const avgGrade = graded.length > 0\n ? graded.reduce((sum, s) => sum + (s.gradeReceived || 0), 0) / graded.length\n : null;\n\n return {\n studentId,\n totalAssignments,\n submittedCount: submitted.length,\n gradedCount: graded.length,\n averageGrade: avgGrade ? Math.round(avgGrade * 10) / 10 : null,\n recentSubmissions: submissions.slice(0, 5).map((s) => ({\n assignment: s.assignment.title,\n gradeReceived: s.gradeReceived,\n maxGrade: s.assignment.maxGrade,\n submittedAt: s.submittedAt?.toISOString() ?? null,\n })),\n };\n } catch (error) {\n logger.error('get_student_progress tool failed', { error, classId, studentId });\n return { error: 'Failed to fetch student progress' };\n }\n },\n },\n\n get_worksheet_details: {\n description: 'Get full details of a worksheet including all questions, answers, and mark schemes.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n worksheetId: { type: 'string', description: 'The worksheet ID to look up' },\n },\n required: ['worksheetId'],\n }),\n execute: async ({ worksheetId }: { worksheetId: string }) => {\n try {\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId, classId },\n include: {\n questions: {\n orderBy: { order: 'asc' },\n },\n },\n });\n\n if (!worksheet) {\n return { error: 'Worksheet not found' };\n }\n\n return {\n id: worksheet.id,\n name: worksheet.name,\n questions: worksheet.questions.map((q) => ({\n id: q.id,\n type: q.type,\n question: q.question,\n answer: q.answer,\n options: q.options,\n points: q.points,\n order: q.order,\n })),\n };\n } catch (error) {\n logger.error('get_worksheet_details tool failed', { error, classId, worksheetId });\n return { error: 'Failed to fetch worksheet' };\n }\n },\n },\n\n get_mark_scheme: {\n description: 'Get a mark scheme (rubric) by ID, including criteria and point allocations.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n markSchemeId: { type: 'string', description: 'The mark scheme ID' },\n },\n required: ['markSchemeId'],\n }),\n execute: async ({ markSchemeId }: { markSchemeId: string }) => {\n try {\n const markScheme = await prisma.markScheme.findUnique({\n where: { id: markSchemeId },\n select: { id: true, name: true, structured: true },\n });\n\n if (!markScheme) {\n return { error: 'Mark scheme not found' };\n }\n\n let parsed: unknown = {};\n try { parsed = JSON.parse(markScheme.structured || '{}'); } catch { /* noop */ }\n\n return {\n id: markScheme.id,\n name: markScheme.name,\n structured: parsed,\n };\n } catch (error) {\n logger.error('get_mark_scheme tool failed', { error, classId, markSchemeId });\n return { error: 'Failed to fetch mark scheme' };\n }\n },\n },\n\n web_search: {\n description: 'Search the web for current information on a topic. Use this when you need up-to-date facts, definitions, explanations, or context beyond the class materials.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n query: { type: 'string', description: 'The search query to look up on the web' },\n },\n required: ['query'],\n }),\n execute: async ({ query }: { query: string }) => {\n try {\n const client = new OpenAI();\n const response = await client.responses.create({\n model: 'gpt-4o-mini',\n tools: [{ type: 'web_search_preview' }],\n input: query,\n });\n\n const messageOutput = response.output.find(\n (item) => item.type === 'message',\n );\n if (!messageOutput || messageOutput.type !== 'message') {\n return { summary: 'No results found.', sources: [] };\n }\n\n const textContent = messageOutput.content.find(\n (c) => c.type === 'output_text',\n );\n if (!textContent || textContent.type !== 'output_text') {\n return { summary: 'No results found.', sources: [] };\n }\n\n const sources = textContent.annotations\n .filter(\n (a): a is Extract<typeof a, { type: 'url_citation' }> =>\n a.type === 'url_citation',\n )\n .map((a) => ({ url: a.url, title: a.title }));\n\n return {\n summary: textContent.text.slice(0, 2000),\n sources: sources.slice(0, 5),\n };\n } catch (error) {\n logger.error('web_search tool failed', { error, query });\n return { summary: 'Web search failed. Please try again.', sources: [] };\n }\n },\n },\n };\n}\n"],"names":[],"mappings":"AAAA;;;;GAIG;;;AACH,OAAO,EAAE,UAAU,EAAgB,MAAM,IAAI,CAAC;AAC9C,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAO5C;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO;QACL,gBAAgB,EAAE;YAChB,WAAW,EAAE,iKAAiK;YAC9K,WAAW,EAAE,UAAU,CAAC;gBACtB,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6CAA6C,EAAE;oBACrF,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wBAAwB,EAAE,OAAO,EAAE,CAAC,EAAE;iBAC7E;gBACD,QAAQ,EAAE,CAAC,OAAO,CAAC;aACpB,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAqC,EAAE,EAAE;gBACzE,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;oBAClE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACzB,UAAU,EAAE,CAAC,CAAC,UAAU;wBACxB,QAAQ,EAAE,CAAC,CAAC,QAAQ;wBACpB,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;wBAChC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG;wBAChD,QAAQ,EAAE,CAAC,CAAC,QAAQ;qBACrB,CAAC,CAAC,CAAC;gBACN,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;oBACxE,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;SACF;QAED,kBAAkB,EAAE;YAClB,WAAW,EAAE,mIAAmI;YAChJ,WAAW,EAAE,UAAU,CAAC;gBACtB,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,EAAE;oBACtE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wBAAwB,EAAE,OAAO,EAAE,CAAC,EAAE;iBAC7E;gBACD,QAAQ,EAAE,CAAC,OAAO,CAAC;aACpB,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,EAAqC,EAAE,EAAE;gBACzE,IAAI,CAAC;oBACH,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC;wBACrC,OAAO;wBACP,KAAK;wBACL,KAAK;wBACL,WAAW,EAAE,CAAC,YAAY,CAAC;qBAC5B,CAAC,CAAC;oBAEH,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;oBACrD,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;wBACnD,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,aAAa,EAAE,EAAE;wBACpC,MAAM,EAAE;4BACN,EAAE,EAAE,IAAI;4BACR,KAAK,EAAE,IAAI;4BACX,YAAY,EAAE,IAAI;4BAClB,IAAI,EAAE,IAAI;4BACV,OAAO,EAAE,IAAI;4BACb,QAAQ,EAAE,IAAI;4BACd,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;yBACpC;qBACF,CAAC,CAAC;oBAEH,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAC7B,EAAE,EAAE,CAAC,CAAC,EAAE;wBACR,KAAK,EAAE,CAAC,CAAC,KAAK;wBACd,YAAY,EAAE,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,IAAI;wBACnD,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE;wBAChC,QAAQ,EAAE,CAAC,CAAC,QAAQ;wBACpB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,IAAI;qBACjC,CAAC,CAAC,CAAC;gBACN,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC1E,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;SACF;QAED,oBAAoB,EAAE;YACpB,WAAW,EAAE,oGAAoG;YACjH,WAAW,EAAE,UAAU,CAAC;gBACtB,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qBAAqB,EAAE;iBAClE;gBACD,QAAQ,EAAE,CAAC,WAAW,CAAC;aACxB,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,SAAS,EAAyB,EAAE,EAAE;gBACtD,IAAI,CAAC;oBACH,MAAM,WAAW,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;wBACnD,KAAK,EAAE;4BACL,SAAS;4BACT,UAAU,EAAE,EAAE,OAAO,EAAE;yBACxB;wBACD,MAAM,EAAE;4BACN,EAAE,EAAE,IAAI;4BACR,aAAa,EAAE,IAAI;4BACnB,WAAW,EAAE,IAAI;4BACjB,UAAU,EAAE;gCACV,MAAM,EAAE;oCACN,KAAK,EAAE,IAAI;oCACX,QAAQ,EAAE,IAAI;oCACd,IAAI,EAAE,IAAI;iCACX;6BACF;yBACF;wBACD,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE;wBAChC,IAAI,EAAE,EAAE;qBACT,CAAC,CAAC;oBAEH,MAAM,gBAAgB,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;wBACrD,KAAK,EAAE,EAAE,OAAO,EAAE;qBACnB,CAAC,CAAC;oBAEH,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;oBAC3D,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC;oBACnE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC;wBAChC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM;wBAC5E,CAAC,CAAC,IAAI,CAAC;oBAET,OAAO;wBACL,SAAS;wBACT,gBAAgB;wBAChB,cAAc,EAAE,SAAS,CAAC,MAAM;wBAChC,WAAW,EAAE,MAAM,CAAC,MAAM;wBAC1B,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI;wBAC9D,iBAAiB,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BACrD,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK;4BAC9B,aAAa,EAAE,CAAC,CAAC,aAAa;4BAC9B,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ;4BAC/B,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,IAAI;yBAClD,CAAC,CAAC;qBACJ,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,kCAAkC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;oBAChF,OAAO,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;gBACvD,CAAC;YACH,CAAC;SACF;QAED,qBAAqB,EAAE;YACrB,WAAW,EAAE,qFAAqF;YAClG,WAAW,EAAE,UAAU,CAAC;gBACtB,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;iBAC5E;gBACD,QAAQ,EAAE,CAAC,aAAa,CAAC;aAC1B,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,WAAW,EAA2B,EAAE,EAAE;gBAC1D,IAAI,CAAC;oBACH,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC;wBAClD,KAAK,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,OAAO,EAAE;wBACnC,OAAO,EAAE;4BACP,SAAS,EAAE;gCACT,OAAO,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;6BAC1B;yBACF;qBACF,CAAC,CAAC;oBAEH,IAAI,CAAC,SAAS,EAAE,CAAC;wBACf,OAAO,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;oBAC1C,CAAC;oBAED,OAAO;wBACL,EAAE,EAAE,SAAS,CAAC,EAAE;wBAChB,IAAI,EAAE,SAAS,CAAC,IAAI;wBACpB,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;4BACzC,EAAE,EAAE,CAAC,CAAC,EAAE;4BACR,IAAI,EAAE,CAAC,CAAC,IAAI;4BACZ,QAAQ,EAAE,CAAC,CAAC,QAAQ;4BACpB,MAAM,EAAE,CAAC,CAAC,MAAM;4BAChB,OAAO,EAAE,CAAC,CAAC,OAAO;4BAClB,MAAM,EAAE,CAAC,CAAC,MAAM;4BAChB,KAAK,EAAE,CAAC,CAAC,KAAK;yBACf,CAAC,CAAC;qBACJ,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;oBACnF,OAAO,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC;gBAChD,CAAC;YACH,CAAC;SACF;QAED,eAAe,EAAE;YACf,WAAW,EAAE,6EAA6E;YAC1F,WAAW,EAAE,UAAU,CAAC;gBACtB,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE;iBACpE;gBACD,QAAQ,EAAE,CAAC,cAAc,CAAC;aAC3B,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,YAAY,EAA4B,EAAE,EAAE;gBAC5D,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC;wBACpD,KAAK,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE;wBAC3B,MAAM,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE;qBACnD,CAAC,CAAC;oBAEH,IAAI,CAAC,UAAU,EAAE,CAAC;wBAChB,OAAO,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;oBAC5C,CAAC;oBAED,IAAI,MAAM,GAAY,EAAE,CAAC;oBACzB,IAAI,CAAC;wBAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,UAAU,IAAI,IAAI,CAAC,CAAC;oBAAC,CAAC;oBAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;oBAEhF,OAAO;wBACL,EAAE,EAAE,UAAU,CAAC,EAAE;wBACjB,IAAI,EAAE,UAAU,CAAC,IAAI;wBACrB,UAAU,EAAE,MAAM;qBACnB,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;oBAC9E,OAAO,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;gBAClD,CAAC;YACH,CAAC;SACF;QAED,UAAU,EAAE;YACV,WAAW,EAAE,+JAA+J;YAC5K,WAAW,EAAE,UAAU,CAAC;gBACtB,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wCAAwC,EAAE;iBACjF;gBACD,QAAQ,EAAE,CAAC,OAAO,CAAC;aACpB,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAqB,EAAE,EAAE;gBAC9C,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;oBAC5B,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;wBAC7C,KAAK,EAAE,aAAa;wBACpB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,CAAC;wBACvC,KAAK,EAAE,KAAK;qBACb,CAAC,CAAC;oBAEH,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CACxC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAClC,CAAC;oBACF,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;wBACvD,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;oBACvD,CAAC;oBAED,MAAM,WAAW,GAAG,aAAa,CAAC,OAAO,CAAC,IAAI,CAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAChC,CAAC;oBACF,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;wBACvD,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;oBACvD,CAAC;oBAED,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW;yBACpC,MAAM,CACL,CAAC,CAAC,EAAoD,EAAE,CACtD,CAAC,CAAC,IAAI,KAAK,cAAc,CAC5B;yBACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;oBAEhD,OAAO;wBACL,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;wBACxC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;qBAC7B,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;oBACzD,OAAO,EAAE,OAAO,EAAE,sCAAsC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;gBAC1E,CAAC;YACH,CAAC;SACF;KACF,CAAC;AACJ,CAAC","debug_id":"08e8556c-8e72-5041-a040-17a623b35c7c"}
|
|
1
|
+
{"version":3,"file":"aiTools.js","sources":["services/aiTools.ts"],"sourceRoot":"/","sourcesContent":["/**\n * AI Tool definitions and execution for agent tool calls.\n * Provides RAG search, assignment lookup, worksheet creation, student progress,\n * and web search tools.\n */\nimport { jsonSchema, type ToolSet } from 'ai';\nimport OpenAI from 'openai';\nimport { searchEmbeddings } from './embedding.js';\nimport { prisma } from '../lib/prisma.js';\nimport { logger } from '../utils/logger.js';\n\nexport interface ToolCallResult {\n toolName: string;\n result: unknown;\n}\n\n/**\n * Build the tool set for a given class context.\n * Tools are scoped to a specific class for security.\n */\nexport function aiTools(classId: string): ToolSet {\n return {\n search_materials: {\n description: 'Search class materials, files, assignments, worksheets, and announcements using semantic similarity. Use this to find relevant context for answering questions.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n query: { type: 'string', description: 'The search query to find relevant materials' },\n limit: { type: 'number', description: 'Maximum results (1-10)', default: 5 },\n },\n required: ['query'],\n }),\n execute: async ({ query, limit = 5 }: { query: string; limit?: number }) => {\n try {\n const results = await searchEmbeddings({ classId, query, limit });\n return results.map((r) => ({\n sourceType: r.sourceType,\n sourceId: r.sourceId,\n content: r.content.slice(0, 500),\n similarity: Math.round(r.similarity * 100) / 100,\n metadata: r.metadata,\n }));\n } catch (error) {\n logger.error('search_materials tool failed', { error, classId, query });\n return [];\n }\n },\n },\n\n search_assignments: {\n description: 'Search existing assignments by title, instructions, or type. Returns assignment details including due dates and submission types.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query for assignments' },\n limit: { type: 'number', description: 'Maximum results (1-10)', default: 5 },\n },\n required: ['query'],\n }),\n execute: async ({ query, limit = 5 }: { query: string; limit?: number }) => {\n try {\n const results = await searchEmbeddings({\n classId,\n query,\n limit,\n sourceTypes: ['ASSIGNMENT'],\n });\n\n const assignmentIds = results.map((r) => r.sourceId);\n const assignments = await prisma.assignment.findMany({\n where: { id: { in: assignmentIds } },\n select: {\n id: true,\n title: true,\n instructions: true,\n type: true,\n dueDate: true,\n maxGrade: true,\n section: { select: { name: true } },\n },\n });\n\n return assignments.map((a) => ({\n id: a.id,\n title: a.title,\n instructions: a.instructions?.slice(0, 200) ?? null,\n type: a.type,\n dueDate: a.dueDate.toISOString(),\n maxGrade: a.maxGrade,\n section: a.section?.name ?? null,\n }));\n } catch (error) {\n logger.error('search_assignments tool failed', { error, classId, query });\n return [];\n }\n },\n },\n\n get_student_progress: {\n description: 'Get progress summary for a specific student in this class, including grades and submission status.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n studentId: { type: 'string', description: 'The student user ID' },\n },\n required: ['studentId'],\n }),\n execute: async ({ studentId }: { studentId: string }) => {\n try {\n const submissions = await prisma.submission.findMany({\n where: {\n studentId,\n assignment: { classId },\n },\n select: {\n id: true,\n gradeReceived: true,\n submittedAt: true,\n assignment: {\n select: {\n title: true,\n maxGrade: true,\n type: true,\n },\n },\n },\n orderBy: { submittedAt: 'desc' },\n take: 20,\n });\n\n const totalAssignments = await prisma.assignment.count({\n where: { classId },\n });\n\n const submitted = submissions.filter((s) => s.submittedAt);\n const graded = submissions.filter((s) => s.gradeReceived !== null);\n const avgGrade = graded.length > 0\n ? graded.reduce((sum, s) => sum + (s.gradeReceived || 0), 0) / graded.length\n : null;\n\n return {\n studentId,\n totalAssignments,\n submittedCount: submitted.length,\n gradedCount: graded.length,\n averageGrade: avgGrade ? Math.round(avgGrade * 10) / 10 : null,\n recentSubmissions: submissions.slice(0, 5).map((s) => ({\n assignment: s.assignment.title,\n gradeReceived: s.gradeReceived,\n maxGrade: s.assignment.maxGrade,\n submittedAt: s.submittedAt?.toISOString() ?? null,\n })),\n };\n } catch (error) {\n logger.error('get_student_progress tool failed', { error, classId, studentId });\n return { error: 'Failed to fetch student progress' };\n }\n },\n },\n\n get_worksheet_details: {\n description: 'Get full details of a worksheet including all questions, answers, and mark schemes.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n worksheetId: { type: 'string', description: 'The worksheet ID to look up' },\n },\n required: ['worksheetId'],\n }),\n execute: async ({ worksheetId }: { worksheetId: string }) => {\n try {\n const worksheet = await prisma.worksheet.findUnique({\n where: { id: worksheetId, classId },\n include: {\n questions: {\n orderBy: { order: 'asc' },\n },\n },\n });\n\n if (!worksheet) {\n return { error: 'Worksheet not found' };\n }\n\n return {\n id: worksheet.id,\n name: worksheet.name,\n questions: worksheet.questions.map((q) => ({\n id: q.id,\n type: q.type,\n question: q.question,\n answer: q.answer,\n options: q.options,\n points: q.points,\n order: q.order,\n })),\n };\n } catch (error) {\n logger.error('get_worksheet_details tool failed', { error, classId, worksheetId });\n return { error: 'Failed to fetch worksheet' };\n }\n },\n },\n\n get_mark_scheme: {\n description: 'Get a mark scheme (rubric) by ID, including criteria and point allocations.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n markSchemeId: { type: 'string', description: 'The mark scheme ID' },\n },\n required: ['markSchemeId'],\n }),\n execute: async ({ markSchemeId }: { markSchemeId: string }) => {\n try {\n const markScheme = await prisma.markScheme.findUnique({\n where: { id: markSchemeId },\n select: { id: true, name: true, structured: true },\n });\n\n if (!markScheme) {\n return { error: 'Mark scheme not found' };\n }\n\n let parsed: unknown = {};\n try { parsed = JSON.parse(markScheme.structured || '{}'); } catch { /* noop */ }\n\n return {\n id: markScheme.id,\n name: markScheme.name,\n structured: parsed,\n };\n } catch (error) {\n logger.error('get_mark_scheme tool failed', { error, classId, markSchemeId });\n return { error: 'Failed to fetch mark scheme' };\n }\n },\n },\n\n web_search: {\n description: 'Search the web for current information on a topic. Use this when you need up-to-date facts, definitions, explanations, or context beyond the class materials.',\n inputSchema: jsonSchema({\n type: 'object',\n properties: {\n query: { type: 'string', description: 'The search query to look up on the web' },\n },\n required: ['query'],\n }),\n execute: async ({ query }: { query: string }) => {\n try {\n const client = new OpenAI();\n const response = await client.responses.create({\n model: 'gpt-4o-mini',\n tools: [{ type: 'web_search' }],\n input: query,\n });\n\n const messageOutput = response.output.find(\n (item) => item.type === 'message',\n );\n if (!messageOutput || messageOutput.type !== 'message') {\n return { summary: 'No results found.', sources: [] };\n }\n\n const textContent = messageOutput.content.find(\n (c) => c.type === 'output_text',\n );\n if (!textContent || textContent.type !== 'output_text') {\n return { summary: 'No results found.', sources: [] };\n }\n\n const sources = textContent.annotations\n .filter(\n (a): a is Extract<typeof a, { type: 'url_citation' }> =>\n a.type === 'url_citation',\n )\n .map((a) => ({ url: a.url, title: a.title }));\n\n return {\n summary: textContent.text.slice(0, 2000),\n sources: sources.slice(0, 5),\n };\n } catch (error) {\n logger.error('web_search tool failed', { error, query });\n return { summary: 'Web search failed. Please try again.', sources: [] };\n }\n },\n },\n };\n}\n"],"names":[],"mappings":"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","debug_id":"92c04dcc-74fa-5dc9-90cb-1ee91299efe7"}
|
|
@@ -698,6 +698,8 @@ export declare function updateAssignmentRecord(userId: string, input: {
|
|
|
698
698
|
email: string;
|
|
699
699
|
password: string;
|
|
700
700
|
verified: boolean;
|
|
701
|
+
termsAcceptedAt: Date | null;
|
|
702
|
+
termsVersion: string | null;
|
|
701
703
|
schoolId: string | null;
|
|
702
704
|
};
|
|
703
705
|
}>;
|
|
@@ -1194,6 +1196,8 @@ export declare function attachMarkSchemeRecord(teacherId: string, assignmentId:
|
|
|
1194
1196
|
email: string;
|
|
1195
1197
|
password: string;
|
|
1196
1198
|
verified: boolean;
|
|
1199
|
+
termsAcceptedAt: Date | null;
|
|
1200
|
+
termsVersion: string | null;
|
|
1197
1201
|
schoolId: string | null;
|
|
1198
1202
|
};
|
|
1199
1203
|
eventAttached: {
|
|
@@ -1284,6 +1288,8 @@ export declare function detachMarkSchemeRecord(teacherId: string, assignmentId:
|
|
|
1284
1288
|
email: string;
|
|
1285
1289
|
password: string;
|
|
1286
1290
|
verified: boolean;
|
|
1291
|
+
termsAcceptedAt: Date | null;
|
|
1292
|
+
termsVersion: string | null;
|
|
1287
1293
|
schoolId: string | null;
|
|
1288
1294
|
};
|
|
1289
1295
|
eventAttached: {
|
|
@@ -1374,6 +1380,8 @@ export declare function attachGradingBoundaryRecord(teacherId: string, assignmen
|
|
|
1374
1380
|
email: string;
|
|
1375
1381
|
password: string;
|
|
1376
1382
|
verified: boolean;
|
|
1383
|
+
termsAcceptedAt: Date | null;
|
|
1384
|
+
termsVersion: string | null;
|
|
1377
1385
|
schoolId: string | null;
|
|
1378
1386
|
};
|
|
1379
1387
|
eventAttached: {
|
|
@@ -1464,6 +1472,8 @@ export declare function detachGradingBoundaryRecord(teacherId: string, assignmen
|
|
|
1464
1472
|
email: string;
|
|
1465
1473
|
password: string;
|
|
1466
1474
|
verified: boolean;
|
|
1475
|
+
termsAcceptedAt: Date | null;
|
|
1476
|
+
termsVersion: string | null;
|
|
1467
1477
|
schoolId: string | null;
|
|
1468
1478
|
};
|
|
1469
1479
|
eventAttached: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assignment.d.ts","sourceRoot":"/","sources":["services/assignment.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"assignment.d.ts","sourceRoot":"/","sources":["services/assignment.ts"],"names":[],"mappings":"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"}
|
package/dist/services/auth.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"/","sources":["services/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"/","sources":["services/auth.ts"],"names":[],"mappings":"AA8BA,qFAAqF;AACrF,wBAAsB,QAAQ,CAAC,KAAK,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,IAAI,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;;;;;GA8EA;AAED,8DAA8D;AAC9D,wBAAsB,KAAK,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;;;;;;;;;;;;;;;;GAoCxE;AAED,iEAAiE;AACjE,wBAAsB,MAAM,CAAC,MAAM,EAAE,MAAM;;GAG1C;AAED,0EAA0E;AAC1E,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;GASzC;AAED,gFAAgF;AAChF,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,MAAM;;GAiC1D;AAED,8EAA8E;AAC9E,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM;;GA+BzC;AAED,kFAAkF;AAClF,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM;;GA+BvD;AAED,mFAAmF;AACnF,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;GAuBlE"}
|
package/dist/services/auth.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Handles session creation, Redis caching, and email notifications.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
!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]="
|
|
6
|
+
!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]="d8981916-8875-5f33-b907-7e722e9a3ce9")}catch(e){}}();
|
|
7
7
|
import { SessionType } from "@prisma/client";
|
|
8
8
|
import { TRPCError } from "@trpc/server";
|
|
9
9
|
import { v4 as uuidv4 } from "uuid";
|
|
@@ -12,10 +12,17 @@ import { sendMail } from "../utils/email.js";
|
|
|
12
12
|
import { prismaWrapper } from "../utils/prismaWrapper.js";
|
|
13
13
|
import { env } from "../lib/config/env.js";
|
|
14
14
|
import { logger } from "../utils/logger.js";
|
|
15
|
+
import { CURRENT_TERMS_VERSION } from "../lib/legal.js";
|
|
15
16
|
import { findUserByUsername, findUserByUsernameOrEmail, findUserByEmail, findUserById, createUser, createSession, deleteSessionsByUserId, deleteShortLivedSessionsByUserId, deleteUserById, findSessionByIdAndType, findSessionByIdWithUserAndType, updateUserVerified, updateUserPassword, deleteSessionById, } from "../models/auth.js";
|
|
16
17
|
/** Register a new user, create verification session, and send verification email. */
|
|
17
18
|
export async function register(input) {
|
|
18
|
-
const { username, email, password } = input;
|
|
19
|
+
const { username, email, password, termsVersion } = input;
|
|
20
|
+
if (termsVersion !== CURRENT_TERMS_VERSION) {
|
|
21
|
+
throw new TRPCError({
|
|
22
|
+
code: "BAD_REQUEST",
|
|
23
|
+
message: "Please accept the current Terms of Service and Privacy Policy.",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
19
26
|
const existingUser = await prismaWrapper.findFirst(() => findUserByUsernameOrEmail(username, email), "checking for existing user during registration");
|
|
20
27
|
if (existingUser && existingUser.verified) {
|
|
21
28
|
if (existingUser.username === username) {
|
|
@@ -39,7 +46,9 @@ export async function register(input) {
|
|
|
39
46
|
username,
|
|
40
47
|
email,
|
|
41
48
|
password: await hash(password, 10),
|
|
42
|
-
verified:
|
|
49
|
+
verified: false,
|
|
50
|
+
termsAcceptedAt: new Date(),
|
|
51
|
+
termsVersion,
|
|
43
52
|
}), "creating new user during registration");
|
|
44
53
|
const verificationToken = await prismaWrapper.create(() => createSession({
|
|
45
54
|
id: uuidv4(),
|
|
@@ -222,4 +231,4 @@ export async function resetPassword(token, password) {
|
|
|
222
231
|
return { success: true };
|
|
223
232
|
}
|
|
224
233
|
//# sourceMappingURL=auth.js.map
|
|
225
|
-
//# debugId=
|
|
234
|
+
//# debugId=d8981916-8875-5f33-b907-7e722e9a3ce9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sources":["services/auth.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Auth service – user registration, login, logout, verification, and password reset.\n * Handles session creation, Redis caching, and email notifications.\n */\nimport { SessionType } from \"@prisma/client\";\nimport { TRPCError } from \"@trpc/server\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { compare, hash } from \"bcryptjs\";\nimport { sendMail } from \"../utils/email.js\";\nimport { prismaWrapper } from \"../utils/prismaWrapper.js\";\nimport { env } from \"../lib/config/env.js\";\nimport { logger } from \"../utils/logger.js\";\nimport {\n findUserByUsername,\n findUserByUsernameOrEmail,\n findUserByEmail,\n findUserById,\n createUser,\n createSession,\n deleteSessionsByUserId,\n deleteShortLivedSessionsByUserId,\n deleteUserById,\n findSessionByIdAndType,\n findSessionByIdWithUserAndType,\n updateUserVerified,\n updateUserPassword,\n deleteSessionById,\n} from \"../models/auth.js\";\n\n/** Register a new user, create verification session, and send verification email. */\nexport async function register(input: {\n username: string;\n email: string;\n password: string;\n}) {\n const { username, email, password } = input;\n\n const existingUser = await prismaWrapper.findFirst(\n () => findUserByUsernameOrEmail(username, email),\n \"checking for existing user during registration\"\n );\n\n if (existingUser && existingUser.verified) {\n if (existingUser.username === username) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Username already exists\",\n });\n }\n if (existingUser.email === email) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Email already exists\",\n });\n }\n } else if (existingUser && !existingUser.verified) {\n await prismaWrapper.deleteMany(\n () => deleteSessionsByUserId(existingUser.id),\n \"deleting existing sessions for unverified user\"\n );\n await prismaWrapper.delete(\n () => deleteUserById(existingUser.id),\n \"deleting unverified user\"\n );\n }\n\n const user = await prismaWrapper.create(\n async () =>\n createUser({\n username,\n email,\n password: await hash(password, 10),\n verified: true,\n }),\n \"creating new user during registration\"\n );\n\n const verificationToken = await prismaWrapper.create(\n () =>\n createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n }),\n \"creating verification token\"\n );\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { user: { id: user.id, username: user.username } };\n}\n\n/** Authenticate user by username/password, create session. */\nexport async function login(input: { username: string; password: string }) {\n const { username, password } = input;\n\n const user = await findUserByUsername(username);\n if (!user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!(await compare(password, user.password))) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!user.verified) {\n return {\n verified: false,\n user: { email: user.email },\n };\n }\n\n const session = await createSession({\n id: uuidv4(),\n type: SessionType.AUTH,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n return {\n token: session.id,\n user: { id: user.id, username: user.username },\n };\n}\n\n/** Delete all sessions for a user (logs them out everywhere). */\nexport async function logout(userId: string) {\n await deleteSessionsByUserId(userId);\n return { success: true };\n}\n\n/** Verify user exists and return profile. Used for session validation. */\nexport async function check(userId: string) {\n const user = await findUserById(userId);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n return { user };\n}\n\n/** Resend verification email. Replaces existing sessions and sends new link. */\nexport async function resendVerificationEmail(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n\n await deleteSessionsByUserId(user.id);\n\n const verificationToken = await createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Verify email via token. Marks user as verified and deletes the session. */\nexport async function verify(token: string) {\n const session = await findSessionByIdAndType(\n token,\n SessionType.EMAIL_VERIFICATION\n );\n if (!session) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Session not found\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Session expired\",\n });\n }\n\n if (!session.userId) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Invalid session state\",\n });\n }\n\n await updateUserVerified(session.userId, true);\n await deleteSessionById(token);\n return { success: true };\n}\n\n/** Send password reset email. Silently succeeds if email not found (security). */\nexport async function requestPasswordReset(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n return { success: true };\n }\n\n const twoHoursFromNow = new Date(Date.now() + 1000 * 60 * 60 * 2);\n await deleteShortLivedSessionsByUserId(user.id, twoHoursFromNow);\n\n const resetToken = await createSession({\n id: uuidv4(),\n type: SessionType.PASSWORD_RESET,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Reset your password\",\n text: `Click the link to reset your password: ${env.NEXT_PUBLIC_APP_URL}/reset-password/${resetToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send password reset email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Reset password using token from email. Validates token and updates password. */\nexport async function resetPassword(token: string, password: string) {\n const session = await findSessionByIdWithUserAndType(\n token,\n SessionType.PASSWORD_RESET\n );\n if (!session || !session.userId) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Invalid or expired reset token\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Reset token has expired\",\n });\n }\n\n await updateUserPassword(session.userId, await hash(password, 10));\n await deleteSessionById(token);\n return { success: true };\n}\n"],"names":[],"mappings":"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","debug_id":"7c41f210-458c-593a-8fe2-a8ecbc675245"}
|
|
1
|
+
{"version":3,"file":"auth.js","sources":["services/auth.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Auth service – user registration, login, logout, verification, and password reset.\n * Handles session creation, Redis caching, and email notifications.\n */\nimport { SessionType } from \"@prisma/client\";\nimport { TRPCError } from \"@trpc/server\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { compare, hash } from \"bcryptjs\";\nimport { sendMail } from \"../utils/email.js\";\nimport { prismaWrapper } from \"../utils/prismaWrapper.js\";\nimport { env } from \"../lib/config/env.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { CURRENT_TERMS_VERSION } from \"../lib/legal.js\";\nimport {\n findUserByUsername,\n findUserByUsernameOrEmail,\n findUserByEmail,\n findUserById,\n createUser,\n createSession,\n deleteSessionsByUserId,\n deleteShortLivedSessionsByUserId,\n deleteUserById,\n findSessionByIdAndType,\n findSessionByIdWithUserAndType,\n updateUserVerified,\n updateUserPassword,\n deleteSessionById,\n} from \"../models/auth.js\";\n\n/** Register a new user, create verification session, and send verification email. */\nexport async function register(input: {\n username: string;\n email: string;\n password: string;\n agreeToTerms: true;\n termsVersion: string;\n}) {\n const { username, email, password, termsVersion } = input;\n\n if (termsVersion !== CURRENT_TERMS_VERSION) {\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Please accept the current Terms of Service and Privacy Policy.\",\n });\n }\n\n const existingUser = await prismaWrapper.findFirst(\n () => findUserByUsernameOrEmail(username, email),\n \"checking for existing user during registration\"\n );\n\n if (existingUser && existingUser.verified) {\n if (existingUser.username === username) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Username already exists\",\n });\n }\n if (existingUser.email === email) {\n throw new TRPCError({\n code: \"CONFLICT\",\n message: \"Email already exists\",\n });\n }\n } else if (existingUser && !existingUser.verified) {\n await prismaWrapper.deleteMany(\n () => deleteSessionsByUserId(existingUser.id),\n \"deleting existing sessions for unverified user\"\n );\n await prismaWrapper.delete(\n () => deleteUserById(existingUser.id),\n \"deleting unverified user\"\n );\n }\n\n const user = await prismaWrapper.create(\n async () =>\n createUser({\n username,\n email,\n password: await hash(password, 10),\n verified: false,\n termsAcceptedAt: new Date(),\n termsVersion,\n }),\n \"creating new user during registration\"\n );\n\n const verificationToken = await prismaWrapper.create(\n () =>\n createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n }),\n \"creating verification token\"\n );\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { user: { id: user.id, username: user.username } };\n}\n\n/** Authenticate user by username/password, create session. */\nexport async function login(input: { username: string; password: string }) {\n const { username, password } = input;\n\n const user = await findUserByUsername(username);\n if (!user) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!(await compare(password, user.password))) {\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Invalid username or password\",\n });\n }\n\n if (!user.verified) {\n return {\n verified: false,\n user: { email: user.email },\n };\n }\n\n const session = await createSession({\n id: uuidv4(),\n type: SessionType.AUTH,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n return {\n token: session.id,\n user: { id: user.id, username: user.username },\n };\n}\n\n/** Delete all sessions for a user (logs them out everywhere). */\nexport async function logout(userId: string) {\n await deleteSessionsByUserId(userId);\n return { success: true };\n}\n\n/** Verify user exists and return profile. Used for session validation. */\nexport async function check(userId: string) {\n const user = await findUserById(userId);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n return { user };\n}\n\n/** Resend verification email. Replaces existing sessions and sends new link. */\nexport async function resendVerificationEmail(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"User not found\",\n });\n }\n\n await deleteSessionsByUserId(user.id);\n\n const verificationToken = await createSession({\n id: uuidv4(),\n type: SessionType.EMAIL_VERIFICATION,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Verify your email\",\n text: `Click the link to verify your email: ${env.NEXT_PUBLIC_APP_URL}/verify/${verificationToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send verification email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Verify email via token. Marks user as verified and deletes the session. */\nexport async function verify(token: string) {\n const session = await findSessionByIdAndType(\n token,\n SessionType.EMAIL_VERIFICATION\n );\n if (!session) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Session not found\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Session expired\",\n });\n }\n\n if (!session.userId) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"BAD_REQUEST\",\n message: \"Invalid session state\",\n });\n }\n\n await updateUserVerified(session.userId, true);\n await deleteSessionById(token);\n return { success: true };\n}\n\n/** Send password reset email. Silently succeeds if email not found (security). */\nexport async function requestPasswordReset(email: string) {\n const user = await findUserByEmail(email);\n if (!user) {\n return { success: true };\n }\n\n const twoHoursFromNow = new Date(Date.now() + 1000 * 60 * 60 * 2);\n await deleteShortLivedSessionsByUserId(user.id, twoHoursFromNow);\n\n const resetToken = await createSession({\n id: uuidv4(),\n type: SessionType.PASSWORD_RESET,\n userId: user.id,\n expiresAt: new Date(Date.now() + 1000 * 60 * 60),\n });\n\n try {\n await sendMail({\n from: \"hello@studious.sh\",\n to: user.email,\n subject: \"Reset your password\",\n text: `Click the link to reset your password: ${env.NEXT_PUBLIC_APP_URL}/reset-password/${resetToken.id}`,\n });\n } catch (err) {\n logger.error(\"Failed to send password reset email\", {\n email: user.email,\n err,\n });\n }\n\n return { success: true };\n}\n\n/** Reset password using token from email. Validates token and updates password. */\nexport async function resetPassword(token: string, password: string) {\n const session = await findSessionByIdWithUserAndType(\n token,\n SessionType.PASSWORD_RESET\n );\n if (!session || !session.userId) {\n throw new TRPCError({\n code: \"NOT_FOUND\",\n message: \"Invalid or expired reset token\",\n });\n }\n\n if (session.expiresAt && session.expiresAt < new Date()) {\n await deleteSessionById(token);\n throw new TRPCError({\n code: \"UNAUTHORIZED\",\n message: \"Reset token has expired\",\n });\n }\n\n await updateUserPassword(session.userId, await hash(password, 10));\n await deleteSessionById(token);\n return { success: true };\n}\n"],"names":[],"mappings":"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","debug_id":"d8981916-8875-5f33-b907-7e722e9a3ce9"}
|
package/dist/services/class.d.ts
CHANGED
|
@@ -263,6 +263,8 @@ export declare function createClass(userId: string, input: {
|
|
|
263
263
|
email: string;
|
|
264
264
|
password: string;
|
|
265
265
|
verified: boolean;
|
|
266
|
+
termsAcceptedAt: Date | null;
|
|
267
|
+
termsVersion: string | null;
|
|
266
268
|
schoolId: string | null;
|
|
267
269
|
}[];
|
|
268
270
|
students: {
|
|
@@ -271,6 +273,8 @@ export declare function createClass(userId: string, input: {
|
|
|
271
273
|
email: string;
|
|
272
274
|
password: string;
|
|
273
275
|
verified: boolean;
|
|
276
|
+
termsAcceptedAt: Date | null;
|
|
277
|
+
termsVersion: string | null;
|
|
274
278
|
schoolId: string | null;
|
|
275
279
|
}[];
|
|
276
280
|
} & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAgC/C,sFAAsF;AACtF,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDjD;AAED,0EAA0E;AAC1E,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqE7D;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;IACJ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;;;;;;;;;;;;GA4CF;AAED,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE;IACL,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB
|
|
1
|
+
{"version":3,"file":"class.d.ts","sourceRoot":"/","sources":["services/class.ts"],"names":[],"mappings":"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"}
|
package/dist/services/event.d.ts
CHANGED
|
@@ -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"}
|
|
@@ -18,27 +18,14 @@ export declare function createSchoolDevelopmentProgramRecord(input: {
|
|
|
18
18
|
}): Promise<{
|
|
19
19
|
id: string;
|
|
20
20
|
}>;
|
|
21
|
-
/**
|
|
21
|
+
/** Public application status lookup (no contact PII). */
|
|
22
22
|
export declare function searchSchoolDevelopmentPrograms(id: string): Promise<{
|
|
23
|
-
type: string;
|
|
24
23
|
status: string;
|
|
25
24
|
id: string;
|
|
26
|
-
website: string | null;
|
|
27
25
|
name: string;
|
|
28
26
|
submittedAt: Date | null;
|
|
29
|
-
address: string;
|
|
30
27
|
city: string;
|
|
31
28
|
country: string;
|
|
32
|
-
numberOfStudents: number;
|
|
33
|
-
numberOfTeachers: number;
|
|
34
|
-
contactName: string | null;
|
|
35
|
-
contactRole: string | null;
|
|
36
|
-
contactEmail: string | null;
|
|
37
|
-
contactPhone: string | null;
|
|
38
|
-
eligibilityInformation: string | null;
|
|
39
|
-
whyHelp: string | null;
|
|
40
|
-
additionalInformation: string | null;
|
|
41
|
-
reviewedAt: Date | null;
|
|
42
29
|
} | null>;
|
|
43
30
|
/** Create an early access request. */
|
|
44
31
|
export declare function createEarlyAccessRequestRecord(input: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketing.d.ts","sourceRoot":"/","sources":["services/marketing.ts"],"names":[],"mappings":"AAUA,4EAA4E;AAC5E,wBAAsB,oCAAoC,CAAC,KAAK,EAAE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;;GAeA;AAED,
|
|
1
|
+
{"version":3,"file":"marketing.d.ts","sourceRoot":"/","sources":["services/marketing.ts"],"names":[],"mappings":"AAUA,4EAA4E;AAC5E,wBAAsB,oCAAoC,CAAC,KAAK,EAAE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;;GAeA;AAED,yDAAyD;AACzD,wBAAsB,+BAA+B,CAAC,EAAE,EAAE,MAAM;;;;;;;UAE/D;AAED,sCAAsC;AACtC,wBAAsB,8BAA8B,CAAC,KAAK,EAAE;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB;;GAGA"}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Marketing service – school development programs and early access requests.
|
|
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]="d5fcb374-2047-58b8-8257-6cca05559642")}catch(e){}}();
|
|
6
6
|
import { v4 } from "uuid";
|
|
7
|
-
import { createSchoolDevelopmentProgram,
|
|
7
|
+
import { createSchoolDevelopmentProgram, findSchoolDevelopmentProgramStatusById, createEarlyAccessRequest, } from "../models/marketing.js";
|
|
8
8
|
/** Create a school development program application. Generates unique ID. */
|
|
9
9
|
export async function createSchoolDevelopmentProgramRecord(input) {
|
|
10
10
|
const date = new Date();
|
|
@@ -19,9 +19,9 @@ export async function createSchoolDevelopmentProgramRecord(input) {
|
|
|
19
19
|
});
|
|
20
20
|
return { id: program.id };
|
|
21
21
|
}
|
|
22
|
-
/**
|
|
22
|
+
/** Public application status lookup (no contact PII). */
|
|
23
23
|
export async function searchSchoolDevelopmentPrograms(id) {
|
|
24
|
-
return
|
|
24
|
+
return findSchoolDevelopmentProgramStatusById(id);
|
|
25
25
|
}
|
|
26
26
|
/** Create an early access request. */
|
|
27
27
|
export async function createEarlyAccessRequestRecord(input) {
|
|
@@ -29,4 +29,4 @@ export async function createEarlyAccessRequestRecord(input) {
|
|
|
29
29
|
return { id: record.id };
|
|
30
30
|
}
|
|
31
31
|
//# sourceMappingURL=marketing.js.map
|
|
32
|
-
//# debugId=
|
|
32
|
+
//# debugId=d5fcb374-2047-58b8-8257-6cca05559642
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketing.js","sources":["services/marketing.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Marketing service – school development programs and early access requests.\n */\nimport { v4 } from \"uuid\";\nimport {\n createSchoolDevelopmentProgram,\n
|
|
1
|
+
{"version":3,"file":"marketing.js","sources":["services/marketing.ts"],"sourceRoot":"/","sourcesContent":["/**\n * Marketing service – school development programs and early access requests.\n */\nimport { v4 } from \"uuid\";\nimport {\n createSchoolDevelopmentProgram,\n findSchoolDevelopmentProgramStatusById,\n createEarlyAccessRequest,\n} from \"../models/marketing.js\";\n\n/** Create a school development program application. Generates unique ID. */\nexport async function createSchoolDevelopmentProgramRecord(input: {\n name: string;\n type: string;\n address: string;\n city: string;\n country: string;\n numberOfStudents: number;\n numberOfTeachers: number;\n website?: string;\n contactName?: string;\n contactRole?: string;\n contactEmail?: string;\n contactPhone?: string;\n eligibilityInformation?: string;\n whyHelp?: string;\n additionalInformation?: string;\n}) {\n const date = new Date();\n const id =\n input.name.slice(0, 3).toUpperCase() +\n \"-\" +\n date.getFullYear() +\n \"-\" +\n v4().slice(0, 4).toUpperCase();\n\n const program = await createSchoolDevelopmentProgram({\n id,\n ...input,\n });\n\n return { id: program.id };\n}\n\n/** Public application status lookup (no contact PII). */\nexport async function searchSchoolDevelopmentPrograms(id: string) {\n return findSchoolDevelopmentProgramStatusById(id);\n}\n\n/** Create an early access request. */\nexport async function createEarlyAccessRequestRecord(input: {\n email: string;\n institutionSize: string;\n}) {\n const record = await createEarlyAccessRequest(input);\n return { id: record.id };\n}\n"],"names":[],"mappings":"AAAA;;GAEG;;;AACH,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EACL,8BAA8B,EAC9B,sCAAsC,EACtC,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAEhC,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,oCAAoC,CAAC,KAgB1D;IACC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;IACxB,MAAM,EAAE,GACN,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE;QACpC,GAAG;QACH,IAAI,CAAC,WAAW,EAAE;QAClB,GAAG;QACH,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAEjC,MAAM,OAAO,GAAG,MAAM,8BAA8B,CAAC;QACnD,EAAE;QACF,GAAG,KAAK;KACT,CAAC,CAAC;IAEH,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;AAC5B,CAAC;AAED,yDAAyD;AACzD,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,EAAU;IAC9D,OAAO,sCAAsC,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC;AAED,sCAAsC;AACtC,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,KAGpD;IACC,MAAM,MAAM,GAAG,MAAM,wBAAwB,CAAC,KAAK,CAAC,CAAC;IACrD,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;AAC3B,CAAC","debug_id":"d5fcb374-2047-58b8-8257-6cca05559642"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"newtonChat.d.ts","sourceRoot":"/","sources":["services/newtonChat.ts"],"names":[],"mappings":"AAuBA,8EAA8E;AAC9E,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM;;;GAqGhB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,gBAAgB,GAAE,MAAM,EAAO,EAC/B,OAAO,GAAE,MAAM,EAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"newtonChat.d.ts","sourceRoot":"/","sources":["services/newtonChat.ts"],"names":[],"mappings":"AAuBA,8EAA8E;AAC9E,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM;;;GAqGhB;AAED,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,gBAAgB,GAAE,MAAM,EAAO,EAC/B,OAAO,GAAE,MAAM,EAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmIvB"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* tutor session, post messages, trigger AI responses. Broadcasts via Pusher.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
!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]="
|
|
6
|
+
!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]="39ab2fff-5212-508b-bb38-849fb5430153")}catch(e){}}();
|
|
7
7
|
import { TRPCError } from "@trpc/server";
|
|
8
8
|
import { logger } from "../utils/logger.js";
|
|
9
9
|
import { chatChannel, pusher } from "../lib/pusher.js";
|
|
@@ -119,12 +119,6 @@ export async function postToNewtonChat(userId, newtonChatId, content, mentionedU
|
|
|
119
119
|
}
|
|
120
120
|
ensureMessageHasContentOrAttachments(content, fileIds);
|
|
121
121
|
const normalizedContent = content.trim();
|
|
122
|
-
if (!normalizedContent) {
|
|
123
|
-
throw new TRPCError({
|
|
124
|
-
code: "BAD_REQUEST",
|
|
125
|
-
message: "Newton chat messages must include text content",
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
122
|
const result = await prisma.$transaction(async (tx) => {
|
|
129
123
|
const message = await tx.message.create({
|
|
130
124
|
data: {
|
|
@@ -213,4 +207,4 @@ export async function postToNewtonChat(userId, newtonChatId, content, mentionedU
|
|
|
213
207
|
};
|
|
214
208
|
}
|
|
215
209
|
//# sourceMappingURL=newtonChat.js.map
|
|
216
|
-
//# debugId=
|
|
210
|
+
//# debugId=39ab2fff-5212-508b-bb38-849fb5430153
|