Commit Graph

106 Commits

Author SHA1 Message Date
e65d5648b8 feat: 批量 unregister 功能 + 性能优化
功能:
- LibraryView 添加批量 unregister 按钮(勾选多个已注册文件后显示)
- 添加确认对话框,支持批量取消注册
- 添加中英日三语翻译

性能优化:
- search_agents API timeout 提升到 90s(避免前端超时)
- thumbnail 并发数从 32 降到 10(减少服务器压力)

修复:
- PeopleView 添加 group_uuid 字段映射
- LibraryView 排序优化(scanning/preparing 优先)
2026-10-07 23:39:31 +08:00
22fd55b0ab fix: 修复 LibraryView pose 过滤结构问题
**问题:**
- v-for 后的空 div 可能导致渲染问题
- 影响整个页面显示

**修复:**
- 使用 template + v-if 组合
- 避免创建多余的空 div
- 保持 TypeScript 类型安全

**测试:**
- 编译成功
- proxy 正常运行
- Library 页面应恢复正常

相关需求: A-8 (移除 pose)
2026-10-05 12:15:44 +08:00
7b83d987e4 fix: LibraryView 过滤 pose 显示(避免 HTML 结构问题)
**修改方法:**
- 使用嵌套 div + v-if 过滤 pose
- 避免使用 template 标签(可能导致结构问题)

**修改位置:**
- Line 353-357: processor output 过滤 pose
- Line 555: QC 检查移除 POSE

**原因:**
- pose 已从 pipeline 移除 (A-8)
- 之前的方法可能导致 HTML 结构问题

**过滤逻辑:**
```vue
<div v-for="(info, proc) in processors">
  <div v-if="proc !== 'pose'">
    <!-- 显示内容 -->
  </div>
</div>
```

相关需求: A-8 (移除 pose)
2026-10-05 11:58:06 +08:00
8758255eee feat: LibraryView 补全 stage 名称映射
**添加内容:**
- 添加 moment_chunks 到 formatStageName 映射
- 返回 'Moment Chunks' 作为显示名称

**Core API Stages 完整列表:**
- processors: Processors (weight: 0.30)
- rule1_ingestion: Rule1 Ingestion
- face_tracing: Face Tracing
- face_dedup: Face Dedup
- tkg_nodes: TKG Nodes
- tkg_edges: TKG Edges
- rule2_ingestion: Rule2 Ingestion
- vlm_summary: VLM Summary (weight: 0.04)
- moment_chunks: Moment Chunks (weight: 0.01)

**前端处理:**
- ✅ 直接使用 API 返回的 overall_progress
- ✅ 直接使用 API 返回的 stages[].weight
- ✅ 直接使用 API 返回的 stages[].progress
- ✅ 无前端权重计算

**API Endpoint:**
- GET /api/v1/pipeline-progress/:file_uuid
- 返回 PipelineProgress 结构

参考文件:
- Core: /Users/accusys/momentry_core/src/core/progress.rs:42-111
- API: /Users/accusys/momentry_core/src/api/scan.rs:1254
2026-10-05 05:03:31 +08:00
ed971c5f98 fix: LibraryView 移除 pose 相关代码
**移除内容:**
- 移除 pose 处理器选项(Line 305-310)
- 移除 procPose 变量定义(Line 1055)
- 移除 selectedProcessors 中的 procPose(Line 1142)
- 移除 processors 列表中的 'pose'(Line 1348, 1408)

**原因:**
- pose 已从 pipeline 移除(A-8)
- 无需在 Library 卡片中显示

**后续:**
- 待确认 VLM Summary 和 moment_chunks 是否需要合并
- 待确认百分比是否需要重新配置

相关需求: A-8 (移除 pose)
2026-10-05 04:57:25 +08:00
40b804c0d1 feat: PeopleView 统一使用 Core thumbnail 端点
- 影格显示改用 Core 端点 /api/v1/file/:uuid/thumbnail?frame=N
- 与 key_frame_url 保持一致(Line 3580 已使用 Core 端点)
- 测试确认两个端点都可工作:
  * Core 端点:/api/v1/file/:uuid/thumbnail?frame=N (62KB)
  * Proxy 端点:/api/v1/media/frame?file_uuid=...&frame=... (119KB)
