Files
momentry_studio/docs/CORE_API_REFERENCE.md

403 lines
8.1 KiB
Markdown
Raw Permalink 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 |
---
## 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>,
}
```