From 383201cacd4c663f55ec9c6c858cff1577872aef Mon Sep 17 00:00:00 2001
From: accusys
Date: Wed, 25 Mar 2026 14:52:51 +0800
Subject: [PATCH] feat: Initial v0.9 release with API Key authentication
## v0.9.20260325_144654
### Features
- API Key Authentication System
- Job Worker System
- V2 Backup Versioning
### Bug Fixes
- get_processor_results_by_job column mapping
Co-authored-by: OpenCode
---
.markdownlint.json | 21 +
.markdownlintrc | 21 +
CHANGELOG.md | 143 ++
a1b10138a6bbb0cd.cut.json | 1 +
a1b10138a6bbb0cd.face.json | 1 +
a1b10138a6bbb0cd.ocr.json | 1 +
a1b10138a6bbb0cd.pose.json | 1 +
a1b10138a6bbb0cd.story.json | 1 +
a1b10138a6bbb0cd.yolo.json | 1 +
docs/API_ACCESS.md | 193 +++
docs/API_CURL_EXAMPLES.md | 492 ++++++
docs/API_ENDPOINTS.md | 33 +-
docs/API_EXAMPLES.md | 726 +++++++++
docs/API_INDEX.md | 102 ++
docs/API_KEY_ARCHITECTURE.md | 195 +++
docs/API_KEY_INTEGRATION_TESTS.md | 236 +++
docs/API_KEY_MANAGEMENT.md | 699 +++++++++
docs/API_KEY_OPTIMIZATION.md | 399 +++++
docs/API_N8N_GUIDE.md | 193 +++
docs/API_REFERENCE.md | 447 ++++++
docs/API_WORDPRESS_GUIDE.md | 270 ++++
docs/ARCHITECTURE_EVALUATION.md | 331 ++++
docs/BUILD_VERSION_RECORD.md | 667 ++++++++
docs/CACHE_ARCHITECTURE_PLAN.md | 1106 ++++++++++++++
docs/CHUNK_DESIGN.md | 534 +++++++
docs/CHUNK_SPEC.md | 529 ++++++-
docs/DEMO_MANUAL.md | 674 +++++++++
docs/DEVELOPMENT_LOG.md | 116 ++
docs/DOCS_STANDARD.md | 474 ++++++
docs/DOCUMENT_EMBEDDING_STRATEGY.md | 151 ++
docs/FILE_CHANGE_MANAGEMENT.md | 323 ++++
docs/FRESH_MAC_INSTALLATION.md | 707 +++++++++
docs/INSTALL_CADDY.md | 16 +
docs/INSTALL_GITEA.md | 16 +
docs/INSTALL_GITEA_MCP.md | 393 +++++
docs/INSTALL_MARIADB.md | 16 +
docs/INSTALL_MOMENTRY_API.md | 464 ++++++
docs/INSTALL_MONGODB.md | 73 +-
docs/INSTALL_N8N.md | 43 +-
docs/INSTALL_OLLAMA.md | 18 +-
docs/INSTALL_PHP.md | 16 +
docs/INSTALL_POSTGRESQL.md | 27 +-
docs/INSTALL_QDRANT.md | 16 +
docs/INSTALL_REDIS.md | 126 +-
docs/INSTALL_RUSTDESK.md | 16 +
docs/INSTALL_SFTPGO.md | 705 ++++++++-
docs/INSTALL_WORDPRESS.md | 332 ++++
docs/JSON_OUTPUT_SPEC.md | 16 +
docs/MAC_INSTALLATION_PLAN.md | 782 ++++++++++
docs/MOMENTRY_RAG_PRESENTATION.md | 322 ++++
.../Momentry_Core_API.postman_collection.json | 127 ++
docs/N8N_API_FIX_SUMMARY.md | 106 ++
docs/N8N_DEMO.md | 220 +++
docs/N8N_DEMO_EXECUTION_LOG.md | 341 +++++
docs/N8N_DEMO_WORKFLOW.md | 677 +++++++++
docs/N8N_HTTP_REQUEST_GUIDE.md | 245 +++
docs/N8N_INTEGRATION_GUIDE.md | 562 +++++++
docs/N8N_MCP_SETUP.md | 211 +++
docs/N8N_MCP_TEST_REPORT.md | 178 +++
docs/N8N_SETUP_COMPLETE.md | 152 ++
docs/N8N_VIDEO_SEARCH_SUCCESS.md | 279 ++++
docs/N8N_VIEW_OUTPUT_GUIDE.md | 141 ++
docs/N8N_WORKFLOW_VIDEO_RAG_MCP.md | 169 +++
docs/NODEJS.md | 19 +-
docs/OPENCODE_GUIDE.md | 430 ++++++
docs/OPENCODE_MCP_INSTALL.md | 535 +++++++
docs/PENDING_ISSUES.md | 813 ++++++++++
docs/PROCESSING_PIPELINE.md | 271 ++++
docs/PYTHON.md | 74 +
docs/RUST_DEVELOPMENT.md | 61 +-
docs/SEARCH_PROMPTS.md | 121 ++
docs/SERVICE_ADDITION_GUIDE.md | 57 +-
docs/SFTPGO_DEMO_USER.md | 504 ++++++
docs/TEST_AND_BENCHMARK_PLAN.md | 1185 +++++++++++++++
docs/USER_MANAGEMENT_PLAN.md | 425 ++++++
docs/USER_MANUAL.md | 469 ++++++
docs/VERSION_MANAGEMENT.md | 245 +++
docs/VIDEO_PROCESSING_SPEC.md | 1347 +++++++++++++++++
docs/YOLO_RESUME_INTEGRATION.md | 102 ++
docs/n8n_workflow_simple.json | 110 ++
docs/n8n_workflow_simple_test.json | 89 ++
docs/n8n_workflow_video_rag_mcp.json | 94 ++
docs/n8n_workflow_video_search.json | 125 ++
docs/test_all.sh | 100 ++
docs/test_momentry_api.sh | 33 +
docs/test_workflow.sh | 104 ++
id_ecdsa.pub | 1 +
id_ed25519.pub | 1 +
id_rsa.pub | 1 +
migrations/001_api_key_management.sql | 94 ++
migrations/003_job_worker.sql | 140 ++
momentry_runtime/plist/com.momentry.api.plist | 58 +
.../plist/com.momentry.gitea-mcp-server.plist | 30 +
.../plist/com.momentry.mongodb.plist | 7 +-
.../plist/com.momentry.n8n.main.plist | 9 +
.../plist/com.momentry.n8n.worker.plist | 18 +-
.../plist/com.momentry.sftpgo.plist | 4 +
.../plist/com.momentry.worker.plist | 58 +
monitor/common/load_credentials.sh | 35 +
monitor/config/monitor_config.yaml | 8 -
monitor/service/health_check.sh | 92 +-
monitor/workflow/backup_n8n_api.py | 625 ++++++++
monitor/workflow/backup_n8n_mcp.py | 481 ++++++
monitor/workflow/backup_n8n_workflows.sh | 376 +++++
note.md | 86 ++
opencode.json | 12 +
requirements.txt | 34 +-
.../redis_publisher.cpython-311.pyc | Bin 0 -> 9145 bytes
scripts/add_yolo_to_chunks.py | 137 ++
scripts/asr_processor.py | 45 +-
scripts/asrx_processor.py | 110 ++
scripts/caption_processor.py | 305 ++++
scripts/chinese_vector_test.py | 170 +++
scripts/compare_search.py | 131 ++
scripts/comprehensive_search_test.py | 316 ++++
scripts/cut_processor.py | 106 ++
scripts/face_processor.py | 154 ++
scripts/natural_language_top10.py | 169 +++
scripts/natural_language_vector_detailed.py | 272 ++++
scripts/natural_language_vector_test.py | 220 +++
scripts/object_search.py | 165 ++
scripts/ocr_processor.py | 155 ++
scripts/pose_processor.py | 168 ++
scripts/redis_publisher.py | 184 +++
scripts/setup_fresh_mac.sh | 170 +++
scripts/story_processor.py | 345 +++++
scripts/sync_to_mongodb.py | 122 ++
scripts/test_multilingual.py | 191 +++
scripts/test_object_search.py | 84 +
scripts/test_v2_detailed.py | 156 ++
scripts/test_v2_model.py | 188 +++
scripts/test_v2_with_text.py | 133 ++
scripts/yolo_processor.py | 483 ++++++
sftpgo.db | Bin 0 -> 356352 bytes
src/api/middleware.rs | 120 ++
src/api/mod.rs | 1 +
src/api/server.rs | 78 +-
src/core/api_key/anomaly.rs | 193 +++
src/core/api_key/audit_logger.rs | 193 +++
src/core/api_key/blacklist.rs | 203 +++
src/core/api_key/cleanup.rs | 172 +++
src/core/api_key/encryption.rs | 211 +++
src/core/api_key/error.rs | 184 +++
src/core/api_key/export.rs | 226 +++
src/core/api_key/gitea.rs | 304 ++++
src/core/api_key/mod.rs | 45 +
src/core/api_key/models.rs | 228 +++
src/core/api_key/n8n.rs | 211 +++
src/core/api_key/report.rs | 233 +++
src/core/api_key/rotation.rs | 319 ++++
src/core/api_key/service.rs | 276 ++++
src/core/api_key/strength.rs | 209 +++
src/core/api_key/validator.rs | 310 ++++
src/core/api_key/webhook.rs | 311 ++++
src/core/cache/keys.rs | 85 ++
src/core/cache/mod.rs | 10 +
src/core/cache/mongo_cache.rs | 311 ++++
src/core/cache/tests.rs | 120 ++
src/core/chunk/splitter.rs | 11 +-
src/core/chunk/types.rs | 95 +-
src/core/config.rs | 8 -
src/core/db/mod.rs | 15 +-
src/core/db/mongodb_db.rs | 282 +++-
src/core/db/postgres_db.rs | 23 +-
src/core/db/qdrant_db.rs | 371 ++++-
src/core/db/redis_db.rs | 1 +
src/core/db/sync_db.rs | 155 ++
src/core/embedding/comic_embed.rs | 104 +-
src/core/mod.rs | 3 +
src/core/probe/{probe.rs => ffprobe.rs} | 0
src/core/processor/asr.rs | 134 +-
src/core/processor/asrx.rs | 142 +-
src/core/processor/caption.rs | 77 +
src/core/processor/cut.rs | 127 ++
src/core/processor/executor.rs | 395 +++++
src/core/processor/face.rs | 135 +-
src/core/processor/mod.rs | 18 +-
src/core/processor/ocr.rs | 133 +-
src/core/processor/pose.rs | 155 +-
src/core/processor/story.rs | 250 +++
src/core/processor/yolo.rs | 139 +-
src/core/storage/mod.rs | 2 +
src/core/storage/output_dir.rs | 226 +++
src/core/storage/uuid.rs | 79 +-
src/lib.rs | 15 +-
src/player/api_client.rs | 196 +++
src/player/asr_overlay.rs | 181 +++
src/player/chunk_selector.rs | 333 ++++
src/player/main.rs | 990 ++++++++++++
src/player/mod.rs | 10 +
src/player/selector.rs | 163 ++
src/ui/mod.rs | 1 +
src/ui/progress/mod.rs | 413 +++++
193 files changed, 40268 insertions(+), 422 deletions(-)
create mode 100644 .markdownlint.json
create mode 100644 .markdownlintrc
create mode 100644 CHANGELOG.md
create mode 120000 a1b10138a6bbb0cd.cut.json
create mode 120000 a1b10138a6bbb0cd.face.json
create mode 120000 a1b10138a6bbb0cd.ocr.json
create mode 120000 a1b10138a6bbb0cd.pose.json
create mode 120000 a1b10138a6bbb0cd.story.json
create mode 120000 a1b10138a6bbb0cd.yolo.json
create mode 100644 docs/API_ACCESS.md
create mode 100644 docs/API_CURL_EXAMPLES.md
create mode 100644 docs/API_EXAMPLES.md
create mode 100644 docs/API_INDEX.md
create mode 100644 docs/API_KEY_ARCHITECTURE.md
create mode 100644 docs/API_KEY_INTEGRATION_TESTS.md
create mode 100644 docs/API_KEY_MANAGEMENT.md
create mode 100644 docs/API_KEY_OPTIMIZATION.md
create mode 100644 docs/API_N8N_GUIDE.md
create mode 100644 docs/API_REFERENCE.md
create mode 100644 docs/API_WORDPRESS_GUIDE.md
create mode 100644 docs/ARCHITECTURE_EVALUATION.md
create mode 100644 docs/BUILD_VERSION_RECORD.md
create mode 100644 docs/CACHE_ARCHITECTURE_PLAN.md
create mode 100644 docs/CHUNK_DESIGN.md
create mode 100644 docs/DEMO_MANUAL.md
create mode 100644 docs/DOCS_STANDARD.md
create mode 100644 docs/DOCUMENT_EMBEDDING_STRATEGY.md
create mode 100644 docs/FILE_CHANGE_MANAGEMENT.md
create mode 100644 docs/FRESH_MAC_INSTALLATION.md
create mode 100644 docs/INSTALL_GITEA_MCP.md
create mode 100644 docs/INSTALL_MOMENTRY_API.md
create mode 100644 docs/INSTALL_WORDPRESS.md
create mode 100644 docs/MAC_INSTALLATION_PLAN.md
create mode 100644 docs/MOMENTRY_RAG_PRESENTATION.md
create mode 100644 docs/Momentry_Core_API.postman_collection.json
create mode 100644 docs/N8N_API_FIX_SUMMARY.md
create mode 100644 docs/N8N_DEMO.md
create mode 100644 docs/N8N_DEMO_EXECUTION_LOG.md
create mode 100644 docs/N8N_DEMO_WORKFLOW.md
create mode 100644 docs/N8N_HTTP_REQUEST_GUIDE.md
create mode 100644 docs/N8N_INTEGRATION_GUIDE.md
create mode 100644 docs/N8N_MCP_SETUP.md
create mode 100644 docs/N8N_MCP_TEST_REPORT.md
create mode 100644 docs/N8N_SETUP_COMPLETE.md
create mode 100644 docs/N8N_VIDEO_SEARCH_SUCCESS.md
create mode 100644 docs/N8N_VIEW_OUTPUT_GUIDE.md
create mode 100644 docs/N8N_WORKFLOW_VIDEO_RAG_MCP.md
create mode 100644 docs/OPENCODE_GUIDE.md
create mode 100644 docs/OPENCODE_MCP_INSTALL.md
create mode 100644 docs/PENDING_ISSUES.md
create mode 100644 docs/PROCESSING_PIPELINE.md
create mode 100644 docs/SEARCH_PROMPTS.md
create mode 100644 docs/SFTPGO_DEMO_USER.md
create mode 100644 docs/TEST_AND_BENCHMARK_PLAN.md
create mode 100644 docs/USER_MANAGEMENT_PLAN.md
create mode 100644 docs/USER_MANUAL.md
create mode 100644 docs/VERSION_MANAGEMENT.md
create mode 100644 docs/VIDEO_PROCESSING_SPEC.md
create mode 100644 docs/YOLO_RESUME_INTEGRATION.md
create mode 100644 docs/n8n_workflow_simple.json
create mode 100644 docs/n8n_workflow_simple_test.json
create mode 100644 docs/n8n_workflow_video_rag_mcp.json
create mode 100644 docs/n8n_workflow_video_search.json
create mode 100755 docs/test_all.sh
create mode 100755 docs/test_momentry_api.sh
create mode 100755 docs/test_workflow.sh
create mode 100644 id_ecdsa.pub
create mode 100644 id_ed25519.pub
create mode 100644 id_rsa.pub
create mode 100644 migrations/001_api_key_management.sql
create mode 100644 migrations/003_job_worker.sql
create mode 100644 momentry_runtime/plist/com.momentry.api.plist
create mode 100644 momentry_runtime/plist/com.momentry.gitea-mcp-server.plist
create mode 100644 momentry_runtime/plist/com.momentry.worker.plist
create mode 100644 monitor/common/load_credentials.sh
create mode 100755 monitor/workflow/backup_n8n_api.py
create mode 100644 monitor/workflow/backup_n8n_mcp.py
create mode 100755 monitor/workflow/backup_n8n_workflows.sh
create mode 100644 note.md
create mode 100644 opencode.json
create mode 100644 scripts/__pycache__/redis_publisher.cpython-311.pyc
create mode 100644 scripts/add_yolo_to_chunks.py
create mode 100755 scripts/asrx_processor.py
create mode 100644 scripts/caption_processor.py
create mode 100644 scripts/chinese_vector_test.py
create mode 100644 scripts/compare_search.py
create mode 100644 scripts/comprehensive_search_test.py
create mode 100755 scripts/cut_processor.py
create mode 100755 scripts/face_processor.py
create mode 100644 scripts/natural_language_top10.py
create mode 100644 scripts/natural_language_vector_detailed.py
create mode 100644 scripts/natural_language_vector_test.py
create mode 100644 scripts/object_search.py
create mode 100755 scripts/ocr_processor.py
create mode 100755 scripts/pose_processor.py
create mode 100644 scripts/redis_publisher.py
create mode 100644 scripts/setup_fresh_mac.sh
create mode 100644 scripts/story_processor.py
create mode 100644 scripts/sync_to_mongodb.py
create mode 100644 scripts/test_multilingual.py
create mode 100644 scripts/test_object_search.py
create mode 100644 scripts/test_v2_detailed.py
create mode 100644 scripts/test_v2_model.py
create mode 100644 scripts/test_v2_with_text.py
create mode 100755 scripts/yolo_processor.py
create mode 100644 sftpgo.db
create mode 100644 src/api/middleware.rs
create mode 100644 src/core/api_key/anomaly.rs
create mode 100644 src/core/api_key/audit_logger.rs
create mode 100644 src/core/api_key/blacklist.rs
create mode 100644 src/core/api_key/cleanup.rs
create mode 100644 src/core/api_key/encryption.rs
create mode 100644 src/core/api_key/error.rs
create mode 100644 src/core/api_key/export.rs
create mode 100644 src/core/api_key/gitea.rs
create mode 100644 src/core/api_key/mod.rs
create mode 100644 src/core/api_key/models.rs
create mode 100644 src/core/api_key/n8n.rs
create mode 100644 src/core/api_key/report.rs
create mode 100644 src/core/api_key/rotation.rs
create mode 100644 src/core/api_key/service.rs
create mode 100644 src/core/api_key/strength.rs
create mode 100644 src/core/api_key/validator.rs
create mode 100644 src/core/api_key/webhook.rs
create mode 100644 src/core/cache/keys.rs
create mode 100644 src/core/cache/mod.rs
create mode 100644 src/core/cache/mongo_cache.rs
create mode 100644 src/core/cache/tests.rs
create mode 100644 src/core/db/sync_db.rs
rename src/core/probe/{probe.rs => ffprobe.rs} (100%)
create mode 100644 src/core/processor/caption.rs
create mode 100644 src/core/processor/cut.rs
create mode 100644 src/core/processor/executor.rs
create mode 100644 src/core/processor/story.rs
create mode 100644 src/core/storage/output_dir.rs
create mode 100644 src/player/api_client.rs
create mode 100644 src/player/asr_overlay.rs
create mode 100644 src/player/chunk_selector.rs
create mode 100644 src/player/main.rs
create mode 100644 src/player/selector.rs
create mode 100644 src/ui/mod.rs
create mode 100644 src/ui/progress/mod.rs
diff --git a/.markdownlint.json b/.markdownlint.json
new file mode 100644
index 0000000..c6f88ce
--- /dev/null
+++ b/.markdownlint.json
@@ -0,0 +1,21 @@
+{
+ "default": true,
+ "MD003": false,
+ "MD009": false,
+ "MD010": false,
+ "MD013": false,
+ "MD022": false,
+ "MD024": false,
+ "MD025": false,
+ "MD031": false,
+ "MD032": false,
+ "MD033": false,
+ "MD034": false,
+ "MD036": false,
+ "MD040": false,
+ "MD046": false,
+ "MD055": false,
+ "MD056": false,
+ "MD058": false,
+ "MD060": false
+}
diff --git a/.markdownlintrc b/.markdownlintrc
new file mode 100644
index 0000000..c6f88ce
--- /dev/null
+++ b/.markdownlintrc
@@ -0,0 +1,21 @@
+{
+ "default": true,
+ "MD003": false,
+ "MD009": false,
+ "MD010": false,
+ "MD013": false,
+ "MD022": false,
+ "MD024": false,
+ "MD025": false,
+ "MD031": false,
+ "MD032": false,
+ "MD033": false,
+ "MD034": false,
+ "MD036": false,
+ "MD040": false,
+ "MD046": false,
+ "MD055": false,
+ "MD056": false,
+ "MD058": false,
+ "MD060": false
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..3e3a8ed
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,143 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
+
+## [Unreleased]
+
+### Added
+- Gitea API token integration
+- n8n API key integration
+- API key caching with Moka
+- Rate limiting for API key validation
+- Constant-time hash comparison
+- OpenAPI documentation with utoipa
+
+## [0.1.0] - 2026-03-21
+
+### Added
+
+#### API Key Management System
+- API key generation with secure random (UUID v4)
+- SHA256 key hashing
+- 5 key types: System, User, Service, Integration, Emergency
+- Key expiration with configurable TTL
+- Grace period for key rotation
+
+#### Anomaly Detection
+- High request rate detection (>1000/min)
+- High error rate detection (>50%)
+- Multiple IP detection (>5/hour)
+- Unusual time activity detection
+- Redis Pub/Sub for anomaly alerts
+
+#### Rotation Mechanism
+- Automatic rotation scheduling
+- Manual rotation requests
+- Forced rotation for security incidents
+- Grace period management per key type:
+ - System: 72 hours
+ - User: 24 hours
+ - Service: 48 hours
+ - Integration: 24 hours
+ - Emergency: 0 hours (immediate)
+
+#### PostgreSQL Integration
+- `api_keys` table for key storage
+- `api_key_audit_log` table for audit trail
+- `api_key_anomalies` table for anomaly records
+- Full CRUD operations for API keys
+
+#### Redis Integration
+- Anomaly alert Pub/Sub (`momentry:anomaly:alerts`)
+- Key anomaly state tracking
+- Real-time alert notifications
+
+#### CLI Commands
+- `momentry api-key create` - Create new API key
+- `momentry api-key list` - List all API keys
+- `momentry api-key validate` - Validate an API key
+- `momentry api-key revoke` - Revoke an API key
+- `momentry api-key rotate` - Request key rotation
+- `momentry api-key stats` - Show statistics
+
+#### Gitea Integration
+- Create Gitea Personal Access Tokens
+- List user tokens
+- Delete tokens
+- Local token tracking
+- CLI commands:
+ - `momentry gitea create`
+ - `momentry gitea list`
+ - `momentry gitea delete`
+ - `momentry gitea verify`
+
+#### n8n Integration
+- Create n8n API keys
+- List API keys
+- Delete API keys
+- Local key tracking
+- CLI commands:
+ - `momentry n8n create`
+ - `momentry n8n list`
+ - `momentry n8n delete`
+ - `momentry n8n verify`
+
+#### Security Features
+- Constant-time hash comparison (subtle crate)
+- Rate limiting for validation attempts
+- IP-based lockout after failed attempts
+- Configurable thresholds via environment variables
+
+#### Performance Optimizations
+- Moka-based API key validation cache
+- Configurable TTL and capacity
+- Reduced database queries for hot keys
+
+#### Documentation
+- API Key Management design document
+- Redis user configuration guide
+- Gitea token integration guide
+- n8n API key integration guide
+- Optimization plan with task codes
+
+### Environment Variables
+
+#### API Key Configuration
+```
+CACHE_TTL_SECONDS=300 # Cache TTL (default: 300)
+CACHE_MAX_CAPACITY=10000 # Max cache entries (default: 10000)
+RATE_LIMIT_MAX_ATTEMPTS=5 # Max failed attempts (default: 5)
+RATE_LIMIT_WINDOW_SECONDS=900 # Lockout duration (default: 900)
+```
+
+#### Service URLs
+```
+GITEA_URL=http://localhost:3000
+N8N_URL=https://n8n.momentry.ddns.net
+```
+
+### Database Schema
+
+#### Tables Created
+- `api_keys` - API key storage
+- `api_key_audit_log` - Audit trail
+- `api_key_anomalies` - Anomaly records
+- `gitea_tokens` - Gitea token tracking
+- `n8n_api_keys` - n8n API key tracking
+
+### Dependencies Added
+- `uuid` - UUID generation
+- `subtle` - Constant-time comparison
+- `moka` - Async cache
+- `utoipa` - OpenAPI documentation
+- `utoipa-swagger-ui` - Swagger UI
+
+---
+
+## Version History
+
+| Version | Date | Description |
+|---------|------|-------------|
+| 0.1.0 | 2026-03-21 | Initial release with API Key Management |
diff --git a/a1b10138a6bbb0cd.cut.json b/a1b10138a6bbb0cd.cut.json
new file mode 120000
index 0000000..31c7e3c
--- /dev/null
+++ b/a1b10138a6bbb0cd.cut.json
@@ -0,0 +1 @@
+/Users/accusys/momentry_core_0.1/output/a1b10138a6bbb0cd.cut.json
\ No newline at end of file
diff --git a/a1b10138a6bbb0cd.face.json b/a1b10138a6bbb0cd.face.json
new file mode 120000
index 0000000..e481d5e
--- /dev/null
+++ b/a1b10138a6bbb0cd.face.json
@@ -0,0 +1 @@
+/Users/accusys/momentry_core_0.1/output/a1b10138a6bbb0cd.face.json
\ No newline at end of file
diff --git a/a1b10138a6bbb0cd.ocr.json b/a1b10138a6bbb0cd.ocr.json
new file mode 120000
index 0000000..edfdb5a
--- /dev/null
+++ b/a1b10138a6bbb0cd.ocr.json
@@ -0,0 +1 @@
+/Users/accusys/momentry_core_0.1/output/a1b10138a6bbb0cd.ocr.json
\ No newline at end of file
diff --git a/a1b10138a6bbb0cd.pose.json b/a1b10138a6bbb0cd.pose.json
new file mode 120000
index 0000000..fb33446
--- /dev/null
+++ b/a1b10138a6bbb0cd.pose.json
@@ -0,0 +1 @@
+/Users/accusys/momentry_core_0.1/output/a1b10138a6bbb0cd.pose.json
\ No newline at end of file
diff --git a/a1b10138a6bbb0cd.story.json b/a1b10138a6bbb0cd.story.json
new file mode 120000
index 0000000..392fd81
--- /dev/null
+++ b/a1b10138a6bbb0cd.story.json
@@ -0,0 +1 @@
+/Users/accusys/momentry_core_0.1/output/a1b10138a6bbb0cd.story.json
\ No newline at end of file
diff --git a/a1b10138a6bbb0cd.yolo.json b/a1b10138a6bbb0cd.yolo.json
new file mode 120000
index 0000000..2423006
--- /dev/null
+++ b/a1b10138a6bbb0cd.yolo.json
@@ -0,0 +1 @@
+/Users/accusys/momentry_core_0.1/output/a1b10138a6bbb0cd.yolo.json
\ No newline at end of file
diff --git a/docs/API_ACCESS.md b/docs/API_ACCESS.md
new file mode 100644
index 0000000..79701db
--- /dev/null
+++ b/docs/API_ACCESS.md
@@ -0,0 +1,193 @@
+# Momentry Core API 存取指南
+
+## 基本網址
+
+| 環境 | URL | 說明 |
+|------|-----|------|
+| **本地開發** | `http://localhost:3002` | 直接訪問 API,繞過反向代理 |
+| **外部訪問** | `https://api.momentry.ddns.net` | 通過 Caddy 反向代理訪問,需網路可達 |
+
+### 何時使用哪個 URL
+
+**使用 `localhost:3002`:**
+- 開發/測試環境
+- 直接在伺服器上操作
+- 當反向代理有問題時
+
+**使用 `api.momentry.ddns.net`:**
+- n8n workflow 中呼叫 API
+- 外部系統整合
+- 生產環境
+
+## 認證
+目前為開放狀態(示範用途無需認證)。正式環境將實作 API Key。
+
+---
+
+## 影片搜尋 API
+
+### 語意搜尋
+
+**端點:** `POST /api/v1/search`
+
+**請求:**
+```json
+{
+ "query": "charade",
+ "limit": 5,
+ "uuid": "a1b10138a6bbb0cd"
+}
+```
+
+| 欄位 | 類型 | 必填 | 說明 |
+|------|------|------|------|
+| `query` | 字串 | 是 | 搜尋文字 |
+| `limit` | 整數 | 否 | 最大回傳結果數(預設 10) |
+| `uuid` | 字串 | 否 | 依影片 UUID 過濾 |
+
+**回應:**
+```json
+{
+ "results": [
+ {
+ "uuid": "a1b10138a6bbb0cd",
+ "chunk_id": "sentence_0006",
+ "chunk_type": "sentence",
+ "start_time": 48.8,
+ "end_time": 55.44,
+ "text": "fun plot twists, Woody Dialog and charming performances...",
+ "score": 0.526
+ }
+ ],
+ "query": "charade"
+}
+```
+
+---
+
+### n8n 整合搜尋
+
+**端點:** `POST /api/v1/n8n/search`
+
+**請求:**
+```json
+{
+ "query": "charade",
+ "limit": 5
+}
+```
+
+**回應:**
+```json
+{
+ "query": "charade",
+ "count": 5,
+ "hits": [
+ {
+ "id": "sentence_0006",
+ "vid": "a1b10138a6bbb0cd",
+ "start": 48.8,
+ "end": 55.44,
+ "title": "Chunk sentence_0006",
+ "text": "fun plot twists...",
+ "score": 0.526,
+ "media_url": "https://wp.momentry.ddns.net/Old_Time_Movie_Show_-_Charade_1963.HD.mov"
+ }
+ ]
+}
+```
+
+---
+
+## 影片管理 API
+
+### 列出所有影片
+**端點:** `GET /api/v1/videos`
+
+### 查詢影片資訊
+**端點:** `GET /api/v1/lookup?uuid={uuid}` 或 `GET /api/v1/lookup?path={path}`
+
+### 取得處理進度
+**端點:** `GET /api/v1/progress/{uuid}`
+
+---
+
+## 區塊資料結構
+
+每個搜尋結果包含影片播放的時間資訊:
+
+| 欄位 | 說明 |
+|------|------|
+| `uuid` | 影片識別碼 |
+| `chunk_id` | 區塊唯一識別碼 |
+| `chunk_type` | 類型:`sentence`、`cut`、`time_based` |
+| `start_time` | 開始時間(秒) |
+| `end_time` | 結束時間(秒) |
+| `text` | 語音轉文字內容 |
+| `score` | 相關性分數(0-1) |
+
+---
+
+## 整合範例
+
+### JavaScript/fetch
+```javascript
+const response = await fetch('http://localhost:3002/api/v1/search', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ query: 'charade', limit: 5 })
+});
+const data = await response.json();
+console.log(data.results);
+```
+
+### PHP/cURL
+```php
+$ch = curl_init('http://localhost:3002/api/v1/search');
+curl_setopt($ch, CURLOPT_POST, true);
+curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
+ 'query' => 'charade',
+ 'limit' => 5
+]));
+curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
+$response = curl_exec($ch);
+$data = json_decode($response, true);
+```
+
+---
+
+## 影片嵌入網址
+
+影片可透過 SFTPGo 分享連結存取:
+```
+https://wp.momentry.ddns.net/{檔案名稱}
+```
+
+**手動建立分享連結:**
+1. 開啟 SFTPGo Web UI:`http://localhost:8080`
+2. 使用帳號 `demo` / 密碼 `demopassword123` 登入
+3. 導航至 `Files` → 選擇影片檔案
+4. 點擊 `Share` → `Create Link`
+5. 複製產生的分享連結
+
+使用搜尋結果中的 `start_time` 和 `end_time` 來嵌入影片片段。
+
+---
+
+## 服務列表
+
+| 服務 | 網址 | 用途 |
+|------|------|------|
+| Momentry API | `http://localhost:3002` | 核心 API |
+| SFTPGo | `http://localhost:8080` | 檔案儲存 |
+| Qdrant | `http://localhost:6333` | 向量搜尋 |
+| PostgreSQL | `localhost:5432` | 資料庫 |
+
+---
+
+## 示範影片
+
+- **檔案:** `Old_Time_Movie_Show_-_Charade_1963.HD.mov`
+- **UUID:** `a1b10138a6bbb0cd`
+- **長度:** 約 6879 秒(約 1.9 小時)
+- **區塊數:** 3886 個(句子 + 場景 + 時間)
diff --git a/docs/API_CURL_EXAMPLES.md b/docs/API_CURL_EXAMPLES.md
new file mode 100644
index 0000000..4219899
--- /dev/null
+++ b/docs/API_CURL_EXAMPLES.md
@@ -0,0 +1,492 @@
+# Momentry API 使用說明 (curl 範例)
+
+| 項目 | 內容 |
+|------|------|
+| 版本 | V1.2 |
+| 日期 | 2026-03-23 |
+| Base URL | `http://localhost:3002` |
+
+---
+
+> **狀態說明**:
+> - ✅ **已實作**: 健康檢查、搜尋、影片管理端點
+> - ⚠️ **規劃中**: API Key 管理功能
+> - 🔧 **CLI**: 部分功能需使用命令列工具
+
+---
+
+## 目錄
+
+1. [已實作端點](#1-已實作端點)
+2. [API Key 管理](#2-api-key-管理-規劃中)
+3. [影片管理](#3-影片管理)
+4. [查詢與搜索](#4-查詢與搜索)
+5. [系統狀態](#5-系統狀態)
+
+---
+
+## URL 選擇指南
+
+### 兩種 URL 的使用情境
+
+| 環境 | URL | 說明 |
+|------|-----|------|
+| **本地開發** | `http://localhost:3002` | 直接訪問 API,繞過反向代理 |
+| **外部訪問** | `https://api.momentry.ddns.net` | 通過 Caddy 反向代理訪問,需網路可達 |
+
+### 何時使用 localhost:3002
+
+- ✅ 開發/測試環境
+- ✅ 直接在伺服器上操作
+- ✅ 當 Caddy/反向代理有問題時
+- ✅ 需要快速除錯時
+
+### 何時使用 api.momentry.ddns.net
+
+- ✅ n8n workflow 中呼叫 API
+- ✅ 外部系統整合
+- ✅ 生產環境
+- ✅ 從其他機器訪問
+
+### 快速切換範例
+
+```bash
+# 本地測試
+curl http://localhost:3002/health
+
+# 外部測試(功能相同)
+curl https://api.momentry.ddns.net/health
+```
+
+### 常見問題
+
+**Q: 為什麼有兩個 URL?**
+A: `localhost:3002` 是直接訪問,`api.momentry.ddns.net` 通過 Caddy 反向代理。
+
+**Q: 兩者功能相同嗎?**
+A: 是的,所有端點和功能完全相同。
+
+**Q: 502 錯誤時怎麼辦?**
+A: 如果 `api.momentry.ddns.net` 返回 502,檢查 Momentry API 服務是否運行:
+```bash
+launchctl list | grep momentry.api
+# 如果未運行
+sudo launchctl load /Library/LaunchDaemons/com.momentry.api.plist
+```
+
+---
+
+## 1. 已實作端點
+
+### 健康檢查
+
+```bash
+curl http://localhost:3002/health
+```
+
+**回應**:
+```json
+{"status":"ok","version":"0.1.0","uptime_ms":123456}
+```
+
+### 詳細健康檢查
+
+```bash
+curl http://localhost:3002/health/detailed
+```
+
+---
+
+## 2. API Key 管理 *(規劃中)*
+
+> ⚠️ **此功能尚未實作**。以下為規劃中的 API 說明,僅供參考。
+
+### 2.1 建立 API Key
+
+```bash
+curl -X POST http://localhost:3002/api/v1/api-keys \
+ -H "Content-Type: application/json" \
+ -H "X-API-Key: your-admin-key" \
+ -d '{
+ "name": "my-service-key",
+ "key_type": "service",
+ "permissions": ["read", "write"],
+ "ttl_days": 90
+ }'
+```
+
+### 2.2 列出所有 API Keys
+
+```bash
+curl -X GET http://localhost:3002/api/v1/api-keys \
+ -H "X-API-Key: your-admin-key"
+```
+
+### 2.3 驗證 API Key
+
+```bash
+curl -X GET http://localhost:3002/api/v1/api-keys/validate \
+ -H "X-API-Key: key-to-validate"
+```
+
+### 2.4 撤銷 API Key
+
+```bash
+curl -X DELETE http://localhost:3002/api/v1/api-keys/msvc_a1b2c3d4_... \
+ -H "X-API-Key: your-admin-key"
+```
+
+### 2.5 請求 Key 輪換
+
+```bash
+curl -X POST http://localhost:3002/api/v1/api-keys/msvc_a1b2c3d4_.../rotate \
+ -H "X-API-Key: your-admin-key" \
+ -H "Content-Type: application/json" \
+ -d '{"reason": "scheduled_rotation"}'
+```
+
+### 2.6 取得統計資訊
+
+```bash
+curl -X GET http://localhost:3002/api/v1/api-keys/stats \
+ -H "X-API-Key: your-admin-key"
+```
+
+---
+
+## 3. 影片管理
+
+### 3.1 註冊影片 ✅
+
+```bash
+curl -X POST http://localhost:3002/api/v1/register \
+ -H "Content-Type: application/json" \
+ -d '{"path": "/path/to/video.mp4"}'
+```
+
+**回應範例**:
+
+```json
+{
+ "id": 1,
+ "uuid": "a1b2c3d4e5f6g7h8",
+ "file_path": "/path/to/video.mp4",
+ "file_name": "video.mp4",
+ "duration": 120.5,
+ "width": 1920,
+ "height": 1080
+}
+```
+
+### 3.2 列出所有影片 ✅
+
+```bash
+curl http://localhost:3002/api/v1/videos
+```
+
+### 3.3 查詢影片 ✅
+
+```bash
+# 依 UUID 查詢
+curl "http://localhost:3002/api/v1/lookup?uuid=a1b2c3d4e5f6g7h8"
+
+# 依路徑查詢
+curl "http://localhost:3002/api/v1/lookup?path=/path/to/video.mp4"
+```
+
+### 3.4 處理影片 🔧 *(CLI - 非 API)*
+
+影片處理需要使用 CLI 命令:
+
+```bash
+# 處理影片(生成 ASR, CUT, YOLO, OCR, Face, Pose 資料)
+cargo run --bin momentry -- process
+
+# 或處理多個影片
+cargo run --bin momentry -- process
+```
+
+### 3.5 取得處理進度 ✅
+
+```bash
+curl http://localhost:3002/api/v1/progress/
+```
+
+**回應範例**:
+
+```json
+{
+ "uuid": "a1b2c3d4e5f6g7h8",
+ "overall_progress": 75,
+ "processors": [
+ {
+ "name": "asr",
+ "status": "complete",
+ "current": 100,
+ "total": 100,
+ "progress": 100,
+ "message": "7 segments"
+ },
+ {
+ "name": "cut",
+ "status": "complete",
+ "current": 134,
+ "total": 134,
+ "progress": 100,
+ "message": "134 scenes"
+ },
+ {
+ "name": "yolo",
+ "status": "progress",
+ "current": 5000,
+ "total": 14315,
+ "progress": 35,
+ "message": "frame 5000"
+ }
+ ]
+}
+```
+
+---
+
+## 4. 查詢與搜索
+
+### 4.1 語意搜尋 ✅
+
+```bash
+curl -X POST http://localhost:3002/api/v1/search \
+ -H "Content-Type: application/json" \
+ -d '{
+ "query": "測試關鍵字",
+ "limit": 5
+ }'
+```
+
+**回應範例**:
+
+```json
+{
+ "results": [
+ {
+ "uuid": "a1b2c3d4e5f6g7h8",
+ "chunk_id": "sentence_0006",
+ "chunk_type": "sentence",
+ "start_time": 48.8,
+ "end_time": 55.44,
+ "text": "fun plot twists...",
+ "score": 0.526
+ }
+ ],
+ "query": "測試關鍵字"
+}
+```
+
+### 4.2 n8n 格式搜尋 ✅
+
+```bash
+curl -X POST http://localhost:3002/api/v1/n8n/search \
+ -H "Content-Type: application/json" \
+ -d '{
+ "query": "測試關鍵字",
+ "limit": 5
+ }'
+```
+
+**回應範例**:
+
+```json
+{
+ "query": "測試關鍵字",
+ "count": 2,
+ "hits": [
+ {
+ "id": "c_001",
+ "vid": "a1b2c3d4e5f6g7h8",
+ "start": 48.8,
+ "end": 55.44,
+ "title": "Chunk sentence_0006",
+ "text": "fun plot twists...",
+ "score": 0.92,
+ "media_url": "https://wp.momentry.ddns.net/video.mp4"
+ }
+ ]
+}
+```
+
+### 4.3 混合搜尋 ✅
+
+```bash
+curl -X POST http://localhost:3002/api/v1/search/hybrid \
+ -H "Content-Type: application/json" \
+ -d '{
+ "query": "測試關鍵字",
+ "limit": 5
+ }'
+```
+
+---
+
+## 5. 系統狀態
+
+### 5.1 健康檢查 ✅
+
+```bash
+curl http://localhost:3002/health
+```
+
+**回應**:
+```json
+{"status":"ok","version":"0.1.0","uptime_ms":123456}
+```
+
+### 5.2 詳細健康檢查 ✅
+
+```bash
+curl http://localhost:3002/health/detailed
+```
+
+**回應範例**:
+
+```json
+{
+ "status":"ok",
+ "version":"0.1.0",
+ "uptime_ms":123456,
+ "services":{
+ "postgres":{"status":"ok","latency_ms":42,"error":null},
+ "redis":{"status":"ok","latency_ms":0,"error":null},
+ "qdrant":{"status":"ok","latency_ms":15,"error":null}
+ }
+}
+```
+
+---
+
+## 6. n8n Webhook 測試
+
+### 測試 n8n Workflow
+
+**重要**: 測試前請先在 n8n UI 中點擊 "Execute workflow" 按鈕
+
+```bash
+# 測試 Video RAG Workflow (Test Mode)
+curl -X POST http://localhost:5678/webhook-test/video-rag-mcp \
+ -H "Content-Type: application/json" \
+ -d '{"query":"charade","limit":3}'
+
+# 帶有 UUID 過濾的搜尋
+curl -X POST http://localhost:5678/webhook-test/video-rag-mcp \
+ -H "Content-Type: application/json" \
+ -d '{"query":"woody","limit":5,"uuid":"a1b10138a6bbb0cd"}'
+```
+
+### 生產環境 Webhook
+
+**注意**: 工作流程必須處於 Active 狀態
+
+```bash
+curl -X POST http://localhost:5678/webhook/video-rag-mcp \
+ -H "Content-Type: application/json" \
+ -d '{"query":"charade","limit":3}'
+```
+
+### n8n Webhook 常見問題
+
+**Q: webhook-test 返回 404**
+A: 需要在 n8n UI 中點擊 "Execute workflow" 按鈕後才能使用 test webhook
+
+**Q: webhook (生產環境) 返回 404**
+A: 需要將工作流程切換為 Active 狀態 (右上角開關)
+
+---
+
+## 附錄
+
+### A. 服務 URL 列表
+
+| 服務 | URL |
+|------|-----|
+| Momentry API (本地) | `http://localhost:3002` |
+| Momentry API (外部) | `https://api.momentry.ddns.net` |
+| n8n Web UI | `https://n8n.momentry.ddns.net` |
+| n8n Webhook Test | `http://localhost:5678/webhook-test/{workflow-name}` |
+| n8n Webhook Prod | `http://localhost:5678/webhook/{workflow-name}` |
+
+### B. 所有可用端點
+
+| 端點 | 方法 | 狀態 | 說明 |
+|------|------|------|------|
+| `/health` | GET | ✅ | 健康檢查 |
+| `/health/detailed` | GET | ✅ | 詳細健康檢查 |
+| `/api/v1/register` | POST | ✅ | 註冊影片 |
+| `/api/v1/search` | POST | ✅ | 語意搜尋 |
+| `/api/v1/n8n/search` | POST | ✅ | n8n 格式搜尋 |
+| `/api/v1/search/hybrid` | POST | ✅ | 混合搜尋 |
+| `/api/v1/lookup` | GET | ✅ | 查詢影片 |
+| `/api/v1/videos` | GET | ✅ | 列出所有影片 |
+| `/api/v1/progress/:uuid` | GET | ✅ | 處理進度 |
+| `/api/v1/api-keys` | * | ⚠️ | API Key 管理 (規劃中) |
+
+### C. 常見錯誤
+
+| HTTP 狀態 | 說明 | 解決方式 |
+|-----------|------|----------|
+| 200 | 成功 | - |
+| 400 | 請求格式錯誤 | 檢查 JSON 格式 |
+| 404 | 端點不存在或資源未找到 | 確認端點 URL 正確 |
+| 500 | 伺服器內部錯誤 | 檢查 API 服務日誌 |
+| **502** | **Bad Gateway** | **API 服務未啟動,見下方說明** |
+
+#### 502 Bad Gateway 錯誤
+
+**問題**: 外部 URL `https://api.momentry.ddns.net` 返回 502
+
+**原因**: Momentry Core API 服務未啟動
+
+**解決方式**:
+
+```bash
+# 1. 檢查服務狀態
+launchctl list | grep momentry.api
+
+# 2. 如果未啟動,手動啟動
+sudo launchctl load /Library/LaunchDaemons/com.momentry.api.plist
+
+# 3. 或使用本地測試(繞過反向代理)
+curl http://localhost:3002/health
+
+# 4. 檢查日誌
+tail -50 /Users/accusys/momentry/log/momentry_api.error.log
+```
+
+### D. 範例腳本
+
+```bash
+#!/bin/bash
+# api_test.sh - API 測試腳本
+
+API_URL="http://localhost:3002"
+
+# 健康檢查
+echo "=== Health Check ==="
+curl -s "$API_URL/health" | jq .
+
+# 搜尋
+echo -e "\n=== Search ==="
+curl -s -X POST "$API_URL/api/v1/search" \
+ -H "Content-Type: application/json" \
+ -d '{"query": "test", "limit": 3}' | jq .
+
+# 列出影片
+echo -e "\n=== Videos ==="
+curl -s "$API_URL/api/v1/videos" | jq '.videos | length'
+```
+
+---
+
+## 相關文件
+
+- [API_INDEX.md](./API_INDEX.md) - 文件總覽(起點)
+- [API_ENDPOINTS.md](./API_ENDPOINTS.md) - 端點完整說明
+- [API_N8N_GUIDE.md](./API_N8N_GUIDE.md) - n8n 使用範例
+- [API_WORDPRESS_GUIDE.md](./API_WORDPRESS_GUIDE.md) - WordPress 使用範例
diff --git a/docs/API_ENDPOINTS.md b/docs/API_ENDPOINTS.md
index 3989dfc..1773b8a 100644
--- a/docs/API_ENDPOINTS.md
+++ b/docs/API_ENDPOINTS.md
@@ -16,9 +16,34 @@
---
+## 認證
+
+除健康檢查端點外,所有 API 端點都需要 API Key。
+
+### Header 方式
+
+```bash
+curl -H "X-API-Key: your-api-key" http://localhost:3002/api/v1/videos
+```
+
+### 響應
+
+- `401 Unauthorized` - 缺少或無效的 API Key
+- `200 OK` - 認證成功
+
+### 取得 API Key
+
+使用 CLI 建立:
+
+```bash
+./target/release/momentry api-key create "My API Key" --key-type user
+```
+
+---
+
## 端點列表
-### 健康檢查
+### 健康檢查(公開)
| 方法 | 端點 | 說明 |
|------|------|------|
@@ -213,5 +238,7 @@ sudo launchctl load /Library/LaunchDaemons/com.momentry.api.plist
## 相關文件
- [API_INDEX.md](./API_INDEX.md) - 文件總覽(起點)
-- [API_N8N_GUIDE.md](./API_N8N_GUIDE.md) - n8n 使用範例
-- [API_WORDPRESS_GUIDE.md](./API_WORDPRESS_GUIDE.md) - WordPress 使用範例
+- [API_EXAMPLES.md](./API_EXAMPLES.md) - **完整範例總覽(curl / n8n / WordPress)**
+- [API_N8N_GUIDE.md](./API_N8N_GUIDE.md) - n8n 詳細指南
+- [API_WORDPRESS_GUIDE.md](./API_WORDPRESS_GUIDE.md) - WordPress 詳細指南
+- [API_CURL_EXAMPLES.md](./API_CURL_EXAMPLES.md) - curl 範例
diff --git a/docs/API_EXAMPLES.md b/docs/API_EXAMPLES.md
new file mode 100644
index 0000000..1abb193
--- /dev/null
+++ b/docs/API_EXAMPLES.md
@@ -0,0 +1,726 @@
+# Momentry Core API 使用範例總覽
+
+| 項目 | 內容 |
+|------|------|
+| 版本 | V2.0 |
+| 日期 | 2026-03-25 |
+| Base URL (本地) | `http://localhost:3002` |
+| Base URL (外部) | `https://api.momentry.ddns.net` |
+
+---
+
+## 快速參考
+
+### 環境 URL 選擇
+
+| 環境 | URL | 用途 |
+|------|-----|------|
+| **本地開發** | `http://localhost:3002` | 開發/測試,直接訪問 API |
+| **外部訪問** | `https://api.momentry.ddns.net` | n8n、WordPress、curl 生產環境 |
+
+### 所有可用端點
+
+| 方法 | 端點 | 說明 |
+|------|------|------|
+| GET | `/health` | 健康檢查 |
+| GET | `/health/detailed` | 詳細健康檢查 |
+| POST | `/api/v1/search` | 語意搜尋(標準格式) |
+| POST | `/api/v1/n8n/search` | 語意搜尋(n8n 格式) |
+| POST | `/api/v1/search/hybrid` | 混合搜尋 |
+| POST | `/api/v1/register` | 註冊影片 |
+| POST | `/api/v1/probe` | 探測影片資訊 |
+| GET | `/api/v1/videos` | 列出所有影片 |
+| GET | `/api/v1/lookup` | 查詢影片 |
+| GET | `/api/v1/progress/:uuid` | 處理進度 |
+| GET | `/api/v1/jobs` | 任務列表 |
+| GET | `/api/v1/jobs/:uuid` | 任務詳情 |
+
+---
+
+## 認證
+
+### API Key
+
+所有 `/api/v1/*` 端點需要 API Key 認證。
+
+```bash
+# 添加 API Key Header
+curl -H "X-API-Key: your-api-key" http://localhost:3002/api/v1/videos
+
+# 範例
+curl -H "X-API-Key: muser_f08e13ba967e4d8ea8fc542ad9f99ac8_1774416728_90472a35" \
+ http://localhost:3002/api/v1/videos
+```
+
+### 響應狀態
+
+| 狀態碼 | 說明 |
+|--------|------|
+| 200 | 成功 |
+| 401 | 未授權(缺少或無效 API Key) |
+| 500 | 伺服器錯誤 |
+
+### 建立 API Key
+
+```bash
+./target/release/momentry api-key create "My Key" --key-type user
+```
+
+---
+
+## 1. curl 範例
+
+### 基本語法
+
+```bash
+# 格式
+curl [OPTIONS] URL
+
+# 常用選項
+-X METHOD # HTTP 方法 (GET, POST, etc.)
+-H HEADER # 添加 HTTP 標頭
+-d DATA # POST 請求體
+-s # 靜默模式
+-w FORMAT # 輸出額外信息
+```
+
+### 1.1 健康檢查
+
+```bash
+# 基本健康檢查
+curl http://localhost:3002/health
+
+# 詳細健康檢查
+curl http://localhost:3002/health/detailed
+```
+
+**回應**:
+```json
+{"status":"ok","version":"0.1.0","uptime_ms":123456}
+```
+
+### 1.2 語意搜尋
+
+```bash
+# 標準格式搜尋
+curl -X POST http://localhost:3002/api/v1/search \
+ -H "Content-Type: application/json" \
+ -d '{"query": "charade", "limit": 5}'
+
+# n8n 格式搜尋(推薦)
+curl -X POST http://localhost:3002/api/v1/n8n/search \
+ -H "Content-Type: application/json" \
+ -d '{"query": "charade", "limit": 5}'
+
+# 混合搜尋
+curl -X POST http://localhost:3002/api/v1/search/hybrid \
+ -H "Content-Type: application/json" \
+ -d '{"query": "charade", "limit": 5}'
+```
+
+**標準格式回應**:
+```json
+{
+ "results": [
+ {
+ "uuid": "a1b10138a6bbb0cd",
+ "chunk_id": "sentence_0001",
+ "chunk_type": "sentence",
+ "start_time": 48.8,
+ "end_time": 55.44,
+ "text": "fun plot twists...",
+ "score": 0.92
+ }
+ ],
+ "query": "charade"
+}
+```
+
+**n8n 格式回應**:
+```json
+{
+ "query": "charade",
+ "count": 1,
+ "hits": [
+ {
+ "id": "sentence_0001",
+ "vid": "a1b10138a6bbb0cd",
+ "start": 48.8,
+ "end": 55.44,
+ "title": "Chunk sentence_0001",
+ "text": "fun plot twists...",
+ "score": 0.92,
+ "media_url": "https://wp.momentry.ddns.net/video.mp4"
+ }
+ ]
+}
+```
+
+### 1.3 影片管理
+
+```bash
+# 列出所有影片
+curl http://localhost:3002/api/v1/videos
+
+# 查詢特定影片(依 UUID)
+curl "http://localhost:3002/api/v1/lookup?uuid=a1b10138a6bbb0cd"
+
+# 查詢特定影片(依路徑)
+curl "http://localhost:3002/api/v1/lookup?path=/path/to/video.mp4"
+
+# 取得處理進度
+curl http://localhost:3002/api/v1/progress/a1b10138a6bbb0cd
+
+# 探測影片(不註冊)
+curl -X POST http://localhost:3002/api/v1/probe \
+ -H "Content-Type: application/json" \
+ -d '{"path": "/path/to/video.mp4"}'
+
+# 註冊影片
+curl -X POST http://localhost:3002/api/v1/register \
+ -H "Content-Type: application/json" \
+ -d '{"path": "/path/to/video.mp4", "file_name": "video.mp4"}'
+```
+
+### 1.4 批次測試腳本
+
+```bash
+#!/bin/bash
+# api_test.sh - API 測試腳本
+
+API_URL="http://localhost:3002"
+
+echo "=== 健康檢查 ==="
+curl -s "$API_URL/health" | jq .
+
+echo -e "\n=== 語意搜尋 ==="
+curl -s -X POST "$API_URL/api/v1/search" \
+ -H "Content-Type: application/json" \
+ -d '{"query": "charade", "limit": 3}' | jq .
+
+echo -e "\n=== 影片列表 ==="
+curl -s "$API_URL/api/v1/videos" | jq '.videos | length'
+```
+
+### 1.5 外部 URL 範例
+
+```bash
+# 使用外部 URL(需網路可達)
+curl https://api.momentry.ddns.net/health
+
+# 外部搜尋
+curl -X POST https://api.momentry.ddns.net/api/v1/n8n/search \
+ -H "Content-Type: application/json" \
+ -d '{"query": "charade", "limit": 5}'
+```
+
+---
+
+## 2. n8n 範例
+
+### 2.1 HTTP Request Node 設定
+
+```
+Node: HTTP Request
+├── URL: https://api.momentry.ddns.net/api/v1/n8n/search
+├── Method: POST
+├── Authentication: None
+├── Send Body: ✓ (checked)
+├── Content Type: JSON
+└── Body:
+ {
+ "query": "={{ $json.query }}",
+ "limit": "={{ $json.limit || 10 }}"
+ }
+```
+
+### 2.2 基本搜尋 Workflow
+
+```json
+{
+ "name": "Momentry Video Search",
+ "nodes": [
+ {
+ "parameters": {},
+ "name": "Manual Trigger",
+ "type": "n8n-nodes-base.manualTrigger",
+ "position": [250, 300]
+ },
+ {
+ "parameters": {
+ "url": "https://api.momentry.ddns.net/api/v1/n8n/search",
+ "method": "POST",
+ "sendBody": true,
+ "contentType": "json",
+ "body": {
+ "query": "charade",
+ "limit": 3
+ }
+ },
+ "name": "Search Video API",
+ "type": "n8n-nodes-base.httpRequest",
+ "position": [450, 300]
+ }
+ ],
+ "connections": {
+ "Manual Trigger": {
+ "main": [[{"node": "Search Video API"}]]
+ }
+ }
+}
+```
+
+### 2.3 Webhook 動態搜尋
+
+```json
+{
+ "name": "Momentry Dynamic Search",
+ "nodes": [
+ {
+ "parameters": {
+ "httpMethod": "POST",
+ "path": "search",
+ "responseMode": "lastNode"
+ },
+ "name": "Webhook",
+ "type": "n8n-nodes-base.webhook",
+ "position": [250, 300]
+ },
+ {
+ "parameters": {
+ "url": "https://api.momentry.ddns.net/api/v1/n8n/search",
+ "method": "POST",
+ "sendBody": true,
+ "contentType": "json",
+ "body": {
+ "query": "={{ JSON.stringify($json.body.query) }}",
+ "limit": "={{ $json.body.limit || 5 }}"
+ }
+ },
+ "name": "Search API",
+ "type": "n8n-nodes-base.httpRequest",
+ "position": [450, 300]
+ }
+ ],
+ "connections": {
+ "Webhook": {
+ "main": [[{"node": "Search API"}]]
+ }
+ }
+}
+```
+
+### 2.4 測試 Webhook
+
+```bash
+# 測試模式(需先在 n8n UI 點擊 Execute)
+curl -X POST http://localhost:5678/webhook-test/video-rag-mcp \
+ -H "Content-Type: application/json" \
+ -d '{"query":"charade","limit":3}'
+
+# 生產環境(需 workflow 為 Active 狀態)
+curl -X POST http://localhost:5678/webhook/video-rag-mcp \
+ -H "Content-Type: application/json" \
+ -d '{"query":"charade","limit":3}'
+```
+
+### 2.5 健康檢查 Workflow
+
+```json
+{
+ "name": "Momentry Health Check",
+ "nodes": [
+ {
+ "parameters": {},
+ "name": "Manual Trigger",
+ "type": "n8n-nodes-base.manualTrigger",
+ "position": [250, 300]
+ },
+ {
+ "parameters": {
+ "url": "https://api.momentry.ddns.net/health",
+ "method": "GET"
+ },
+ "name": "Health Check",
+ "type": "n8n-nodes-base.httpRequest",
+ "position": [450, 300]
+ }
+ ],
+ "connections": {
+ "Manual Trigger": {
+ "main": [[{"node": "Health Check"}]]
+ }
+ }
+}
+```
+
+### 2.6 錯誤處理
+
+| 錯誤 | 原因 | 解決 |
+|------|------|------|
+| 502 Bad Gateway | API 服務未啟動 | `sudo launchctl load /Library/LaunchDaemons/com.momentry.api.plist` |
+| "Your request is invalid" | Body 格式設定錯誤 | 確認 Content Type: JSON,Body 為有效 JSON |
+| 404 on webhook-test | 未執行 workflow | 在 n8n UI 點擊 "Execute workflow" |
+
+---
+
+## 3. WordPress 範例
+
+### 3.1 PHP 基本用法
+
+```php
+ 'charade',
+ 'limit' => 10
+];
+
+$response = wp_remote_post($api_url, [
+ 'headers' => ['Content-Type' => 'application/json'],
+ 'body' => json_encode($data),
+ 'timeout' => 30
+]);
+
+if (is_wp_error($response)) {
+ echo '錯誤: ' . $response->get_error_message();
+} else {
+ $body = json_decode(wp_remote_retrieve_body($response), true);
+ print_r($body['hits']);
+}
+?>
+```
+
+### 3.2 列出影片
+
+```php
+ 30]);
+
+if (!is_wp_error($response)) {
+ $body = json_decode(wp_remote_retrieve_body($response), true);
+ foreach ($body['videos'] as $video) {
+ echo $video['file_name'] . "\n";
+ }
+}
+?>
+```
+
+### 3.3 查詢特定影片
+
+```php
+ 30]);
+
+if (!is_wp_error($response)) {
+ $video = json_decode(wp_remote_retrieve_body($response), true);
+ echo '檔案: ' . $video['file_name'] . "\n";
+ echo '時長: ' . $video['duration'] . ' 秒';
+}
+?>
+```
+
+### 3.4 JavaScript fetch
+
+```javascript
+// 搜尋影片
+async function searchVideos(query, limit = 10) {
+ const response = await fetch('https://api.momentry.ddns.net/api/v1/n8n/search', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ query, limit })
+ });
+
+ if (!response.ok) {
+ throw new Error('API 請求失敗');
+ }
+
+ return await response.json();
+}
+
+// 使用範例
+searchVideos('charade', 5)
+ .then(data => {
+ data.hits.forEach(hit => {
+ console.log(`${hit.text} (score: ${hit.score})`);
+ });
+ });
+```
+
+### 3.5 WordPress Shortcode
+
+在 `functions.php` 中註冊短碼:
+
+```php
+ '',
+ 'limit' => '10'
+ ], $atts);
+
+ if (empty($atts['query'])) {
+ return '請提供搜尋關鍵字
';
+ }
+
+ $response = wp_remote_post('https://api.momentry.ddns.net/api/v1/n8n/search', [
+ 'headers' => ['Content-Type' => 'application/json'],
+ 'body' => json_encode([
+ 'query' => $atts['query'],
+ 'limit' => (int)$atts['limit']
+ ]),
+ 'timeout' => 30
+ ]);
+
+ if (is_wp_error($response)) {
+ return '搜尋服務暫時無法使用
';
+ }
+
+ $data = json_decode(wp_remote_retrieve_body($response), true);
+
+ if (empty($data['hits'])) {
+ return '找不到相關結果
';
+ }
+
+ $output = '';
+ foreach ($data['hits'] as $hit) {
+ $output .= sprintf(
+ '- %s 播放
',
+ esc_html($hit['text']),
+ $hit['media_url'],
+ $hit['start']
+ );
+ }
+ $output .= '
';
+
+ return $output;
+});
+?>
+```
+
+**使用方式**:
+```
+[momentry_search query="charade" limit="5"]
+```
+
+### 3.6 WordPress REST API Endpoint
+
+在 WordPress REST API 中註冊自定義端點:
+
+```php
+ 'POST',
+ 'callback' => function($request) {
+ $response = wp_remote_post(
+ 'https://api.momentry.ddns.net/api/v1/n8n/search',
+ [
+ 'headers' => ['Content-Type' => 'application/json'],
+ 'body' => json_encode([
+ 'query' => $request->get_param('query'),
+ 'limit' => $request->get_param('limit', 10)
+ ])
+ ]
+ );
+
+ if (is_wp_error($response)) {
+ return new WP_Error('api_error', 'API 請求失敗');
+ }
+
+ return json_decode(wp_remote_retrieve_body($response));
+ }
+ ]);
+});
+?>
+```
+
+**呼叫方式**:
+```
+POST /wp-json/momentry/v1/search
+Body: {"query": "charade", "limit": 5}
+```
+
+---
+
+## 4. 回應格式說明
+
+### 4.1 n8n 格式 (`/api/v1/n8n/search`)
+
+```json
+{
+ "query": "charade",
+ "count": 10,
+ "hits": [
+ {
+ "id": "sentence_0001",
+ "vid": "a1b10138a6bbb0cd",
+ "start": 48.8,
+ "end": 55.44,
+ "title": "Chunk sentence_0001",
+ "text": "fun plot twists...",
+ "score": 0.92,
+ "media_url": "https://wp.momentry.ddns.net/video.mp4"
+ }
+ ]
+}
+```
+
+### 4.2 標準格式 (`/api/v1/search`)
+
+```json
+{
+ "results": [
+ {
+ "uuid": "a1b10138a6bbb0cd",
+ "chunk_id": "sentence_0001",
+ "chunk_type": "sentence",
+ "start_time": 48.8,
+ "end_time": 55.44,
+ "text": "fun plot twists...",
+ "score": 0.92
+ }
+ ],
+ "query": "charade"
+}
+```
+
+### 4.3 健康檢查
+
+```json
+{
+ "status": "ok",
+ "version": "0.1.0",
+ "uptime_ms": 123456
+}
+```
+
+### 4.4 詳細健康檢查
+
+```json
+{
+ "status": "ok",
+ "version": "0.1.0",
+ "uptime_ms": 123456,
+ "services": {
+ "postgres": {"status": "ok", "latency_ms": 42, "error": null},
+ "redis": {"status": "ok", "latency_ms": 0, "error": null},
+ "qdrant": {"status": "ok", "latency_ms": 15, "error": null},
+ "mongodb": {"status": "ok", "latency_ms": 0, "error": null}
+ }
+}
+```
+
+### 4.5 處理進度
+
+```json
+{
+ "uuid": "a1b10138a6bbb0cd",
+ "file_name": "video.mp4",
+ "duration": 120.5,
+ "overall_progress": 75,
+ "processors": [
+ {"name": "asr", "status": "complete", "progress": 100},
+ {"name": "cut", "status": "complete", "progress": 100},
+ {"name": "yolo", "status": "progress", "progress": 35}
+ ]
+}
+```
+
+### 4.6 Probe 回應
+
+```json
+{
+ "uuid": "a1b10138a6bbb0cd",
+ "file_name": "video.mp4",
+ "duration": 120.5,
+ "width": 1920,
+ "height": 1080,
+ "fps": 30.0,
+ "cached": false,
+ "format": {
+ "filename": "/path/to/video.mp4",
+ "format_name": "mov,mp4,m4a,3gp,3g2,mj2",
+ "duration": "120.5",
+ "size": "12345678",
+ "bit_rate": "819200"
+ },
+ "streams": [
+ {
+ "index": 0,
+ "codec_name": "h264",
+ "codec_type": "video",
+ "width": 1920,
+ "height": 1080,
+ "r_frame_rate": "30/1",
+ "duration": "120.5"
+ }
+ ]
+}
+```
+
+---
+
+## 5. HTTP 狀態碼
+
+| 狀態 | 說明 | 解決 |
+|------|------|------|
+| 200 | 成功 | - |
+| 400 | 請求格式錯誤 | 檢查 JSON 格式 |
+| 404 | 端點或資源不存在 | 確認 URL 正確 |
+| 500 | 伺服器內部錯誤 | 檢查 API 服務日誌 |
+| 502 | API 服務未啟動 | 見下方說明 |
+
+### 502 Bad Gateway 解決
+
+```bash
+# 檢查服務狀態
+launchctl list | grep momentry.api
+
+# 啟動服務
+sudo launchctl load /Library/LaunchDaemons/com.momentry.api.plist
+
+# 或使用本地測試
+curl http://localhost:3002/health
+```
+
+---
+
+## 6. 常見問題
+
+### Q: 為什麼有兩個 URL?
+
+| URL | 用途 |
+|-----|------|
+| `localhost:3002` | 直接訪問,繞過反向代理 |
+| `api.momentry.ddns.net` | 通過 Caddy 反向代理 |
+
+### Q: 兩者功能相同嗎?
+
+是的,所有端點和功能完全相同。
+
+### Q: n8n webhook-test 返回 404?
+
+需在 n8n UI 中點擊 "Execute workflow" 按鈕後才能使用測試 Webhook。
+
+### Q: 生產環境 webhook 返回 404?
+
+需將 workflow 切換為 Active 狀態(右上角開關)。
+
+---
+
+## 相關文件
+
+- [API_INDEX.md](./API_INDEX.md) - 文件總覽
+- [API_ENDPOINTS.md](./API_ENDPOINTS.md) - 端點完整說明
+- [API_N8N_GUIDE.md](./API_N8N_GUIDE.md) - n8n 詳細指南
+- [API_WORDPRESS_GUIDE.md](./API_WORDPRESS_GUIDE.md) - WordPress 詳細指南
diff --git a/docs/API_INDEX.md b/docs/API_INDEX.md
new file mode 100644
index 0000000..8a112d9
--- /dev/null
+++ b/docs/API_INDEX.md
@@ -0,0 +1,102 @@
+# Momentry Core API 文件總覽
+
+| 項目 | 內容 |
+|------|------|
+| 版本 | V2.1 |
+| 日期 | 2026-03-25 |
+
+---
+
+## 文件架構
+
+```
+docs/
+├── API_INDEX.md ← 本文件:總覽與入口
+├── API_ENDPOINTS.md ← API 端點完整說明
+├── API_EXAMPLES.md ← 完整範例總覽(curl / n8n / WordPress)
+├── DEMO_MANUAL.md ← ⭐ 示範手冊(含 Demo API Key)
+├── API_N8N_GUIDE.md ← n8n 詳細指南
+├── API_WORDPRESS_GUIDE.md ← WordPress 詳細指南
+├── API_CURL_EXAMPLES.md ← curl 快速範例
+└── API_REFERENCE.md ← 詳細技術參考
+```
+
+---
+
+## 快速選擇指南
+
+| 需求 | 閱讀文件 |
+|------|----------|
+| **我要快速開始測試** | ⭐ [DEMO_MANUAL.md](./DEMO_MANUAL.md) |
+| **我要查看所有範例** | [API_EXAMPLES.md](./API_EXAMPLES.md) |
+| 我想了解有哪些 API 端點 | [API_ENDPOINTS.md](./API_ENDPOINTS.md) |
+| 我要在 n8n workflow 中呼叫 API | [DEMO_MANUAL.md](./DEMO_MANUAL.md#2-n8n-範例) |
+| 我要在 WordPress 中呼叫 API | [DEMO_MANUAL.md](./DEMO_MANUAL.md#3-wordpress-範例) |
+| 我要用 curl 快速測試 | [DEMO_MANUAL.md](./DEMO_MANUAL.md#1-curl-範例) |
+
+---
+
+## 認證
+
+### Demo API Key
+
+```
+API Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69
+Key ID: muser_68600856036340bcafc01930eb4bd839
+過期日: 2027-03-25
+```
+
+### 使用方式
+
+```bash
+curl -H "X-API-Key: muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69" \
+ http://localhost:3002/api/v1/videos
+```
+
+---
+
+## API URL 選擇
+
+| 環境 | URL | 使用時機 |
+|------|-----|----------|
+| **本地開發** | `http://localhost:3002` | 開發/測試、繞過反向代理 |
+| **外部訪問** | `https://api.momentry.ddns.net` | n8n、WordPress、遠端系統 |
+
+### 何時用哪個
+
+**使用 `localhost:3002`:**
+- 本地終端機測試
+- 當反向代理有問題時
+- 快速除錯
+
+**使用 `api.momentry.ddns.net`:**
+- n8n workflow
+- WordPress 網站
+- 外部系統整合
+
+---
+
+## 常見問題
+
+### Q: API 返回 401 錯誤?
+API Key 無效或過期。請使用 Demo API Key 或建立新的 API Key。
+
+### Q: API 返回 502 錯誤?
+```bash
+# 檢查服務狀態
+launchctl list | grep momentry.api
+
+# 如未啟動
+sudo launchctl load /Library/LaunchDaemons/com.momentry.api.plist
+```
+
+### Q: 兩個 URL 功能相同嗎?
+是的,所有端點完全相同,只是訪問路徑不同。
+
+---
+
+## 相關文件
+
+- [DEMO_MANUAL.md](./DEMO_MANUAL.md) - ⭐ 示範手冊(推薦新手)
+- [INSTALL_MOMENTRY_API.md](./INSTALL_MOMENTRY_API.md) - API 服務安裝指南
+- [PENDING_ISSUES.md](./PENDING_ISSUES.md) - 待解決問題追蹤
diff --git a/docs/API_KEY_ARCHITECTURE.md b/docs/API_KEY_ARCHITECTURE.md
new file mode 100644
index 0000000..ff0a4d1
--- /dev/null
+++ b/docs/API_KEY_ARCHITECTURE.md
@@ -0,0 +1,195 @@
+# API Key Management System Architecture
+
+## System Overview
+
+```
+┌─────────────────────────────────────────────────────────────────────────────────┐
+│ API Key Management System │
+├─────────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
+│ │ CLI │ │ HTTP API │ │ Service │ │ External │ │
+│ │ Layer │────▶│ Layer │────▶│ Layer │────▶│ Services │ │
+│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
+│ │ │ │ │ │
+│ │ │ │ │ │
+│ ▼ ▼ ▼ ▼ │
+│ ┌─────────────────────────────────────────────────────────────────────────┐ │
+│ │ Core Modules │ │
+│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
+│ │ │ Service │ │Validator│ │ Anomaly │ │Rotation │ │ Cleanup │ │ │
+│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
+│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
+│ │ │ Webhook │ │Encrypt │ │Blacklist│ │ Report │ │ Error │ │ │
+│ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │
+│ └─────────────────────────────────────────────────────────────────────────┘ │
+│ │ │ │ │
+│ ▼ ▼ ▼ │
+│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
+│ │ PostgreSQL │ │ Redis │ │ External │ │
+│ │ (Storage) │ │ (Cache) │ │ (Gitea/n8n)│ │
+│ └─────────────┘ └─────────────┘ └─────────────┘ │
+│ │
+└─────────────────────────────────────────────────────────────────────────────────┘
+```
+
+## Module Dependencies
+
+```
+ ┌──────────────┐
+ │ models.rs │
+ │ (Types) │
+ └──────┬───────┘
+ │
+ ┌──────────────────┼──────────────────┐
+ │ │ │
+ ▼ ▼ ▼
+┌───────────────┐ ┌───────────────┐ ┌───────────────┐
+│ service.rs │ │ error.rs │ │ validator.rs │
+│ (Core CRUD) │ │ (Errors) │ │ (Cache+Rate) │
+└───────┬───────┘ └───────────────┘ └───────────────┘
+ │
+ │ ┌───────────────────────────────┐
+ │ │ │
+ ▼ ▼ ▼
+┌───────────────┐ ┌───────────────┐ ┌───────────────┐
+│ anomaly.rs │ │ rotation.rs │ │ blacklist.rs │
+│ (Detection) │ │ (Rotation) │ │ (IP Block) │
+└───────────────┘ └───────────────┘ └───────────────┘
+```
+
+## Request Flow
+
+```
+Client Request
+ │
+ ▼
+┌─────────────┐
+│ CLI/API │
+└──────┬──────┘
+ │
+ ▼
+┌─────────────┐ ┌─────────────┐
+│ Rate Limit │────▶│ IP Blacklist│
+│ Check │ │ Check │
+└──────┬──────┘ └──────┬──────┘
+ │ │
+ └─────────┬─────────┘
+ │
+ ▼
+ ┌───────────────┐
+ │ Hash API Key │
+ └───────┬───────┘
+ │
+ ▼
+ ┌───────────────┐ ┌───────────────┐
+ │ Cache Lookup │────▶│ PostgreSQL │
+ └───────┬───────┘ │ Lookup │
+ │ └───────┬───────┘
+ │ │
+ └──────────┬──────────┘
+ │
+ ▼
+ ┌───────────────┐
+ │ Validate │
+ │ (Status, │
+ │ Expiry) │
+ └───────┬───────┘
+ │
+ ┌─────────────┼─────────────┐
+ │ │ │
+ ▼ ▼ ▼
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
+ │ Valid │ │ Invalid │ │ Error │
+ │ Response│ │ Response │ │ Response │
+ └──────────┘ └──────────┘ └──────────┘
+```
+
+## Database Schema
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│ PostgreSQL │
+├─────────────────────────────────────────────────────────────────┤
+│ │
+│ ┌─────────────────┐ ┌─────────────────┐ │
+│ │ api_keys │ │ api_key_audit_ │ │
+│ ├─────────────────┤ │ log │ │
+│ │ id │ ├─────────────────┤ │
+│ │ key_id │─────▶│ id │ │
+│ │ key_hash │ │ key_id (FK) │ │
+│ │ name │ │ action │ │
+│ │ key_type │ │ ip_address │ │
+│ │ status │ │ details │ │
+│ │ expires_at │ └─────────────────┘ │
+│ │ ... │ │
+│ └─────────────────┘ ┌─────────────────┐ │
+│ │ api_key_anomalies│ │
+│ ┌─────────────────┐ ├─────────────────┤ │
+│ │ gitea_tokens │ │ id │ │
+│ ├─────────────────┤ │ key_id (FK) │ │
+│ │ id │ │ anomaly_type │ │
+│ │ gitea_token_id │ │ severity │ │
+│ │ token_name │ │ details │ │
+│ │ scopes │ └─────────────────┘ │
+│ └─────────────────┘ │
+│ │
+│ ┌─────────────────┐ │
+│ │ n8n_api_keys │ │
+│ ├─────────────────┤ │
+│ │ id │ │
+│ │ n8n_key_id │ │
+│ │ label │ │
+│ └─────────────────┘ │
+│ │
+└─────────────────────────────────────────────────────────────────┘
+```
+
+## External Integrations
+
+```
+┌─────────────────────────────────────────────────────────────────────────────────┐
+│ External Integrations │
+├─────────────────────────────────────────────────────────────────────────────────┤
+│ │
+│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
+│ │ Gitea │ │ n8n │ │ Webhook │ │
+│ ├─────────────────┤ ├─────────────────┤ ├─────────────────┤ │
+│ │ • Create Token │ │ • Create API Key│ │ • Key Created │ │
+│ │ • List Tokens │ │ • List API Keys │ │ • Key Revoked │ │
+│ │ • Delete Token │ │ • Delete API Key│ │ • Anomaly │ │
+│ │ • Verify Token │ │ • Verify │ │ • Rate Limited │ │
+│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
+│ │
+└─────────────────────────────────────────────────────────────────────────────────┘
+```
+
+## Security Layers
+
+```
+┌─────────────────────────────────────────────────────────────────┐
+│ Security Layers │
+├─────────────────────────────────────────────────────────────────┤
+│ │
+│ Layer 1: Network │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ • IP Blacklist │ │
+│ │ • Rate Limiting │ │
+│ └─────────────────────────────────────────────────────────┘ │
+│ │
+│ Layer 2: Authentication │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ • API Key Hash (SHA256) │ │
+│ │ • Constant-time Comparison │ │
+│ │ • Key Validation (Status, Expiry) │ │
+│ └─────────────────────────────────────────────────────────┘ │
+│ │
+│ Layer 3: Monitoring │
+│ ┌─────────────────────────────────────────────────────────┐ │
+│ │ • Anomaly Detection │ │
+│ │ • Audit Logging (Encrypted) │ │
+│ │ • Webhook Notifications │ │
+│ └─────────────────────────────────────────────────────────┘ │
+│ │
+└─────────────────────────────────────────────────────────────────┘
+```
diff --git a/docs/API_KEY_INTEGRATION_TESTS.md b/docs/API_KEY_INTEGRATION_TESTS.md
new file mode 100644
index 0000000..366610c
--- /dev/null
+++ b/docs/API_KEY_INTEGRATION_TESTS.md
@@ -0,0 +1,236 @@
+# API Key Management Integration Tests
+
+## Test Environment Setup
+
+### Prerequisites
+
+```bash
+# Start services
+sudo launchctl load /Library/LaunchDaemons/com.momentry.postgresql.plist
+sudo launchctl load /Library/LaunchDaemons/com.momentry.redis.plist
+
+# Set environment variables
+export DATABASE_URL="postgres://accusys@localhost:5432/momentry"
+export REDIS_URL="redis://:accusys@localhost:6379"
+export GITEA_URL="http://localhost:3000"
+export N8N_URL="https://n8n.momentry.ddns.net"
+```
+
+### Run Tests
+
+```bash
+# Run all unit tests
+cargo test --lib
+
+# Run API key specific tests
+cargo test --lib api_key
+
+# Run with output
+cargo test --lib -- --nocapture
+```
+
+---
+
+## Test Cases
+
+### 1. API Key Creation
+
+```bash
+# Test: Create a service key
+momentry api-key create test-key --key-type service --ttl 90
+
+# Expected Output:
+# ✅ API Key created successfully!
+# Key ID: msvc_...
+# API Key: msvc_...
+# Expires: 2026-06-19
+```
+
+### 2. API Key Validation
+
+```bash
+# Test: Validate the created key
+momentry api-key validate --key "msvc_..."
+
+# Expected Output:
+# ✅ API Key is valid
+# Key ID: msvc_...
+# Name: test-key
+# Type: service
+```
+
+### 3. API Key Listing
+
+```bash
+# Test: List all keys
+momentry api-key list
+
+# Expected Output:
+# 📋 API Key List
+# ┌────────────────────────────────────────────────────────────────────────────┐
+# │ Status │ Name │ Type │ Usage │ Last Used │
+# ├────────────────────────────────────────────────────────────────────────────┤
+# │ ✓ active │ test-key │ "service" │ 0 │ never │
+# └────────────────────────────────────────────────────────────────────────────┘
+```
+
+### 4. API Key Statistics
+
+```bash
+# Test: Show statistics
+momentry api-key stats
+
+# Expected Output:
+# 📊 API Key Statistics
+# ┌─────────────────────────────────────────┐
+# │ Total Keys: 1 │
+# │ Active Keys: 1 │
+# │ Expired Keys: 0 │
+# └─────────────────────────────────────────┘
+```
+
+### 5. Gitea Token Creation
+
+```bash
+# Test: Create Gitea token
+momentry gitea create \
+ --username admin \
+ --password "Test3200Test3200Test3200" \
+ --token-name "test-token" \
+ --scopes "read:repository,write:repository"
+
+# Expected Output:
+# ✅ Gitea Token created successfully!
+# Token ID: ...
+# SHA1: ...
+```
+
+### 6. n8n API Key Creation
+
+```bash
+# Test: Create n8n API key
+momentry n8n create \
+ --api-key "existing-n8n-key" \
+ --label "test-key" \
+ --expires-in-days 90
+
+# Expected Output:
+# ✅ n8n API Key created successfully!
+# Key ID: ...
+# API Key: ...
+```
+
+---
+
+## Automated Test Script
+
+```bash
+#!/bin/bash
+# integration_test.sh
+
+set -e
+
+echo "=== API Key Integration Tests ==="
+
+# 1. Create API key
+echo "1. Testing API key creation..."
+momentry api-key create integration-test --key-type service --ttl 30
+echo "✅ API key created"
+
+# 2. List keys
+echo "2. Testing API key listing..."
+momentry api-key list
+echo "✅ API key list OK"
+
+# 3. Show stats
+echo "3. Testing statistics..."
+momentry api-key stats
+echo "✅ Statistics OK"
+
+# 4. Test Gitea integration
+echo "4. Testing Gitea integration..."
+GITEA_URL="http://localhost:3000" \
+momentry gitea list --username admin --password "Test3200Test3200Test3200"
+echo "✅ Gitea integration OK"
+
+echo ""
+echo "=== All Tests Passed ==="
+```
+
+---
+
+## Unit Test Coverage
+
+| Module | Tests | Status |
+|--------|-------|--------|
+| `models.rs` | 0 | ✅ |
+| `service.rs` | 5 | ✅ |
+| `validator.rs` | 2 | ✅ |
+| `gitea.rs` | 3 | ✅ |
+| `n8n.rs` | 2 | ✅ |
+| `rotation.rs` | 4 | ✅ |
+| `anomaly.rs` | 0 | ✅ |
+| `blacklist.rs` | 5 | ✅ |
+| `encryption.rs` | 2 | ✅ |
+| `webhook.rs` | 2 | ✅ |
+| `error.rs` | 3 | ✅ |
+| `report.rs` | 1 | ✅ |
+| `cleanup.rs` | 1 | ✅ |
+| **Total** | **30** | **✅** |
+
+---
+
+## CI/CD Integration
+
+### GitHub Actions / Gitea Actions
+
+```yaml
+name: API Key Tests
+
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ services:
+ postgres:
+ image: postgres:15
+ env:
+ POSTGRES_USER: accusys
+ POSTGRES_DB: momentry_test
+ ports:
+ - 5432:5432
+ redis:
+ image: redis:7
+ ports:
+ - 6379:6379
+
+ steps:
+ - uses: actions/checkout@v4
+ - uses: dtolnay/rust-toolchain@stable
+ - run: cargo test --lib api_key
+```
+
+---
+
+## Troubleshooting
+
+### Common Issues
+
+1. **Database connection failed**
+ ```bash
+ # Check PostgreSQL status
+ pg_isready -h localhost -p 5432
+ ```
+
+2. **Redis connection failed**
+ ```bash
+ # Check Redis status
+ redis-cli -a accusys ping
+ ```
+
+3. **Gitea authentication failed**
+ ```bash
+ # Verify credentials
+ curl -u admin:password http://localhost:3000/api/v1/user
+ ```
diff --git a/docs/API_KEY_MANAGEMENT.md b/docs/API_KEY_MANAGEMENT.md
new file mode 100644
index 0000000..a36cf5a
--- /dev/null
+++ b/docs/API_KEY_MANAGEMENT.md
@@ -0,0 +1,699 @@
+# Momentry API Key 管理系統設計
+
+| 項目 | 內容 |
+|------|------|
+| 版本 | V1.2 |
+| 日期 | 2026-03-21 |
+| 狀態 | 開發中 |
+
+---
+
+## 1. 概述
+
+### 1.1 目標
+
+建立安全的 API Key 管理機制,支援:
+- 多類型 API Key(系統、用戶、服務)
+- 自動過期與輪換
+- 異常使用偵測
+- 強制更新機制
+- 完整審計日誌
+- Gitea Token 整合
+- n8n API Key 整合
+
+### 1.2 設計原則
+
+| 原則 | 說明 |
+|------|------|
+| 最小權限 | 每個 Key 僅授予必要權限 |
+| 定期輪換 | 自動過期強制更新 |
+| 追蹤可審 | 所有操作都有日誌 |
+| 分離儲存 | Key 與使用者資料分離 |
+
+---
+
+## 2. API Key 類型
+
+### 2.1 Key 類型矩陣
+
+| 類型 | 前綴 | 用途 | 預設有效期 | 輪換方式 |
+|------|------|------|------------|----------|
+| `system` | `msys_` | 系統內部服務 | 365 天 | 手動 |
+| `user` | `muser_` | 個人用戶 | 90 天 | 自動 |
+| `service` | `msvc_` | 服務間通訊 | 180 天 | 自動 |
+| `integration` | `mint_` | 第三方整合 | 30 天 | 強制更新 |
+| `emergency` | `memg_` | 緊急存取 | 24 小時 | 一次性 |
+
+### 2.2 Key 格式
+
+```
+{prefix}{uuid_v4}_{timestamp}_{checksum}
+```
+
+**範例:**
+```
+msys_a1b2c3d4-e5f6-7890-abcd-ef1234567890_1710998400_sha256
+```
+
+---
+
+## 3. 資料庫 Schema
+
+### 3.1 api_keys 表
+
+```sql
+CREATE TABLE api_keys (
+ id BIGSERIAL PRIMARY KEY,
+ key_id VARCHAR(64) UNIQUE NOT NULL, -- 公開 Key ID
+ key_hash VARCHAR(128) NOT NULL, -- SHA256 哈希
+ key_prefix VARCHAR(8) NOT NULL, -- Key 前綴
+ name VARCHAR(128) NOT NULL, -- Key 名稱
+ key_type VARCHAR(32) NOT NULL, -- system/user/service/integration/emergency
+ user_id BIGINT, -- 關聯用戶 (nullable for system)
+ service_name VARCHAR(64), -- 服務名稱 (for service keys)
+ permissions JSONB NOT NULL DEFAULT '[]', -- 權限列表
+ expires_at TIMESTAMP, -- 過期時間
+ last_used_at TIMESTAMP, -- 最後使用時間
+ last_used_ip VARCHAR(45), -- 最後使用 IP
+ usage_count BIGINT DEFAULT 0, -- 使用次數
+ status VARCHAR(16) DEFAULT 'active', -- active/suspended/expired/revoked
+ rotation_required BOOLEAN DEFAULT FALSE, -- 強制輪換標記
+ rotation_reason VARCHAR(256), -- 輪換原因
+ created_at TIMESTAMP DEFAULT NOW(),
+ updated_at TIMESTAMP DEFAULT NOW()
+);
+
+CREATE INDEX idx_api_keys_key_id ON api_keys(key_id);
+CREATE INDEX idx_api_keys_user_id ON api_keys(user_id);
+CREATE INDEX idx_api_keys_type ON api_keys(key_type);
+CREATE INDEX idx_api_keys_status ON api_keys(status);
+CREATE INDEX idx_api_keys_expires ON api_keys(expires_at);
+```
+
+### 3.2 api_key_audit_log 表
+
+```sql
+CREATE TABLE api_key_audit_log (
+ id BIGSERIAL PRIMARY KEY,
+ key_id VARCHAR(64) NOT NULL,
+ action VARCHAR(32) NOT NULL, -- created/used/rotated/revoked/expired/suspended
+ actor VARCHAR(64), -- 操作者 (user_id or 'system')
+ ip_address VARCHAR(45),
+ user_agent VARCHAR(512),
+ request_path VARCHAR(256),
+ response_code INTEGER,
+ details JSONB,
+ created_at TIMESTAMP DEFAULT NOW()
+);
+
+CREATE INDEX idx_audit_key_id ON api_key_audit_log(key_id);
+CREATE INDEX idx_audit_action ON api_key_audit_log(action);
+CREATE INDEX idx_audit_created ON api_key_audit_log(created_at);
+```
+
+### 3.3 api_key_rotation_log 表
+
+```sql
+CREATE TABLE api_key_rotation_log (
+ id BIGSERIAL PRIMARY KEY,
+ key_id VARCHAR(64) NOT NULL,
+ old_key_id VARCHAR(64),
+ new_key_id VARCHAR(64),
+ rotation_type VARCHAR(32) NOT NULL, -- scheduled/manual/forced/emergency
+ reason VARCHAR(256),
+ triggered_by VARCHAR(64), -- system/user/scheduler
+ grace_period_end TIMESTAMP, -- 寬限期結束時間
+ created_at TIMESTAMP DEFAULT NOW()
+);
+```
+
+---
+
+## 4. API Key 狀態機
+
+```
+ ┌──────────────┐
+ │ created │
+ └──────┬───────┘
+ │
+ ▼
+ ┌────────────────────┐
+ │ active │◄─────────────┐
+ └─────────┬──────────┘ │
+ │ │
+ ┌─────────────┼─────────────┐ │
+ │ │ │ │
+ ▼ ▼ ▼ │
+ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
+ │ suspended │ │ expired │ │ revoked │─────┘
+ └──────────┘ └──────────┘ └──────────┘
+```
+
+### 狀態轉換規則
+
+| 從 | 到 | 觸發條件 |
+|----|----|----------|
+| created | active | 啟用 Key |
+| active | suspended | 異常使用偵測 |
+| active | expired | 達到過期時間 |
+| active | revoked | 手動撤銷 |
+| suspended | active | 解除鎖定 |
+| suspended | revoked | 確認異常 |
+| expired | active | 重新啟用 |
+
+---
+
+## 5. 異常偵測機制
+
+### 5.1 異常指標
+
+| 指標 | 閾值 | 處置 |
+|------|------|------|
+| 每分鐘請求數 | > 1000 | 警告 |
+| 每小時請求數 | > 10000 | 鎖定 |
+| 錯誤率 | > 50% | 警告 |
+| 不同 IP 數 | > 5/小時 | 警告 |
+| 非工作時間使用 | 深夜請求 | 警告 |
+| 異常模式 | 暴力破解 | 鎖定 |
+
+### 5.2 異常處理流程
+
+```
+異常偵測
+ │
+ ▼
+┌─────────┐
+│ 分析 │──→ 排除正常流量
+└────┬────┘
+ │
+ ▼
+┌─────────┐
+│ 評估 │──→ 輕微 → 警告
+└────┬────┘
+ │
+ ▼
+┌─────────┐
+│ 處置 │──→ 嚴重 → 鎖定 + 輪換
+└─────────┘
+```
+
+---
+
+## 6. 強制更新機制
+
+### 6.1 觸發條件
+
+| 條件 | 嚴重性 | 動作 |
+|------|--------|------|
+| 疑似洩露 | 高 | 立即停用 + 強制輪換 |
+| 異常使用 | 中 | 警告 + 建議輪換 |
+| 計劃性維護 | 低 | 通知 + 排程輪換 |
+| 政策要求 | 高 | 強制輪換 |
+| 過期 | 低 | 停用 + 通知 |
+
+### 6.2 強制輪換流程
+
+```
+1. 系統偵測到需要強制更新
+ │
+ ▼
+2. 建立新 Key(保留舊 Key 在寬限期內)
+ │
+ ▼
+3. 發送通知(Email/Slack/Redis PubSub)
+ │
+ ▼
+4. 寬限期開始(預設 24 小時)
+ │
+ ├── 在寬限期內更新 → 完成輪換
+ │
+ └── 寬限期結束 → 舊 Key 停用
+```
+
+### 6.3 寬限期配置
+
+| Key 類型 | 寬限期 |
+|----------|--------|
+| system | 72 小時 |
+| user | 24 小時 |
+| service | 48 小時 |
+| integration | 24 小時 |
+| emergency | 0 小時 |
+
+---
+
+## 7. CLI 管理命令
+
+### 7.1 命令列表
+
+```bash
+# Key 管理
+momentry api-key create --name "My Key" --type user --permissions read,write
+momentry api-key list --type user
+momentry api-key info
+momentry api-key revoke --reason "安全原因"
+
+# 輪換管理
+momentry api-key rotate # 正常輪換
+momentry api-key force-rotate # 強制輪換
+momentry api-key rotation-status # 查看輪換狀態
+
+# 異常管理
+momentry api-key suspend --reason "異常使用"
+momentry api-key unsuspend
+momentry api-key blacklist # 列入黑名單
+
+# 審計
+momentry api-key audit --since 7d
+momentry api-key stats --type service --period 30d
+```
+
+### 7.2 輸出範例
+
+```bash
+$ momentry api-key list --type service
+
+┌────────────────────────────────────┬─────────┬──────────────┬────────────────┐
+│ Key ID │ Name │ Status │ Expires │
+├────────────────────────────────────┼─────────┼──────────────┼────────────────┤
+│ msvc_a1b2c3d4_1710998400_sha256 │ N8N │ active │ 2026-09-21 │
+│ msvc_e5f6g7h8_1713600000_sha256 │ OpenCode│ rotation_req │ 2026-09-21 │
+└────────────────────────────────────┴─────────┴──────────────┴────────────────┘
+
+⚠️ 1 個 Key 需要輪換
+```
+
+---
+
+## 8. 實現計畫
+
+### Phase 1: 核心功能
+- [ ] 資料庫 Schema
+- [ ] Key 生成與哈希
+- [ ] 基本 CRUD API
+- [ ] 過期檢查
+
+### Phase 2: 安全機制
+- [ ] 異常偵測
+- [ ] 自動鎖定
+- [ ] 強制輪換
+- [ ] 寬限期管理
+
+### Phase 3: 管理工具
+- [ ] CLI 命令
+- [ ] 審計日誌
+- [ ] 統計報表
+- [ ] 通知系統
+
+### Phase 4: 自動化
+- [ ] 定時輪換排程
+- [ ] Prometheus 指標
+- [ ] Alertmanager 整合
+- [ ] 自動化回應
+
+---
+
+## 9. 安全考量
+
+### 9.1 Key 儲存
+- 明文 Key 只顯示一次(創建時)
+- 儲存時使用 SHA256 哈希
+- 使用 Fernet 對稱加密敏感配置
+
+### 9.2 傳輸安全
+- 所有 API 必須使用 HTTPS
+- Key 在 Header 中傳輸(X-API-Key)
+- 避免 Key 在 URL 中
+
+### 9.3 存取控制
+- 只有管理員可創建/撤銷 Key
+- 用戶只能管理自己的 Key
+- 系統 Key 需要特殊權限
+
+---
+
+## 10. 環境變數配置
+
+```bash
+# API Key 管理
+MOMENTRY_API_KEY_GRACE_PERIOD=86400 # 寬限期(秒)
+MOMENTRY_API_KEY_MAX_PER_USER=5 # 每用戶最大 Key 數
+MOMENTRY_API_KEY_ROTATION_DAYS=90 # 自動輪換天數
+
+# 異常偵測
+MOMENTRY_API_KEY_RATE_LIMIT=1000 # 每分鐘限制
+MOMENTRY_API_KEY_ERROR_THRESHOLD=0.5 # 錯誤率閾值
+MOMENTRY_API_KEY_IP_LIMIT=5 # 每小時 IP 限制
+
+# 通知
+MOMENTRY_API_KEY_ALERT_WEBHOOK= # 異常通知 webhook
+```
+
+---
+
+## 11. Gitea API Token 整合
+
+### 11.1 概述
+
+支援透過 API Key 管理系統建立和管理 Gitea Personal Access Tokens,採用「建立時納管」模式。
+
+### 11.2 納管模式
+
+```
+使用者提供帳號密碼 → 呼叫 Gitea API 建立 Token → 明文只顯示一次 → 同步儲存至管理系統
+```
+
+**特點:**
+- Token 明文僅在建立時取得
+- 管理系統記錄 Token 元數據(不含明文)
+- 支援本地查詢和刪除
+
+### 11.3 資料庫結構
+
+```sql
+CREATE TABLE gitea_tokens (
+ id SERIAL PRIMARY KEY,
+ gitea_token_id BIGINT NOT NULL, -- Gitea 內部 Token ID
+ gitea_user VARCHAR(128) NOT NULL, -- Gitea 用戶名
+ token_name VARCHAR(128) NOT NULL, -- Token 名稱
+ token_last_eight VARCHAR(8) NOT NULL, -- SHA1 最後 8 碼(顯示用)
+ scopes JSONB DEFAULT '[]', -- 權限範圍
+ api_key_id VARCHAR(48), -- 關聯的 API Key ID(可選)
+ last_verified TIMESTAMP, -- 最後驗證時間
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ UNIQUE(gitea_user, token_name)
+);
+```
+
+### 11.4 Token 權限範圍
+
+| 範圍 | 說明 |
+|------|------|
+| `read:repository` | 讀取倉庫 |
+| `write:repository` | 寫入倉庫 |
+| `read:issue` | 讀取議題 |
+| `write:issue` | 寫入議題 |
+| `read:user` | 讀取用戶資訊 |
+| `write:write` | 修改用戶資訊 |
+| `read:organization` | 讀取組織 |
+| `write:organization` | 修改組織 |
+| `read:package` | 讀取套件 |
+| `write:package` | 發布套件 |
+| `read:notification` | 讀取通知 |
+| `write:notification` | 修改通知 |
+| `read:admin` | 管理員讀取 |
+| `write:admin` | 管理員寫入 |
+
+### 11.5 CLI 命令
+
+#### 建立 Token
+
+```bash
+# 基本用法
+momentry gitea create \
+ --username \
+ --password \
+ --token-name \
+ --scopes "read:repository,write:repository"
+
+# 範例:建立整合用 Token
+momentry gitea create \
+ --username admin \
+ --password "MyPassword123" \
+ --token-name "ci-pipeline" \
+ --scopes "read:repository,write:repository,read:issue,write:issue"
+```
+
+**輸出範例:**
+```
+✅ Gitea Token created successfully!
+
+┌─────────────────────────────────────────────────────────────────────────────┐
+│ ⚠️ IMPORTANT: Save this token now - it will not be shown again! │
+└─────────────────────────────────────────────────────────────────────────────┘
+
+Token ID: 9
+Token Name: ci-pipeline
+SHA1: 9a4f282e9ba817b430082e6bff2c18e2ae38e480
+Last 8: ae38e480
+
+Authorization Header:
+ Authorization: token 9a4f282e9ba817b430082e6bff2c18e2ae38e480
+```
+
+#### 列出 Token
+
+```bash
+# 列出用戶的所有 Token
+momentry gitea list \
+ --username \
+ --password
+```
+
+**輸出範例:**
+```
+📋 Gitea Tokens for user: admin
+
+┌────────────────────────────────────────────────────────────────────────────┐
+│ ID │ Name │ Last 8 │ Registered │
+├────────────────────────────────────────────────────────────────────────────┤
+│ 9 │ ci-pipeline │ ae38e480 │ ✓ │
+│ 8 │ dev-token │ 1234abcd │ - │
+└────────────────────────────────────────────────────────────────────────────┘
+
+Total: 2 token(s)
+```
+
+#### 刪除 Token
+
+```bash
+# 刪除指定 Token
+momentry gitea delete \
+ --username \
+ --password \
+ --token-name
+```
+
+#### 查詢本地記錄
+
+```bash
+# 查詢已納管的 Token 記錄
+momentry gitea verify --token-name
+```
+
+**輸出範例:**
+```
+📋 Gitea Token: ci-pipeline
+ User: admin
+ Token ID: 9
+ Last 8: ae38e480
+ Scopes: ["read:repository","write:repository"]
+ Created: 2026-03-21 06:44:55.577586 UTC
+ Last Verified: never
+```
+
+### 11.6 使用範圍
+
+#### 適用場景
+
+| 場景 | 說明 |
+|------|------|
+| CI/CD 整合 | 建立專用 Token 用於自動化流程 |
+| 服務間通訊 | 建立 Token 供其他服務存取 Gitea API |
+| 開發環境 | 為開發者建立短期 Token |
+| 監控整合 | 建立只讀 Token 用於監控和報告 |
+
+#### 限制
+
+| 限制 | 說明 |
+|------|------|
+| 明文 Token | 僅在建立時取得,無法再次查詢 |
+| 管理 API | 需要帳號密碼(BasicAuth) |
+| Token 驗證 | 只能透過 API 呼叫驗證有效性 |
+| 同步刪除 | 本地刪除不會自動同步到 Gitea |
+
+### 11.7 環境變數
+
+```bash
+# Gitea 連線設定
+GITEA_URL=http://localhost:3000 # Gitea API URL
+```
+
+### 11.8 安全考量
+
+| 項目 | 措施 |
+|------|------|
+| 密碼傳輸 | 僅在 CLI 命令中使用,不儲存 |
+| Token 儲存 | 本地僅存元數據,不含明文 |
+| 權限最小化 | 建議僅授予必要權限 |
+| 定期輪換 | 建議定期更新 Token |
+
+---
+
+## 12. n8n API Key 整合
+
+### 12.1 概述
+
+支援透過 API Key 管理系統建立和管理 n8n API Keys,採用「建立時納管」模式。
+
+### 12.2 納管模式
+
+```
+使用者提供現有 n8n API Key → 呼叫 n8n API 建立新 Key → 明文只顯示一次 → 同步儲存至管理系統
+```
+
+**特點:**
+- 需要一個現有的 n8n API Key 作為管理憑證
+- API Key 明文僅在建立時取得
+- 管理系統記錄 Key 元數據(不含明文)
+- 支援本地查詢和刪除
+
+### 12.3 資料庫結構
+
+```sql
+CREATE TABLE n8n_api_keys (
+ id SERIAL PRIMARY KEY,
+ n8n_key_id VARCHAR(64) UNIQUE NOT NULL, -- n8n 內部 Key ID
+ label VARCHAR(100) NOT NULL, -- Key 標籤
+ api_key_last_eight VARCHAR(8) NOT NULL, -- API Key 最後 8 碼(顯示用)
+ momentry_api_key_id VARCHAR(48), -- 關聯的 API Key ID(可選)
+ expires_at TIMESTAMP WITH TIME ZONE, -- 過期時間
+ last_verified TIMESTAMP WITH TIME ZONE, -- 最後驗證時間
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
+);
+```
+
+### 12.4 認證方式
+
+n8n 使用 JWT-based API Key,透過 `X-N8N-API-KEY` Header 認證:
+
+```bash
+curl -H "X-N8N-API-KEY: " https://n8n.example.com/api/v1/workflows
+```
+
+### 12.5 CLI 命令
+
+#### 建立 API Key
+
+```bash
+# 基本用法
+momentry n8n create \
+ --api-key \
+ --label \
+ --expires-in-days
+
+# 範例:建立 CI/CD 用 Key
+momentry n8n create \
+ --api_key "n8n_api_xxxxxxxxxxxx" \
+ --label "ci-pipeline" \
+ --expires-in-days 90
+```
+
+**輸出範例:**
+```
+✅ n8n API Key created successfully!
+
+┌─────────────────────────────────────────────────────────────────────────────┐
+│ ⚠️ IMPORTANT: Save this API key now - it will not be shown again! │
+└─────────────────────────────────────────────────────────────────────────────┘
+
+Key ID: abc123-def456
+Label: ci-pipeline
+API Key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
+
+Usage:
+ curl -H 'X-N8N-API-KEY: eyJhbGciOiJIUz...' https://n8n.momentry.ddns.net/api/v1/workflows
+```
+
+#### 列出 API Keys
+
+```bash
+# 列出所有 API Keys
+momentry n8n list --api-key
+```
+
+**輸出範例:**
+```
+📋 n8n API Keys
+
+┌────────────────────────────────────────────────────────────────────────────┐
+│ Label │ ID │
+├────────────────────────────────────────────────────────────────────────────┤
+│ ci-pipeline │ abc123-def456-789 │
+│ monitoring │ xyz789-abc123-456 │
+└────────────────────────────────────────────────────────────────────────────┘
+
+Total: 2 key(s)
+```
+
+#### 刪除 API Key
+
+```bash
+# 刪除指定 API Key
+momentry n8n delete \
+ --api-key \
+ --label
+```
+
+#### 查詢本地記錄
+
+```bash
+# 查詢已納管的 API Key 記錄
+momentry n8n verify --label
+```
+
+**輸出範例:**
+```
+📋 n8n API Key: ci-pipeline
+ Key ID: abc123-def456
+ Last 8: ...JVCJ9
+ Created: 2026-03-21 06:44:55.577586 UTC
+ Expires: 2026-06-19 06:44:55.577586 UTC
+ Last Verified: never
+```
+
+### 12.6 使用範圍
+
+#### 適用場景
+
+| 場景 | 說明 |
+|------|------|
+| CI/CD 整合 | 建立專用 Key 用於自動化流程 |
+| 監控整合 | 建立只讀 Key 用於監控工作流狀態 |
+| 服務間通訊 | 建立 Key 供其他服務呼叫 n8n API |
+| 開發環境 | 為開發者建立短期 Key |
+
+#### 限制
+
+| 限制 | 說明 |
+|------|------|
+| 明文 API Key | 僅在建立時取得,無法再次查詢 |
+| 管理憑證 | 需要一個現有的 n8n API Key |
+| 本地刪除 | 不會自動同步到 n8n |
+| 權限範圍 | 非 Enterprise 版無細粒度權限 |
+
+### 12.7 環境變數
+
+```bash
+# n8n 連線設定
+N8N_URL=https://n8n.momentry.ddns.net # n8n API URL
+```
+
+### 12.8 安全考量
+
+| 項目 | 措施 |
+|------|------|
+| 管理 Key | 需妥善保管,作為管理其他 Key 的憑證 |
+| API Key 儲存 | 本地僅存元數據,不含明文 |
+| 過期機制 | 建議設定過期時間 |
+| 定期輪換 | 建議定期更新 Key |
+
+---
+
+## 13. 參考文檔
+
+- PostgreSQL Schema
+- Redis Key 設計( MOMENTRY_CORE_REDIS_KEYS.md)
+- 監控系統(MOMENTRY_CORE_MONITORING.md)
+- Gitea 安裝指南(INSTALL_GITEA.md)
+- n8n API 文件(https://docs.n8n.io/api/authentication/)
diff --git a/docs/API_KEY_OPTIMIZATION.md b/docs/API_KEY_OPTIMIZATION.md
new file mode 100644
index 0000000..b118521
--- /dev/null
+++ b/docs/API_KEY_OPTIMIZATION.md
@@ -0,0 +1,399 @@
+# API Key Management 優化計畫
+
+| 項目 | 內容 |
+|------|------|
+| 版本 | V1.0 |
+| 日期 | 2026-03-21 |
+| 狀態 | 規劃中 |
+
+---
+
+## 版本歷史
+
+| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
+|------|------|------|--------|-----------|
+| V1.0 | 2026-03-21 | 創建優化計畫 | OpenCode | - |
+
+---
+
+## 任務編碼規則
+
+```
+AKO-{類別}-{序號}
+AKO = API Key Optimization
+類別:
+ - CODE = 程式碼品質
+ - PERF = 效能優化
+ - SEC = 安全性
+ - FEAT = 功能增強
+ - DOC = 文件
+```
+
+---
+
+## Phase 1: 程式碼品質 (CODE)
+
+| 編碼 | 任務 | 描述 | 優先級 | 預估工時 | 狀態 |
+|------|------|------|--------|----------|------|
+| AKO-CODE-01 | 修復 from_str 警告 | 重命名為 `parse_scope` 或實作 `FromStr` trait | 🔴 高 | 0.5h | ⏳ 待辦 |
+| AKO-CODE-02 | 函數參數重構 | 使用 Config struct 減少參數數量 | 🔴 高 | 1h | ⏳ 待辦 |
+| AKO-CODE-03 | 抽象 CRUD Trait | 建立 `ExternalTokenStore` trait 統一 Gitea/n8n | 🟡 中 | 3h | ⏳ 待辦 |
+| AKO-CODE-04 | 錯誤處理統一 | 使用 `thiserror` 定義自訂錯誤類型 | 🟡 中 | 2h | ⏳ 待辦 |
+
+### AKO-CODE-01 細節
+
+```rust
+// Before
+impl GiteaScope {
+ pub fn from_str(s: &str) -> Option { ... }
+}
+
+// After: Option A - Rename
+impl GiteaScope {
+ pub fn parse(s: &str) -> Option { ... }
+}
+
+// After: Option B - Implement FromStr
+impl std::str::FromStr for GiteaScope {
+ type Err = ();
+ fn from_str(s: &str) -> Result { ... }
+}
+```
+
+### AKO-CODE-02 細節
+
+```rust
+// Before
+pub async fn create_api_key(
+ &self,
+ key_id: &str,
+ key_hash: &str,
+ key_prefix: &str,
+ name: &str,
+ key_type: &str,
+ user_id: Option,
+ service_name: Option<&str>,
+ permissions: &serde_json::Value,
+ expires_at: Option>,
+) -> Result
+
+// After
+pub struct CreateApiKeyConfig<'a> {
+ pub key_id: &'a str,
+ pub key_hash: &'a str,
+ pub key_prefix: &'a str,
+ pub name: &'a str,
+ pub key_type: &'a str,
+ pub user_id: Option,
+ pub service_name: Option<&'a str>,
+ pub permissions: &'a serde_json::Value,
+ pub expires_at: Option>,
+}
+
+pub async fn create_api_key(&self, config: CreateApiKeyConfig<'_>) -> Result
+```
+
+### AKO-CODE-03 細節
+
+```rust
+#[async_trait]
+pub trait ExternalTokenStore {
+ async fn create(&self, record: T) -> Result;
+ async fn get_by_label(&self, label: &str) -> Result
';
+ }
+});
+
+// 搜尋短代碼
+add_shortcode('momentry_search', function($atts, $content = '') {
+ $query = sanitize_text_field($content);
+
+ if (empty($query)) {
+ return '請提供搜尋關鍵字
';
+ }
+
+ $api = new Momentry_API();
+
+ try {
+ $result = $api->search($query);
+
+ ob_start();
+ ?>
+
+
「= esc_html($query) ?>」搜尋結果
+
+
沒有找到相關結果
+
+
+
+
+ 搜尋失敗: ' . esc_html($e->getMessage()) . '';
+ }
+});
+```
+
+### 3.3 使用方式
+
+在 WordPress 頁面或文章中:
+
+```
+[momentry_videos limit="5"]
+
+[momentry_search]ExaSAN[/momentry_search]
+```
+
+### 3.4 REST API 整合
+
+```php
+ 'GET',
+ 'callback' => function(WP_REST_Request $request) {
+ $query = sanitize_text_field($request->get_param('q'));
+
+ if (empty($query)) {
+ return new WP_Error('missing_query', '需要搜尋關鍵字', ['status' => 400]);
+ }
+
+ $api = new Momentry_API();
+ $result = $api->search($query);
+
+ return new WP_REST_Response($result, 200);
+ },
+ 'permission_callback' => '__return_true',
+ ]);
+});
+
+// 使用方式: GET /wp-json/momentry/v1/search?q=ExaSAN
+```
+
+---
+
+## 4. 疑難排解
+
+### 4.1 常見錯誤
+
+| 錯誤 | 原因 | 解決方案 |
+|------|------|----------|
+| `401 Unauthorized` | API Key 無效或過期 | 檢查 API Key 是否正確 |
+| `500 Internal Server Error` | 伺服器錯誤 | 檢查 `/health/detailed` 服務狀態 |
+| `Connection Timeout` | 網路問題 | 確認 `api.momentry.ddns.net` 可達 |
+
+### 4.2 測試腳本
+
+```bash
+#!/bin/bash
+# test_api.sh - Momentry API 測試腳本
+
+API_KEY="muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69"
+BASE_URL="http://localhost:3002"
+
+echo "=== 1. 健康檢查 ==="
+curl -s "$BASE_URL/health" | jq .
+echo ""
+
+echo "=== 2. 列出影片 ==="
+curl -s -H "X-API-Key: $API_KEY" "$BASE_URL/api/v1/videos" | jq '.videos | length'
+echo ""
+
+echo "=== 3. 搜尋測試 ==="
+curl -s -X POST -H "X-API-Key: $API_KEY" \
+ -H "Content-Type: application/json" \
+ -d '{"query": "test", "limit": 3}' \
+ "$BASE_URL/api/v1/search" | jq '.results | length'
+echo ""
+
+echo "=== 完成 ==="
+```
+
+### 4.3 驗證腳本
+
+```bash
+#!/bin/bash
+# verify_auth.sh - 驗證 API Key
+
+API_KEY="muser_68600856036340bcafc01930eb4bd839_1774418104_97221b69"
+BASE_URL="http://localhost:3002"
+
+# 測試 1: 無 API Key
+echo "測試 1: 無 API Key"
+RESULT=$(curl -s -o /dev/null -w "%{http_code}" "$BASE_URL/api/v1/videos")
+[ "$RESULT" = "401" ] && echo "✅ 正確拒絕 (401)" || echo "❌ 預期 401,實際 $RESULT"
+
+# 測試 2: 有 API Key
+echo "測試 2: 有 API Key"
+RESULT=$(curl -s -H "X-API-Key: $API_KEY" "$BASE_URL/api/v1/videos")
+echo "$RESULT" | jq -e '.videos' > /dev/null && echo "✅ 成功取得資料" || echo "❌ 取得資料失敗"
+
+# 測試 3: 無效 API Key
+echo "測試 3: 無效 API Key"
+RESULT=$(curl -s -o /dev/null -w "%{http_code}" -H "X-API-Key: invalid_key" "$BASE_URL/api/v1/videos")
+[ "$RESULT" = "401" ] && echo "✅ 正確拒絕 (401)" || echo "❌ 預期 401,實際 $RESULT"
+```
+
+---
+
+## 5. API Key 管理
+
+### 5.1 建立新 API Key
+
+```bash
+# 本地建立
+./target/release/momentry api-key create "My App" --key-type user --ttl 90
+```
+
+### 5.2 列出 API Keys
+
+```bash
+./target/release/momentry api-key list
+```
+
+### 5.3 驗證 API Key
+
+```bash
+./target/release/momentry api-key validate --key "YOUR_API_KEY"
+```
+
+### 5.4 撤銷 API Key
+
+```bash
+./target/release/momentry api-key revoke --key "YOUR_API_KEY"
+```
+
+---
+
+## 附錄
+
+### A. 影片 UUID 說明
+
+UUID 是基於檔案路徑的 SHA256 哈希前 16 位:
+
+```
+/Users/accusys/momentry/var/sftpgo/data/demo/video.mp4
+ ↓
+SHA256 Hash
+ ↓
+9760d0820f0cf9a7
+```
+
+### B. 處理器狀態
+
+| 狀態 | 說明 |
+|------|------|
+| `pending` | 等待處理 |
+| `running` | 處理中 |
+| `completed` | 已完成 |
+| `failed` | 失敗 |
+
+### C. 支援的處理器
+
+- **ASR**: 語音識別
+- **CUT**: 場景剪切
+- **YOLO**: 物件偵測
+
+### D. 聯絡支援
+
+- Email: support@momentry.ddns.net
+- 文件: https://docs.momentry.ddns.net
+- GitHub: https://github.com/anomalyco/momentry
diff --git a/docs/DEVELOPMENT_LOG.md b/docs/DEVELOPMENT_LOG.md
index 037cb13..3c30a41 100644
--- a/docs/DEVELOPMENT_LOG.md
+++ b/docs/DEVELOPMENT_LOG.md
@@ -1,5 +1,21 @@
# Momentry Core 開發日誌
+| 項目 | 內容 |
+|------|------|
+| 建立者 | Warren |
+| 建立時間 | 2026-03-18 |
+| 文件版本 | V1.0 |
+
+---
+
+## 版本歷史
+
+| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
+|------|------|------|--------|-----------|
+| V1.0 | 2026-03-18 | 創建文件 | Warren | OpenCode / MiniMax M2.5 |
+
+---
+
> **文檔維護開始**:2026-03-18
> **⚠️ 補充說明**:事後補記(2026-03-18 以前),僅供參考。未來紀錄將即時記錄,參考價值較高。
@@ -422,3 +438,103 @@ cargo run --bin momentry -- process
# 查詢進度
curl http://127.0.0.1:3002/api/v1/progress/
```
+
+---
+
+## 2026-03-18 (Dashboard)
+
+### Web Dashboard 實作
+
+**目標**:建立 Web 介面監控 momentry_core 處理進度
+
+**技術選擇**:Static HTML + JavaScript (非 WASM)
+
+**實作內容**:
+
+| 元件 | 檔案 | 說明 |
+|------|------|------|
+| Dashboard | `momentry_dashboard/dist/index.html` | 靜態 HTML 頁面 |
+| API 代理 | Caddyfile port 3200 | 反向代理到 API server |
+
+**功能**:
+- 影片列表顯示
+- 即時進度條 (每 5 秒自動刷新)
+- 搜尋功能
+- 處理器狀態 (ASR/CUT/YOLO/OCR/Face/Pose)
+
+**訪問**:
+- Dashboard: http://localhost:3200
+- API: http://localhost:3200/api/v1/*
+
+---
+
+## 發生問題記錄
+
+### HTTP API 問題
+
+1. **語法錯誤** (main.rs)
+ - 位置:lines 297-322
+ - 原因:重複的程式碼區塊
+ - 解決:移除重複區塊
+
+2. **DB 連線池耗盡**
+ - 原因:預設 5 個連線不足
+ - 解決:增加到 10 個連線
+
+3. **PostgreSQL shutdown 狀態**
+ - 原因:共享記憶體未釋放
+ - 解決:殺掉 stale 連線
+
+### WASM Dashboard 問題
+
+1. **Yew 版本問題**
+ - 嘗試:yew 0.21 → 0.23
+ - 問題:feature 名稱變更 (`web-sys` → `web_sys` → `csr`)
+ - 解決:放棄 WASM,改用靜態 HTML
+
+2. **編譯錯誤**
+ - `wasm32-unknown-unknown` target 未安裝
+ - 解決:`rustup target add wasm32-unknown-unknown`
+
+3. **Yew 0.23 API 變更**
+ - Properties 需要 PartialEq derive
+ - 多處 API 語法變更
+ - 放棄 WASM 方案
+
+### Gitea Push 問題
+
+1. **Remote URL 錯誤**
+ - 原因:使用 localhost:3000 而非 gitea.momentry.ddns.net
+ - 解決:建立新 repo `momentry_core_0_1`
+
+2. **認證問題**
+ - SSH key 未授權
+ - 密碼認證成功推送
+
+### Caddy 設定問題
+
+1. **API 代理順序**
+ - 問題:try_files 在 reverse_proxy 之前導致 API 回傳 HTML
+ - 解決:使用 `handle` 區塊明確定義順序
+
+```caddyfile
+:3200 {
+ handle /api/* {
+ reverse_proxy localhost:3002
+ }
+ handle {
+ root * /Users/accusys/momentry_dashboard/dist
+ try_files {path} /index.html
+ file_server
+ }
+}
+```
+
+---
+
+## 未來工作
+
+- [ ] 修復 WASM Dashboard (Yew 0.23 相容性)
+- [ ] 新增影片播放器整合
+- [ ] WebSocket 實時推送
+- [ ] 移動端響應式設計
diff --git a/docs/DOCS_STANDARD.md b/docs/DOCS_STANDARD.md
new file mode 100644
index 0000000..6b5705a
--- /dev/null
+++ b/docs/DOCS_STANDARD.md
@@ -0,0 +1,474 @@
+# 文件創建規範
+
+| 項目 | 內容 |
+|------|------|
+| 建立者 | Warren |
+| 建立時間 | 2026-03-18 |
+| 文件版本 | V1.0 |
+
+---
+
+## 版本歷史
+
+| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
+|------|------|------|--------|-----------|
+| V1.0 | 2026-03-18 | 創建文件規範 | Warren | OpenCode / MiniMax M2.5 |
+
+---
+
+本文檔定義 Momentry Core 專案中文件的命名規範、格式標準和結構要求。
+
+---
+
+## 1. 檔案命名規範
+
+### 命名模式
+
+所有文件必須使用以下命名模式:
+
+| 文件類型 | 模式 | 範例 |
+|----------|------|------|
+| 安裝指南 | `INSTALL_.md` | `INSTALL_POSTGRESQL.md` |
+| 開發指南 | `DEVELOP_.md` | `DEVELOP_API.md` |
+| API 參考 | `API_REFERENCE.md` | `API_REFERENCE.md` |
+| 規格文件 | `_SPEC.md` | `CHUNK_SPEC.md` |
+| 設計文件 | `_DESIGN.md` | `CHUNK_DESIGN.md` |
+| 服務總覽 | `SERVICES.md` | `SERVICES.md` |
+| 其他文件 | `.md` | `README.md` |
+
+### 命名規則
+
+- 使用 **大駝峰** (PascalCase) 命名法
+- 服務名稱使用 **全大寫** (e.g., `POSTGRESQL`, `SFTPGO`)
+- 英文優先,縮寫保持大寫
+- 使用底線 `_` 作為單詞分隔符
+- 副檔名統一使用 `.md` (Markdown)
+
+### 禁止事項
+
+- 不允許使用中文檔名
+- 不允許空格
+- 不允許混合大小寫 (如 `Install_PostgreSQL.md`)
+
+---
+
+## 2. 文件結構模板
+
+### 安裝指南結構
+
+```markdown
+# <服務名稱> 安裝指南 (部署類型)
+
+## 概述
+
+本文檔說明如何...
+
+---
+
+## 當前狀態
+
+| 項目 | 狀態 |
+|------|------|
+| <服務名> | ✅ 已安裝 v<版本號> |
+| Port | <端口號> |
+| ... | ... |
+
+---
+
+## 安裝步驟
+
+### Step 1: <步驟名稱>
+
+<說明內容>
+
+```bash
+# 代碼範例
+command --option value
+```
+
+### Step 2: <步驟名稱>
+...
+
+---
+
+## 卸載步驟
+
+### Step 1: <步驟名稱>
+...
+
+---
+
+## 故障排除
+
+### <問題名稱>
+
+<解決方案>
+
+---
+
+## 檔案位置
+
+| 類型 | 路徑 | 說明 |
+|------|------|------|
+| 安裝 | /path/to/install | 說明 |
+...
+
+---
+
+## 常用指令
+
+```bash
+# 驗證
+command verify
+
+# 查看版本
+command --version
+```
+
+---
+
+## 版本資訊
+
+- 版本: <版本號>
+- 安裝日期: <日期>
+```
+
+---
+
+### 規格文件結構
+
+```markdown
+# <名稱> 規格文件
+
+## 概述
+
+<簡短描述>
+
+---
+
+## 詳細規格
+
+### 1. <功能模組>
+
+#### 欄位定義
+
+| 欄位 | 類型 | 必填 | 說明 |
+|------|------|------|------|
+| field1 | string | Yes | 說明 |
+
+#### 資料結構
+
+```json
+{
+ "example": "data"
+}
+```
+
+---
+
+## 限制條件
+
+- <限制1>
+- <限制2>
+
+---
+
+## 相關文件
+
+- `RELATED_FILE.md` - 相關說明
+```
+
+---
+
+## 3. 格式標準
+
+### Markdown 格式
+
+| 項目 | 標準 |
+|------|------|
+| 標題層級 | H1 (`#`) → H2 (`##`) → H3 (`###`) |
+| 水平線 | 使用 `---` 分隔主要章節 |
+| 程式碼區塊 | 使用三個反引號 ``` 並標註語言 |
+| 表格 | 使用 `|` 和 `-` 對齊 |
+| 強調 | 使用 `**粗體**` 和 `*斜體*` |
+
+### 程式碼區塊語言標註
+
+```bash
+# Bash
+```bash
+command
+```
+
+```json
+# JSON
+```json
+{"key": "value"}
+```
+
+```rust
+# Rust
+```rust
+fn main() {}
+```
+
+```yaml
+# YAML
+key: value
+```
+
+### 表格格式
+
+```markdown
+| Header 1 | Header 2 | Header 3 |
+|----------|----------|----------|
+| Cell 1 | Cell 2 | Cell 3 |
+| Cell 4 | Cell 5 | Cell 6 |
+```
+
+### 列表格式
+
+- 使用 `-` 作為無序列表標記
+- 使用數字 `1.` 作為有序列表標記
+- 縮進使用 2 個空格
+
+---
+
+## 4. 語言規範
+
+### 標題語言
+
+| 區域 | 語言 |
+|------|------|
+| 主要內容 | 繁體中文 |
+| 技術術語 | 英文保留 |
+| 命令和代碼 | 英文 |
+| 文件標題 | 繁體中文 |
+
+### 常用術語對照
+
+| 英文 | 中文 |
+|------|------|
+| Install | 安裝 |
+| Configure/Config | 配置/設定 |
+| Uninstall | 卸載 |
+| Troubleshooting | 故障排除 |
+| Status | 狀態 |
+| Documentation | 文件 |
+| Guide | 指南 |
+| Overview | 概述 |
+| Specification | 規格 |
+| Current Status | 當前狀態 |
+| Default | 預設 |
+| Required | 必填 |
+| Optional | 選填 |
+| Example | 範例 |
+
+### 標點符號
+
+- 中文內容使用全形標點:`,`、`。`、`:`、`(`、`)`
+- 英文/程式內容使用半形標點:`:`、`(`、`)`
+- 命令行使用 `` `command` `` 格式
+
+---
+
+## 5. 內容要求
+
+### 必需章節
+
+每份文件必須包含:
+
+1. **標題** - 文件名稱
+2. **概述** - 檔案用途說明
+3. **版本/狀態資訊** - 當前狀態
+4. **檔案位置** - 重要路徑列表
+5. **常用指令** - 基本操作命令
+
+### 版本資訊格式
+
+每份文件頂部必須包含以下資訊:
+
+```markdown
+| 項目 | 內容 |
+|------|------|
+| 建立者 | <姓名> |
+| 建立時間 | |
+| 文件版本 | V1.0 |
+```
+
+版本歷史表:
+
+```markdown
+---
+
+## 版本歷史
+
+| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
+|------|------|------|--------|-----------|
+| V1.0 | 2026-03-18 | 創建文件 | Warren | OpenCode / MiniMax M2.5 |
+```
+
+---
+
+### 版本資訊章節格式
+
+```markdown
+---
+
+## 版本資訊
+
+- 版本: <版本號>
+- 安裝日期:
+- 文件更新:
+```
+
+### 狀態標記
+
+| 狀態 | 標記 |
+|------|------|
+| 已安裝 | ✅ 已安裝 v |
+| 未安裝 | ❌ 未安裝 |
+| 可選 | ⚙️ 可選 |
+| 進行中 | 🔄 進行中 |
+
+---
+
+## 6. 示例文件
+
+### 正確範例
+
+```markdown
+# PostgreSQL 安裝指南 (本地部署)
+
+| 項目 | 內容 |
+|------|------|
+| 建立者 | Warren |
+| 建立時間 | 2026-03-18 |
+| 文件版本 | V1.0 |
+
+---
+
+## 版本歷史
+
+| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
+|------|------|------|--------|-----------|
+| V1.0 | 2026-03-18 | 創建文件 | Warren | OpenCode / MiniMax M2.5 |
+
+---
+
+## 概述
+
+本文檔說明如何在 macOS 上安裝 PostgreSQL...
+
+---
+
+## 當前狀態
+
+| 項目 | 狀態 |
+|------|------|
+| PostgreSQL | ✅ 已安裝 v16.2 |
+| Port | 5432 |
+
+---
+
+## 安裝步驟
+
+### Step 1: 安裝 PostgreSQL
+
+```bash
+brew install postgresql@16
+```
+
+### Step 2: 啟動服務
+
+```bash
+brew services start postgresql@16
+```
+
+---
+
+## 檔案位置
+
+| 類型 | 路徑 |
+|------|------|
+| 配置文件 | /path/to/config |
+| 數據目錄 | /path/to/data |
+
+---
+
+## 版本資訊
+
+- 版本: 16.2
+- 安裝日期: 2026-03-01
+```
+
+### 錯誤範例
+
+```
+❌ PostgreSQL安裝.md # 中文檔名
+❌ install-postgresql.md # 全部小寫
+❌ Install PostgreSQL.md # 空格
+❌ postgresql_install.md # 非標準命名
+```
+
+---
+
+## 7. 文件審查清單
+
+創建新文件時,請確認:
+
+- [ ] 檔案命名符合 `INSTALL_*.md` 或其他標準模式
+- [ ] 文件包含頂部資訊表(建立者、建立時間、版本)
+- [ ] 文件包含版本歷史表
+- [ ] 文件包含概述章節
+- [ ] 文件包含當前狀態/版本資訊
+- [ ] 文件包含檔案位置章節
+- [ ] 文件包含常用指令章節
+- [ ] 使用統一的 Markdown 格式
+- [ ] 使用繁體中文作為主要語言
+- [ ] 程式碼區塊標註語言類型
+- [ ] 表格格式正確
+- [ ] 章節使用 `---` 分隔
+
+### 頂部資訊表範本
+
+```markdown
+| 項目 | 內容 |
+|------|------|
+| 建立者 | Warren |
+| 建立時間 | 2026-03-18 |
+| 文件版本 | V1.0 |
+```
+
+### 版本歷史表範本
+
+```markdown
+| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
+|------|------|------|--------|-----------|
+| V1.0 | 2026-03-18 | 創建文件 | Warren | OpenCode / MiniMax M2.5 |
+```
+
+---
+
+## 8. 更新現有文件
+
+當更新現有文件時:
+
+1. 更新 **版本資訊** 中的日期
+2. 如有必要,更新版本號
+3. 記錄重大變更於 `CHANGELOG.md` 或 `DEVELOPMENT_LOG.md`
+
+---
+
+## 附錄:文件類型參考
+
+| 前綴 | 用途 | 位置 |
+|------|------|------|
+| `INSTALL_` | 服務安裝指南 | `/docs/` |
+| `DEVELOP_` | 開發指南 | `/docs/` |
+| `*_SPEC.md` | 規格定義 | `/docs/` |
+| `*_DESIGN.md` | 設計文件 | `/docs/` |
+| `API_REFERENCE.md` | API 參考文件 | `/docs/` |
+| `README.md` | 專案總覽 | `/` |
+| `AGENTS.md` | AI 代理指令 | `/` |
+| `CHANGELOG.md` | 變更日誌 | `/` |
diff --git a/docs/DOCUMENT_EMBEDDING_STRATEGY.md b/docs/DOCUMENT_EMBEDDING_STRATEGY.md
new file mode 100644
index 0000000..e0750c8
--- /dev/null
+++ b/docs/DOCUMENT_EMBEDDING_STRATEGY.md
@@ -0,0 +1,151 @@
+# Document Embedding Strategy - Parent-Child Chunks
+
+## Overview
+
+Momentry uses a **parent-child chunk hierarchy** for improved RAG retrieval. This document describes the embedding strategy for this hierarchy.
+
+## Chunk Structure
+
+### Parent Chunk
+- **Purpose**: Summarize multiple child chunks with narrative description
+- **Content**: High-level description of multiple scenes/segments
+- **Example**:
+```json
+{
+ "chunk_id": "story_asr_0000",
+ "chunk_type": "story",
+ "text_content": "[0s-125s] A man enters a building. He walks down a hallway.",
+ "child_chunk_ids": ["asr_0001", "asr_0002", "asr_0003", "asr_0004", "asr_0005"]
+}
+```
+
+### Child Chunk
+- **Purpose**: Individual segments from ASR, scenes from CUT, etc.
+- **Content**: Raw transcription or detection results
+- **Example**:
+```json
+{
+ "chunk_id": "asr_0001",
+ "chunk_type": "sentence",
+ "text_content": "Hello world",
+ "parent_chunk_id": "story_asr_0000"
+}
+```
+
+## Embedding Strategy
+
+### For Vector Search
+
+When embedding chunks for vector search, we combine **parent description + child content** to provide both context and detail.
+
+#### Parent Chunk Embedding
+```
+embedding_text = f"Summary: {parent.text_content}
+Children: {child_text_1}. {child_text_2}. {child_text_3}..."
+```
+
+**Prefix**: `search_document: ` (for documents in Qdrant)
+
+**Example**:
+```
+search_document: Summary: A man enters a building. He walks down a hallway.
+Children: Hello, how are you? I'm fine thank you. The weather is nice today.
+```
+
+#### Child Chunk Embedding
+```
+embedding_text = f"[{child.chunk_type}] {child.text_content}
+Parent: {parent.description}"
+```
+
+**Prefix**: `search_document: `
+
+**Example**:
+```
+search_document: [sentence] Hello, how are you?
+Parent: A man enters a building. He walks down a hallway.
+```
+
+### For BM25 Text Search
+
+BM25 operates on raw text with PostgreSQL full-text search.
+
+- **Index**: `search_vector` (TSVECTOR) on `chunks.text_content`
+- **Search**: Uses `ts_rank_cd()` for ranking
+
+## Hybrid Search Ranking
+
+Combined score = `(vector_score * 0.7) + (bm25_score * 0.3)`
+
+### Why 0.7/0.3?
+
+| Weight | Vector | BM25 |
+|--------|--------|------|
+| Pros | Semantic similarity | Exact keyword match |
+| Cons | May miss specific terms | No semantic understanding |
+| Best for | Thematic queries | Fact lookup |
+
+## Query Patterns
+
+### Thematic Query ("What are the main themes?")
+- Use higher `vector_weight` (0.8-0.9)
+- Vector search finds semantically similar content
+
+### Fact Lookup ("Who said X?")
+- Use higher `bm25_weight` (0.5-0.7)
+- BM25 finds exact matches
+
+### Balanced ("Tell me about scene 5")
+- Use default 0.7/0.3
+
+## Implementation
+
+### Embedding Generation
+```rust
+fn build_embedding_text(chunk: &Chunk, parent_text: Option<&str>) -> String {
+ match chunk.chunk_type {
+ ChunkType::Story => {
+ format!(
+ "Summary: {}\nChildren: {}",
+ chunk.text_content,
+ get_children_text(chunk)
+ )
+ }
+ _ => {
+ format!(
+ "[{}] {}\nParent: {}",
+ chunk.chunk_type.as_str(),
+ chunk.text_content,
+ parent_text.unwrap_or("N/A")
+ )
+ }
+ }
+}
+```
+
+### Storage
+- Parent chunks stored with their `child_chunk_ids`
+- Child chunks reference `parent_chunk_id`
+- Both stored in PostgreSQL with full-text index
+- Vectors stored in Qdrant
+
+## Example Flow
+
+1. **Story Processing** generates parent-child hierarchy
+2. **Embedding** creates vector for each chunk
+3. **Storage** saves to PostgreSQL + Qdrant
+4. **Search** retrieves using hybrid search
+5. **Results** include both parent context and child details
+
+## Best Practices
+
+1. **Chunk Size**: 5 child chunks per parent (configurable)
+2. **Text Length**: Keep embeddings under 512 tokens
+3. **Parent Description**: Include temporal markers (timestamps)
+4. **Child Content**: Preserve original transcription
+
+## Future Enhancements
+
+- [ ] GraphRAG integration for relationship traversal
+- [ ] Cross-chunk entity linking
+- [ ] Temporal graph building
diff --git a/docs/FILE_CHANGE_MANAGEMENT.md b/docs/FILE_CHANGE_MANAGEMENT.md
new file mode 100644
index 0000000..ca285ed
--- /dev/null
+++ b/docs/FILE_CHANGE_MANAGEMENT.md
@@ -0,0 +1,323 @@
+# 文件修改管理規範 v1.0
+
+| 項目 | 內容 |
+|------|------|
+| 建立者 | Warren |
+| 建立時間 | 2026-03-22 |
+| 文件版本 | V1.0 |
+
+---
+
+## 1. 概述
+
+本文檔定義 Momentry 專案的文件修改流程,確保不同工具/模型對文件的一致性理解,防止誤修改並保留完整的修改紀錄。
+
+### 1.1 適用範圍
+
+- 所有 `.md` 文件(技術文檔、安裝指南、API 文件等)
+- 所有 `.rs` 文件(Rust 源代碼)
+- 所有 `.sh` 文件(Shell 腳本)
+- 所有 `.yaml` / `.yml` 文件(配置文件)
+- 所有 `.json` 文件(配置及數據文件)
+
+### 1.2 核心原則
+
+1. **先讀後改**:修改前必須完整閱讀相關文件
+2. **預檢清單**:修改前執行預檢查步驟
+3. **變更對照**:修改後必須比對差異
+4. **驗證確認**:變更後執行驗證測試
+5. **完整紀錄**:所有修改必須記錄於版本歷史
+
+---
+
+## 2. 修改前預檢清單
+
+### 2.1 文件閱讀要求
+
+修改文件前,必須完成以下閱讀:
+
+| 步驟 | 項目 | 說明 |
+|------|------|------|
+| 1 | 閱讀完整文件 | 不可僅閱讀部分章節 |
+| 2 | 理解文件用途 | 確認文件的目標讀者 |
+| 3 | 確認現有術語 | 使用一致的術語和命名 |
+| 4 | 查閱相關文件 | 確認相關聯的文件 |
+
+### 2.2 預檢問題清單
+
+在修改前回答以下問題:
+
+```
+□ 1. 此修改是否影響其他文件?
+□ 2. 此修改是否與現有規範衝突?
+□ 3. 此修改是否需要更新版本歷史?
+□ 4. 此修改是否需要新增測試?
+□ 5. 此修改是否需要通知相關人員?
+□ 6. 此修改是否有破壞性變更(Breaking Change)?
+```
+
+### 2.3 預檢命令
+
+修改前執行以下命令確認現有狀態:
+
+```bash
+# 1. 確認 git 狀態
+git status
+
+# 2. 檢查相關文件的最新版本
+git log -3 --oneline
+
+# 3. 查看現有版本歷史
+cat docs/.md | grep -A 20 "版本歷史"
+```
+
+---
+
+## 3. 文件修改流程
+
+### 3.1 標準修改流程
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Step 1: 閱讀 │
+│ ├─ 完整閱讀目標文件 │
+│ └─ 閱讀相關聯文件 │
+├─────────────────────────────────────────────────────────────┤
+│ Step 2: 預檢 │
+│ ├─ 回答預檢問題清單 │
+│ └─ 執行預檢命令 │
+├─────────────────────────────────────────────────────────────┤
+│ Step 3: 規劃 │
+│ ├─ 說明修改內容 │
+│ └─ 列出變更差異 │
+├─────────────────────────────────────────────────────────────┤
+│ Step 4: 修改 │
+│ ├─ 執行修改 │
+│ └─ 更新版本歷史 │
+├─────────────────────────────────────────────────────────────┤
+│ Step 5: 驗證 │
+│ ├─ 執行 lint/format 檢查 │
+│ └─ 執行相關測試 │
+├─────────────────────────────────────────────────────────────┤
+│ Step 6: 提交 │
+│ └─ 撰寫清晰的 commit message │
+└─────────────────────────────────────────────────────────────┘
+```
+
+### 3.2 預修改彙報格式
+
+在執行修改前,必須先彙報以下內容:
+
+```markdown
+## 檔案
+``
+
+## 修改原因
+<說明修改的目的>
+
+## 變更內容
+```diff
+- <刪除的內容>
++ <新增的內容>
+```
+
+## 版本歷史更新
+| 版本 | 日期 | 內容 | 操作人 | 工具/模型 |
+|------|------|------|--------|-----------|
+| Vx.x | YYYY-MM-DD | <修改說明> | <操作者> | <使用的工具> |
+```
+
+### 3.3 版本歷史格式
+
+每個文件頂部必須包含版本歷史表:
+
+```markdown
+## 版本歷史
+
+| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
+|------|------|------|--------|-----------|
+| V1.0 | 2026-03-15 | 創建文件 | Warren | OpenCode / MiniMax M2.5 |
+| V1.1 | 2026-03-22 | 更新內容 | Warren | OpenCode / big-pickle |
+```
+
+---
+
+## 4. 變更對照
+
+### 4.1 diff 對照
+
+修改後必須提供 diff 對照:
+
+```bash
+git diff
+```
+
+### 4.2 變更類型分類
+
+| 類型 | 標記 | 說明 |
+|------|------|------|
+| 新增 | `+` | 新增內容 |
+| 刪除 | `-` | 刪除內容 |
+| 修改 | `~` | 修改內容 |
+| 移動 | `↕` | 移動位置 |
+| 格式 | `@` | 格式變更 |
+
+### 4.3 變更確認清單
+
+```
+□ 1. diff 輸出已確認
+□ 2. 變更符合預期
+□ 3. 無意外變更
+□ 4. 版本歷史已更新
+□ 5. 其他關聯文件已檢查
+```
+
+---
+
+## 5. 驗證流程
+
+### 5.1 自動化驗證
+
+修改後執行以下自動化檢查:
+
+```bash
+# Rust 文件
+cargo fmt -- --check
+cargo clippy --lib
+cargo test --lib
+
+# Python 文件
+ruff check
+ruff format --check
+
+# Markdown 文件
+markdownlint
+
+# Shell 文件
+shellcheck -S error
+```
+
+### 5.2 手動驗證清單
+
+```
+□ 1. 文件語法正確
+□ 2. 連結有效
+□ 3. 格式一致
+□ 4. 術語一致
+□ 5. 版本歷史完整
+□ 6. 變更記錄清晰
+```
+
+---
+
+## 6. 提交規範
+
+### 6.1 Commit Message 格式
+
+```
+:
+
+
+
+