From 01bebb645a0183577b25b31c4315cfa64a321f3c Mon Sep 17 00:00:00 2001 From: Accusys Date: Mon, 18 May 2026 00:42:27 +0800 Subject: [PATCH] docs: fix endpoint names, remove dead signlas/unbound, correct unmounted routes list --- .../API_WORKSPACE/modules/03_register.md | 184 +++++++++++ .../API_WORKSPACE/modules/07_identity.md | 307 ++++++++++++++++++ .../API_WORKSPACE/modules/10_pipeline.md | 4 +- docs_v1.0/doc/03_register.html | 2 +- docs_v1.0/doc/07_identity.html | 8 - docs_v1.0/doc/10_pipeline.html | 10 +- 6 files changed, 494 insertions(+), 21 deletions(-) create mode 100644 docs_v1.0/API_WORKSPACE/modules/03_register.md create mode 100644 docs_v1.0/API_WORKSPACE/modules/07_identity.md diff --git a/docs_v1.0/API_WORKSPACE/modules/03_register.md b/docs_v1.0/API_WORKSPACE/modules/03_register.md new file mode 100644 index 0000000..9bae26f --- /dev/null +++ b/docs_v1.0/API_WORKSPACE/modules/03_register.md @@ -0,0 +1,184 @@ + + + + +## File Registration + +### `POST /api/v1/files/register` + +**Auth**: Required +**Scope**: file-level + +Register a video file for processing. Returns the file's metadata and UUID. + +**New in v0.1.2**: Registration now **automatically triggers the processing pipeline** — no need to call `POST /api/v1/file/:file_uuid/process` separately. The system will: +1. Register the file and run ffprobe +2. Auto-run offline TMDb probe (reads local identity files, no API calls) +3. Create a monitor job for the worker +4. Worker starts all 10 processors (Cut → ASR → ASRX → YOLO → OCR → Face → Pose → VisualChunk → Story → 5W1H) + +If the file already exists (same content hash), returns the existing record with `already_exists: true`. + +#### Request Parameters + +| Field | Type | Required | Default | Description | +|-------|------|----------|---------|-------------| +| `file_path` | string | Yes | — | Path to video file on disk | +| `pattern` | string | No | — | Regex pattern for batch register (requires `file_path` to be a directory) | +| `user_id` | integer | No | — | User ID to associate with registration | +| `content_hash` | string | No | — | Pre-computed SHA-256 hash (skips computation) | + +#### Example + +```bash +# Register a single file +curl -s -X POST "$API/api/v1/files/register" \ + -H "Content-Type: application/json" \ + -H "X-API-Key: $KEY" \ + -d '{"file_path": "/path/to/video.mp4"}' + +# Batch register files matching a pattern in a directory +curl -s -X POST "$API/api/v1/files/register" \ + -H "Content-Type: application/json" \ + -H "X-API-Key: $KEY" \ + -d '{"file_path": "/path/to/dir", "pattern": ".*\\.mp4$"}' +``` + +#### Response (200) + +```json +{ + "success": true, + "file_uuid": "3a6c1865...", + "file_name": "video.mp4", + "file_path": "/path/to/video.mp4", + "file_type": "video", + "duration": 120.5, + "width": 1920, + "height": 1080, + "fps": 24.0, + "total_frames": 2892, + "already_exists": false, + "message": "File registered successfully" +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `success` | boolean | Always true on 200 | +| `file_uuid` | string | 32-char hex UUID of the registered file | +| `file_name` | string | File name (auto-renamed if name conflict) | +| `file_path` | string | Canonical path on disk | +| `file_type` | string | `"video"`, `"audio"`, or `"unknown"` | +| `duration` | float | Duration in seconds | +| `width` | integer | Video width in pixels | +| `height` | integer | Video height in pixels | +| `fps` | float | Frames per second | +| `total_frames` | integer | Total frame count | +| `already_exists` | boolean | True if same content was already registered | +| `message` | string | Human-readable status | + +#### Error Responses + +| HTTP | When | +|------|------| +| `401` | Missing or invalid API key | +| `400` | Invalid request body | +| `404` | File path does not exist | + +--- + +### `GET /api/v1/files/scan` + +**Auth**: Required +**Scope**: file-level + +Scan the filesystem directory and list all media files, showing which are registered, processing, or unregistered. + +#### Query Parameters + +| Field | Type | Required | Default | Description | +|-------|------|----------|---------|-------------| +| `page` | integer | No | 1 | Page number (1-based) | +| `page_size` | integer | No | all | Items per page (alias: `limit`) | +| `limit` | integer | No | all | Max items (alias for `page_size`) | +| `pattern` | string | No | — | Regex filter on file name (e.g., `.*\\.mp4$`) | +| `sort_by` | string | No | `name` | Sort field: `name`, `size`, `modified`, `status` | +| `sort_order` | string | No | `asc` | Sort direction: `asc` or `desc` | + +#### Example + +```bash +# Full scan +curl -s "$API/api/v1/files/scan" -H "X-API-Key: $KEY" | jq '{total, registered_count, unregistered_count}' + +# Paginated (page 1, 5 per page) +curl -s "$API/api/v1/files/scan?page=1&page_size=5" -H "X-API-Key: $KEY" | jq '{page, total_pages, files: [.files[].file_name]}' + +# Regex filter: only mp4 files +curl -s "$API/api/v1/files/scan?pattern=.*\\.mp4$" -H "X-API-Key: $KEY" | jq '{filtered_total, files: [.files[].file_name]}' + +# Sort by file size (largest first) +curl -s "$API/api/v1/files/scan?sort_by=size&sort_order=desc&page_size=5" -H "X-API-Key: $KEY" | jq '[.files[] | {file_name, file_size}]' + +# Sort by modified time (most recent first) +curl -s "$API/api/v1/files/scan?sort_by=modified&sort_order=desc&page_size=5" -H "X-API-Key: $KEY" | jq '[.files[] | {file_name, modified_time}]' + +# Sort by status +curl -s "$API/api/v1/files/scan?sort_by=status&page_size=5" -H "X-API-Key: $KEY" | jq '[.files[] | {file_name, status}]' +``` + +#### Response (200) + +```json +{ + "files": [ + { + "file_name": "video.mp4", + "file_size": 12345678, + "is_registered": true, + "file_uuid": "3a6c1865...", + "status": "completed", + "registration_time": "2026-05-16T12:00:00Z", + "job_id": 42 + } + ], + "total": 107, + "filtered_total": 80, + "page": 1, + "page_size": 20, + "total_pages": 4, + "registered_count": 26, + "unregistered_count": 81 +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `files` | array | Array of file info objects (paginated) | +| `files[].file_name` | string | File name | +| `files[].relative_path` | string | Path relative to scan root | +| `files[].file_path` | string | Absolute path on disk | +| `files[].file_size` | integer | File size in bytes | +| `files[].modified_time` | string | Last modified timestamp (ISO8601) | +| `files[].is_registered` | boolean | Whether file is registered in DB | +| `files[].file_uuid` | string | 32-char hex UUID (only if registered) | +| `files[].status` | string | `"completed"`, `"processing"`, `"registered"`, `"unregistered"`, or `null` | +| `files[].registration_time` | string | DB registration timestamp (only if registered) | +| `files[].job_id` | integer | Processing job ID (only if a job exists) | +| `total` | integer | Total files found on disk (unfiltered) | +| `filtered_total` | integer | Files matching regex filter | +| `page` | integer | Current page number | +| `page_size` | integer | Items per page | +| `total_pages` | integer | Total pages | +| `registered_count` | integer | Files registered in DB | +| `unregistered_count` | integer | Files not yet registered | + +#### Notes + +| Feature | Behavior | +|---------|----------| +| **Regex** | Case-insensitive (`(?i)` prefix auto-applied). Applied to `file_name`. | +| **Sort order** | Default (`sort_by=name`): registered files first, then alphabetically. `sort_by=status`: alphabetical by status string. | +| **Pagination** | `page_size` and `limit` are aliases. Default: show all results. | +| **Processing order** | `pattern` regex filter → `sort_by`/`sort_order` → `page`/`page_size` slice. | diff --git a/docs_v1.0/API_WORKSPACE/modules/07_identity.md b/docs_v1.0/API_WORKSPACE/modules/07_identity.md new file mode 100644 index 0000000..d009bc9 --- /dev/null +++ b/docs_v1.0/API_WORKSPACE/modules/07_identity.md @@ -0,0 +1,307 @@ + + + + +## Global Identities + +### `GET /api/v1/identities` + +**Auth**: Required +**Scope**: identity-level + +List all registered identities with pagination. + +#### Example + +```bash +curl -s "$API/api/v1/identities?page=1&page_size=20" -H "X-API-Key: $KEY" | jq '{count, identities: [.identities[] | {name}]}' +``` + +--- + +### `GET /api/v1/identity/:identity_uuid` + +**Auth**: Required +**Scope**: identity-level + +Get detailed information for a specific identity, including metadata and TMDb references. + +#### Example + +```bash +curl -s "$API/api/v1/identity/$IDENTITY_UUID" -H "X-API-Key: $KEY" +``` + +#### Response (200) + +```json +{ + "success": true, + "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", + "name": "Cary Grant", + "identity_type": "people", + "source": "tmdb", + "status": "confirmed", + "tmdb_id": 112, + "tmdb_profile": "https://image.tmdb.org/t/p/w185/abc.jpg", + "metadata": {}, + "reference_data": {}, + "created_at": "2026-05-16T12:00:00Z", + "updated_at": null +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `identity_uuid` | string | Identity identifier | +| `name` | string | Identity name | +| `identity_type` | string | `"people"` or null | +| `source` | string | `.json`, `auto`, `tmdb`, `user_defined`, or `merged` | +| `status` | string | `"confirmed"`, `"pending"`, or `"inactive"` | +| `tmdb_id` | integer | TMDb person ID (only if source = tmdb) | +| `tmdb_profile` | string | TMDb profile image URL | +| `metadata` | object | Metadata JSON (tmdb_character, cast_order, etc.) | +| `created_at` | string | Creation timestamp | + +--- + +### `DELETE /api/v1/identity/:identity_uuid` + +**Auth**: Required +**Scope**: identity-level + +Delete an identity permanently. + +--- + +### `GET /api/v1/identity/:identity_uuid/files` + +**Auth**: Required +**Scope**: identity-level + +Get all files where this identity appears. Returns per-file summary including face count, confidence, and appearance time range. + +#### Example + +```bash +curl -s "$API/api/v1/identity/$IDENTITY_UUID/files" -H "X-API-Key: $KEY" +``` + +--- + +### `GET /api/v1/identity/:identity_uuid/faces` + +**Auth**: Required +**Scope**: identity-level + +Get all face detection records associated with this identity. + +#### Example + +```bash +curl -s "$API/api/v1/identity/$IDENTITY_UUID/faces" -H "X-API-Key: $KEY" +``` + +| Field | Type | Description | +|-------|------|-------------| +| `file_uuid` | string | File where face was detected | +| `frame_number` | integer | Frame number of detection | +| `face_id` | string | Face ID (format: `face_{frame_number}`) | +| `confidence` | float | Detection confidence | + +--- + +### `GET /api/v1/identity/:identity_uuid/chunks` + +**Auth**: Required +**Scope**: identity-level + +Get all text chunks (sentences) spoken while this identity's face was on screen. Useful for finding what a person said. + +#### Example + +```bash +curl -s "$API/api/v1/identity/$IDENTITY_UUID/chunks" -H "X-API-Key: $KEY" +``` + +| Field | Type | Description | +|-------|------|-------------| +| `file_uuid` | string | File identifier | +| `chunk_id` | string | Sentence chunk identifier | +| `start_time` | float | Start time in seconds | +| `end_time` | float | End time in seconds | +| `text` | string | Spoken text content | + +--- + +### `POST /api/v1/identity/:identity_uuid/bind` + +**Auth**: Required +**Scope**: identity-level + +Bind a face detection to an identity. Associates the face trace with the identity for future search and recognition. + +#### Request Parameters + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `file_uuid` | string | Yes | File where face is detected | +| `face_id` | string | Yes | Face ID (format: `{frame}_{idx}`) | + +#### Example + +```bash +curl -s -X POST "$API/api/v1/identity/$IDENTITY_UUID/bind" \ + -H "X-API-Key: $KEY" \ + -H "Content-Type: application/json" \ + -d '{"file_uuid": "'"$FILE_UUID"'", "face_id": "1_5"}' +``` + +--- + +### `POST /api/v1/identity/:identity_uuid/unbind` + +**Auth**: Required +**Scope**: identity-level + +Unbind a face detection from an identity. Removes the identity association from the face record. + +--- + +### `GET /api/v1/identities/search` + +**Auth**: Required +**Scope**: identity-level + +Search identities by name (ILIKE search). Returns matching identity records. + +#### Example + +```bash +curl -s "$API/api/v1/identities/search?q=Cary" -H "X-API-Key: $KEY" +``` + +| Field | Type | Description | +|-------|------|-------------| +| `name` | string | Identity name | +| `source` | string | Identity source | +| `tmdb_id` | integer | TMDb ID (if source = tmdb) | +| `file_uuid` | string | Associated file | + +--- + +--- + +### `POST /api/v1/identity/upload` + +**Auth**: Required +**Scope**: identity-level + +Upload an identity.json file to create or update an identity. Accepts the same format as the identity.json files stored on disk. + +If an identity with the same `name` already exists, it will be updated with the new values. + +#### Request + +The request body is an `IdentityFile` object: + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `identity_uuid` | string | Yes | Identity identifier | +| `name` | string | Yes | Identity display name | +| `identity_type` | string | No | `"people"` or null | +| `source` | string | No | `.json`, `auto`, `tmdb`, `user_defined`, or `merged` | +| `status` | string | No | `"confirmed"`, `"pending"`, or `"inactive"` | +| `tmdb_id` | integer | No | TMDb person ID | +| `tmdb_profile` | string | No | TMDb profile image URL | +| `metadata` | object | No | Arbitrary metadata JSON | +| `file_bindings` | array | No | Array of `{ file_uuid, trace_ids, face_count }` (informational) | + +#### Example + +```bash +curl -s -X POST "$API/api/v1/identity/upload" \ + -H "X-API-Key: $KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "version": 1, + "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", + "name": "Cary Grant", + "identity_type": "people", + "source": ".json", + "status": "confirmed", + "metadata": {}, + "file_bindings": [] + }' +``` + +#### Response (200) + +```json +{ + "success": true, + "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", + "name": "Cary Grant", + "message": "Identity uploaded successfully" +} +``` + +--- + +--- + +### `POST /api/v1/identity/:identity_uuid/profile-image` + +**Auth**: Required +**Scope**: identity-level + +Upload a profile image (JPEG or PNG) for an identity. The image is saved to `{output}/identities/{uuid}/profile.{ext}`. + +Uses `multipart/form-data` with field name `image`. + +#### Example + +```bash +curl -s -X POST "$API/api/v1/identity/$IDENTITY_UUID/profile-image" \ + -H "X-API-Key: $KEY" \ + -F "image=@/path/to/photo.jpg" +``` + +#### Response (200) + +```json +{ + "success": true, + "identity_uuid": "a9a901056d6b46ff92da0c3c1a57dff4", + "path": "/path/to/output/identities/.../profile.jpg", + "message": "Profile image saved: profile.jpg" +} +``` + +#### Error Responses + +| HTTP | When | +|------|------| +| `400` | Missing image field or unsupported format | +| `404` | Identity not found | +| `415` | Unsupported image type (use JPEG or PNG) | + +--- + +### `GET /api/v1/identity/:identity_uuid/profile-image` + +**Auth**: Required +**Scope**: identity-level + +Retrieve the profile image for an identity. Returns the raw image data with appropriate Content-Type header. + +```bash +curl -s "$API/api/v1/identity/$IDENTITY_UUID/profile-image" \ + -H "X-API-Key: $KEY" -o profile.jpg +``` + +| Response Header | Value | +|----------------|-------| +| `content-type` | `image/jpeg` or `image/png` | + + diff --git a/docs_v1.0/API_WORKSPACE/modules/10_pipeline.md b/docs_v1.0/API_WORKSPACE/modules/10_pipeline.md index 20f2e04..c4b2432 100644 --- a/docs_v1.0/API_WORKSPACE/modules/10_pipeline.md +++ b/docs_v1.0/API_WORKSPACE/modules/10_pipeline.md @@ -157,8 +157,6 @@ The following routes are defined in source code but are **NOT** currently mounte | Endpoint | Source file | |----------|-------------| -| `/api/v1/search/universal` | `universal_search.rs` | -| `/api/v1/search/frames` | `universal_search.rs` | -| `/api/v1/search/persons` | `universal_search.rs` | +| `/api/v1/search/persons` | `universal_search.rs` (not mounted) | | `/api/v1/who` | `who.rs` | | `/api/v1/who/candidates` | `who.rs` | diff --git a/docs_v1.0/doc/03_register.html b/docs_v1.0/doc/03_register.html index f5f5bc8..8e211ba 100644 --- a/docs_v1.0/doc/03_register.html +++ b/docs_v1.0/doc/03_register.html @@ -34,7 +34,7 @@ a { color: #0066cc; }

