portal-auth P3 前置:graph 粗閘 helpers(D-4)+session 能力欄位+kbdb-proxy 透傳 library(P1 順延)

- portal.ts:export 共用 helpers(requirePortalUser/parseLibraries/kbdbFetch/run…)
  +graphSourceLibraries/hasGraphAccess/workflowsVisible;/portal/session 補
  graph_allowed、workflows_visible(顯示提示,真閘在 /portal/data/* 路由層)
- portal_library seed 加 graph_source slot;ensurePortalTemplates 冪等補舊 template
  缺的 slots(updateRecord 對 template 外 slot 會 reject,不補就寫不進標記)
- admin libraries PATCH 收 graph_source(boolean);toPublicLibrary 回 graph_source
- kbdb-proxy /kbdb/search 與 /kbdb/entries 白名單加 library(tasks.md P1 順延一行)
- PORTAL_SHOW_WORKFLOWS var(D-8,預設 admin)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
uncle6me-web
2026-07-14 12:59:41 +08:00
parent d4611950c0
commit 5668d48d37
6 changed files with 117 additions and 26 deletions
+7 -5
View File
@@ -121,8 +121,10 @@ kbdbProxyRouter.get('/kbdb/records/:recordId', async (c) => {
// ── search(限本租戶範圍內)────────────────────────────────────────────────────
// GET /kbdb/search?q=&entry_type=&source=&mode= — entries 搜尋,限本租戶 owner_id。
// 透傳 entry_typebase 通用 filterworkflow-discovery Q4/ source / mode 給 KBDB /entries/search。
// GET /kbdb/search?q=&entry_type=&source=&library=&mode= — entries 搜尋,限本租戶 owner_id。
// 透傳 entry_typebase 通用 filterworkflow-discovery Q4/ source / library(多值逗號分隔,
// portal-auth P1 順延項——owner/admin 面自選庫過濾;portal 一般用戶不經這,走 /portal/data/*
// 的 server 注入)/ mode 給 KBDB /entries/search。
kbdbProxyRouter.get('/kbdb/search', async (c) => {
const owner = tenant(c);
if (!owner) return c.json(NEED_KEY, 401);
@@ -130,7 +132,7 @@ kbdbProxyRouter.get('/kbdb/search', async (c) => {
if (!q) return c.json({ error: 'q 必填' }, 400);
const { base, headers } = kbdbBase(c.env);
const params = new URLSearchParams({ q, owner_id: owner });
for (const k of ['entry_type', 'source', 'mode']) {
for (const k of ['entry_type', 'source', 'library', 'mode']) {
const v = c.req.query(k);
if (v) params.set(k, v);
}
@@ -160,7 +162,7 @@ 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 / source / q(search) / limit / offset)。
// GET /kbdb/entries — listfilters: entry_type / parent_id / page_name / source / library / q(search) / limit / offset)。
// owner_id 強制覆寫成本租戶(防跨租戶讀;caller 不能查別人的 owner_id)。
// Arcrun#3 發現①根因:本白名單原本沒有 q/searchcaller 帶 search= 會被這裡靜默丟棄,
// 打到 base 永遠是「無過濾 list」——不是 458K 筆搜不到,是這個 filter 從沒被轉發過。
@@ -171,7 +173,7 @@ kbdbProxyRouter.get('/kbdb/entries', async (c) => {
const { base, headers } = kbdbBase(c.env);
const params = new URLSearchParams();
params.set('owner_id', owner); // 強制本租戶,不接受 caller 覆寫
for (const k of ['entry_type', 'parent_id', 'page_name', 'source', 'limit', 'offset']) {
for (const k of ['entry_type', 'parent_id', 'page_name', 'source', 'library', 'limit', 'offset']) {
const v = c.req.query(k);
if (v) params.set(k, v);
}