import { Router, Response } from "express"; import prisma from "../lib/prisma"; import { getDeepSeekClient } from "../lib/deepseek"; import type { AuthRequest } from "../middleware/auth"; const router = Router(); router.get("/history", async (req: AuthRequest, res: Response) => { const studentId = req.studentId!; const messages = await prisma.chatMessage.findMany({ where: { studentId }, orderBy: { createdAt: "asc" }, take: 100, }); res.json(messages); }); router.post("/", async (req: AuthRequest, res: Response) => { const { message } = req.body; const studentId = req.studentId!; if (!message || typeof message !== "string") { res.status(400).json({ error: "Message is required" }); return; } await prisma.chatMessage.create({ data: { role: "user", content: message, studentId }, }); const history = await prisma.chatMessage.findMany({ where: { studentId }, orderBy: { createdAt: "asc" }, take: 50, }); const client = await getDeepSeekClient(); const messages = history.map((m: { role: string; content: string }) => ({ role: m.role as "user" | "assistant", content: m.content, })); res.setHeader("Content-Type", "text/event-stream"); res.setHeader("Cache-Control", "no-cache"); res.setHeader("Connection", "keep-alive"); try { const stream = await client.chat.completions.create({ model: "deepseek-chat", messages, stream: true, }); let fullResponse = ""; for await (const chunk of stream) { const content = chunk.choices[0]?.delta?.content || ""; if (content) { fullResponse += content; res.write(`data: ${JSON.stringify({ content })}\n\n`); } } await prisma.chatMessage.create({ data: { role: "assistant", content: fullResponse, studentId }, }); res.write(`data: [DONE]\n\n`); res.end(); } catch (err: any) { res.write(`data: ${JSON.stringify({ error: err.message })}\n\n`); res.end(); } }); router.delete("/history", async (req: AuthRequest, res: Response) => { const studentId = req.studentId!; await prisma.chatMessage.deleteMany({ where: { studentId } }); res.json({ success: true }); }); export default router;