8.1 KiB
8.1 KiB
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:
{"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 結構:
{
"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 結構:
{
"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 結構:
{
"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:
{"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:
{"success": true, "message": "Unbound face ... from ..."}
POST /api/v1/identity/{uuid}/mergeinto
| 項目 | 內容 |
|---|---|
| Method | POST |
| Body | {"into_uuid": "string"} |
| HTTP | 200 (成功) / 404 (目標不存在) |
注意: URL 中的 {uuid} 是 來源 identity,body 中的 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 映射建議
// 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>,
}