添加 documents CRUD 路由(语言层数据库核心)
This commit is contained in:
parent
f04394d7a1
commit
674c7f7a8d
134
persona-brain-db/api/routes/documents.js
Normal file
134
persona-brain-db/api/routes/documents.js
Normal file
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* 文档 · /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;
|
||||
Loading…
x
Reference in New Issue
Block a user