934b9265d9
按 issue 分段標明(檔 #5/#8 改動交疊處無法乾淨拆檔,故併一個 commit): #4 thin-shell §3.1 自力救濟階梯 + code-node 規則(純文檔/規則,code-node 零件未實作) #5 KBDB source filter(json_extract metadata_json 零建表)+ 能力對照;documents 聚合與 DELETE proxy 部分擱置等頂層 T8 #7 base embed 模組(kbdb/src/embed.ts)+ vectorize 開關(deploy/config/wrangler.toml 註解範本) + 語義查詢降級閉環(mode=semantic 未開→LIKE+capability_hint) #8 部分(workflow-discovery): - KBDB /entries/search 加 base 通用 entry_type filter(entry-crud/embed/route/kbdb-proxy 透傳) - /webhooks/named 強制 description(空→400,訊息要求操盤 AI 據實寫一句) - 部署雙寫 entry_type=workflow embeddable entry(waitUntil 非阻塞,供 search) - cypher GET /workflows/search + MCP u6u_search_workflows(優先語意、降級 hint) - cypher POST /workflows/backfill-search-entries(無 desc 列出不編造) - GET /webhooks/named 補回 description/created_at 欄位(為 list 來源收斂備) ⚠️ tsc 綠 = code done,非完成(mindset §7 禁假綠): - #7/#8 端到端待 leo21c 部署驗(Vectorize 需官方憑證、CC 跑不了) - #8 ①-a(MCP deploy 改打 /webhooks/named)未做、MCP deploy 那半仍 404 - #8 端到端(強制填擋空/語義命中/租戶隔離/降級 hint)未驗 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
50 lines
2.1 KiB
TypeScript
50 lines
2.1 KiB
TypeScript
// Records route — structured records (entry_values composed by a template).
|
|
import { Hono } from 'hono';
|
|
import type { Bindings } from '../types';
|
|
import { createRecord, getRecord, searchByTemplate, updateRecord } from '../actions/record-crud';
|
|
|
|
export const recordRoutes = new Hono<{ Bindings: Bindings }>();
|
|
|
|
// POST /records — { template, values:{slot:content}, owner_id? }
|
|
recordRoutes.post('/', async (c) => {
|
|
const body = await c.req.json().catch(() => null);
|
|
if (!body || !body.template || !body.values) {
|
|
return c.json({ success: false, error: 'template and values required' }, 400);
|
|
}
|
|
try {
|
|
const rec = await createRecord(c.env.DB, body);
|
|
return c.json({ success: true, record: rec });
|
|
} catch (e) {
|
|
return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 400);
|
|
}
|
|
});
|
|
|
|
// GET /records/by-template/:template — list records of a template
|
|
recordRoutes.get('/by-template/:template', async (c) => {
|
|
const records = await searchByTemplate(c.env.DB, c.req.param('template'), c.req.query('owner_id') || undefined);
|
|
return c.json({ success: true, records, count: records.length });
|
|
});
|
|
|
|
// GET /records/:recordId
|
|
recordRoutes.get('/:recordId', async (c) => {
|
|
const rec = await getRecord(c.env.DB, c.req.param('recordId'));
|
|
if (!rec) return c.json({ success: false, error: 'not found' }, 404);
|
|
return c.json({ success: true, record: rec });
|
|
});
|
|
|
|
// PATCH /records/:recordId — { values:{slot:content} } update existing record slot values
|
|
// (mira-dissolve T2.1 / issue #6; deprecate = flip a slot value, append-only tables untouched).
|
|
recordRoutes.patch('/:recordId', async (c) => {
|
|
const body = await c.req.json().catch(() => null);
|
|
if (!body || !body.values || typeof body.values !== 'object') {
|
|
return c.json({ success: false, error: 'values required' }, 400);
|
|
}
|
|
try {
|
|
const rec = await updateRecord(c.env.DB, c.req.param('recordId'), body.values);
|
|
if (!rec) return c.json({ success: false, error: 'not found' }, 404);
|
|
return c.json({ success: true, record: rec });
|
|
} catch (e) {
|
|
return c.json({ success: false, error: e instanceof Error ? e.message : String(e) }, 400);
|
|
}
|
|
});
|