Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

93 lines
2.6 KiB
JavaScript

/*
* /api/persona-db — 人格层右栏数据 (只读)
* 守护: 铸渊 · ICE-GL-ZY001
*
* 数据源:
* 1. 优先读 PORTAL_DATA_DIR/persona-db-snapshot.json (生产环境由部署时打包)
* 2. 回退 repo 内 persona-brain-db/seed-data/*.json (开发/演示用)
*
* 设计理念 (cc-004):
* 不直接连 GitHub 或 Notion API — 国内 2C2G 不稳, 也暴露主权.
* 一律走本地快照, 把不稳定性吞进部署管道.
*/
"use strict";
const express = require("express");
const fs = require("fs");
const path = require("path");
const router = express.Router();
let cache = null;
let cacheTs = 0;
const CACHE_MS = 30 * 1000;
function loadSnapshot(dataDir, repoRoot) {
// 1. 部署时打包的快照
const snap = path.join(dataDir, "persona-db-snapshot.json");
if (fs.existsSync(snap)) {
try {
return JSON.parse(fs.readFileSync(snap, "utf8"));
} catch (_) {
/* fallthrough */
}
}
// 2. 仓库内的 seed-data
const items = [];
const seedDir = path.join(repoRoot, "persona-brain-db", "seed-data");
if (fs.existsSync(seedDir)) {
for (const f of fs.readdirSync(seedDir)) {
if (!f.endsWith(".json")) continue;
try {
const j = JSON.parse(fs.readFileSync(path.join(seedDir, f), "utf8"));
const item = normalize(f, j);
if (item) items.push(item);
} catch (_) {
/* ignore broken seed file */
}
}
}
return { items };
}
function normalize(filename, raw) {
if (!raw || typeof raw !== "object") return null;
const stem = filename.replace(/\.json$/, "");
if (Array.isArray(raw)) {
return {
title: stem,
tags: ["seed", "list", `${raw.length}`],
summary: `数组型种子数据, 共 ${raw.length}`
};
}
// 取一些常见字段做摘要
const title =
raw.title ||
raw.name ||
raw.persona_name ||
raw.display_name ||
stem;
const summary =
raw.summary ||
raw.description ||
raw.bio ||
(Array.isArray(raw.entries) ? `${raw.entries.length} 条记忆条目` : "");
const tags = [];
if (raw.persona_id) tags.push(raw.persona_id);
if (raw.scope) tags.push(raw.scope);
if (raw.layer) tags.push(raw.layer);
if (!tags.length) tags.push("seed");
return { title: String(title).slice(0, 48), tags, summary: String(summary || "").slice(0, 240) };
}
router.get("/", (req, res) => {
const now = Date.now();
if (!cache || now - cacheTs > CACHE_MS) {
cache = loadSnapshot(req.ctx.dataDir, req.ctx.repoRoot);
cacheTs = now;
}
res.json({ source: "persona-brain-db", ...(cache || { items: [] }) });
});
module.exports = router;