- 选择 Core 端点原因:
  1. 统一端点风格(与 key_frame_url 一致)
  2. 更小的文件大小(可能是优化后的缩略图)
  3. 通过 fallback_handler 转发到 Core API

相关需求:B-3 (PeopleView 影格端点选择)
2026-10-04 15:15:45 +08:00
26ac0e90df fix: 完成 B-1, B-2, B-4(proxy 硬编码移除 + re-scan 端点)
B-1: 移除 proxy 硬编码路径
- 移除 API_KEY 常量,改为 get_api_key() 从环境变量读取
- 移除 PROFILE_DIRS,改为 get_output_dir() 从环境变量读取
- 移除 output_bases (identity_matches, trace_profile),改为环境变量驱动
- 移除 ADMIN_CONFIG_PATH,改为 get_admin_config_path() 从环境变量读取
- 添加 dev fallback 支持开发环境

B-2: API key 改为环境变量
- MOMENTRY_API_KEY 环境变量必须设置
- 未设置时会明确报错启动

B-4: 改用 re-scan 端点
- 简化 doReprocess 函数从 92 行减少到 32 行
- 改用单一 POST /api/v1/re-scan API
- 显式传 auto_pipeline: true
- 移除 unregister → register → process 手动串接
- 原子性操作,避免中间失败留下不一致状态

环境变量:
- MOMENTRY_API_KEY (必需)
- MOMENTRY_OUTPUT_DIR (可选,默认 /Users/accusys/momentry/output)
- MOMENTRY_DATA_DIR (可选,默认 /Users/accusys/momentry/data)
- MOMENTRY_ADMIN_CONFIG (可选,默认 /Users/accusys/momentry/config/admin_config.json)
2026-10-04 15:00:45 +08:00
f96ba33c7a fix: 保持产品名称和标语使用英文
- 添加 app.productName 和 app.tagline 翻译键
- 所有语言文件中都保持英文
- SearchView 使用翻译函数显示
- 确保不会被错误翻译
2026-10-02 06:02:10 +08:00
1bc53ae584 fix: AdminView 保存配置前先加载现有数据
- 避免空对象覆盖数据库中的现有配置
- 保存前先 GET 当前配置
- 合并修改的字段后再 POST
- 确保所有字段都正确保存
2026-10-02 05:42:31 +08:00
4eb423e424 fix: AdminView 确保 search config 正确保存
- 添加默认值处理
- vlm_min_score: 默认 0.0
- vlm_max_results: 默认 5
- vlm_output_language: 默认 'en'
- 修复空字符串导致保存失败的问题
2026-10-02 05:39:37 +08:00
51ded78f90 fix: PeopleView 强制使用最小过滤参数显示所有 faces
- 设置 ffMinConfPct = 0 (min confidence)
- 设置 ffMinSizePx = 0 (min size)
- 设置 ffMinQuality = 0 (min quality)
- 忽略 file profile 和 admin config 的过滤值
- 确保所有 face groups 和 unassigned faces 都能显示
2026-10-01 12:21:02 +08:00
28dfd3255d fix: PeopleView 从 cluster 数据提取 trace_ids 和 representative_trace
- 构建 faceIdToTraceId 映射
- 从 representative_face.face_id 找到 trace_id
- 为每个 cluster 设置 trace_ids 字段
- 设置 representative_trace 字段
- 修复 group 缩略图无法显示的问题
2026-10-01 11:22:44 +08:00
f3d75ebce8 feat: Library 批量注册 + PeopleView 修复 + 国际化
Library:
- 添加 checkbox 和鼠标框选功能
- Unregistered 卡片添加快速注册按钮
- 状态标签移至左下方,人脸图标移至左侧中间
- Deep Scan 改为 unregister -> register -> process
- 完整国际化(日语、繁体中文、英语)

PeopleView:
- 修复卡片不显示问题(使用 get_file_traces API)
- 移除对 identity_id 字段的依赖

