diff --git a/docs_v1.0/doc/02_health.html b/docs_v1.0/doc/02_health.html
index 0ed4b92..99073f4 100644
--- a/docs_v1.0/doc/02_health.html
+++ b/docs_v1.0/doc/02_health.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
@@ -223,12 +229,73 @@ a { color: #0066cc; }
Identity file count matches DB count |
+config |
+object |
+Runtime toggle states (cache, auto-pipeline, watcher) |
+
+
integrations.tmdb |
object |
TMDB API key config and reachability |
+
GET /health/consistency
+
Auth: Required
+Scope: system-level
+
Scans the database for data consistency issues. Reports anomalies without modifying any data.
+
Example
+
curl -s "$API/health/consistency" -H "X-API-Key: $KEY" | jq '.checks[] | {check, severity, count}'
+
+
+
Response (200)
+
{
+ "status": "degraded",
+ "checked_at": "2026-05-18T17:30:00Z",
+ "checks": [
+ {
+ "check": "stale_processing",
+ "severity": "warn",
+ "count": 3,
+ "files": [
+ {"file_name": "video.mp4", "file_uuid": "abc123...", "status": "processing", "detail": "job_id is null"}
+ ]
+ }
+ ]
+}
+
+
+
+
+
+| Check |
+Description |
+Severity |
+
+
+
+
+stale_processing |
+Status=processing but job_id is null |
+warn |
+
+
+orphaned_processing |
+Status=processing but no active monitor_job |
+warn |
+
+
+processing_job_done |
+Status=processing but job already completed |
+warn |
+
+
+unregistered_with_uuid |
+Status=unregistered but row still in DB (migration residue) |
+info |
+
+
+
Health status rules
diff --git a/docs_v1.0/doc/03_register.html b/docs_v1.0/doc/03_register.html
index 8e211ba..afc7a0f 100644
--- a/docs_v1.0/doc/03_register.html
+++ b/docs_v1.0/doc/03_register.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
@@ -34,7 +40,8 @@ a { color: #0066cc; }
Auth: Required
Scope: file-level
Register a video file for processing. Returns the file's metadata and UUID.
-
New in v0.1.2: Registration now automatically triggers the processing pipeline — no need to call POST /api/v1/file/:file_uuid/process separately. The system will:
+
Registration can automatically trigger the processing pipeline if the
+auto-pipeline toggle is enabled (disabled by default). The system will:
1. Register the file and run ffprobe
2. Auto-run offline TMDb probe (reads local identity files, no API calls)
3. Create a monitor job for the worker
diff --git a/docs_v1.0/doc/04_lookup.html b/docs_v1.0/doc/04_lookup.html
index 1ce9106..f1e58e7 100644
--- a/docs_v1.0/doc/04_lookup.html
+++ b/docs_v1.0/doc/04_lookup.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
diff --git a/docs_v1.0/doc/05_process.html b/docs_v1.0/doc/05_process.html
index 69cba53..ae1a491 100644
--- a/docs_v1.0/doc/05_process.html
+++ b/docs_v1.0/doc/05_process.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
diff --git a/docs_v1.0/doc/06_search.html b/docs_v1.0/doc/06_search.html
index 9843461..7646532 100644
--- a/docs_v1.0/doc/06_search.html
+++ b/docs_v1.0/doc/06_search.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
@@ -47,7 +53,7 @@ a { color: #0066cc; }
-uuid |
+file_uuid |
string |
Yes |
— |
@@ -61,6 +67,13 @@ a { color: #0066cc; }
Search text |
+limit |
+integer |
+No |
+5 |
+Max results to return |
+
+
page |
integer |
No |
@@ -80,7 +93,7 @@ a { color: #0066cc; }
curl -s -X POST "$API/api/v1/search/smart" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JWT" \
- -d '{"uuid": "'"$FILE_UUID"'", "query": "Audrey Hepburn"}'
+ -d '{"file_uuid": "'"$FILE_UUID"'", "query": "Audrey Hepburn"}'
Response (200)
@@ -88,13 +101,19 @@ a { color: #0066cc; }
"query": "Audrey Hepburn",
"results": [
{
- "parent_id": 12345,
- "start_time": 299.0,
- "end_time": 300.0,
- "summary": "[299s-300s, 1s] Cast: Audrey Hepburn. Total: 1 lines, 5 words...",
- "similarity": 0.72
+ "parent_id": 1087822,
+ "scene_order": 1087822,
+ "start_frame": 104438,
+ "end_frame": 104538,
+ "fps": 24.0,
+ "start_time": 4351.6,
+ "end_time": 4355.76,
+ "summary": "[4352s-4356s, 4s] Cast: Audrey Hepburn. Total: 2 lines, 10 words. Speakers: Audrey Hepburn (2 lines)",
+ "similarity": 0.67
}
],
+ "page": 1,
+ "page_size": 5,
"strategy": "semantic_vector_search"
}
@@ -124,7 +143,7 @@ a { color: #0066cc; }
Search text |
-uuid |
+file_uuid |
string |
No |
— |
@@ -138,6 +157,13 @@ a { color: #0066cc; }
Search types |
+limit |
+integer |
+No |
+10 |
+Max results per type |
+
+
page |
integer |
No |
@@ -157,7 +183,7 @@ a { color: #0066cc; }
curl -s -X POST "$API/api/v1/search/universal" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $JWT" \
- -d '{"uuid": "'"$FILE_UUID"'", "query": "Cary Grant"}'
+ -d '{"file_uuid": "'"$FILE_UUID"'", "query": "Cary Grant"}'
Response (200)
@@ -165,11 +191,13 @@ a { color: #0066cc; }
"results": [
{
"type": "chunk",
- "chunk_id": "uuid_1429",
+ "chunk_id": "bd80fec92b0b6963d177a2c55bf713e2_2",
"chunk_type": "story_child",
- "start_time": 429.16,
- "end_time": 430.5,
- "text": "You could have the stamps.",
+ "start_frame": 5103,
+ "end_frame": 5127,
+ "start_time": 212.64,
+ "end_time": 213.64,
+ "text": "[213s-214s] Cary Grant: \"Olá!\"",
"score": 0.9
}
],
diff --git a/docs_v1.0/doc/07_identity.html b/docs_v1.0/doc/07_identity.html
index fd24783..b8e58b5 100644
--- a/docs_v1.0/doc/07_identity.html
+++ b/docs_v1.0/doc/07_identity.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
@@ -56,7 +62,7 @@ a { color: #0066cc; }
"source": "tmdb",
"status": "confirmed",
"tmdb_id": 112,
-
"tmdb_profile": "https://image.tmdb.org/t/p/w185/abc.jpg",
+
"tmdb_profile": "{output}/identities/{identity_uuid}/profile.jpg",
"metadata": {},
"reference_data": {},
"created_at": "2026-05-16T12:00:00Z",
@@ -106,7 +112,7 @@ a { color: #0066cc; }
tmdb_profile |
string |
-TMDb profile image URL |
+Local profile image path ({output}/identities/{uuid}/profile.jpg) |
metadata |
@@ -183,6 +189,27 @@ a { color: #0066cc; }
curl -s "$API/api/v1/identity/$IDENTITY_UUID/chunks" -H "X-API-Key: $KEY"
+Response (200)
+{
+ "success": true,
+ "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4",
+ "data": [
+ {
+ "id": 0,
+ "file_uuid": "bd80fec92b0b6963d177a2c55bf713e2",
+ "chunk_id": "bd80fec92b0b6963d177a2c55bf713e2_2",
+ "chunk_type": "sentence",
+ "start_frame": 5103,
+ "end_frame": 5127,
+ "fps": 24.0,
+ "start_time": 212.64,
+ "end_time": 213.64,
+ "text_content": "[213s-214s] Cary Grant: \"Olá!\""
+ }
+ ]
+}
+
+
@@ -203,6 +230,21 @@ a { color: #0066cc; }
| Sentence chunk identifier |
+start_frame |
+integer |
+Frame-accurate start position |
+
+
+end_frame |
+integer |
+Frame-accurate end position |
+
+
+fps |
+float |
+Frames per second |
+
+
start_time |
float |
Start time in seconds |
@@ -213,7 +255,7 @@ a { color: #0066cc; }
End time in seconds |
-text |
+text_content |
string |
Spoken text content |
diff --git a/docs_v1.0/doc/08_identity_agent.html b/docs_v1.0/doc/08_identity_agent.html
index 64a8bed..1d1c527 100644
--- a/docs_v1.0/doc/08_identity_agent.html
+++ b/docs_v1.0/doc/08_identity_agent.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
diff --git a/docs_v1.0/doc/08_media.html b/docs_v1.0/doc/08_media.html
index fae655d..6c33a28 100644
--- a/docs_v1.0/doc/08_media.html
+++ b/docs_v1.0/doc/08_media.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
diff --git a/docs_v1.0/doc/09_tmdb.html b/docs_v1.0/doc/09_tmdb.html
index 0f48d89..aa15d8e 100644
--- a/docs_v1.0/doc/09_tmdb.html
+++ b/docs_v1.0/doc/09_tmdb.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
diff --git a/docs_v1.0/doc/10_pipeline.html b/docs_v1.0/doc/10_pipeline.html
index 75eb932..f93d4e9 100644
--- a/docs_v1.0/doc/10_pipeline.html
+++ b/docs_v1.0/doc/10_pipeline.html
@@ -20,58 +20,33 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
Pipeline
-
Dependency Graph
-
flowchart TB
- subgraph Processors["10 Processors"]
- Cut[Cut] --> ASR[ASR]
- ASR --> ASRX[ASRX]
- ASRX --> Story[Story]
- Cut --> Story
- YOLO[YOLO] --> VisualChunk[VisualChunk]
- VisualChunk --> Story
- Face[Face] --> Story
- Story --> FiveW1H[5W1H]
- OCR[OCR]
- Pose[Pose]
- end
-
- subgraph Ingestion["入庫 (Post-Processing)"]
- ASR --> Rule1[Rule 1 Sentence]
- ASRX --> Rule1
- Rule1 --> Vectorize[Auto-Vectorize]
- Rule1 --> Phase1[Phase 1 Pack]
-
- Cut --> Rule3[Rule 3 Scene]
- ASR --> Rule3
-
- Face --> Trace[Face Trace]
- Trace --> Qdrant[Qdrant Sync]
- Trace --> TraceChunks[Trace Chunks]
- Trace --> TKG[TKG Builder]
-
- Face --> TMDbMatch[TMDb Match]
- Face --> SceneMeta[Scene Metadata]
- YOLO --> SceneMeta
- Face --> IdentityAgent[Identity Agent]
- ASRX --> IdentityAgent
-
- Cut --> Agent5W1H[5W1H Agent]
- ASR --> Agent5W1H
- Agent5W1H --> Phase2[Phase 2 Pack]
- end
-
- style Processors fill:#1a1a2e,stroke:#e94560
- style Ingestion fill:#16213e,stroke:#0f3460
+Pipeline Completion Flow
+The pipeline is not complete until both the 10 processors AND the 入庫 (ingestion) steps have finished. The worker polls every 3 seconds and only marks the job as completed when all ingestion steps verify OK.
+10 processors done
+ ↓ (job status stays "running")
+Algorithm 1 Trigger: Rule 1 + Vectorize + Phase 1 Pack
+ ↓ (job runs in parallel)
+Algorithm 2 Trigger: Face Trace → TKG, Scene Metadata, Identity Agent, 5W1H Agent
+ ↓ (poll checks every 3s)
+Ingestion verification: rule1 ✓ vectorize ✓ rule3 ✓ face_trace ✓ tkg ✓ scene_meta ✓ 5w1h ✓
+ ↓
+job status = "completed"
10 Processor Stages
@@ -147,95 +122,119 @@ a { color: #0066cc; }
-Post-Processing (入庫)
-After all 10 processors complete, the pipeline runs the following storage & enrichment steps:
+入庫 (Post-Processing / Ingestion)
+These steps run after the 10 processors and are required for pipeline completion. The worker checks all of them before marking the job as done.
| # |
Step |
-Requires |
-Evidence |
+Triggers When |
+Verification |
| 1 |
Rule 1 Sentence Chunking |
-ASR + ASRX |
-chunk table, chunk_type = 'sentence' |
+ASR + ASRX done |
+chunk table has rows with chunk_type = 'sentence' |
| 2 |
Auto-Vectorize |
-Rule 1 |
-chunk.embedding IS NOT NULL (pgvector) |
+Rule 1 done |
+chunk.embedding IS NOT NULL for sentence chunks |
| 3 |
Phase 1 Pack |
-Rule 1 |
-release_pack.py --phase 1 |
+Rule 1 done |
+release_pack.py --phase 1 executed |
| 4 |
Rule 3 Scene Chunking |
-Cut + ASR |
-chunk table, chunk_type = 'cut' |
+All 10 processors done + Cut + ASR |
+chunk table has rows with chunk_type = 'cut' |
| 5 |
Face Trace |
-Face |
+All 10 processors done + Face |
face_detections.trace_id IS NOT NULL |
| 6 |
Qdrant Face Sync |
-Face Trace |
-Qdrant face_embedding collection |
+Face Trace done |
+Qdrant face_embedding collection populated |
| 7 |
Trace Chunks |
-Face Trace |
-chunk table, chunk_type = 'trace' |
+Face Trace done |
+chunk table has rows with chunk_type = 'trace' |
| 8 |
TKG Builder |
-Face Trace |
-tkg_nodes + tkg_edges tables |
+Face Trace done |
+tkg_nodes + tkg_edges tables have rows |
| 9 |
TMDb Face Matching |
-Face + TMDb enabled |
+TMDb enabled + Face done |
face_detections.identity_id IS NOT NULL |
| 10 |
Heuristic Scene Metadata |
-Face + YOLO |
-{file_uuid}.scene_meta.json on disk |
+Face + YOLO done |
+{file_uuid}.scene_meta.json exists on disk |
| 11 |
-Identity Agent |
-Face + ASRX |
-identities with source = 'identity_agent' |
+Template 5W1H Story Summary (PG) |
+Story done |
+chunk.embedding IS NOT NULL for story chunks |
| 12 |
-5W1H Agent |
-Cut + ASR |
-chunk.summary_text IS NOT NULL (chunk_type = 'cut') |
+LLM 5W1H Summary (PG) |
+5W1H done |
+chunk.embedding IS NOT NULL for llm chunks |
| 13 |
+Voice Embedding (Qdrant) |
+ASRX done |
+Qdrant voice collection populated |
+
+
+| 14 |
+Face Embedding (Qdrant) |
+Face done |
+Qdrant face collection populated |
+
+
+| 15 |
+Identity Agent |
+Face + ASRX done |
+identities with source = 'identity_agent' |
+
+
+| 16 |
+5W1H Agent |
+Cut + ASR done |
+chunk.summary_text IS NOT NULL for cut chunks |
+
+
+| 17 |
Release Pack |
-5W1H Agent |
-release_pack.py --phase 2 output |
+5W1H Agent done |
+release_pack.py --phase 2 executed |
@@ -292,36 +291,29 @@ a { color: #0066cc; }
Configuration
-
POST /api/v1/config/cache
-
Auth: Required
-Scope: system-level
-
Toggle the Redis cache on or off.
-
Request Parameters
+
See 13_config.md for runtime configuration endpoints:
-| Field |
-Type |
-Required |
+Endpoint |
Description |
-enabled |
-boolean |
-Yes |
-true to enable, false to disable |
+POST /api/v1/config/cache |
+Toggle Redis cache |
+
+
+POST /api/v1/config/auto-pipeline |
+Toggle auto-pipeline on register |
+
+
+POST /api/v1/config/watcher-auto-register |
+Toggle watcher auto-register |
-
Example
-
curl -s -X POST "$API/api/v1/config/cache" \
- -H "Content-Type: application/json" \
- -H "X-API-Key: $KEY" \
- -d '{"enabled": false}'
-
-
Unmounted Routes
The following routes are defined in source code but are NOT currently mounted in the router:
diff --git a/docs_v1.0/doc/12_agent.html b/docs_v1.0/doc/12_agent.html
index 79f83ee..46f7c4f 100644
--- a/docs_v1.0/doc/12_agent.html
+++ b/docs_v1.0/doc/12_agent.html
@@ -20,11 +20,17 @@ pre code { background: none; padding: 0; }
a { color: #0066cc; }
.back { display: inline-block; margin-bottom: 20px; color: #666; }
.back:hover { color: #333; }
+.topbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
Agent Endpoints
Agent endpoints provide AI-powered capabilities including translation, identity analysis, and 5W1H extraction.
POST /api/v1/agents/translate
diff --git a/docs_v1.0/doc/index.html b/docs_v1.0/doc/index.html
index 62b15f8..ae9d116 100644
--- a/docs_v1.0/doc/index.html
+++ b/docs_v1.0/doc/index.html
@@ -17,11 +17,17 @@ td.cn { width: 140px; font-weight: 600; color: #333; }
td.en { color: #666; font-size: 14px; }
a { color: #0066cc; text-decoration: none; display: block; }
a:hover td { background: #f8f8f8; border-radius: 4px; }
+.topbar { display: flex; justify-content: space-between; align-items: baseline; }
+.logout-btn { font-size: 13px; color: #999; text-decoration: none; }
+.logout-btn:hover { color: #cc0000; }
+
API 參考手冊 — 登入後可瀏覽各模組文件
| 安全認證 | Authentication |
| 健康檢查 | Health |
| 檔案註冊 | File Registration |
| 檔案屬性查詢 | File Lookup |
| 處理流程 | Processing |
| 搜尋功能 | Search |
| 身份識別 | Identity |
| 智能身份綁定 | Smart Identity Binding |
| 串流與截圖 | Streaming & Thumbnails |
| TMDb 整合 | TMDb Integration |
| 生產線 | Pipeline |
| 智慧代理 | AI Agents |
diff --git a/docs_v1.0/doc/login.html b/docs_v1.0/doc/login.html
index c199107..e98ceef 100644
--- a/docs_v1.0/doc/login.html
+++ b/docs_v1.0/doc/login.html
@@ -11,7 +11,10 @@ h1 { font-size: 24px; margin-bottom: 24px; text-align: center; }
input { width: 100%; padding: 10px 12px; margin-bottom: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 14px; }
button { width: 100%; padding: 10px; background: #0066cc; color: white; border: none; border-radius: 6px; font-size: 16px; cursor: pointer; }
button:hover { background: #0052a3; }
+.btn-logout { background: #888; margin-top: 8px; font-size: 13px; padding: 6px; }
+.btn-logout:hover { background: #666; }
.error { color: #cc0000; font-size: 13px; margin-bottom: 12px; display: none; }
+.success { color: #006600; font-size: 13px; margin-bottom: 12px; display: none; }
@@ -19,9 +22,11 @@ button:hover { background: #0052a3; }
Momentry Docs