guanghulab/server/portal/routes/conversations.js

80 lines
2.5 KiB
JavaScript
Raw Permalink Normal View History

/*
* /api/conversations
* 守护: 铸渊 · ICE-GL-ZY001
*
* GET / 列表 ( updated_at desc)
* POST / 新建对话, 返回 {id, ...}
* GET /:id/messages 单对话 + 历史
*/
"use strict";
const express = require("express");
const crypto = require("crypto");
const router = express.Router();
function genConvId() {
return "conv_" + crypto.randomBytes(8).toString("hex");
}
function isValidId(id) {
return typeof id === "string" && /^conv_[0-9a-f]{16}$/.test(id);
}
router.get("/", (req, res) => {
const rows = req.ctx.db
.prepare("SELECT id, title, active_model, created_at, updated_at FROM conversations ORDER BY updated_at DESC LIMIT 200")
.all();
res.json({ items: rows.map((r) => ({ ...r, created_at: new Date(r.created_at).toISOString(), updated_at: new Date(r.updated_at).toISOString() })) });
});
router.post("/", (req, res) => {
const body = req.body || {};
let active = body.active_model;
if (active !== "mother" && active !== "coder") active = "mother";
let title = typeof body.title === "string" ? body.title.trim().slice(0, 64) : "";
if (!title) title = "(新对话)";
const id = genConvId();
const now = Date.now();
req.ctx.db
.prepare(
"INSERT INTO conversations (id, title, active_model, created_at, updated_at) VALUES (?, ?, ?, ?, ?)"
)
.run(id, title, active, now, now);
res.status(201).json({
id,
title,
active_model: active,
created_at: new Date(now).toISOString(),
updated_at: new Date(now).toISOString()
});
});
router.get("/:id/messages", (req, res) => {
const id = req.params.id;
if (!isValidId(id)) {
return res.status(400).json({ error: true, code: "bad_id", message: "对话 id 格式不合法" });
}
const conv = req.ctx.db
.prepare("SELECT id, title, active_model, created_at, updated_at FROM conversations WHERE id = ?")
.get(id);
if (!conv) {
return res.status(404).json({ error: true, code: "not_found", message: "对话不存在: " + id });
}
const rows = req.ctx.db
.prepare("SELECT id, role, content, ts FROM messages WHERE conv_id = ? ORDER BY ts ASC, id ASC LIMIT 1000")
.all(id);
res.json({
conversation: {
...conv,
created_at: new Date(conv.created_at).toISOString(),
updated_at: new Date(conv.updated_at).toISOString()
},
items: rows.map((r) => ({ ...r, ts: new Date(r.ts).toISOString() }))
});
});
module.exports = router;
module.exports.isValidId = isValidId;
module.exports.genConvId = genConvId;