cleanup: remove dead code and duplicate docs
- Remove session-ses_2f27.md (161KB raw session log) - Remove 49 ROOT_* duplicate files across REFERENCE/ - Remove 14 duplicate files between REFERENCE/ root and history/ - Remove asr_legacy.rs (dead code, replaced by asr.rs) - Remove src/core/worker/ (duplicate JobWorker) - Remove src/core/layers/ (empty directory) - Remove 4 .bak files in src/ - Remove 7 dead private methods in worker/processor.rs - Remove backup directory from git tracking
This commit is contained in:
@@ -1,208 +0,0 @@
|
||||
# file_uuid 設計理念與規格
|
||||
|
||||
> Version: 1.0 | Date: 2026-04-30
|
||||
> Architecture: Birth Identity Model (戶籍制度模型)
|
||||
|
||||
---
|
||||
|
||||
## 1. 核心概念
|
||||
|
||||
系統將每個媒體檔案視為一個「自然人」,擁有一個**終身不變的身份證字號** (`file_uuid`)。
|
||||
|
||||
| 戶籍概念 | 系統對應 | 說明 |
|
||||
| :--- | :--- | :--- |
|
||||
| **身分證字號** | `file_uuid` | 檔案的終身唯一標識,出生後永不變更 |
|
||||
| **出生登記** | 首次 `register` | 檔案首次被系統納管,觸發分析處理 (ASR, Face, etc.) |
|
||||
| **戶籍地** | `file_path` | 檔案當前存放位置,可隨搬家而變更 |
|
||||
| **主管單位** | `MAC Address` | 核發身份的伺服器/機器,確保跨機器的管轄獨立 |
|
||||
| **居住證申請時間** | `registration_time` | 檔案在該管轄單位登記的時間戳記 |
|
||||
|
||||
---
|
||||
|
||||
## 2. file_uuid 生成公式
|
||||
|
||||
```text
|
||||
file_uuid = SHA256( MAC_Address | Birthday | Canonical_Path | Filename )[0:32]
|
||||
```
|
||||
|
||||
### 設計原則
|
||||
|
||||
| 原則 | 說明 |
|
||||
| :--- | :--- |
|
||||
| **唯一性** | 同一台機器上,相同路徑與檔名只會產生一個 UUID |
|
||||
| **穩定性** | **生日 (Birthday)** 是身份錨點。如果檔案在原地重新註冊,系統會找回原始生日,確保 UUID 不變 |
|
||||
| **管轄獨立** | 不同機器的 MAC 不同,確保跨伺服器身份獨立 |
|
||||
| **路徑綁定** | **Canonical Path** 參與計算。檔案移動到新路徑會產生新 UUID(視為新環境下的註冊) |
|
||||
| **隱私保護** | 所有元素經 Hash 處理,無法反推出原始資訊 |
|
||||
|
||||
### 關鍵元素
|
||||
|
||||
| 元素 | 說明 |
|
||||
| :--- | :--- |
|
||||
| `Birthday` | 首次註冊的時間戳記。系統會透過檔名查詢資料庫,找回原始生日,確保身份連續 |
|
||||
| `Canonical Path` | 檔案的絕對路徑。確保位置的唯一性 |
|
||||
| `Filename` | 檔案名稱 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 生命週期
|
||||
|
||||
### 3.1 出生 (Birth / 首次納管)
|
||||
|
||||
當檔案首次被系統發現並執行 `register` 時:
|
||||
|
||||
```
|
||||
1. 取得本机 MAC Address
|
||||
2. 讀取 Filename
|
||||
3. 查詢資料庫:是否有同檔名 (Filename) 的紀錄?
|
||||
├─ 有紀錄 → 取出其 registration_time 作為「生日 (Birthday)」
|
||||
└─ 無紀錄 → 使用 NOW() 作為「生日 (Birthday)」
|
||||
4. 計算 file_uuid = SHA256(MAC | Birthday | Canonical_Path | Filename)[0:32]
|
||||
5. 檢查 DB 是否已存在該 UUID
|
||||
├─ 已存在 → 拒絕重複登記 (已有出生紀錄)
|
||||
└─ 不存在 → 建立新生紀錄
|
||||
6. 記錄 registration_time (居住證申請時間)
|
||||
```
|
||||
|
||||
**出生後**:`file_uuid` 即成為該檔案的終身身份,不可更改。
|
||||
|
||||
### 3.2 搬家 (Move / 路徑變更)
|
||||
|
||||
當檔案從 `/data/demo/` 移動到 `/archive/2024/` 時:
|
||||
|
||||
```
|
||||
1. 檔案路徑變更 (Canonical Path 改變)
|
||||
2. 系統以新 Path 計算 UUID → 產生新 UUID
|
||||
3. 查詢 DB → 找不到該 UUID (視為新身份)
|
||||
4. 但若檔名相同,會查詢到舊的「生日 (Birthday)」
|
||||
5. 執行動作:
|
||||
├─ 建立新紀錄 (新 UUID,新路徑)
|
||||
├─ 使用原始的 Birthday (保持血緣關係)
|
||||
└─ 可選擇是否繼承舊紀錄的分析結果
|
||||
```
|
||||
|
||||
**關鍵邏輯**:
|
||||
- 路徑改變 = 新環境 = 新 UUID
|
||||
- 但透過 **Birthday 查詢機制**,系統知道這是同一個「人」搬到了新家
|
||||
|
||||
### 3.3 跨機器遷移 (Cross-Machine)
|
||||
|
||||
當檔案從 Server-A 複製到 Server-B 時:
|
||||
|
||||
```
|
||||
Server-A (MAC: aa:bb:cc:dd:ee:ff):
|
||||
file_uuid = SHA256("aa:bb:cc:dd:ee:ff|Birthday|/path|video.mp4") → "abc123..."
|
||||
|
||||
Server-B (MAC: 11:22:33:44:55:66):
|
||||
file_uuid = SHA256("11:22:33:44:55:66|Birthday|/path|video.mp4") → "def456..."
|
||||
```
|
||||
|
||||
- **結果**:兩台伺服器各自擁有獨立管轄權
|
||||
- **意義**:各管各的戶口,互不干擾
|
||||
|
||||
---
|
||||
|
||||
## 4. 資料庫欄位定義
|
||||
|
||||
### videos 表
|
||||
|
||||
| 欄位 | 類型 | 說明 | 範例 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `file_uuid` | VARCHAR(32) | **身分證字號** (不可變) | `384b0ff44aaaa1f1...` |
|
||||
| `file_path` | TEXT | **戶籍地址** (可變) | `/data/demo/video.mp4` |
|
||||
| `file_name` | VARCHAR(255) | 原始檔名 | `video.mp4` |
|
||||
| `registration_time` | TIMESTAMPTZ | **居住證申請時間** | `2026-04-30T02:00:00+08` |
|
||||
| `birth_registration` | JSONB | 出生登記詳情 | 見下方結構 |
|
||||
|
||||
### birth_registration JSONB 結構
|
||||
|
||||
```json
|
||||
{
|
||||
"registration_source": {
|
||||
"mac_address": "ba:f5:ee:bc:45:78",
|
||||
"original_path": "/Users/accusys/momentry/var/sftpgo/data/demo",
|
||||
"original_filename": "Old_Time_Movie_Show_-_Charade_1963.HD.mov",
|
||||
"timestamp": "2026-04-29T02:25:14+08:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 代碼實作
|
||||
|
||||
### 5.1 UUID 計算 (`src/core/storage/uuid.rs`)
|
||||
|
||||
```rust
|
||||
pub fn compute_birth_uuid(
|
||||
mac_address: &str,
|
||||
birthday: &str,
|
||||
path: &str,
|
||||
filename: &str,
|
||||
) -> String {
|
||||
let key = format!("{}|{}|{}|{}", mac_address, birthday, path, filename);
|
||||
let hash = Sha256::digest(key.as_bytes());
|
||||
hex::encode(hash)[0..32].to_string()
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 註冊流程 (`src/api/server.rs`)
|
||||
|
||||
```rust
|
||||
// 1. 取得 MAC、路徑與檔名
|
||||
let mac_address = get_mac_address();
|
||||
let canonical_path = path.canonicalize()...;
|
||||
let filename = path.file_name()...;
|
||||
|
||||
// 2. 查詢生日 (Identity Anchor)
|
||||
// 以檔名查詢 DB,若有紀錄則使用原始生日,否則使用 NOW()
|
||||
let birthday = db.find_birthday_by_filename(&filename).await.unwrap_or(now());
|
||||
|
||||
// 3. 計算穩定身份
|
||||
let file_uuid = compute_birth_uuid(&mac_address, &birthday, &canonical_path, &filename);
|
||||
|
||||
// 4. 檢查是否已出生
|
||||
if let Some(existing) = db.get_video_by_uuid(&file_uuid).await? {
|
||||
if existing.registration_time.is_some() {
|
||||
return Ok(already_exists_response);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 新生登記 + 觸發分析
|
||||
db.register_video(&record).await?;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 情境對照表
|
||||
|
||||
| 情境 | file_uuid | file_path | Birthday | 觸發分析? | 說明 |
|
||||
| :--- | :--- | :--- | :--- | :--- | :--- |
|
||||
| **首次註冊** | 新生成 | 記錄當前路徑 | NOW() | ✅ 是 | 出生登記,全面納管 |
|
||||
| **同一檔案再次註冊** | 相同 | 不變 | 原始 | ❌ 否 | 已有戶籍,拒絕重複 |
|
||||
| **檔案移動到同機另一目錄** | **不同** | 新路徑 | 原始 | ✅ 是 | 新位置視為新環境 |
|
||||
| **檔案複製到另一台伺服器** | 不同 | 記錄新路徑 | ✅ 是 | 新管轄區,獨立登記 |
|
||||
| **檔名變更** | 不同 | 記錄新路徑 | ✅ 是 | 視為不同身份 |
|
||||
| **檔案刪除後重新加入** | 相同 | 記錄新路徑 | ⚠️ 視情況 | 若 DB 紀錄仍存在,可恢復關聯 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 設計優勢
|
||||
|
||||
1. **身份錨點**:透過 Birthday 機制,即使路徑改變,系統仍能識別檔案的歷史血緣
|
||||
2. **路徑綁定**:UUID 包含 Canonical Path,確保每個位置的檔案都有獨立身份,避免混淆
|
||||
3. **管轄清晰**:MAC Address 確保每台伺服器的數據獨立
|
||||
4. **可追溯性**:`birth_registration` 記錄原始出處與 Birthday,便於審計
|
||||
5. **防止重複**:系統以 UUID 為準,同一位置同一檔案絕不會重複登記
|
||||
|
||||
---
|
||||
|
||||
## 8. 相關文件
|
||||
|
||||
| 文件 | 說明 |
|
||||
| :--- | :--- |
|
||||
| `src/core/storage/uuid.rs` | UUID 生成實作 |
|
||||
| `src/api/server.rs` | 註冊端點與流程 |
|
||||
| `src/core/ingestion.rs` | Watcher 自動 ingestion 邏輯 |
|
||||
| `docs_v1.0/UUID_LENGTH_ISSUE.md` | 舊版 UUID 長度問題分析 |
|
||||
| `docs_v1.0/UUID_CLEANUP_PLAN.md` | 歷史數據清理方案 |
|
||||
Reference in New Issue
Block a user