docs: update docs_v1.0/ documentation

- Fix markdown lint issues (MD030, MD047, MD051, MD028, MD005)
- Update AI agents, architecture, implementation docs
- Add new identity, face recognition, and API documentation
- Remove deprecated face/person API guides
This commit is contained in:
Warren
2026-04-30 15:10:41 +08:00
parent 8f05a7c188
commit 4d75b2e251
185 changed files with 21071 additions and 1605 deletions

View File

@@ -529,4 +529,4 @@ curl -X POST http://localhost:3002/api/v1/unregister \
- [API 範例總覽](./API_EXAMPLES.md) - 完整使用範例
- [API 端點列表](./API_ENDPOINTS.md) - 端點簡介
- [Curl 範例指南](./API_CURL_EXAMPLES.md) - curl 命令範例
- [n8n 整合指南](./API_N8N_GUIDE.md) - n8n 工作流程整合
- [n8n 整合指南](./API_N8N_GUIDE.md) - n8n 工作流程整合

View File

@@ -202,7 +202,7 @@ curl -X POST http://localhost:3002/api/v1/search/visual/class \
| GET | `/api/v1/face/list` | Yes | List all faces |
| GET | `/api/v1/face/:face_id` | Yes | Get face details |
| DELETE | `/api/v1/face/:face_id` | Yes | Delete a face |
| GET | `/api/v1/face/results/:video_uuid` | Yes | Get recognition results |
| GET | `/api/v1/face/results/:file_uuid` | Yes | Get recognition results |
---

View File

