feat: KBDB-graph 插件獨立 — 全面改寫成走基本盤 API(API-as-Wall)
按 leo 鐵律(2026-06-14)把插件從「直接 SQL 操作基本盤表」改寫成 「只透過基本盤 arcrun/kbdb HTTP API 讀寫」。零建表、零 migration、零 SQL。 - 新增 src/lib/kbdb-client.ts:唯一對外通道,封裝 entries/templates/records API - 新增 src/lib/templates.ts:triplet/entity template 定義(替代建表) - 改寫 21 個違規 action(triplet/graph/entity/search)→ 走 client,圖在插件層記憶體組裝 - 移除所有 migrations、D1/Vectorize/AI 綁定;embedding/語意搜尋歸基本盤 optional 模組 - index.ts 只掛 triplets/graph/entities/search 路由;基本盤路由歸 arcrun/kbdb - 測試改走 mock client(純 node);裁剪 CLAUDE.md 只留 graph 插件 + 鐵律 - 修正 SDD design.md「讀現狀推翻鐵律」的錯誤判斷(共用 D1 → API-as-Wall) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
// graph 查詢 — 圖在插件層記憶體組裝(不靠 DB VIEW),走 mock client。
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { createTriplet } from '../src/actions/triplet-crud';
|
||||
import { listNodes, getNodeEdges, getNeighbors } from '../src/actions/graph-nodes';
|
||||
import { findShortestPath } from '../src/actions/graph-path';
|
||||
import { mockClient } from './mock-client';
|
||||
import type { KbdbClient } from '../src/lib/kbdb-client';
|
||||
|
||||
async function seed(c: KbdbClient) {
|
||||
// A — B — C,D 孤立連 A
|
||||
await createTriplet(c, { subject: 'A', predicate: 'r', object: 'B' });
|
||||
await createTriplet(c, { subject: 'B', predicate: 'r', object: 'C' });
|
||||
await createTriplet(c, { subject: 'A', predicate: 'r', object: 'D' });
|
||||
}
|
||||
|
||||
describe('graph-nodes', () => {
|
||||
it('listNodes 統計 edge_count', async () => {
|
||||
const c = mockClient();
|
||||
await seed(c);
|
||||
const nodes = await listNodes(c, {});
|
||||
const a = nodes.find((n) => n.node === 'A');
|
||||
expect(a?.edge_count).toBe(2);
|
||||
});
|
||||
|
||||
it('getNeighbors 收鄰居', async () => {
|
||||
const c = mockClient();
|
||||
await seed(c);
|
||||
const neighbors = await getNeighbors(c, 'A');
|
||||
expect(neighbors.sort()).toEqual(['B', 'D']);
|
||||
});
|
||||
|
||||
it('getNodeEdges 取邊', async () => {
|
||||
const c = mockClient();
|
||||
await seed(c);
|
||||
const edges = await getNodeEdges(c, 'B');
|
||||
expect(edges.length).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('graph-path', () => {
|
||||
it('A→C 最短路經過 B', async () => {
|
||||
const c = mockClient();
|
||||
await seed(c);
|
||||
const res = await findShortestPath(c, 'A', 'C');
|
||||
expect(res.path).toEqual(['A', 'B', 'C']);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user