79 lines
4.0 KiB
Markdown
79 lines
4.0 KiB
Markdown
# Sync Notes 2026-05-21
|
||
|
||
## M5Max128 收到後需要做的事
|
||
|
||
```bash
|
||
cd ~/momentry_core
|
||
git pull origin main # 拉取所有變更
|
||
cat SYNC_V1.1.md # 閱讀此文件
|
||
|
||
# 資料庫變更(必須先執行,否則 worker 會 fail)
|
||
psql -U accusys -d momentry -c "ALTER TABLE public.pre_chunks ALTER COLUMN coordinate_index SET DEFAULT 0;"
|
||
|
||
# 重建 + 重啟
|
||
cargo build --release --bin momentry
|
||
./run-server-3002.sh
|
||
```
|
||
|
||
---
|
||
|
||
## Bugs Fixed (13)
|
||
|
||
| # | 問題 | 根因 | 修復 |
|
||
|---|------|------|------|
|
||
| 1 | `GET /identity/:uuid/files` 空資料 | SQL 缺 `REPLACE(uuid)` + 缺 `JOIN videos` | 改用 `REPLACE(uuid::text...)` + JOIN videos + `frame_number/fps` |
|
||
| 2 | `GET /identity/:uuid/faces` crash + 空 | `i64`/`INT4` 型別不符 + 硬編碼 NULL/0 | `id::bigint`、`confidence::float8` + 真實欄位 |
|
||
| 3 | `GET /identity/:uuid` crash | `IdentityDetailRecord.id` 是 `i64` 但 DB 是 `INT4` | `id::bigint as id` |
|
||
| 4 | `GET /file/:uuid/identities` 空 | 雙重 stub(handler + DB 都 `Vec::new()`) | 完整實作 + 正確 total count |
|
||
| 5 | `GET /identities/search?q=Louis` 500 | `c.text_content` NULL 但 Rust tuple 用 `String` | 改 `Option<String>` |
|
||
| 6 | `POST /search/universal` person type first/last_time null | `search_persons_internal` 用 `timestamp_secs` | 改 `frame_number/fps` + JOIN videos |
|
||
| 7 | faces/files/chunks total 不正確 | `total: data.len()` | 獨立 COUNT 查詢 |
|
||
| 8 | `GET /identity/:uuid/traces` 無分頁 | 缺 page/page_size | 新增 `TracesQuery` + LIMIT/OFFSET |
|
||
| 9 | 身分比對 frame-level 不穩定 | frame-level Qdrant | 改 **trace-level**(AVG embedding per trace) |
|
||
| 10 | Charade face embedding 不在 Qdrant | 沒跑 `sync_face_embeddings` | match API 自動 push + ANN search |
|
||
| 11 | 無眼睛 face 推入 Qdrant | 無 QC 過濾 | `face_landmark_qc.py --apply` + Qdrant sync 過濾 `qc_ok` |
|
||
| 12 | TMDb 比對 dev/prod 不一致 | Qdrant ANN 不同 collection | trace-level 改善穩定性 |
|
||
| 13 | `faces/files/chunks total` 顯示 page_size | `total: data.len()` | 改為獨立 COUNT 查詢 |
|
||
|
||
## ✨ 新功能 (6)
|
||
|
||
| # | 功能 | 說明 |
|
||
|---|------|------|
|
||
| 1 | `POST /api/v1/tmdb/fetch` | 從 TMDb 下載 cast → 建立 identity + json + jpg + Qdrant |
|
||
| 2 | `POST /api/v1/agents/tmdb/match/:file_uuid` | 推 face → Qdrant ANN search → bind identity |
|
||
| 3 | `GET /api/v1/identity/:uuid/status` | 檢查 identity.json + profile.jpg 是否存在 |
|
||
| 4 | `/health` 新增 watcher/worker/時區 | `watcher_running`、`worker_running`、`system_timezone` |
|
||
| 5 | `SYSTEM_TIMEZONE` config | 自動偵測系統時區,可 `MOMENTRY_TIMEZONE` 覆蓋 |
|
||
| 6 | `GET /identity/:uuid/traces` 分頁 | `?page=1&page_size=20` |
|
||
|
||
## 🔧 資料庫變更
|
||
|
||
```sql
|
||
-- 必須執行(否則 worker 的 CUT processor 會失敗)
|
||
ALTER TABLE public.pre_chunks ALTER COLUMN coordinate_index SET DEFAULT 0;
|
||
|
||
-- 選擇性(face_landmark_qc.py --apply 需要)
|
||
ALTER TABLE public.face_detections ADD COLUMN metadata jsonb DEFAULT '{}'::jsonb;
|
||
```
|
||
|
||
## 🗑️ 清理
|
||
|
||
- 刪除 2,769 個孤兒 `person_xxx` identity(無 face_detections)
|
||
- `person_identities` + `person_appearances` table 已 DROP
|
||
|
||
## 📂 主要檔案變更
|
||
|
||
| 檔案 | 說明 |
|
||
|------|------|
|
||
| `src/api/identity_api.rs` | identity detail/files/faces total 修正 + status endpoint |
|
||
| `src/api/identity_binding.rs` | traces 分頁(新增 `page`/`page_size`/`total`) |
|
||
| `src/api/server.rs` | health 新增 watcher/worker/system_timezone |
|
||
| `src/api/tmdb_api.rs` | **新檔案** — tmdb/fetch + match 端點 |
|
||
| `src/api/universal_search.rs` | person search 改 frame_number/fps |
|
||
| `src/core/config.rs` | 新增 SYSTEM_TIMEZONE |
|
||
| `src/core/db/qdrant_db.rs` | search_face_collection + sync_trace_embeddings + batch upsert |
|
||
| `src/core/db/postgres_db.rs` | get_identity_files/faces 修正 + get_file_identities 實作 |
|
||
| `src/core/tmdb/probe.rs` | extract_movie_name 改進(只取 `(` 前) |
|
||
| `scripts/face_landmark_qc.py` | 新增 `--apply` + `--schema` 參數 |
|
||
| `Cargo.toml` | reqwest 加 `gzip` feature |
|