@@ -2,8 +2,8 @@
document_type: "reference_doc"
service: "MOMENTRY_CORE"
title: "Momentry Core API 教育訓練手冊"
date: "2026-03-25"
version: "V1.0"
date: "2026-04-27"
version: "V1.5"
status: "active"
owner: "Warren"
created_by: "OpenCode"
@@ -11,16 +11,18 @@ tags:
- "momentry"
- "core"
- "教育訓練手冊"
- "processing_status"
ai_query_hints:
- "查詢 Momentry Core API 教育訓練手冊 的內容"
- "Momentry Core API 教育訓練手冊 的主要目的是什麼?"
- "如何操作或實施 Momentry Core API 教育訓練手冊?"
- "processing_status 字段說明"
---
# Momentry Core API 教育訓練手冊
> **對象**: marcom 團隊
> **版本**: V1.4 | **日期**: 2026-03-25
> **版本**: V1.5 | **日期**: 2026-04-27
---
@@ -213,7 +215,7 @@ n8n 專用搜尋(包含完整影片檔案路徑 file_path
```json
{
"uuid": "9760d0820f0cf9a7",
"video_uuid": "5dea6618a606e7c7",
"file_uuid": "5dea6618a606e7c7",
"status": "completed",
"progress": 100,
"created_at": "2026-03-25T10:00:00Z",
@@ -388,11 +390,28 @@ GET /api/v1/jobs/{uuid}
| 狀態 | 說明 |
|------|------|
| `uploading` | 上傳中 |
| `pending` | 等待處理 |
| `processing` | 處理中 |
| `ready` | 已就緒 |
| `error` | 錯誤 |
| `completed` | 已完成 |
| `failed` | 處理失敗 |
### 影片詳細狀態 (processing_status)
| 狀態 | 說明 | Portal 顯示 |
|------|------|-------------|
| `REGISTERED` | 已註冊 | 藍色「已註冊」 |
| `PENDING` | 等待處理 | 黃色「等待處理」 |
| `PROBING` | 探測中 | 紫色「分析中」 |
| `ASR` | 語音識別中 | 靛藍「語音識別」 |
| `OCR` | 文字識別中 | 靛藍「文字識別」 |
| `YOLO` | 物體檢測中 | 靛藍「物體檢測」 |
| `FACE` | 人臉檢測中 | 靛藍「人臉檢測」 |
| `POSE` | 姿態檢測中 | 靛藍「姿態檢測」 |
| `CUT` | 鏡頭分析中 | 靛藍「鏡頭分析」 |
| `COMPLETED` | 完成 | 綠色「已完成」 |
| `FAILED` | 失敗 | 紅色「處理失敗」 |
**說明**Portal 顯示優先使用 `processing_status`詳細狀態Fallback 使用 `status`(基本狀態)。
---
@@ -405,3 +424,4 @@ GET /api/v1/jobs/{uuid}
| V1.2 | 2026-03-25 | 新增 Chunk 欄位說明、類型、播放方式 | OpenCode |
| V1.3 | 2026-03-25 | 新增 Demo 測試帳號SFTPGo| OpenCode |
| V1.4 | 2026-03-25 | 更新 n8n 搜尋回傳欄位說明 (media_url→file_path) | OpenCode |
| V1.5 | 2026-04-27 | 新增 processing_status 字段說明,移除 'ready' 狀態 | OpenCode |

View File

@@ -644,4 +644,4 @@ pub mod asr {
*版本: 1.0.0*
*更新日期: 2026-03-27*
*負責人: Warren (Technical Lead)*
*狀態: 草案*
*狀態: 草案*

View File

@@ -0,0 +1,416 @@
---
document_type: "guide"
service: "MOMENTRY_CORE"
title: "Portal API Demo 示範指南"
date: "2026-04-30"
version: "V1.0"
status: "active"
current_state: "approved"
owner: "Warren"
created_by: "OpenCode"
tags:
- "portal"
- "api-demo"
- "wordpress"
- "frontend"
- "query"
- "operation"
- "application"
ai_query_hints:
- "查詢 Portal API Demo 示範指南的內容"
- "Portal API Demo 的主要目的是什麼?"
- "如何使用 Portal API Demo 頁面?"
- "Portal API Demo 頁面分類與功能"
- "如何設定 API Demo 頁面"
- "API Demo 查詢/展示/操作/應用頁面說明"
- "Momentry Playground 啟動方式"
related_documents:
- "REFERENCE/API_INDEX.md"
- "REFERENCE/API_ENDPOINTS.md"
- "REFERENCE/PORTAL_DEVELOPMENT_PLAN.md"
- "FILE_UUID_SPEC.md"
---
# Portal API Demo 示範指南
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-30 |
| 文件版本 | V1.0 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-04-30 | 創建 Portal API Demo 示範指南 | OpenCode | big-pickle |
---
## 概述
本文檔說明 Momentry Portal 中四個 API Demo 頁面的功能、設定方式與使用流程。
Demo 頁面以 **file-centric** 設計理念為核心,將檔案 (file) 作為主要管理目標,
身份 (identity) 為附隨目標,分類系統用於形容主體。
---
## 關鍵術語定義
| 術語 | 定義 |
|------|------|
| file_uuid | 檔案唯一識別碼,由 MAC、Birthday、Path、Filename 計算得出 |
| identity_uuid | 全域人員身份識別碼,跨檔案關聯 |
| file-centric | 以檔案為中心的設計理念,檔案是主要管理目標 |
| Birth/Migration | 檔案註冊與遷移的身份模型 |
| Portal | WordPress 前端展示與操作介面 |
| Playground | Momentry 開發伺服器 (port 3003) |
---
## 頁面分類總覽
Momentry Portal 提供四個 API Demo 頁面,涵蓋查詢、展示、操作、應用四大類別:
| 頁面 | 檔案名稱 | 類別 | 主要功能 |
|------|----------|------|----------|
| API Demo - 查詢 | `page-api-demo-query.php` | 查詢 | 檔案查詢、身份查詢、處理狀態、遷移歷史、語義搜尋 |
| API Demo - 展示 | `page-api-demo-display.php` | 展示 | 檔案詳情儀表板、身份視覺化、片段展示、分類結果 |
| API Demo - 操作 | `page-api-demo-operation.php` | 操作 | 檔案註冊、身份綁定、處理觸發、身份合併、處理器重試 |
| API Demo - 應用 | `page-api-demo-application.php` | 應用 | 完整工作流程、身份追蹤、遷移示範、批次處理、語義搜尋工作流 |
---
## 檔案位置
| 類型 | 路徑 | 說明 |
|------|------|------|
| 查詢頁面 | `/wp-content/themes/momentry/page-api-demo-query.php` | WordPress 頁面模板 |
| 展示頁面 | `/wp-content/themes/momentry/page-api-demo-display.php` | WordPress 頁面模板 |
| 操作頁面 | `/wp-content/themes/momentry/page-api-demo-operation.php` | WordPress 頁面模板 |
| 應用頁面 | `/wp-content/themes/momentry/page-api-demo-application.php` | WordPress 頁面模板 |
| 共用樣式 | `/wp-content/themes/momentry/style.css` | CSS 樣式表 |
| 設定說明 | `/wp-content/themes/momentry/API_DEMO_README.md` | 技術設定文件 |
---
## 環境需求
| 項目 | 狀態 | 說明 |
|------|------|------|
| WordPress | ✅ 已安裝 | 本地 WordPress 環境 |
| Momentry Theme | ✅ 已安裝 | 自定義 momentry 主題 |
| PostgreSQL | ✅ 已安裝 | Momentry Core 資料庫 |
| Momentry Playground | 🔄 需啟動 | 開發伺服器 (port 3003) |
---
## 設定步驟
### Step 1: 啟動 Momentry Playground
API Demo 頁面需要連線到 Momentry Playground API server
```bash
cd /Users/accusys/momentry_core_0.1
cargo run --bin momentry_playground -- server --host 0.0.0.0 --port 3003
```
驗證伺服器啟動:
```bash
curl http://localhost:3003/api/v1/health
```
### Step 2: 在 WordPress 建立頁面
1. 進入 WordPress 後台:`http://localhost/wp-admin`
2. 點擊 **Pages > Add New**
3. 建立以下四個頁面:
| 頁面標題 | URL Slug | Template |
|----------|----------|----------|
| API Demo - 查詢 | `api-demo-query` | API Demo - 查詢 |
| API Demo - 展示 | `api-demo-display` | API Demo - 展示 |
| API Demo - 操作 | `api-demo-operation` | API Demo - 操作 |
| API Demo - 應用 | `api-demo-application` | API Demo - 應用 |
1. 建立時,在右側 **Page Attributes** 選擇對應的 **Template**
2. 點擊 **Publish**
### Step 3: 訪問示範頁面
| 頁面 | URL |
|------|-----|
| 查詢 | `http://localhost/api-demo-query/` |
| 展示 | `http://localhost/api-demo-display/` |
| 操作 | `http://localhost/api-demo-operation/` |
| 應用 | `http://localhost/api-demo-application/` |
---
## 頁面功能詳解
### 1. 查詢頁面 (Query)
查詢頁面用於示範各類資料查詢 API 的使用方式。
#### 1.1 檔案查詢 (GET /api/v1/files/:uuid)
- **用途**:透過 file_uuid 查詢檔案的完整資訊
- **操作**:輸入 file_uuid點擊「查詢」
- **回應**:檔案元數據、處理狀態、分類標籤等
#### 1.2 身份查詢 (GET /api/v1/identities/:uuid)
- **用途**:查詢跨檔案的全域身份資訊
- **操作**:輸入 identity_uuid點擊「查詢」
- **回應**:身份名稱、關聯檔案、臉部特徵、品質分數
#### 1.3 處理狀態查詢 (GET /api/v1/jobs/:uuid/status)
- **用途**:查詢檔案的處理進度與各處理器狀態
- **操作**:輸入 file_uuid點擊「查詢」
- **回應**:處理進度百分比、已完成/失敗的處理器列表
#### 1.4 檔案遷移歷史 (GET /api/v1/files/:uuid/history)
- **用途**:查詢檔案因移動而產生的身份變更鏈
- **操作**:輸入 file_uuid點擊「查詢」
- **回應**parent_uuid 關聯鏈、遷移時間記錄
#### 1.5 語義搜尋 (POST /api/v1/search)
- **用途**:使用自然語言搜尋相關的影片片段或身份
- **操作**:輸入搜尋查詢,選擇搜尋類型,點擊「搜尋」
- **回應**:搜尋結果列表、相似度分數
---
### 2. 展示頁面 (Display)
展示頁面用於示範如何將 API 資料轉化為視覺化的展示元件。
#### 2.1 檔案詳情儀表板
- **用途**:整合展示檔案的元數據、處理進度、分類標籤等完整資訊
- **操作**:輸入 file_uuid點擊「載入」
- **展示內容**
- 基本資訊:檔案名稱、類型、時長、解析度、幀率
- 處理狀態:狀態徽章、處理進度、已完成處理器
- 分類標籤:分類標籤、語義標籤
- 關聯身份:檢測到身份數量、主要身份
#### 2.2 身份視覺化
- **用途**:展示身份的跨檔案關聯、臉部檢測統計、品質分數
- **操作**:輸入 identity_uuid點擊「視覺化」
- **展示內容**
- 身份名稱與品質分數
- 關聯檔案列表
- 臉部統計 (檢測次數、平均品質)
- 角度覆蓋視覺化
#### 2.3 影片片段展示
- **用途**:展示影片的語義片段、說話者分段、鏡頭切換等分類結果
- **操作**:輸入 file_uuid選擇片段類型點擊「載入片段」
- **片段類型**:語義片段、鏡頭切換、時間片段
#### 2.4 分類結果展示
- **用途**:展示 YOLO 檢測、姿勢估計、動作識別等視覺分類結果
- **操作**:輸入 file_uuid選擇處理器類型點擊「載入結果」
- **處理器類型**YOLO、Pose、Face、OCR
---
### 3. 操作頁面 (Operation)
操作頁面用於示範各類寫入與修改 API 的實際使用。
#### 3.1 檔案註冊 (POST /api/v1/register)
- **用途**:將新影片或音訊檔案註冊到系統
- **操作**:輸入檔案路徑,點擊「註冊」
- **快速測試**:提供預設測試路徑按鈕
#### 3.2 身份綁定 (POST /api/v1/identities/bind)
- **用途**:將臉部檢測綁定到特定身份
- **操作**:輸入 Face ID 和 Identity UUID點擊「綁定」
#### 3.3 處理觸發 (POST /api/v1/files/:uuid/process)
- **用途**:手動觸發檔案的處理流程
- **操作**:輸入 file_uuid選擇要執行的處理器 (ASR、YOLO、Face、OCR、Pose、CUT),點擊「觸發處理」
#### 3.4 身份合併 (POST /api/v1/identities/merge)
- **用途**:將多個身份合併為單一身份
- **操作**:輸入目標 Identity UUID 和來源 Identity UUIDs (逗號分隔),點擊「合併」
#### 3.5 處理器重試 (POST /api/v1/jobs/:uuid/retry)
- **用途**:重試失敗的處理器
- **操作**:輸入 file_uuid選擇要重試的處理器點擊「重試」
---
### 4. 應用頁面 (Application)
應用頁面示範結合多個 API 的實際應用場景與工作流程。
#### 4.1 完整工作流程示範
端到端展示從檔案註冊到處理完成的完整流程:
| 步驟 | 操作 | 說明 |
|------|------|------|
| 1 | 註冊檔案 | 輸入影片路徑,呼叫 `/register` |
| 2 | 查詢處理狀態 | 定期檢查 `/jobs/:uuid/status` 直到完成 |
| 3 | 查詢檢測結果 | 取得身份和片段資訊 |
| 4 | 搜尋身份 | 展示檔案中檢測到的身份列表 |
每步完成後自動解鎖下一步,狀態以顏色標示 (等待中/執行中/完成)。
#### 4.2 跨檔案身份追蹤
- **用途**:追蹤特定身份在所有檔案中的出現情況
- **操作**:輸入 Identity UUID點擊「開始追蹤」
- **展示內容**
- 身份名稱與關聯檔案數量
- 時間軸展示各檔案中的出現記錄
- 統計資訊 (總檢測次數、平均品質、覆蓋角度)
#### 4.3 檔案遷移與身份繼承示範
展示 Birth/Migration 模型的實際運作:
| 步驟 | 操作 | 說明 |
|------|------|------|
| 1 | 原始註冊 | 註冊原始路徑的檔案 |
| 2 | 模擬移動 | 使用新路徑重新註冊,系統產生新的 file_uuid |
| 3 | 查詢歷史 | 透過 `/files/:uuid/history` 查看遷移鏈 |
#### 4.4 批次檔案處理
- **用途**:一次註冊多個檔案,監控批次處理進度
- **操作**:輸入多個檔案路徑 (每行一個),點擊「批次註冊」
- **展示內容**:進度條、每個檔案的註冊結果
#### 4.5 語義搜尋與片段提取工作流
- **用途**:使用語義搜尋找到相關片段,然後提取詳細資訊
- **操作**:輸入自然語言查詢,點擊「搜尋」
- **展示內容**:搜尋結果摘要、詳細片段列表 (含相似度分數)
---
## API 端點參考
### 查詢類 API
| 端點 | 方法 | 說明 |
|------|------|------|
| `/api/v1/files/:uuid` | GET | 查詢檔案詳細資訊 |
| `/api/v1/files` | GET | 查詢檔案列表 |
| `/api/v1/identities/:uuid` | GET | 查詢身份資訊 |
| `/api/v1/jobs/:uuid/status` | GET | 查詢處理狀態 |
| `/api/v1/files/:uuid/history` | GET | 查詢遷移歷史 |
| `/api/v1/search` | POST | 語義搜尋 |
### 操作類 API
| 端點 | 方法 | 說明 |
|------|------|------|
| `/api/v1/register` | POST | 註冊檔案 |
| `/api/v1/identities/bind` | POST | 綁定身份 |
| `/api/v1/files/:uuid/process` | POST | 觸發處理 |
| `/api/v1/identities/merge` | POST | 合併身份 |
| `/api/v1/jobs/:uuid/retry` | POST | 重試處理器 |
---
## 常見問題
### Q1: 頁面無法連線到 API
- 確認 Playground server 已啟動:`cargo run --bin momentry_playground -- server`
- 檢查 API base URL 設定 (各頁面的 `const API_BASE = 'http://localhost:3003/api/v1'`)
- 確認 CORS 設定允許來自 WordPress 的請求
### Q2: 註冊檔案時返回錯誤
- 確認檔案路徑正確且檔案存在
- 確認 PostgreSQL 資料庫連線正常
- 檢查 Playground server 日誌
### Q3: 遷移歷史查詢無結果
- 確認檔案確實有 parent_uuid 記錄
- 使用 `SELECT file_uuid, parent_uuid FROM dev.videos WHERE parent_uuid IS NOT NULL;` 檢查資料庫
---
## 常用指令
```bash
# 啟動 Playground 伺服器
cargo run --bin momentry_playground -- server --host 0.0.0.0 --port 3003
# 檢查 API 健康狀態
curl http://localhost:3003/api/v1/health
# 查詢檔案列表
curl http://localhost:3003/api/v1/files?limit=5
# 註冊檔案
curl -X POST http://localhost:3003/api/v1/register \
-H "Content-Type: application/json" \
-d '{"file_path": "/path/to/video.mp4"}'
# 查詢檔案詳情
curl http://localhost:3003/api/v1/files/<file_uuid>
# 查詢遷移歷史
curl http://localhost:3003/api/v1/files/<file_uuid>/history
```
---
## 設計理念
### File-Centric 架構
Momentry 系統採用 **file-centric** 設計理念:
| 概念 | 說明 |
|------|------|
| **File (檔案)** | 主要管理目標file_uuid 為核心識別 |
| **Identity (身份)** | 附隨目標,跨檔案關聯人員身份 |
| **Classification (分類)** | 形容主體的標籤系統 (YOLO、ASR、Face 等處理器結果) |
### Birth/Migration 模型
| 概念 | 說明 |
|------|------|
| **Birth (註冊)** | 檔案首次註冊,產生初始 file_uuid |
| **Migration (遷移)** | 檔案移動後重新註冊,產生新 file_uuid 並記錄 parent_uuid |
| **Birthday (生日)** | 原始註冊時間,遷移時保留以證明身份連續性 |
### UUID 計算公式
```
file_uuid = SHA256(MAC_Address | Birthday | Canonical_Path | Filename)[0:32]
```
---
## 版本資訊
- 版本: V1.0
- 建立日期: 2026-04-30
- 文件更新: 2026-04-30

View File

@@ -0,0 +1,682 @@
---
document_type: "reference_doc"
service: "MOMENTRY_CORE"
title: "processing_status JSONB 字段規範"
date: "2026-04-27"
version: "V1.2"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "jsonb"
- "processing_status"
- "進度追蹤"
- "processor"
- "rule"
- "agent"
ai_query_hints:
- "查詢 processing_status JSONB 字段規範的內容"
- "processing_status JSONB 結構定義"
- "如何查詢 processing_status JSONB 字段"
- "pre_chunks_summary 結構說明"
- "chunks_summary 結構說明"
- "Agent 進度追蹤字段"
- "processing_status SQL 查詢範例"
- "processing_status Rust 實作範例"
---
# processing_status JSONB 字段規範
| 項目 | 內容 |
|------|------|
| 建立者 | OpenCode |
| 建立時間 | 2026-04-27 |
| 文件版本 | V1.2 |
---
## 版本歷史
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.2 | 2026-04-27 | 從 VARCHAR 改為 JSONB支持多層級進度追蹤 | OpenCode | GLM-5 |
---
## 概述
從 V1.2 起,`videos` 表的 `processing_status` 字段改為 **JSONB** 格式,支持:
- 多處理器並行進度追蹤
- pre_chunks/chunks 絕計(按 processor 和按 rule
- Agent 任務狀態追蹤
- Rule 完成狀態記錄
---
## 當前狀態
| 項目 | 狀態 |
|------|------|
| processing_status 字段類型 | ✅ JSONB默認 `'{}'::jsonb` |
| VideoRow/VideoRecord 結構體 | ✅ `Option<serde_json::Value>` |
| init_processing_status | ✅ 已實作(初始化 JSONB |
| update_processor_progress | ✅ 已實作(更新進度) |
| update_processing_status_completed | ✅ 已實作(完成狀態) |
---
## 1. JSONB 結構定義
### 1.1 完整結構
```json
{
"phase": "PROCESSING" | "COMPLETED" | "FAILED",
"active_processors": ["ASR", "YOLO"],
"total_frames": 412343,
"processing_summary": {
"processors_completed": ["asr", "cut", "yolo", "ocr", "face", "pose"],
"processors_failed": [],
"processors_pending": [],
"duration_secs": {
"asr": 607.4,
"yolo": 1200.5
}
},
"pre_chunks_summary": {
"total_records": 25000,
"by_processor": {
"asr": {
"records": 1466,
"coverage_type": "time-based",
"avg_segment_length": 4.7
},
"cut": {
"records": 1332,
"coverage_type": "time-based"
},
"yolo": {
"records": 11000,
"coverage_type": "frame-based",
"unique_frames": 412343,
"coverage_pct": 100.0
},
"ocr": {
"records": 8000,
"coverage_type": "frame-based",
"unique_frames": 350000,
"coverage_pct": 84.8
},
"face": {
"records": 5000,
"coverage_type": "frame-based",
"unique_frames": 250000,
"coverage_pct": 60.7
},
"pose": {
"records": 6000,
"coverage_type": "frame-based",
"unique_frames": 300000,
"coverage_pct": 72.9
}
},
"frame_coverage": {
"processors_with_full_coverage": ["yolo"],
"processors_with_partial_coverage": ["ocr", "face", "pose"]
}
},
"chunks_summary": {
"total_chunks": 2798,
"total_frames_in_chunks": 1260754,
"by_rule": {
"rule_1": {
"triggered": true,
"chunks_count": 1466,
"chunk_type": "sentence",
"source": "pre_chunks(asr + asrx + yolo + face)",
"metadata_enriched": true
},
"rule_3": {
"triggered": true,
"chunks_count": 1332,
"chunk_type": "scene",
"source": "pre_chunks(cut) + chunks_rule1",
"scenes_created": 1332
}
},
"by_type": {
"sentence": 1466,
"scene": 1332,
"time": 688
}
},
"agents": {
"5w1h": {
"status": "running" | "completed" | "pending" | "failed",
"scenes_processed": 5,
"scenes_total": 1332,
"progress_pct": 0.4,
"started_at": "2026-04-27T05:45:00Z",
"updated_at": "2026-04-27T05:46:00Z",
"model": "gemma4",
"avg_duration_per_scene": 1.2
},
"translation": {
"status": "pending"
}
},
"vectorization_summary": {
"rule_1_vectors": 1466,
"rule_3_vectors": 1332,
"total_vectors": 2798,
"vector_model": "nomic-embed-text-v2-moe:latest",
"collection": "momentry_rule1"
},
"progress": {
"ASR": {
"current_frame": 1466,
"total_frames": 412343,
"percentage": 0.4,
"status": "completed",
"started_at": "2026-04-27T05:30:00Z",
"completed_at": "2026-04-27T05:40:00Z"
},
"YOLO": {
"current_frame": 412343,
"total_frames": 412343,
"percentage": 100.0,
"status": "completed",
"started_at": "2026-04-27T05:40:00Z",
"completed_at": "2026-04-27T06:00:00Z"
}
}
}
```
---
### 1.2 簡化結構(處理中)
```json
{
"phase": "PROCESSING",
"active_processors": ["YOLO", "OCR"],
"total_frames": 412343,
"pre_chunks_summary": {
"total_records": 0,
"by_processor": {}
},
"chunks_summary": {
"total_chunks": 0,
"by_rule": {}
},
"agents": {},
"progress": {
"YOLO": {
"current_frame": 25000,
"total_frames": 412343,
"percentage": 6.0,
"status": "running"
},
"OCR": {
"current_frame": 0,
"total_frames": 412343,
"percentage": 0,
"status": "pending"
}
}
}
```
---
### 1.3 結構(完成狀態)
```json
{
"phase": "COMPLETED",
"active_processors": [],
"total_frames": 412343,
"processing_summary": {
"processors_completed": ["asr", "cut", "yolo", "ocr", "face", "pose"],
"processors_failed": [],
"processors_pending": []
},
"pre_chunks_summary": {
"total_records": 25000,
"by_processor": {
"asr": {"records": 1466},
"cut": {"records": 1332},
"yolo": {"records": 11000}
}
},
"chunks_summary": {
"total_chunks": 2798,
"by_rule": {
"rule_1": {"triggered": true, "chunks_count": 1466},
"rule_3": {"triggered": true, "chunks_count": 1332}
}
},
"agents": {
"5w1h": {"status": "completed"}
}
}
```
---
## 2. 字段說明
### 2.1 phase階段
| 值 | 說明 | 適用場景 |
|------|------|----------|
| `PROCESSING` | 正在處理 | 處理器/Rule/Agent 執行中 |
| `COMPLETED` | 完成 | 所有處理完成 |
| `FAILED` | 失敗 | 有處理器失敗 |
---
### 2.2 active_processors
**說明**: 正在執行的處理器列表(大寫)。
**範例**:
```json
["ASR", "YOLO", "OCR"]
```
---
### 2.3 processing_summary
**說明**: 處理器完成狀態總覽。
| 字段 | 類型 | 說明 |
|------|------|------|
| `processors_completed` | Array[String] | 已完成的處理器(小寫) |
| `processors_failed` | Array[String] | 失敗的處理器 |
| `processors_pending` | Array[String] | 等待中的處理器 |
| `duration_secs` | Object | 各處理器執行秒數 |
---
### 2.4 pre_chunks_summary
**說明**: 絕計 `pre_chunks` 表的數據(按處理器)。
#### 2.4.1 by_processor 字段
| 字段 | 類型 | 說明 | 適用處理器 |
|------|------|------|------------|
| `records` | Integer | 處理器產生的記錄數 | 所有 |
| `coverage_type` | String | `time-based``frame-based` | 所有 |
| `avg_segment_length` | Float | 平均段落長度(秒) | ASR |
| `unique_frames` | Integer | 唯一帧數 | YOLO/OCR/Face/Pose |
| `coverage_pct` | Float | 覆盖率百分比 | YOLO/OCR/Face/Pose |
#### 2.4.2 coverage_type 說明
| 處理器 | coverage_type | 說明 |
|------|---------------|------|
| ASR | `time-based` | 時間段落start_time → end_time |
| CUT | `time-based` | 時間段落cut_time |
| YOLO | `frame-based` | 單帧檢測結果 |
| OCR | `frame-based` | 單帧 OCR 文字 |
| Face | `frame-based` | 單帧人臉檢測 |
| Pose | `frame-based` | 單帧姿態估計 |
---
### 2.5 chunks_summary
**說明**: 絕計 `chunks` 表的數據(按 Rule
#### 2.5.1 by_rule 字段
| 字段 | 類型 | 說明 |
|------|------|------|
| `triggered` | Boolean | Rule 是否觸發 |
| `chunks_count` | Integer | Rule 產生的 chunks 數 |
| `chunk_type` | String | Chunk 類型sentence/scene/time |
| `source` | String | Rule 數據源描述 |
| `metadata_enriched` | Boolean | 是否包含 YOLO/Face metadata |
#### 2.5.2 by_type 字段
| chunk_type | 說明 | 來源 Rule |
|------------|------|-----------|
| `sentence` | 語句 Chunk | Rule 1ASR + metadata |
| `scene` | 場景 Chunk | Rule 3CUT + Rule 1 |
| `time` | 時間 Chunk | Rule 5時間分段 |
---
### 2.6 agents
**說明**: Agent 任務狀態。
| 字段 | 類型 | 說明 |
|------|------|------|
| `status` | String | `pending` / `running` / `completed` / `failed` |
| `scenes_processed` | Integer | 已處理場景數 |
| `scenes_total` | Integer | 總場景數 |
| `progress_pct` | Float | 進度百分比 |
| `started_at` | String | 開始時間ISO 8601 |
| `updated_at` | String | 更新時間ISO 8601 |
| `model` | String | 使用模型gemma4 |
| `avg_duration_per_scene` | Float | 平均處理時間(秒) |
---
### 2.7 vectorization_summary
**說明**: 向量化統計。
| 字段 | 類型 | 說明 |
|------|------|------|
| `rule_1_vectors` | Integer | Rule 1 向量數 |
| `rule_3_vectors` | Integer | Rule 3 向量數 |
| `total_vectors` | Integer | 總向量數 |
| `vector_model` | String | 向量模型名稱 |
| `collection` | String | Qdrant Collection 名稱 |
---
### 2.8 progress
**說明**: 各處理器詳細進度。
| 字段 | 類型 | 說明 |
|------|------|------|
| `current_frame` | Integer | 當前處理帧數 |
| `total_frames` | Integer | 總帧數 |
| `percentage` | Float | 進度百分比 |
| `status` | String | `pending` / `running` / `completed` / `failed` |
| `started_at` | String | 開始時間ISO 8601 |
| `completed_at` | String | 完成時間ISO 8601 |
---
## 3. SQL 查詢範例
### 3.1 基本查詢
```sql
-- 取得處理狀態
SELECT
uuid,
processing_status->>'phase' as phase,
processing_status->'active_processors' as active_processors,
processing_status->'pre_chunks_summary'->>'total_records' as pre_chunks_count,
processing_status->'chunks_summary'->>'total_chunks' as chunks_count,
processing_status->'agents'->'5w1h'->>'status' as agent_5w1h_status
FROM videos
WHERE uuid = '384b0ff44aaaa1f14cb2cd63b3fea966';
```
---
### 3.2 更新進度
```sql
-- 更新處理器進度
UPDATE videos
SET processing_status = jsonb_set(
processing_status,
'{progress,YOLO}',
'{"current_frame": 25000, "percentage": 6.0, "status": "running"}'::jsonb
)
WHERE uuid = '384b0ff44aaaa1f14cb2cd63b3fea966';
-- 添加 Agent 狀態
UPDATE videos
SET processing_status = jsonb_set(
processing_status,
'{agents,5w1h}',
'{"status": "running", "scenes_processed": 5}'::jsonb
)
WHERE uuid = '384b0ff44aaaa1f14cb2cd63b3fea966';
```
---
### 3.3 絕計查詢
```sql
-- 查詢 pre_chunks 按處理器絕計
SELECT
uuid,
processing_status->'pre_chunks_summary'->'by_processor'->'yolo'->>'records' as yolo_records,
processing_status->'pre_chunks_summary'->'by_processor'->'yolo'->>'coverage_pct' as yolo_coverage
FROM videos
WHERE processing_status->>'phase' = 'COMPLETED';
-- 查詢 chunks 按 Rule 絕計
SELECT
uuid,
processing_status->'chunks_summary'->'by_rule'->'rule_1'->>'chunks_count' as rule1_chunks,
processing_status->'chunks_summary'->'by_rule'->'rule_3'->>'chunks_count' as rule3_chunks
FROM videos
WHERE processing_status->>'phase' = 'COMPLETED';
```
---
### 3.4 查詢 Agent 進度
```sql
-- 查詢 5W1H Agent 進度
SELECT
uuid,
processing_status->'agents'->'5w1h'->>'status' as status,
processing_status->'agents'->'5w1h'->>'scenes_processed' as processed,
processing_status->'agents'->'5w1h'->>'scenes_total' as total,
processing_status->'agents'->'5w1h'->>'progress_pct' as progress
FROM videos
WHERE processing_status->'agents'->'5w1h'->>'status' = 'running';
```
---
## 4. Rust 實作範例
### 4.1 初始化 processing_status
```rust
pub async fn init_processing_status(
&self,
uuid: &str,
processors: Vec<&str>,
total_frames: u64,
) -> Result<()> {
let progress: serde_json::Map<String, serde_json::Value> = processors
.iter()
.map(|p| {
(p.to_uppercase(), serde_json::json!({
"current_frame": 0,
"total_frames": total_frames,
"percentage": 0,
"status": "pending"
}))
})
.collect();
let status = serde_json::json!({
"phase": "PROCESSING",
"active_processors": processors.iter().map(|p| p.to_uppercase()).collect::<Vec<_>>(),
"total_frames": total_frames,
"processing_summary": {
"processors_completed": [],
"processors_failed": [],
"processors_pending": processors.iter().map(|p| p.to_lowercase()).collect::<Vec<_>>()
},
"pre_chunks_summary": {
"total_records": 0,
"by_processor": {}
},
"chunks_summary": {
"total_chunks": 0,
"by_rule": {}
},
"agents": {},
"progress": progress
});
sqlx::query(&format!(
"UPDATE {} SET processing_status = $1 WHERE uuid = $2",
schema::table_name("videos")
))
.bind(&status)
.bind(uuid)
.execute(&self.pool)
.await?;
Ok(())
}
```
---
### 4.2 更新處理器進度
```rust
pub async fn update_processor_progress(
&self,
uuid: &str,
processor: &str,
current_frame: u64,
total_frames: u64,
status: &str,
) -> Result<()> {
let processor_key = processor.to_uppercase();
let percentage = if total_frames > 0 {
((current_frame as f64 / total_frames as f64) * 100.0).round() as u32
} else {
0
};
let progress_update = serde_json::json!({
"current_frame": current_frame,
"total_frames": total_frames,
"percentage": percentage,
"status": status
});
sqlx::query(&format!(
"UPDATE {} SET processing_status = jsonb_set(
processing_status,
'{{progress,{}}}',
$1::jsonb
) WHERE uuid = $2",
schema::table_name("videos"),
processor_key
))
.bind(&progress_update)
.bind(uuid)
.execute(&self.pool)
.await?;
Ok(())
}
```
---
### 4.3 更新完成狀態
詳見 `src/core/db/postgres_db.rs:update_processing_status_completed()`
---
## 5. 版本對照
### 5.1 V1.0VARCHARvs V1.2JSONB
| 項目 | V1.0VARCHAR | V1.2JSONB |
|------|-----------------|---------------|
| 字段類型 | VARCHAR(50) | JSONB |
| 默認值 | `'REGISTERED'` | `'{}'::jsonb` |
| 狀態表示 | 單一狀態字串 | 多層級結構 |
| 處理器進度 | ❌ 不支持 | ✅ 支持progress 字段) |
| Agent 狀態 | ❌ 不支持 | ✅ 支持agents 字段) |
| pre_chunks/chunks 絕計 | ❌ 不支持 | ✅ 支持 |
| Rule 絕計 | ❌ 不支持 | ✅ 支持 |
---
### 5.2 遷移步驟
```sql
-- Step 1: 修改字段類型
ALTER TABLE videos
ALTER COLUMN processing_status TYPE JSONB
USCASE processing_status::text::jsonb;
-- Step 2: 設置默認值
ALTER TABLE videos
ALTER COLUMN processing_status SET DEFAULT '{}'::jsonb;
-- Step 3: 初始化現有記錄(可選)
UPDATE videos
SET processing_status = '{"phase": "COMPLETED"}'::jsonb
WHERE processing_status IS NULL OR processing_status = '{}'::jsonb;
```
---
## 6. 相關文件
| 文件 | 說明 |
|------|------|
| `JOB_WORKER_IMPLEMENTATION_PLAN.md` | Worker 實作計畫B.1.2 JSONB 章節) |
| `VIDEO_PROCESSING_SPEC.md` | Video 解析行為規範SQL 映射) |
| `PROCESSING_PIPELINE.md` | Pipeline 狀態追蹤 |
| `AGENT_SPEC.md` | Agent 設計規範Agent 進度追蹤) |
---
## 7. 檔案位置
| 類型 | 路徑 | 說明 |
|------|------|------|
| Rust 實作 | `src/core/db/postgres_db.rs` | processing_status 相關函數 |
| VideoRow 結構體 | `src/core/db/postgres_db.rs` | `processing_status: Option<serde_json::Value>` |
| VideoRecord 結構體 | `src/core/db/video.rs` | `processing_status: Option<serde_json::Value>` |
---
## 8. 常用指令
### 8.1 查詢處理狀態
```bash
# 查詢 UUID 的處理狀態
psql -d momentry -c "SELECT uuid, processing_status->>'phase' FROM videos WHERE uuid = '384b0ff44aaaa1f14cb2cd63b3fea966';"
# 查詢所有處理中的視頻
psql -d momentry -c "SELECT uuid, processing_status->'active_processors' FROM videos WHERE processing_status->>'phase' = 'PROCESSING';"
```
---
### 8.2 更新 JSONB 字段
```bash
# 更新處理器進度(範例)
psql -d momentry -c "UPDATE videos SET processing_status = jsonb_set(processing_status, '{progress,ASR}', '{\"percentage\": 50}'::jsonb) WHERE uuid = '384b0ff44aaaa1f14cb2cd63b3fea966';"
```
---
## 版本資訊
- 版本: V1.2
- 建立日期: 2026-04-27
- 文件更新: 2026-04-27

