feat: integrate MarkBase Search Session API into Studio

- Created useSearchSession composable for session management
- Added 7 API endpoints in api/index.ts
- Updated SearchView.vue to use sessions instead of history
- Session sidebar with create, rename, delete functionality
- Auto-save messages to current session after each search
- Auto-create default session on first load
- Updated CSS for session active state and new session button
This commit is contained in:
2026-10-27 05:06:03 +08:00
parent 86d90f4f53
commit fe91afff98
7 changed files with 1959 additions and 243 deletions

View File

@@ -0,0 +1,344 @@
# MarkBase Search Session API 需求
## 背景
Momentry Studio 需要將搜尋歷史(Search History)升級為以 Session 為單位的管理系統,並整合到 MarkBase 的 SQLite 資料庫中。目前 Studio 使用本地 SQLite 儲存搜尋記錄,現在需要改為透過 MarkBase API 存取。
---
## 1. SQLite Schema 需求
### 1.1 新增 search_sessions 表
```sql
CREATE TABLE IF NOT EXISTS search_sessions (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL,
title TEXT NOT NULL DEFAULT '未命名搜尋',
mode TEXT DEFAULT 'keyword', -- keyword | visual | people | agent
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX idx_sessions_user ON search_sessions(user_id);
CREATE INDEX idx_sessions_updated ON search_sessions(user_id, updated_at DESC);
```
### 1.2 新增 search_messages 表
```sql
CREATE TABLE IF NOT EXISTS search_messages (
id TEXT PRIMARY KEY,
session_id TEXT NOT NULL REFERENCES search_sessions(id) ON DELETE CASCADE,
role TEXT NOT NULL, -- 'user' | 'assistant'
content TEXT, -- 使用者輸入或 AI 回答
results TEXT, -- JSON 格式的搜尋結果
mode TEXT DEFAULT 'keyword', -- 搜尋模式
created_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX idx_messages_session ON search_messages(session_id, created_at);
```
### 1.3 修改現有 search_history 表(選用)
如果要保留向後相容性:
```sql
ALTER TABLE search_history ADD COLUMN session_id TEXT REFERENCES search_sessions(id);
```
---
## 2. API 端點需求
所有端點前綴:`/api/v2/search-sessions`
### 2.1 列出 Session
**端點**: `GET /api/v2/search-sessions`
**認證**: 需要 Bearer Token
**查詢參數**:
| 參數 | 類型 | 必填 | 說明 | 預設 |
|---|---|---|---|---|
| limit | number | ❌ | 返回數量 | 30 |
| offset | number | ❌ | 偏移量 | 0 |
**回應**:
```json
{
"success": true,
"total": 15,
"sessions": [
{
"id": "sess_abc123",
"title": "廚房場景搜尋",
"mode": "visual",
"message_count": 5,
"created_at": "2026-10-27T10:00:00Z",
"updated_at": "2026-10-27T10:30:00Z"
}
]
}
```
---
### 2.2 建立 Session
**端點**: `POST /api/v2/search-sessions`
**認證**: 需要 Bearer Token
**請求**:
```json
{
"title": "廚房場景搜尋",
"mode": "visual"
}
```
**回應**:
```json
{
"success": true,
"session": {
"id": "sess_abc123",
"title": "廚房場景搜尋",
"mode": "visual",
"created_at": "2026-10-27T10:00:00Z",
"updated_at": "2026-10-27T10:00:00Z"
}
}
```
---
### 2.3 更新 Session
**端點**: `PUT /api/v2/search-sessions/:id`
**認證**: 需要 Bearer Token
**請求**:
```json
{
"title": "重新命名的搜尋"
}
```
**回應**:
```json
{
"success": true,
"message": "Session updated"
}
```
---
### 2.4 刪除 Session
**端點**: `DELETE /api/v2/search-sessions/:id`
**認證**: 需要 Bearer Token
**回應**:
```json
{
"success": true,
"message": "Session deleted"
}
```
---
### 2.5 取得 Session 對話
**端點**: `GET /api/v2/search-sessions/:id/messages`
**認證**: 需要 Bearer Token
**回應**:
```json
{
"success": true,
"messages": [
{
"id": "msg_001",
"role": "user",
"content": "Find kitchen scenes",
"results": null,
"created_at": "2026-10-27T10:00:00Z"
},
{
"id": "msg_002",
"role": "assistant",
"content": "Found 3 kitchen scenes...",
"results": "[...]",
"created_at": "2026-10-27T10:00:01Z"
}
]
}
```
---
### 2.6 新增訊息到 Session
**端點**: `POST /api/v2/search-sessions/:id/messages`
**認證**: 需要 Bearer Token
**請求**:
```json
{
"role": "user",
"content": "Find kitchen scenes",
"mode": "visual",
"results": null
}
```
**回應**:
```json
{
"success": true,
"message": {
"id": "msg_001",
"role": "user",
"content": "Find kitchen scenes",
"created_at": "2026-10-27T10:00:00Z"
}
}
```
---
### 2.7 更新訊息結果(AI 回答後)
**端點**: `PATCH /api/v2/search-sessions/:id/messages/:msgId`
**認證**: 需要 Bearer Token
**請求**:
```json
{
"role": "assistant",
"content": "Found 3 kitchen scenes...",
"results": [{...}, {...}]
}
```
**回應**:
```json
{
"success": true,
"message": "Message updated"
}
```
---
## 3. 業務邏輯需求
### 3.1 自動清理
- 未命名的 Session 超過 24 小時自動刪除
- 每個使用者最多保留 50 個 Session
- 超出限制時,刪除最舊的未命名 Session
### 3.2 使用者隔離
- 所有查詢自動過濾 `user_id`
- Token 中必須包含 `user_id` 或從 token 解析
### 3.3 預設 Session
- 使用者首次進入 Search 頁面時,自動建立 "Default" Session
- 後續搜尋都歸入目前活躍的 Session
---
## 4. 錯誤處理
### 統一錯誤格式
```json
{
"success": false,
"error": "Session not found",
"code": "SESSION_NOT_FOUND"
}
```
### 錯誤代碼
| 代碼 | HTTP 狀態 | 說明 |
|---|---|---|
| SESSION_NOT_FOUND | 404 | Session 不存在 |
| UNAUTHORIZED | 401 | 無效 Token |
| VALIDATION_ERROR | 400 | 請求格式錯誤 |
| LIMIT_EXCEEDED | 429 | 超過 Session 數量限制 |
---
## 5. 前端整合計劃
### 5.1 Studio 修改項目
| 檔案 | 修改內容 |
|---|---|
| `src/composables/useSearchSession.ts` | 新增 Session 管理 composable |
| `src/views/SearchView.vue` | 側邊欄改為 Session 列表 |
| `src/api/index.ts` | 新增 search-session 相關 HTTP 呼叫 |
### 5.2 移除項目
| 檔案 | 移除內容 |
|---|---|
| `src-tauri/src/db.rs` | search_history 相關函數 |
| `src-tauri/src/proxy.rs` | search-history handler |
| `src-tauri/src/main.rs` | search_history Tauri commands |
---
## 6. 測試清單
### 6.1 API 測試
- [ ] 建立 Session
- [ ] 列出 Sessions(分頁)
- [ ] 更新 Session 標題
- [ ] 刪除 Session
- [ ] 新增訊息
- [ ] 更新訊息結果
- [ ] 取得 Session 對話
- [ ] 使用者隔離測試
- [ ] 自動清理測試
### 6.2 前端測試
- [ ] 新 Session 建立
- [ ] Session 命名
- [ ] 切換 Session
- [ ] 刪除 Session
- [ ] 對話還原
- [ ] 自動建立 Default Session
---
## 7. 優先順序
| 優先級 | 任務 | 說明 |
|---|---|---|
| **P0** | SQLite Schema | search_sessions + search_messages 表 |
| **P0** | CRUD API | Session 增刪改查 |
| **P0** | Messages API | 訊息增刪改查 |
| **P1** | 自動清理 | 24 小時 + 50 筆限制 |
| **P1** | 使用者隔離 | Token 解析 + user_id 過濾 |
| **P2** | 效能優化 | 索引 + 分頁 |
---
## 8. 時間預估
| 階段 | 預估工時 |
|---|---|
| Schema 設計 + 實作 | 30 min |
| CRUD API 實作 | 60 min |
| Messages API 實作 | 45 min |
| 自動清理邏輯 | 30 min |
| 測試 + 文檔 | 30 min |
| **總計** | **~3 小時** |

File diff suppressed because it is too large Load Diff