135 lines
4.6 KiB
JavaScript
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;
|