135 lines
4.6 KiB
JavaScript

/**
* 文档 · /brain/documents
* 用途:语言层数据库核心——人格体读写,人类只读(渲染)
*/
const { Router } = require('express');
const crypto = require('crypto');
const router = Router();
// GET /brain/documents — 列出文档(支持树形查询)
router.get('/', (req, res) => {
try {
let sql = 'SELECT document_id, persona_id, parent_id, path, title, content_type, source, version, created_at, updated_at FROM documents WHERE 1=1';
const params = [];
if (req.query.parent_id) {
sql += ' AND parent_id = ?';
params.push(req.query.parent_id);
}
if (req.query.persona_id) {
sql += ' AND persona_id = ?';
params.push(req.query.persona_id);
}
if (req.query.root) {
sql += ' AND parent_id IS NULL';
}
sql += ' ORDER BY path ASC';
const rows = req.db.prepare(sql).all(...params);
res.json({ data: rows, total: rows.length });
} catch (err) {
res.status(500).json({ error: true, message: err.message });
}
});
// GET /brain/documents/:id — 读取单个文档(含完整内容)
router.get('/:id', (req, res) => {
try {
const row = req.db.prepare('SELECT * FROM documents WHERE document_id = ?').get(req.params.id);
if (!row) {
return res.status(404).json({ error: true, message: 'Document not found' });
}
if (row.tags) {
try { row.tags = JSON.parse(row.tags); } catch (_e) {}
}
res.json({ data: row });
} catch (err) {
res.status(500).json({ error: true, message: err.message });
}
});
// POST /brain/documents — 创建新文档
router.post('/', (req, res) => {
try {
const { persona_id, parent_id, path, title, content, content_type, source, tags } = req.body;
if (!title) {
return res.status(400).json({ error: true, message: 'Missing required field: title' });
}
const document_id = `DOC-${Date.now()}-${crypto.randomBytes(4).toString('hex')}`;
const docPath = path || (parent_id ? `${parent_id}/${title}` : `/root/${title}`);
req.db.prepare(`
INSERT INTO documents (document_id, persona_id, parent_id, path, title, content, content_type, source, tags)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
`).run(
document_id,
persona_id || 'SY-001',
parent_id || null,
docPath,
title,
content || '',
content_type || 'markdown',
source || 'api',
tags ? JSON.stringify(tags) : null
);
const created = req.db.prepare('SELECT * FROM documents WHERE document_id = ?').get(document_id);
res.status(201).json({ data: created, message: 'Document created' });
} catch (err) {
res.status(500).json({ error: true, message: err.message });
}
});
// PUT /brain/documents/:id — 更新文档
router.put('/:id', (req, res) => {
try {
const existing = req.db.prepare('SELECT * FROM documents WHERE document_id = ?').get(req.params.id);
if (!existing) {
return res.status(404).json({ error: true, message: 'Document not found' });
}
const { title, content, parent_id, path, tags } = req.body;
const updates = [];
const params = [];
if (title !== undefined) { updates.push('title = ?'); params.push(title); }
if (content !== undefined) { updates.push('content = ?'); params.push(content); }
if (parent_id !== undefined) { updates.push('parent_id = ?'); params.push(parent_id); }
if (path !== undefined) { updates.push('path = ?'); params.push(path); }
if (tags !== undefined) { updates.push('tags = ?'); params.push(JSON.stringify(tags)); }
if (updates.length > 0) {
params.push(req.params.id);
req.db.prepare(`UPDATE documents SET ${updates.join(', ')}, updated_at = CURRENT_TIMESTAMP WHERE document_id = ?`).run(...params);
}
const updated = req.db.prepare('SELECT * FROM documents WHERE document_id = ?').get(req.params.id);
res.json({ data: updated, message: 'Document updated' });
} catch (err) {
res.status(500).json({ error: true, message: err.message });
}
});
// DELETE /brain/documents/:id — 软删除
router.delete('/:id', (req, res) => {
try {
const existing = req.db.prepare('SELECT * FROM documents WHERE document_id = ?').get(req.params.id);
if (!existing) {
return res.status(404).json({ error: true, message: 'Document not found' });
}
const deletedId = `deleted_${req.params.id}`;
req.db.prepare('UPDATE documents SET document_id = ?, path = ? WHERE document_id = ?')
.run(deletedId, `/trash/${req.params.id}`, req.params.id);
res.json({ data: { document_id: deletedId }, message: 'Document moved to trash' });
} catch (err) {
res.status(500).json({ error: true, message: err.message });
}
});
module.exports = router;