fix: face group name read consistency, sync_file_status fix, cleanup ghost records, identity_agent replaced with face_dedup
- get_face_groups_handler: COALESCE(tp.name, tn.label) for name consistency - sync_file_status: compare JSON vs pre_chunks (not chunk table) - face consistency: compare frames.len() not total_faces - cleanup 2 ghost records with NULL file_name/file_path - replace identity_agent with face_dedup in pipeline stages - remove identity_agent_api.rs and all references - update required_processors to match actual processors - update AGENTS.md with team responsibilities - add Studio pipeline changes documentation
This commit is contained in:
@@ -37,68 +37,154 @@ a { color: #0066cc; }
|
||||
|
||||
<h2>Temporal Knowledge Graph (TKG)</h2>
|
||||
<p>TKG is a time-aligned knowledge graph built from multi-processor outputs (face, yolo, ocr, pose, asrx, gaze, lip, appearance). It produces 9 node types and 14 edge types stored in <code>dev.tkg_nodes</code> and <code>dev.tkg_edges</code>.</p>
|
||||
<p><strong>Node naming convention:</strong> All trace types use <code>_track</code> suffix. Text uses <code>_region</code> (non-temporal).</p>
|
||||
<p><strong>See also:</strong> <code>docs_v1.0/DESIGN/TKG_FORMATION_V1.0.md</code> for formation phases, flow diagrams, and query examples.</p>
|
||||
<h3>Node Types</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Node Type</th>
|
||||
<th>External ID Format</th>
|
||||
<th>Description</th>
|
||||
<th>Key Properties</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>face_trace</code></td>
|
||||
<td><code>face_track</code></td>
|
||||
<td><code>trace_{trace_id}</code></td>
|
||||
<td>A tracked face identity over time</td>
|
||||
<td><code>trace_id</code>, <code>face_count</code>, <code>avg_confidence</code></td>
|
||||
<td><code>trace_id</code>, <code>frame_count</code>, <code>status</code>, <code>avg_bbox</code>, <code>avg_yaw</code>, <code>avg_pitch</code>, <code>avg_roll</code>, <code>start_frame</code>, <code>end_frame</code>, <code>pose_count</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>gaze_trace</code></td>
|
||||
<td><code>gaze_track</code></td>
|
||||
<td><code>gaze_track_{id}</code></td>
|
||||
<td>Gaze direction over time</td>
|
||||
<td><code>direction</code> (frontal/left/right/up/down + diagonals)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>lip_trace</code></td>
|
||||
<td><code>lip_track</code></td>
|
||||
<td><code>lip_track_{id}</code></td>
|
||||
<td>Lip movement synced with speech</td>
|
||||
<td><code>speaker_id</code>, <code>lip_area_range</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>text_trace</code></td>
|
||||
<td><code>text_region</code></td>
|
||||
<td><code>text_region_{id}</code></td>
|
||||
<td>Spoken text aligned to time</td>
|
||||
<td><code>speaker_id</code>, <code>text</code>, <code>start_time</code>, <code>end_time</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>appearance_trace</code></td>
|
||||
<td><code>appearance_{trace_id}</code></td>
|
||||
<td>Human appearance (clothing) over time</td>
|
||||
<td><code>clothing_color</code>, <code>upper_cloth</code>, <code>lower_cloth</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>skin_tone_trace</code></td>
|
||||
<td>Fitzpatrick skin tone classification</td>
|
||||
<td><code>fitzpatrick_type</code> (I–VI)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>accessory</code></td>
|
||||
<td><code>accessory_{id}</code></td>
|
||||
<td>Detected accessories</td>
|
||||
<td><code>type</code> (glasses/hat/etc.), <code>confidence</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>object</code></td>
|
||||
<td><code>object_{class}_{id}</code></td>
|
||||
<td>YOLO-detected object</td>
|
||||
<td><code>class</code>, <code>confidence</code>, <code>frame_count</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>speaker</code></td>
|
||||
<td><code>speaker_{speaker_id}</code></td>
|
||||
<td>ASRX speaker segment</td>
|
||||
<td><code>speaker_id</code>, <code>segment_count</code>, <code>total_duration</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<h3>Identity Agent Integration (face_track nodes)</h3>
|
||||
<p>Identity Agent marks face_track nodes with identity binding status.</p>
|
||||
<h4>face_track Status Values</h4>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Status</th>
|
||||
<th>Description</th>
|
||||
<th>Properties</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>pending</code></td>
|
||||
<td>No identity suggestion</td>
|
||||
<td>Default state</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>suggested</code></td>
|
||||
<td>Identity Agent suggested</td>
|
||||
<td><code>pending_identity_name</code>, <code>pending_identity_uuid</code>, <code>suggested_by</code>, <code>confidence</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>confirmed</code></td>
|
||||
<td>User confirmed binding</td>
|
||||
<td><code>identity_uuid</code>, <code>identity_id</code>, <code>identity_ref</code>, <code>identity_name</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>stranger</code></td>
|
||||
<td>Stranger cluster member</td>
|
||||
<td><code>stranger_id</code>, <code>stranger_ref</code></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h4>Suggested By Values</h4>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Value</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>tmdb</code></td>
|
||||
<td>TMDb seed matched</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>propagation</code></td>
|
||||
<td>Confirmed trace propagation</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>manual</code></td>
|
||||
<td>User manual selection</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h4>Example face_track Node</h4>
|
||||
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"node_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"face_track"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"external_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"face_track_1"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"label"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Face Track 1"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"trace_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"frame_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">45</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"start_frame"</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"end_frame"</span><span class="p">:</span><span class="w"> </span><span class="mi">300</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"avg_bbox"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="nt">"x"</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span><span class="w"> </span><span class="nt">"y"</span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="p">,</span><span class="w"> </span><span class="nt">"width"</span><span class="p">:</span><span class="w"> </span><span class="mi">80</span><span class="p">,</span><span class="w"> </span><span class="nt">"height"</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="p">},</span>
|
||||
<span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"suggested"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"pending_identity_name"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Tom Hanks"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"pending_identity_uuid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"xxx-xxx"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"suggested_by"</span><span class="p">:</span><span class="w"> </span><span class="s2">"tmdb"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"confidence"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.91</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
|
||||
<hr />
|
||||
<h3>Edge Types</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Edge Type</th>
|
||||
<th>Storage Name</th>
|
||||
<th>Source → Target</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
@@ -106,39 +192,52 @@ a { color: #0066cc; }
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>co_occurs</code></td>
|
||||
<td><code>CO_OCCURS_WITH</code></td>
|
||||
<td>object ↔ object</td>
|
||||
<td>Two objects appear together in same frame</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>speaker_face</code></td>
|
||||
<td>speaker ↔ face_trace</td>
|
||||
<td>Speaker matched to face trace via lip sync</td>
|
||||
<td><code>SPEAKS_AS</code></td>
|
||||
<td>speaker → face_track</td>
|
||||
<td>Speaker matched to face track via lip sync</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>face_face</code></td>
|
||||
<td>face_trace ↔ face_trace</td>
|
||||
<td>Two face traces interact (mutual gaze)</td>
|
||||
<td><code>INTERACTS_WITH</code></td>
|
||||
<td>face_track ↔ face_track</td>
|
||||
<td>Two face tracks interact (mutual gaze)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>mutual_gaze</code></td>
|
||||
<td>gaze_trace ↔ gaze_trace</td>
|
||||
<td><code>MUTUAL_GAZE</code></td>
|
||||
<td>gaze_track ↔ gaze_track</td>
|
||||
<td>Two people looking at each other</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>lip_sync</code></td>
|
||||
<td>lip_trace ↔ text_trace</td>
|
||||
<td><code>LIP_SYNC</code></td>
|
||||
<td>lip_track → text_region</td>
|
||||
<td>Lip movement aligned with spoken text</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>has_appearance</code></td>
|
||||
<td>face_trace ↔ appearance_trace</td>
|
||||
<td><code>HAS_APPEARANCE</code></td>
|
||||
<td>face_track → appearance_trace</td>
|
||||
<td>Face has specific appearance</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>wears</code></td>
|
||||
<td>face_trace ↔ accessory</td>
|
||||
<td><code>WEARS</code></td>
|
||||
<td>face_track → accessory</td>
|
||||
<td>Face wears an accessory</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>hand_object</code></td>
|
||||
<td><code>HOLDS</code></td>
|
||||
<td>hand → object</td>
|
||||
<td>Hand holding object</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
@@ -156,10 +255,10 @@ a { color: #0066cc; }
|
||||
<span class="w"> </span><span class="nt">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"file_uuid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"d3f9ae8e471a1fc4d47022c66091b920"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"result"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"face_trace_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">16</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"gaze_trace_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">16</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"lip_trace_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">12</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"text_trace_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">24</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"face_track_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">16</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"gaze_track_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">16</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"lip_track_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">12</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"text_region_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">24</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"appearance_trace_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">8</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"skin_tone_trace_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"accessory_nodes"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span>
|
||||
@@ -230,7 +329,7 @@ a { color: #0066cc; }
|
||||
<td>string</td>
|
||||
<td>No</td>
|
||||
<td>all</td>
|
||||
<td>Filter by node type: <code>face_trace</code>, <code>gaze_trace</code>, <code>lip_trace</code>, <code>text_trace</code>, <code>appearance_trace</code>, <code>skin_tone_trace</code>, <code>accessory</code>, <code>object</code>, <code>speaker</code></td>
|
||||
<td>Filter by node type: <code>face_track</code>, <code>gaze_track</code>, <code>lip_track</code>, <code>text_region</code>, <code>appearance_trace</code>, <code>skin_tone_trace</code>, <code>accessory</code>, <code>object</code>, <code>speaker</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>page</code></td>
|
||||
@@ -249,11 +348,11 @@ a { color: #0066cc; }
|
||||
</tbody>
|
||||
</table>
|
||||
<h4>Example</h4>
|
||||
<div class="codehilite"><pre><span></span><code><span class="c1"># Get all face_trace nodes</span>
|
||||
<div class="codehilite"><pre><span></span><code><span class="c1"># Get all face_track nodes</span>
|
||||
curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span><span class="s2">"</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/tkg/nodes"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-API-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"node_type": "face_trace", "page": 1, "page_size": 50}'</span>
|
||||
<span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"node_type": "face_track", "page": 1, "page_size": 50}'</span>
|
||||
|
||||
<span class="c1"># Get all nodes</span>
|
||||
curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span><span class="s2">"</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/tkg/nodes"</span><span class="w"> </span><span class="se">\</span>
|
||||
@@ -272,12 +371,12 @@ curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>
|
||||
<span class="w"> </span><span class="nt">"nodes"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||||
<span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"node_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"face_trace"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"external_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"trace_0"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"label"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Face Trace 0"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"node_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"face_track"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"external_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"face_track_0"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"label"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Face Track 0"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"trace_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"face_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">142</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"frame_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">142</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"avg_confidence"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.87</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
@@ -406,17 +505,17 @@ curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>
|
||||
</tbody>
|
||||
</table>
|
||||
<h4>Example</h4>
|
||||
<div class="codehilite"><pre><span></span><code><span class="c1"># Get all co_occurrence edges</span>
|
||||
<div class="codehilite"><pre><span></span><code><span class="c1"># Get all co_occurs edges</span>
|
||||
curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span><span class="s2">"</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/tkg/edges"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-API-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"edge_type": "co_occurs"}'</span>
|
||||
|
||||
<span class="c1"># Get edges between face_trace and speaker nodes</span>
|
||||
<span class="c1"># Get edges between face_track and speaker nodes</span>
|
||||
curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span><span class="s2">"</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/tkg/edges"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-API-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"source_type": "speaker", "target_type": "face_trace"}'</span>
|
||||
<span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"source_type": "speaker", "target_type": "face_track"}'</span>
|
||||
</code></pre></div>
|
||||
|
||||
<h4>Response (200)</h4>
|
||||
@@ -522,12 +621,12 @@ curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>
|
||||
<span class="w"> </span><span class="nt">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"node"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"node_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"face_trace"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"external_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"trace_0"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"label"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Face Trace 0"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"node_type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"face_track"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"external_id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"face_track_0"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"label"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Face Track 0"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"properties"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"trace_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"face_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">142</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"frame_count"</span><span class="p">:</span><span class="w"> </span><span class="mi">142</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"avg_confidence"</span><span class="p">:</span><span class="w"> </span><span class="mf">0.87</span>
|
||||
<span class="w"> </span><span class="p">}</span>
|
||||
<span class="w"> </span><span class="p">},</span>
|
||||
@@ -722,7 +821,95 @@ curl<span class="w"> </span>-s<span class="w"> </span>-X<span class="w"> </span>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<p><em>Updated: 2026-06-20 12:00:00</em></p>
|
||||
<h3>Trace Management</h3>
|
||||
<p>Endpoints for managing face traces: list, delete, restore, and merge.</p>
|
||||
<h4><code>DELETE /api/v1/file/:file_uuid/trace/:trace_id</code></h4>
|
||||
<p><strong>Auth</strong>: Required</p>
|
||||
<p>Soft-delete a face trace (default) or hard-delete with <code>{"hard_delete": true}</code>.</p>
|
||||
<p>Soft delete marks Qdrant points with <code>status: "deleted"</code> and TKG nodes with <code>status: "deleted"</code> in properties. Deleted traces are excluded from the traces list.</p>
|
||||
<p>Hard delete permanently removes Qdrant points and TKG nodes.</p>
|
||||
<p><strong>Request Body</strong> (optional):</p>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Type</th>
|
||||
<th>Default</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>hard_delete</code></td>
|
||||
<td>boolean</td>
|
||||
<td><code>false</code></td>
|
||||
<td>Permanently delete instead of marking</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p><strong>Example</strong>:</p>
|
||||
<div class="codehilite"><pre><span></span><code><span class="c1"># Soft delete</span>
|
||||
curl<span class="w"> </span>-X<span class="w"> </span>DELETE<span class="w"> </span><span class="s2">"</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/trace/8"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-API-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span>-d<span class="w"> </span><span class="s1">'{}'</span>
|
||||
|
||||
<span class="c1"># Hard delete</span>
|
||||
curl<span class="w"> </span>-X<span class="w"> </span>DELETE<span class="w"> </span><span class="s2">"</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/trace/8"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-API-Key: </span><span class="nv">$KEY</span><span class="s2">"</span><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Content-Type: application/json"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"hard_delete": true}'</span>
|
||||
</code></pre></div>
|
||||
|
||||
<p><strong>Response</strong>:</p>
|
||||
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"file_uuid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"9f6a9cd55a5809f977f5a6589b9045c5"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"trace_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">8</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"hard_delete"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"qdrant_marked"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"tkg_nodes_marked"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
|
||||
<hr />
|
||||
<h4><code>POST /api/v1/file/:file_uuid/trace/:trace_id/restore</code></h4>
|
||||
<p><strong>Auth</strong>: Required</p>
|
||||
<p>Undo a soft-deleted trace. Clears <code>status: "deleted"</code> from Qdrant points and TKG node properties.</p>
|
||||
<p><strong>Example</strong>:</p>
|
||||
<div class="codehilite"><pre><span></span><code>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span><span class="s2">"</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/trace/8/restore"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-API-Key: </span><span class="nv">$KEY</span><span class="s2">"</span>
|
||||
</code></pre></div>
|
||||
|
||||
<p><strong>Response</strong>:</p>
|
||||
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"file_uuid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"9f6a9cd55a5809f977f5a6589b9045c5"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"trace_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">8</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"qdrant_restored"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"tkg_nodes_restored"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
|
||||
<hr />
|
||||
<h4><code>POST /api/v1/file/:file_uuid/trace/:source_trace_id/merge/:target_trace_id</code></h4>
|
||||
<p><strong>Auth</strong>: Required</p>
|
||||
<p>Merge all face points from source trace into target trace. Updates Qdrant <code>trace_id</code> and deletes source TKG node.</p>
|
||||
<p><strong>Example</strong>:</p>
|
||||
<div class="codehilite"><pre><span></span><code>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span><span class="s2">"</span><span class="nv">$API</span><span class="s2">/api/v1/file/</span><span class="nv">$FILE_UUID</span><span class="s2">/trace/16/merge/3"</span><span class="w"> </span><span class="se">\</span>
|
||||
<span class="w"> </span>-H<span class="w"> </span><span class="s2">"X-API-Key: </span><span class="nv">$KEY</span><span class="s2">"</span>
|
||||
</code></pre></div>
|
||||
|
||||
<p><strong>Response</strong>:</p>
|
||||
<div class="codehilite"><pre><span></span><code><span class="p">{</span>
|
||||
<span class="w"> </span><span class="nt">"success"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"file_uuid"</span><span class="p">:</span><span class="w"> </span><span class="s2">"9f6a9cd55a5809f977f5a6589b9045c5"</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"source_trace_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">16</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"target_trace_id"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"points_moved"</span><span class="p">:</span><span class="w"> </span><span class="mi">58</span><span class="p">,</span>
|
||||
<span class="w"> </span><span class="nt">"tkg_nodes_deleted"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span>
|
||||
<span class="p">}</span>
|
||||
</code></pre></div>
|
||||
|
||||
<hr />
|
||||
<p><em>Updated: 2026-07-21 01:00:00</em></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -505,7 +505,8 @@ a { color: #0066cc; }
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<p><em>Updated: 2026-07-18 — New profile module: trace-profile (GET, PUT, PUT group) and file-profile (GET, PUT)</em></p>
|
||||
<p><em>Updated: 2026-07-21 — Fixed external_id matching (trace_N + face_track_N formats), fixed parameter ordering in UPDATE query</em>
|
||||
<em>Updated: 2026-07-18 — New profile module: trace-profile (GET, PUT, PUT group) and file-profile (GET, PUT)</em></p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -29,7 +29,7 @@ a:hover td { background: #f8f8f8; border-radius: 4px; }
|
||||
<a class="logout-btn" href="#" onclick="fetch('/api/v1/auth/logout',{method:'POST'}).then(()=>window.location.reload());return false">Logout</a>
|
||||
</div>
|
||||
<p class="subtitle">API 參考手冊 — 登入後可瀏覽各模組文件</p>
|
||||
<table><tr onclick="window.location='11_error_codes.html'" style="cursor:pointer"><td class="cn">錯誤碼</td><td class="en">Error Codes</td></tr><tr onclick="window.location='14_identity_history.html'" style="cursor:pointer"><td class="cn">14 Identity History</td><td class="en"></td></tr><tr onclick="window.location='15_tkg.html'" style="cursor:pointer"><td class="cn">15 Tkg</td><td class="en"></td></tr><tr onclick="window.location='16_workspace.html'" style="cursor:pointer"><td class="cn">16 Workspace</td><td class="en"></td></tr><tr onclick="window.location='99_incomplete.html'" style="cursor:pointer"><td class="cn">99 Incomplete</td><td class="en"></td></tr></table>
|
||||
<table><tr onclick="window.location='11_error_codes.html'" style="cursor:pointer"><td class="cn">錯誤碼</td><td class="en">Error Codes</td></tr><tr onclick="window.location='14_identity_history.html'" style="cursor:pointer"><td class="cn">14 Identity History</td><td class="en"></td></tr><tr onclick="window.location='15_tkg.html'" style="cursor:pointer"><td class="cn">15 Tkg</td><td class="en"></td></tr><tr onclick="window.location='16_workspace.html'" style="cursor:pointer"><td class="cn">16 Workspace</td><td class="en"></td></tr><tr onclick="window.location='17_progress.html'" style="cursor:pointer"><td class="cn">17 Progress</td><td class="en"></td></tr><tr onclick="window.location='18_profile.html'" style="cursor:pointer"><td class="cn">18 Profile</td><td class="en"></td></tr><tr onclick="window.location='99_incomplete.html'" style="cursor:pointer"><td class="cn">99 Incomplete</td><td class="en"></td></tr></table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user