Files
momentry_studio/docs/CORE_API_REFERENCE.md

470 lines
9.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Core API 完整測試報告
> 測試時間2026-06-14
> Base URL`http://localhost:3002`
> 所有端點均需附 `?api_key=KEY`
---
## 1. Files API
### GET /api/v1/files/scan
| 項目 | 內容 |
|---|---|
| **Method** | GET |
| **Params** | `page_size` (int), `page` (int), `pattern` (string), `sort_by` (string), `sort_order` (string) |
| **HTTP** | 200 |
| **Response Key** | `files` (array) |
**欄位:**
```
file_name, relative_path, file_path, file_size, modified_time,
is_registered, file_uuid, status, registration_time, job_id
```
**注意:**
- 未註冊檔案 `file_uuid``null`Rust 需 fallback 到 `file_path`
- `status``"completed"``"unregistered"`
---
## 2. Search API
### POST /api/v1/search/llm-smart
| 項目 | 內容 |
|---|---|
| **Method** | POST |
| **Body** | `{"query": "string", "limit": int}` |
| **HTTP** | 200 |
| **Response Key** | `results` (array) |
**欄位:**
```
id, file_uuid, parent_id, scene_order, start_frame, end_frame, fps,
start_time, end_time, raw_text, summary, metadata, similarity,
file_name, serve_url, thumbnail_url
```
---
## 3. Identities API
### GET /api/v1/identities (list)
| 項目 | 內容 |
|---|---|
| **Method** | GET |
| **Params** | `page` (int), `per_page` (int) |
| **HTTP** | 200 |
| **Response Key** | `identities` (array) |
**欄位:**
```
id, identity_uuid, name, metadata
```
**metadata 欄位:**
```
role, aliases, starred, tmdb_gender, tmdb_aliases, tmdb_imdb_id,
tmdb_birthday, tmdb_deathday, tmdb_homepage, tmdb_movie_id,
tmdb_biography, tmdb_character, tmdb_cast_order, tmdb_department,
tmdb_popularity, tmdb_movie_title, tmdb_place_of_birth
```
**注意:** `starred` 在 metadata 內
### GET /api/v1/identities/search
| 項目 | 內容 |
|---|---|
| **Method** | GET |
| **Params** | `q` (string) |
| **HTTP** | 200 |
| **Response Key** | `results` (array) |
**欄位search result 不同於 list**
```
identity_id, name, source, tmdb_id, file_uuid, trace_id, chunk_id,
start_frame, end_frame, fps, start_time, end_time, text_content
```
---
## 4. Identity Detail API
### GET /api/v1/identity/{uuid}
| 項目 | 內容 |
|---|---|
| **Method** | GET |
| **HTTP** | 200 |
| **Response Key** | 頂層物件 |
**欄位:**
```
success, identity_uuid, name, identity_type, source, status,
metadata, reference_data, tmdb_id, tmdb_profile, created_at, updated_at
```
**注意:** `tmdb_profile` 為本地絕對路徑(如 `/Users/accusys/momentry/output/identities/{uuid}/profile.jpg`
### PATCH /api/v1/identity/{uuid} (update)
| 項目 | 內容 |
|---|---|
| **Method** | PATCH |
| **Body** | `{"name": "string"}` 或其他可更新欄位 |
| **HTTP** | 200 |
**Response**
```json
{"success": true, "identity_uuid": "...", "updated_fields": ["name"]}
```
### DELETE /api/v1/identity/{uuid}
| 項目 | 內容 |
|---|---|
| **Method** | DELETE |
| **HTTP** | 204 (成功) / 404 (找不到) |
### POST /api/v1/identity (create)
| 項目 | 內容 |
|---|---|
| **Method** | POST |
| **Body** | 需要 `face_json_path` + `identity_name` 等欄位 |
| **HTTP** | 500 (缺少必要欄位時) |
**注意:** 此 API 需要 face JSON 路徑,不是單純建立空人物。需有 face data 才能建立。
---
## 5. Identity Faces API
### GET /api/v1/identity/{uuid}/faces
| 項目 | 內容 |
|---|---|
| **Method** | GET |
| **Params** | `page_size` (int) |
| **HTTP** | 200 |
| **Response Key** | `data` (array) **不是** `faces` |
**欄位data 內):**
```
id, file_uuid, frame_number, timestamp_secs, face_id, bbox, confidence
```
**Response 結構:**
```json
{
"success": true,
"identity_uuid": "...",
"name": "...",
"total": int,
"page": int,
"page_size": int,
"data": [...]
}
```
---
## 6. Identity Traces API
### GET /api/v1/identity/{uuid}/traces
| 項目 | 內容 |
|---|---|
| **Method** | GET |
| **Params** | `page_size` (int) |
| **HTTP** | 200 |
| **Response Key** | `traces` (array) |
**欄位:**
```
file_uuid, trace_id, frame_count, first_frame, last_frame,
first_sec, last_sec, avg_confidence
```
**Response 結構:**
```json
{
"success": true,
"identity_uuid": "...",
"name": "...",
"total": int,
"page": int,
"page_size": int,
"total_faces": int,
"traces": [...]
}
```
---
## 7. Face Candidates API
### GET /api/v1/faces/candidates
| 項目 | 內容 |
|---|---|
| **Method** | GET |
| **Params** | `page` (int), `page_size` (int) |
| **HTTP** | 200 |
| **Response Key** | `candidates` (array) |
**欄位:**
```
id, face_id, file_uuid, frame_number, confidence, bbox, attributes
```
**Response 結構:**
```json
{
"candidates": [...],
"total": int,
"page": int,
"page_size": int
}
```
---
## 8. Bind / Unbind / Merge APIs
### POST /api/v1/identity/{uuid}/bind
| 項目 | 內容 |
|---|---|
| **Method** | POST |
| **Body** | `{"face_id": "string", "file_uuid": "string"}` |
| **HTTP** | 200 |
**Response**
```json
{"success": true, "message": "Bound face ... to ...", "data": {"rows_affected": 0}}
```
**注意:** `face_id` 必須是 **string**,不能是 integer
### POST /api/v1/identity/{uuid}/unbind
| 項目 | 內容 |
|---|---|
| **Method** | POST |
| **Body** | `{"face_id": "string", "file_uuid": "string"}` |
| **HTTP** | 200 |
**Response**
```json
{"success": true, "message": "Unbound face ... from ..."}
```
### POST /api/v1/identity/{uuid}/mergeinto
| 項目 | 內容 |
|---|---|
| **Method** | POST |
| **Body** | `{"into_uuid": "string"}` |
| **HTTP** | 200 (成功) / 404 (目標不存在) |
**注意:** URL 中的 `{uuid}`**來源** identitybody 中的 `into_uuid`**目標** identity
---
## 9. Media APIs
### GET /api/v1/file/{uuid}/thumbnail
| 項目 | 內容 |
|---|---|
| **Method** | GET |
| **Params** | `frame` (int, default 30) |
| **HTTP** | 200 |
| **Content-Type** | `image/jpeg` |
| **Response** | Binary image data |
### GET /api/v1/file/{uuid}/video
| 項目 | 內容 |
|---|---|
| **Method** | GET |
| **Params** | `start_time` (float), `end_time` (float), `start_frame` (int), `end_frame` (int) |
| **HTTP** | 200 |
| **Content-Type** | `video/mp4` |
| **Response** | Binary MP4 data |
| **格式** | ISO Media, MP4 Base Media v1 |
---
## 10. Unregister API
### POST /api/v1/unregister
**Auth**: Required
Delete a registered file from the system. Supports single file by UUID, or batch by directory + regex pattern.
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `file_uuid` | string | * | — | Single file UUID to delete |
| `file_path` | string | * | — | Directory path (for batch delete) |
| `pattern` | string | * | — | Regex pattern (requires `file_path`) |
| `delete_output_files` | boolean | No | `true` | Also delete processor output JSON files |
**Response (200)**:
```json
{
"success": true,
"file_uuid": "8703db16...",
"message": "File ... unregistered successfully.",
"deleted_face_detections": 0,
"deleted_processor_results": 0,
"deleted_chunks": 0,
"deleted_qdrant_vectors": 1,
"deleted_redis_keys": 1,
"deleted_output_files": 10
}
```
**Error**: `400` (missing params), `404` (UUID not found), `401` (bad API key)
---
## 11. Process API
### POST /api/v1/file/{uuid}/process
Trigger processing pipeline for a registered file. Runs asynchronously.
| Field | Type | Required | Default | Description |
|-------|------|----------|---------|-------------|
| `processors` | string[] | No | all | Processors: `cut`, `asr`, `asrx`, `yolo`, `ocr`, `face`, `pose`, `visual_chunk`, `story`, `5w1h` |
| `rules` | string[] | No | all | Rule names (currently unused) |
**Response (200)**:
```json
{
"success": true,
"job_id": 42,
"file_uuid": "3a6c1865...",
"status": "processing",
"pids": [12345, 12346],
"message": "Processing triggered for video.mp4"
}
```
### GET /api/v1/progress/{uuid}
Real-time processing progress.
### GET /api/v1/jobs
List all processing jobs.
---
## API Response Key 摘要
| 端點 | Response Key | 備註 |
|---|---|---|
| `/files/scan` | `files` | |
| `/search/llm-smart` | `results` | |
| `/identities` (list) | `identities` | |
| `/identities/search` | `results` | 欄位不同於 list |
| `/identity/{uuid}` | 頂層物件 | 包含 `success` |
| `/identity/{uuid}/faces` | `data` | **不是** `faces` |
| `/identity/{uuid}/traces` | `traces` | |
| `/faces/candidates` | `candidates` | |
---
## Rust Struct 映射建議
```rust
// Files
struct FileInfo {
file_uuid: String, // null 時 fallback file_path
file_name: String,
file_size: i64,
modified_time: String,
is_registered: bool,
}
// Identities (list)
struct PersonInfo {
identity_uuid: String,
name: String,
starred: bool, // 從 metadata.starred 提取
}
// Identity detail
struct IdentityDetail {
identity_uuid: String,
name: String,
identity_type: String,
source: String,
status: String,
tmdb_id: Option<i64>,
tmdb_profile: Option<String>, // 本地路徑
created_at: String,
}
// Face (from /faces endpoint)
struct FaceInfo {
id: i64,
file_uuid: String,
frame_number: i64,
timestamp_secs: f64,
face_id: Option<String>,
bbox: Option<BBox>,
confidence: f64,
}
// Trace
struct TraceInfo {
trace_id: i64,
file_uuid: String,
frame_count: i64,
first_frame: i64,
last_frame: i64,
first_sec: f64,
last_sec: f64,
avg_confidence: f64,
}
// Face Candidate
struct FaceCandidate {
id: i64,
face_id: Option<String>,
file_uuid: String,
frame_number: i64,
confidence: f64,
bbox: Option<BBox>,
}
struct BBox {
x: f64,
y: f64,
width: f64,
height: f64,
}
// Search result (不同於 list)
struct SearchIdentityResult {
identity_id: i64,
name: String,
source: String,
tmdb_id: Option<i64>,
file_uuid: Option<String>,
trace_id: Option<i64>,
start_time: f64,
end_time: f64,
text_content: Option<String>,
}
```