fix(kbdb): entries list 端點加 q/search filter + 誠實 total 欄位 (Arcrun#3 發現①)

根因(CF D1 直查已核實):owner_id='leo' 租戶下 D1 實際有 458,357 筆,但
/kbdb/entries(list)從沒接過 search/q 參數——proxy 轉發白名單漏了它、base
listEntries() 也沒這個 filter,caller 帶 search= 會被靜默丟棄,永遠回「無過濾
list」。加上舊版 count 欄位=本頁筆數(非總數),容易被誤讀成「總共只有這幾筆」。

修法:
- kbdb/src/actions/entry-crud.ts:ListEntriesFilter 加 q,listEntries 回傳
  { entries, total }(total = 符合條件全部筆數,COUNT(*) 與 list 查詢並行跑)。
- kbdb/src/routes/entries.ts:GET / 讀 q 或 search(別名)當 LIKE filter,
  回應同時帶 count(本頁)與 total(全部)。
- cypher-executor/src/routes/kbdb-proxy.ts:GET /kbdb/entries 轉發白名單加
  q/search → 統一轉發成 base 認得的 q。

驗證見 issue #3 留言(CF D1 直查 + curl /kbdb/entries?search=遷移 有真實命中)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Leo
2026-07-03 08:51:29 +00:00
parent 406f0fedf8
commit 9024f22534
5 changed files with 6645 additions and 10 deletions
+6 -1
View File
@@ -160,8 +160,11 @@ kbdbProxyRouter.post('/kbdb/entries', async (c) => {
return new Response(res.body, { status: res.status, headers: { 'Content-Type': 'application/json' } });
});
// GET /kbdb/entries — listfilters: entry_type / parent_id / page_name / limit / offset)。
// GET /kbdb/entries — listfilters: entry_type / parent_id / page_name / source / q(search) / limit / offset)。
// owner_id 強制覆寫成本租戶(防跨租戶讀;caller 不能查別人的 owner_id)。
// Arcrun#3 發現①根因:本白名單原本沒有 q/searchcaller 帶 search= 會被這裡靜默丟棄,
// 打到 base 永遠是「無過濾 list」——不是 458K 筆搜不到,是這個 filter 從沒被轉發過。
// 修法:q 與 search 都收,統一轉發成 base 認得的 qbase 端見 entries.ts 同步修)。
kbdbProxyRouter.get('/kbdb/entries', async (c) => {
const owner = tenant(c);
if (!owner) return c.json(NEED_KEY, 401);
@@ -172,6 +175,8 @@ kbdbProxyRouter.get('/kbdb/entries', async (c) => {
const v = c.req.query(k);
if (v) params.set(k, v);
}
const q = c.req.query('q') || c.req.query('search');
if (q) params.set('q', q);
const res = await fetch(`${base}/entries?${params.toString()}`, { headers });
return new Response(res.body, { status: res.status, headers: { 'Content-Type': 'application/json' } });
});