# 系統架構

KuraDB 是單一 Go 執行檔，各層構成單向 pipeline：檔案從監看資料夾進入、寫進每個資料庫各自的 SQLite 檔，只能經由唯讀查詢介面取出。

## 系統概覽

```mermaid
flowchart TD
  inbox["~/Kura_name inbox folder"] --> watcher["Watcher: 10 s poll"]
  watcher --> parsers["Parsers: text, PDF, DOCX, PPTX, CSV/TSV, XLSX"]
  parsers --> handler["databaseHandler: Upsert / Dismiss"]
  handler --> sqlite[("data.db: file_data table")]
  sqlite --> search["search.Search"]
  search --> http["HTTP API: /api/search"]
  search --> mcp["MCP tools: list_rag / search_rag"]
  mcp --> stdio["kura mcp over stdio"]
  mcp --> remote["/mcp over HTTP, opt-in"]
```

## 分層

| 層 | 套件 | 職責 |
|---|---|---|
| CLI 與 daemon | `cmd/app` | 子指令分派、daemon fork、每個資料庫的 watcher 迴圈、HTTP listener |
| Registry（註冊表） | `internal/database`（`registry.go`） | 以 mutex 保護的 `db.json` 已註冊資料庫清單 |
| 儲存 | `internal/database`（`database.go`、`schema/file_data.sql`） | 每個資料庫開一個 SQLite 檔，讀寫連線池分開，並套用 schema |
| 寫入 | `internal/database/handler`（`upsert.go`、`dismiss.go`） | 唯一會寫入 `file_data` 的程式碼 |
| 匯入 | `internal/filesystem` | 目錄走訪、變更偵測、依檔案類型分派、段落與表格切塊 |
| 查詢 | `internal/search` | 查詢解析、關鍵字比對、依來源檔分組 |
| HTTP | `internal/api` | `/api/*` 的 Gin router 與可選的 `/mcp` 掛載 |
| MCP | `internal/mcp` | MCP 伺服器、工具 schema，以及呼叫 `search.Search` 的 store |
| Runtime | `internal/runtime` | `runtime.uid` PID 檔、存活檢查、優雅停止 |
| 設定 | `internal/config` | 含 `port` 與 `remote` 的 `config.json` |

## 跨層原則

| 原則 | 效果 |
|---|---|
| 唯讀介面 | HTTP 與 MCP 只提供查詢，沒有任何寫入資料的端點 |
| 單一寫入路徑 | 只有 watcher 會呼叫 `databaseHandler.Upsert` 與 `databaseHandler.Dismiss`，其他層不碰 `file_data` |
| 軟刪除 | 被移除或取代的內容標記 `dismiss = TRUE`，所有查詢都會過濾 |
| 單一搜尋實作 | MCP 工具直接呼叫 `search.Search`，不回打 HTTP API，兩個介面結果一致 |
| 資料庫各自隔離 | 每個資料庫有自己的資料夾、SQLite 檔與快照；單一資料庫失敗只會被略過，不影響其他資料庫 |

這些原則讓 KuraDB 與其他 RAG 工具走不同路線。RAGFlow 是結合檢索與 agent 能力的自架 RAG 引擎，WeKnora 是以 embedding、向量搜尋與 reranking 組成的知識庫平台，AnythingLLM 是內建向量資料庫的本地優先 agent 應用，haiku.rag 則在 LanceDB 上做混合檢索與 reranking，並提供 MCP Server。KuraDB 不跑 embedding 模型、不建向量索引：它是單一 Go 執行檔，每個資料庫一個 SQLite 檔存放文字 chunk，以關鍵字比對，推理交給呼叫它的 agent。mnemos 形式較接近，同樣是以 SQLite 提供 MCP 的單一 Go 執行檔，但定位是 agent 的記憶伺服器；KuraDB 只索引放進監看資料夾的檔案，不儲存對話紀錄。

## 延伸閱讀

- [索引流程](/zh/indexing-pipeline)
- [關鍵字搜尋](/zh/keyword-search)
- [Daemon 生命週期](/zh/daemon)