Auth: Required Scope: file-level

Register a video file for processing. Returns the file's metadata and UUID.

-

New in v0.1.2: Registration now automatically triggers the processing pipeline — no need to call POST /api/v1/file/:uuid/process separately. The system will: +

New in v0.1.2: Registration now automatically triggers the processing pipeline — no need to call POST /api/v1/file/:file_uuid/process separately. The system will: 1. Register the file and run ffprobe 2. Auto-run offline TMDb probe (reads local identity files, no API calls) 3. Create a monitor job for the worker diff --git a/docs_v1.0/doc/07_identity.html b/docs_v1.0/doc/07_identity.html index 239e688..fd24783 100644 --- a/docs_v1.0/doc/07_identity.html +++ b/docs_v1.0/doc/07_identity.html @@ -469,14 +469,6 @@ a { color: #0066cc; } -


-

GET /api/v1/signals/unbound

-

Auth: Required -Scope: identity-level

-

List unbound face signals — face detections that have not yet been assigned to any identity.

-

Example

-
curl -s "$API/api/v1/signals/unbound" -H "X-API-Key: $KEY"
-
\ No newline at end of file diff --git a/docs_v1.0/doc/10_pipeline.html b/docs_v1.0/doc/10_pipeline.html index 937c7cb..75eb932 100644 --- a/docs_v1.0/doc/10_pipeline.html +++ b/docs_v1.0/doc/10_pipeline.html @@ -333,16 +333,8 @@ a { color: #0066cc; } -/api/v1/search/universal -universal_search.rs - - -/api/v1/search/frames -universal_search.rs - - /api/v1/search/persons -universal_search.rs +universal_search.rs (not mounted) /api/v1/who