View File

@@ -2,18 +2,20 @@
document_type: "reference_doc"
service: "MOMENTRY_CORE"
title: "Video 解析行為規範"
date: "2026-03-16"
version: "V1.0"
date: "2026-04-27"
version: "V1.1"
status: "active"
owner: "Warren"
created_by: "OpenCode"
tags:
- "解析行為規範"
- "video"
- "processing_status"
ai_query_hints:
- "查詢 Video 解析行為規範 的內容"
- "Video 解析行為規範 的主要目的是什麼?"
- "如何操作或實施 Video 解析行為規範?"
- "processing_status 字段的 SQL 映射"
---
# Video 解析行為規範
@@ -22,7 +24,7 @@ ai_query_hints:
|------|------|
| 建立者 | Warren |
| 建立時間 | 2026-03-16 |
| 文件版本 | V1.0 |
| 文件版本 | V1.1 |
---
@@ -31,6 +33,7 @@ ai_query_hints:
| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-03-16 | 創建文件 | Warren | OpenCode / MiniMax M2.5 |
| V1.1 | 2026-04-27 | 添加 processing_status 字段 SQL 映射說明 | OpenCode | GLM-5 |
---
@@ -136,6 +139,91 @@ pub enum ProcessStatus {
}
```
#### 2.1.1 SQL 映射說明
ProcessStatus enum 映射到 PostgreSQL `videos` 表的 `processing_status` 字段:
| Rust Enum | SQL 值 | 說明 |
|-----------|--------|------|
| `Pending` | `'PENDING'` | 等待處理(觸發後狀態) |
| `Registered` | `'REGISTERED'` | 已註冊(註冊後狀態) |
| `Probing` | `'PROBING'` | 探測中ffprobe 分析) |
| `AsrProcessing` | `'ASR'` | ASR 處理中 |
| `AsrxProcessing` | `'ASRX'` | 說話者分離中 |
| `OcrProcessing` | `'OCR'` | OCR 處理中 |
| `YoloProcessing` | `'YOLO'` | YOLO 物體檢測中 |
| `FaceProcessing` | `'FACE'` | 人臉偵測中 |
| `PoseProcessing` | `'POSE'` | 姿態估計中 |
| `Chunking` | `'CUT'` | 分塊處理中 |
| `Completed` | `'COMPLETED'` | 完成 |
| `Failed` | `'FAILED'` | 失敗 |
| `Paused` | `'PAUSED'` | 暫停 |
| `Resuming` | `'RESUMING'` | 恢復中 |
#### 2.1.2 SQL 約束
```sql
ALTER TABLE videos
ADD CONSTRAINT videos_processing_status_check
CHECK (
processing_status IS NULL OR
processing_status IN ('REGISTERED', 'PENDING', 'PROBING', 'ASR', 'OCR', 'YOLO', 'FACE', 'POSE', 'CUT', 'ASRX', 'COMPLETED', 'FAILED', 'PAUSED', 'RESUMING')
);
```
#### 2.1.3 與 status 字段的關係
`processing_status` 字段與 `status` 字段協同工作:
| status | processing_status | 說明 |
|--------|-------------------|------|
| `pending` | `REGISTERED` | 新註冊的視頻,尚未觸發處理 |
| `processing` | `PENDING` | 已觸發處理,等待作業分配 |
| `processing` | `PROBING` | ffprobe 分析中 |
| `processing` | `ASR`/`OCR`/`YOLO`... | 各處理器作業執行中 |
| `completed` | `COMPLETED` | 所有處理完成 |
| `failed` | `FAILED` | 處理失敗 |
Portal 顯示優先使用 `processing_status`詳細狀態Fallback 使用 `status`(基本狀態)。
#### 2.1.4 processing_status JSONB 映射說明V1.2 起)
從 V1.2 起,`processing_status` 改為 **JSONB** 格式,詳見 `REFERENCE/PROCESSING_STATUS_JSONB_SPEC.md`
##### JSONB 字段映射
| PostgreSQL 字段 | JSONB 路徑 | 說明 |
|-----------------|-----------|------|
| `phase` | `processing_status->>'phase'` | 當前階段(對應舊版 VARCHAR |
| `active_processors` | `processing_status->'active_processors'` | 正在執行的處理器 |
| `pre_chunks_count` | `processing_status->'pre_chunks_summary'->>'total_records'` | pre_chunks 總數 |
| `chunks_count` | `processing_status->'chunks_summary'->>'total_chunks'` | chunks 總數 |
| `agent_status` | `processing_status->'agents'->'5w1h'->>'status'` | Agent 狀態 |
##### SQL 查詢範例
```sql
-- 取得處理狀態
SELECT
uuid,
processing_status->>'phase' as phase,
processing_status->'active_processors' as active,
processing_status->'pre_chunks_summary'->>'total_records' as pre_chunks_count,
processing_status->'chunks_summary'->>'total_chunks' as chunks_count
FROM videos WHERE uuid = '384b0ff44aaaa1f14cb2cd63b3fea966';
-- 更新處理器進度
UPDATE videos
SET processing_status = jsonb_set(
processing_status,
'{progress,ASR}',
'{"current_frame": 500, "percentage": 12}'::jsonb
)
WHERE uuid = '384b0ff44aaaa1f14cb2cd63b3fea966';
```
---
### 2.2 狀態輸出格式
#### 2.2.1 標準輸出 (stdout)