- Add UNREGISTER_TIMEOUT=200000 (200s) for large file unregister
- Add timeout field to buildHttpRequest return type
- httpCall now uses per-request timeout override
- unregister_file now uses asyncMode: true for better UX
- Show "Removing in background..." toast for async mode
Fixes timeout error when unregistering large files (83K faces, 20K nodes).
Replace merge_trace implementation with merge_groups API
Changes:
1. src/api/index.ts:
- Add merge_groups API definition
- POST /api/v1/file/:file_uuid/groups/merge
- Parameters: file_uuid, source_groups[], target_group_name
2. src/views/PeopleView.vue:
- Rewrite executeMerge() function
- Use group names instead of trace IDs
- Single API call for all groups
- Remove trace-level loop
3. src/views/PeopleView.vue:
- Delete updateClusterAfterMerge() function
- No longer needed with new API
Benefits:
- ✅ Atomic operation (single API call)
- ✅ Correct merge behavior (groups, not traces)
- ✅ Better performance (1 call vs N calls)
- ✅ Data consistency guaranteed
API behavior:
- Merge N groups into 1 target group
- All traces from source groups merged to target
- Source groups deleted after merge
- Returns traces_merged count
Core API: Implemented by Core Team (2026-07-25)
Status: Ready for testing
Core Changes:
- Fix SearchView to use start_frame/end_frame directly (no time*fps conversion)
- Add hard_delete support to delete_trace API
- VideoPlayer: Main timeline + Mark system foundation
- Proxy: Add local routes for auth, media, identity-matches, cluster-results
- Add .gitignore to exclude build artifacts and dependencies
Design Documents:
- Multi-track Mark system design (.opencode/plans/)
- Video editing positioning standards research
Files Modified:
- src/views/SearchView.vue: Frame positioning, ensureMinDuration (240 frames)
- src/views/PeopleView.vue: batchDeleteGroups with hard_delete
- src/api/index.ts: delete_trace with hard_delete body
- src/components/VideoPlayer.vue: Timeline + Mark UI
- src-tauri/src/proxy.rs: New local routes
- AGENTS.md: Update documentation
- Core API: bind/unbind accept id (integer PK) when face_id is null
- Tauri proxy: stream video responses instead of buffering for seek bar
- VideoPlayer: remove muted attribute, unmute by default
- LibraryView: call invalidateFiles() before ensureFiles() on register/unregister
- PeopleView: close sort panel on click-outside, not just hamburger toggle
- bind_face: prefer face_id, fallback to id when face_id is null