其他:
- 添加日语语言包
- 添加 useDragSelect composable
- 新增文档:Face Bbox Null Bug Report
2026-10-01 00:42:13 +08:00
7b60ca3d2d feat: add face filter components and integration guide
- useFaceFilter composable: manages face filtering state and API calls
- FaceFilterPanel component: UI for filtering controls
- FaceCard component: text-only face display card
- Integration guide: step-by-step guide for integrating into PeopleView

Implements hybrid filtering mode with:
- Instant mode: client-side filtering (5-10ms)
- Backend mode: server-side complex filtering
- Hybrid mode: backend + instant filtering (AND)

Uses actual Core API endpoints:
- GET /file/{uuid}/faces
- POST /file/{uuid}/faces/filter
- GET /file/{uuid}/face/{faceId}/filter-report
- GET /file/{uuid}/filter-stats

Preferences stored in localStorage.
2026-08-09 21:24:52 +08:00
97a5fef0b2 fix: createNewGroupAndMove should rename trace profiles, not create identity
Changed from apiCall('create_identity_from_face') to updateTraceProfileGroup(name).
This correctly creates a new face group by renaming trace_profiles.name
instead of trying to register a global identity.
2026-08-01 05:55:33 +08:00
beea6b1c35 fix: moveToGroup should rename traces, not merge them
Changed from apiCall('merge_trace', ...) to updateTraceProfileGroup(name=targetGroup.name).
This just changes the trace profile name to join the target group,
without actually merging trace data together.
2026-08-01 05:50:10 +08:00
1c0f15664e fix: batchDeleteGroups should ungroup (rename to Unassigned), not hard delete
Changed from apiCall('delete_trace', ...) to updateTraceProfileGroup(name='Unassigned').
This preserves all trace data and just removes the group assignment.
Traces move back to Pending Faces instead of being deleted.
2026-08-01 05:40:46 +08:00
adc8d944c6 perf: use direct trace-thumb endpoint + fallback for face group thumbnails
- loadTraceThumb now uses /api/v1/trace-thumb/{uuid}/{tid} (~8ms)
- Face group imgs use direct trace-thumb URL with fallback
- Merge dialogs also use direct trace-thumb with fallback
- MAX_CONCURRENT increased to 32

Fallback chain:
1. c.rep_trace.file_uuid/trace_id (full trace data)
2. selectedFileUuid/representative_trace (group data only)
3. SVG silhouette
2026-08-01 05:29:55 +08:00
5be57aec7d Revert "perf: lazy load face group thumbnails + increase concurrency to 32"
This reverts commit 26b94f7243.
2026-08-01 01:58:01 +08:00
26b94f7243 perf: lazy load face group thumbnails + increase concurrency to 32
- Add v-observe directive to face groups for lazy thumbnail loading
- Increase MAX_CONCURRENT from 16 to 32 for faster parallel loading
- Apply lazy loading to merge dialogs and candidate groups
- Only load thumbnails when cards become visible (IntersectionObserver)

Improves initial load time for Charade (153 groups, 2451 traces) from
~76s to <5s for visible groups.
2026-08-01 01:49:45 +08:00
9d58fdb9d9 fix: unregister timeout 200s + async mode
- 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).
2026-07-31 18:32:50 +08:00
1a0b3f2c1f fix: use search/people API (no identity concept) 2026-07-25 20:38:30 +08:00
9386a8e8ef fix: fallback to search_identities (search/people endpoint not deployed) 2026-07-25 20:35:47 +08:00
fb9a55a64c feat: use new search/people API for People search mode 2026-07-25 20:33:15 +08:00
660f01c6c5 fix: People search mode label 2026-07-25 19:27:56 +08:00
cb7ebfb633 feat: add Face Group search mode back to SearchView
- Add 'Face Group' mode to search modes
- Use search_identities API temporarily
- Update summary: 'Identity' → 'FS'
- Will replace with Core Team's search_tkg_node_face_trace_profile API
2026-07-25 19:24:54 +08:00
0b19a0af0d refactor: QC report - 'Trace Profile' → 'FS Profile' 2026-07-25 15:53:37 +08:00
cf397b268e refactor: QC - use FS instead of Trace
- Display format: FS#123 instead of Trace #123
- Update labels: 'Traces' → 'FS'
- Update messages: 'clusters' → 'groups'
2026-07-25 15:53:17 +08:00
aa25600580 refactor: remove identity/pending concepts
- identity_uuid → group_uuid
- Remove status: 'pending'
- Remove starred: false
- Keep only: face, FS, face group
2026-07-25 15:51:38 +08:00
464ddd16a9 chore: remove debug console.log from faceGroups 2026-07-25 15:49:27 +08:00
4463ff2f96 style: change 'Faces' → 'FS' in Face Groups card 2026-07-25 15:48:13 +08:00
15647a47ac fix: replace all clusterAsPending → faceGroups 2026-07-25 15:43:28 +08:00
0a7902c2f5 refactor: rename clusterAsPending → faceGroups (no pending concept)
- Rename computed property to match current API semantics
- face_groups are definitive, not pending
- Add detailed console.log for debugging empty groups issue
2026-07-25 15:43:15 +08:00
d3cd940818 fix: revert to clusterAsPending (remove allGroupsForMove) 2026-07-25 15:42:31 +08:00
7cc4708c66 debug: add more console.log for clusterAsPending diagnosis 2026-07-25 15:42:17 +08:00
5db1b68fa0 debug: add allGroupsForMove computed for Move Faces Modal
- Explicitly define data source for Move Faces Modal
- Use clusterAsPending directly
- Add console.log for debugging

