# self-hosted KBDB 能力清單（查詢能力對照）

> 來源：issue #5（普世框架視角——任何 self-hosted 用戶都該知道自架 `arcrun-kbdb` 提供哪些查詢能力）。
> 範圍：**base tier（D1-only，免費不綁卡）**。optional 模組（embed/triplet）另標。
> 鐵律：API-as-Wall（只經 HTTP API，不直連 D1）／零建表／零 SQL 暴露給用戶。

---

## 兩條存取路徑

| 路徑 | 對象 | 入口 | 隔離 |
|------|------|------|------|
| **cypher proxy `/kbdb/*`** | app 前端 / CLI（`acr kbdb`） | `cypher.arcrun.dev/kbdb/*`（self-hosted 指自己的 cypher） | X-Arcrun-API-Key → owner_id，自動租戶隔離 |
| **raw worker** | 內部 / MCP service binding | `arcrun-kbdb.<sub>.workers.dev` | 無 auth（內網），owner_id 由 caller 帶 |

> **前端存取準則**：app（如自架的任何 Next.js 前端）**走 cypher proxy `/kbdb/*`**，不直連 raw worker——proxy 才有 owner_id 租戶隔離。CLI/MCP 是薄殼（thin-shell §0），底層同一條 proxy。

---

## base 查詢能力（現有）

### entries（原子資料 / 樹節點）

| 能力 | 端點 | filter / 參數 |
|------|------|------|
| 建 | `POST /entries` | `entry_type`(必), content, owner_id, parent_id, page_name, metadata_json… |
| 列 + 過濾 | `GET /entries` | `entry_type` / `owner_id` / `parent_id` / `page_name` / **`source`**(#5.1) / `limit` / `offset` |
| 取單筆 | `GET /entries/:id` | — |
| 改 | `PATCH /entries/:id` | 任意可改欄位（proxy 會剝 owner_id 防認領） |
| 刪 | `DELETE /entries/:id` | ⚠️ **raw 有；cypher proxy 暫未開**（見下「擱置」） |
| **關鍵字搜尋** | `GET /entries/search?q=` | D1 `LIKE`，回 `mode:'keyword'`。owner_id 限本租戶 |

- **`source` 過濾（#5.1，2026-06-26）**：按 ingest 來源篩（envelope `source.uri`）。實作走 SQLite
  `json_extract(metadata_json,'$.source')`——**source 埋在 metadata_json，零建表**即可查。
  例：`GET /kbdb/entries?source=logseq://vault/foo.md`。

### templates（虛擬表定義＝替代建表）

| 能力 | 端點 |
|------|------|
| 建 / 列 / 取 / 改 slots | `POST /templates`、`GET /templates`、`GET /templates/:idOrName`、`PATCH /templates/:id` |

> 鐵律：template = 萬用表的 slot 定義，**不是建真表**。AI/用戶只能「建 template(name+slots) + 填 record」，無 CREATE TABLE / SQL。

### records（template 實例＝填 slot）

| 能力 | 端點 |
|------|------|
| 建 | `POST /records`（template + values） |
| 列某 template 下 | `GET /records/by-template/:template`（owner_id 限本租戶） |
| 取單筆 | `GET /records/:recordId` |
| **改 slot 值** | `PATCH /records/:recordId`（#6，翻 slot 值＝改底層 entries.content，三表 append-only 不破） |

### recipe-stats（市場成功率）

| 能力 | 端點 |
|------|------|
| 記一次成功/失敗 | `POST /recipe-stats/record` |
| 查某 recipe 統計 | `GET /recipe-stats/:canonical_id` |

---

## 語義搜尋（optional embed 模組）

- **base 不含語義搜尋**——關鍵字 `GET /entries/search` 是 `LIKE`（`mode:'keyword'`）。
- 開 **embed 模組**（CF Vectorize binding，自付費）後升級語義（`mode:'semantic'`）。是 base 的 optional 模組，
  不裝保持輕（free-tier 友善）。開法 + 行為見 issue #7 / kbdb-base SDD T2.4。

---

## 擱置 / 不做（誠實標明，避免用戶誤以為有）

| 項 | 狀態 | 原因 |
|----|------|------|
| cypher proxy `DELETE /kbdb/entries/:id` | ⏸ **暫擱置** | 依賴頂層「死資料自動刪除原則」（mira-dissolve T8 未定）。raw worker 有 DELETE，但裸 delete-by-id 無 owner 檢查，經 proxy 暴露＝跨租戶刪除風險 → 補時要先驗 owner_id 才放行。 |
| documents 聚合（GROUP BY page_name → block_count） | ❌ **不做** | 「跨 vault 的圖」走 **graph MCP**（traverse/neighbors），不靠 KBDB 出 SQL 聚合端點。普世用戶不需要。 |

> 這份**不列**「documents / process-page 待移植」——那是舊 SaaS KBDB（kbdb.finally.click）/ 舊河道頁視角，
> 新架構不移植。self-hosted base 的能力以本清單為準。
