Initial commit: Edu Helper (Docker, React, Express, Prisma)
Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user