Purpose: Diagnose why only one group shows in Move Faces Modal
2026-07-25 15:40:48 +08:00
ec8d8d9d1a fix: add fallback for missing group names in Move Faces Modal
Problem:
- Some groups may not have name field
- Display would show blank or undefined

Solution:
- Add fallback: c.name || 'Unnamed Group'
- Add fallback: c.trace_count || 0
- Ensures always shows meaningful text

Impact:
- Move Faces Modal now always shows group names
- No blank entries even with incomplete data
2026-07-25 15:40:01 +08:00
f727b21e99 refactor: remove unused updateClusterAfterMerge function
- No longer needed with new merge_groups API
- merge_groups API handles group merging server-side
- Frontend only needs to refresh data after merge
2026-07-25 14:25:59 +08:00
8af2dc6128 feat: integrate new merge_groups API from Core Team
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
2026-07-25 14:25:35 +08:00
042bb45574 fix: update Pending Faces display to FS# format
- Line 102: Pending Faces name display
- Changed from F# to FS# (Face Sequence)
- Consistent with other Face Trace displays
2026-07-25 13:55:18 +08:00
e6b9b7b4b8 refactor: add # separator to display format
Display format with # separator:
- Frame: F#{number} (e.g., F#333)
- Face Trace: FS#{number} (e.g., FS#233)

Changes:
- Line 105: Frame range display (F#2219–F#2225)
- Line 143: Face Detail Modal (file_uuid:FS#233)
- Line 262: Cluster strip fallback (FS#233)
- Line 264: Cluster strip label (FS#233)

Benefits:
- # separator makes ID clearer
- Consistent format across all displays
- Visual distinction between type and number
2026-07-25 13:55:01 +08:00
98534bebfb refactor: change Face Trace display from 'Face{id}' to 'FS{id}'
Display format clarification:
- Frame: F{number} (e.g., F333)
- Face Trace: FS{number} (e.g., FS233)

Internal data remains: trace_id = 233 (integer)
Display text: FS233 (Face Sequence)

Changes:
- Line 143: Face Detail Modal display
- Line 262: Cluster strip fallback display
- Line 264: Cluster strip label

Reason:
- FS = Face Sequence (clear meaning)
- Avoid confusion with Frame (F)
- Separation of concerns: internal ID vs display text
2026-07-25 13:54:01 +08:00
39ce37e69c fix: remove premature updateClusterAfterMerge call in merge loop
Critical bug fix:
- updateClusterAfterMerge() was called after EACH trace merge
- This caused source group to be deleted after first trace
- Remaining traces had no group to merge into

Problem flow:
1. Merge trace #1 from Group B → Group A
2. updateClusterAfterMerge(B, A) deletes Group B
3. Try to merge trace #2 from Group B → Group B is gone!
4. Result: All source groups deleted after first trace

Solution:
- Remove updateClusterAfterMerge() from loop
- Let all traces merge successfully
- Reload cluster data at the end (Line 1813)
- Core API handles the merge, we just refresh UI

Impact:
- Merge now works correctly for all traces in a group
- No premature deletion of source groups
- UI refreshes after all operations complete
2026-07-25 13:29:47 +08:00
7b5650d098 fix: correct updateClusterAfterMerge to trigger computed update
Problem:
- Previous commit tried to splice computed property (clusterAsPending)
- Computed properties cannot be modified directly
- Need to update underlying data (clusterResultsCache)

Solution:
- Remove incorrect clusterAsPending.value.splice()
- Trigger reactive update via clusterResultsCache reassignment
- clusterAsPending computed will auto-update

Technical details:
- Vue computed properties are read-only
- Must modify underlying reactive data
- Reassignment triggers computed recalculation
2026-07-25 13:25:41 +08:00
c235d11d03 fix: handle empty groups after merge operation
Problem:
- After merge, source groups become empty
- Empty groups stay in UI as garbage data
- User sees empty groups with 0 faces

Solution:
- updateClusterAfterMerge() now removes source groups after merge
- Added removal from clusterAsPending computed property
- Ensures clean UI after merge operation

Behavior:
- Source group is deleted after all members merged to target
- Target group receives all members
- No empty groups left in UI

Related: merge functionality debug logging added in previous commit
2026-07-25 13:25:16 +08:00
361a01a025 debug: add comprehensive logging for merge groups functionality
Add debug logs to diagnose merge not working issue:

1. batchMergeGroups():
   - Log selected groupIds
   - Log mergeCandidateGroups count

2. executeMerge():
   - Log targetGroupId and targetGroup
   - Log targetTraceId type and value
   - Log targetTrace data
   - Log sourceGroups count
   - Log totalTraces and validTraces
   - Log each merge_trace API call params
   - Log success/fail counts

Purpose: Identify why merge fails when move works
Next: Check browser console for specific errors
2026-07-25 13:24:45 +08:00
c0832f32f9 refactor: complete face trace display migration to 'Face{id}'
Additional changes:
- Line 143: Face detail modal trace ID display
- Line 262: Cluster strip fallback display

All trace_id displays now use 'Face{id}' format:
- F13 → Face13
- F142 → Face142

Frame displays remain with 'F' prefix:
- F2219-2225 (frame range) - unchanged

Total changes: 3 locations in PeopleView.vue
2026-07-25 13:12:10 +08:00
e7f9740e72 refactor: change face trace display from 'F{id}' to 'Face{id}'
Problem:
- 'F13' display text confused with Frame numbers
- Users cannot distinguish between Trace ID and Frame Number

Solution:
- Change display format from 'F{trace_id}' to 'Face{trace_id}'
- Example: F13 → Face13, F142 → Face142

Changes:
- src/views/PeopleView.vue:264 - Cluster Detail Modal label

Benefits:
- Clear semantic meaning (Face vs Frame)
- No ambiguity for users
- Display layer only, data layer unchanged (still trace_id)
2026-07-25 13:11:47 +08:00
c347c200b2 fix: load pipeline stats in syncFileStatus and handle missing pipeline data
Problem:
- syncFileStatus() doesn't load pipeline progress data
- Files stuck in 'processing' without percentage display
- pollPipelineProgress() not started when pipeline data missing

Solution:
1. Add loadPipelineStats() call in syncFileStatus() for processing files
2. Start pollPipelineProgress() even when pipeline data is missing
3. Ensure progress bar always has data to display

Impact:
- Progress bar now shows percentage during deep scan
- Files no longer stuck in 'processing' state indefinitely
- Better handling of edge cases when API data is missing

Related: Core team needs to verify get_pipeline_stats API accuracy
2026-07-25 01:36:28 +08:00
58e614cb5c fix: unify status text to 'Scanning...' in LibraryView
Problem:
- Status badge showed 'Scanning'
- Progress bar showed 'Processing...'
- Two different texts displayed simultaneously

Solution:
- Change progress bar text to 'Scanning...'
- Now both badge and progress bar use consistent terminology
2026-07-25 01:27:16 +08:00