# Video Registration

| 項目 | 內容 |
|------|------|
| 建立者 | Warren |
| 建立時間 | 2026-03-25 |
| 文件版本 | V1.1 |

---

## 版本歷史

| 版本 | 日期 | 目的 | 操作人 | 工具/模型 |
|------|------|------|--------|-----------|
| V1.0 | 2026-03-25 | 創建文件 | Warren | OpenCode |
| V1.1 | 2026-03-26 | 修正 curl 範例，新增 API Key 驗證標頭 | OpenCode | deepseek-reasoner |

---

## 概述

影片註冊 API (`POST /api/v1/register`) 用於將影片加入 Momentry Core 系統進行處理。

## 路徑格式

### 支援的路徑格式

| 格式 | 範例 | 說明 |
|------|------|------|
| 相對路徑 | `./demo/video.mp4` | 推薦格式 |
| 相對路徑（無 ./） | `demo/video.mp4` | 自動加上 `./` |
| 絕對路徑 | `/Users/.../sftpgo/data/demo/video.mp4` | 支援但不推薦 |

### 路徑結構

```
./username/filepath
│    │       │
│    │       └── 檔案路徑（可以是多層目錄）
│    └── 使用者名稱（SFTPgo 用戶目錄名稱）
└── 相對路徑前綴
```

**範例**：
- `./demo/video.mp4` → username=`demo`, filepath=`video.mp4`
- `./demo/movies/2024/video.mp4` → username=`demo`, filepath=`movies/2024/video.mp4`
- `./warren/project1/interview.mp4` → username=`warren`, filepath=`project1/interview.mp4`

## UUID 計算

### 計算規則

```
UUID = SHA256(username/filepath)[0:16]
```

**範例**：
```rust
// 路徑: ./demo/video.mp4
// username: "demo"
// filepath: "video.mp4"
// key: "demo/video.mp4"
// UUID: SHA256("demo/video.mp4")[0:16]
```

### 特性

| 特性 | 說明 |
|------|------|
| 用戶隔離 | 不同用戶的相同檔名會產生不同 UUID |
| 一致性 | 相同相對路徑一定產生相同 UUID |
| 遷移安全 | SFTPgo 資料路徑變更後 UUID 保持一致 |

### 範例

```rust
// 用戶 demo 的影片
compute_uuid_from_relative_path("./demo/video.mp4")
// → "9760d0820f0cf9a7"

// 用戶 warren 的相同檔名影片
compute_uuid_from_relative_path("./warren/video.mp4")
// → "a1b2c3d4e5f6g7h8" (不同的 UUID)
```

## 重複註冊檢查

### 行為

1. 系統檢查 UUID 是否已存在於資料庫
2. 如果存在，返回 `already_exists: true` 和現有影片資訊
3. 如果不存在，創建新的影片記錄

### API 回應

**新註冊**：
```json
{
  "uuid": "9760d0820f0cf9a7",
  "video_id": 18,
  "job_id": 2,
  "file_name": "video.mp4",
  "duration": 159.637188,
  "width": 640,
  "height": 360,
  "already_exists": false
}
```

**重複註冊**：
```json
{
  "uuid": "9760d0820f0cf9a7",
  "video_id": 18,
  "job_id": 2,
  "file_name": "video.mp4",
  "duration": 159.637188,
  "width": 640,
  "height": 360,
  "already_exists": true
}
```

## SFTPgo 整合

### 目錄結構

SFTPgo 的用戶目錄結構：

```
/Users/accusys/momentry/var/sftpgo/data/
├── demo/                    ← 用戶目錄
│   ├── video.mp4
│   └── movies/
│       └── movie1.mp4
├── warren/                  ← 用戶目錄
│   └── project1/
│       └── interview.mp4
└── momentry/                ← 用戶目錄
    └── presentation.mp4
```

### 註冊流程

1. SFTPgo 用戶上傳檔案到各自的目錄
2. n8n 或其他服務調用註冊 API
3. 使用相對路徑格式：`./username/filepath`
4. 系統計算 UUID 並檢查重複
5. 創建處理任務

## 程式碼範例

### 註冊影片

```bash
# 使用相對路徑註冊
curl -X POST http://localhost:3002/api/v1/register \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"path": "./demo/video.mp4"}'

# 或使用多層目錄
curl -X POST http://localhost:3002/api/v1/register \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"path": "./demo/movies/2024/video.mp4"}'
```

### UUID 計算函數

```rust
// 使用相對路徑計算 UUID
pub fn compute_uuid_from_relative_path(relative_path: &str) -> String {
    let (username, filepath) = extract_user_from_relative_path(relative_path);
    compute_uuid(&username, &filepath)
}

// 從相對路徑提取用戶名和檔案路徑
pub fn extract_user_from_relative_path(relative_path: &str) -> (String, String) {
    let path = relative_path.strip_prefix("./").unwrap_or(relative_path);
    let path_buf = PathBuf::from(path);
    
    let mut components = path_buf.components();
    let username = components
        .next()
        .map(|c| c.as_os_str().to_string_lossy().to_string())
        .unwrap_or_default();
    
    let filepath: String = components
        .map(|c| c.as_os_str().to_string_lossy().to_string())
        .collect::<Vec<_>>()
        .join("/");
    
    (username, filepath)
}
```

## 相關 API

### Probe API（僅探測，不註冊）

如果只需要取得影片資訊而不註冊，可以使用 Probe API：

```bash
curl -X POST http://localhost:3002/api/v1/probe \
  -H "Content-Type: application/json" \
  -H "X-API-Key: YOUR_API_KEY" \
  -d '{"path": "./demo/video.mp4"}'
```

**回應範例**：
```json
{
  "uuid": "a1b10138a6bbb0cd",
  "file_name": "video.mp4",
  "duration": 120.5,
  "width": 1920,
  "height": 1080,
  "fps": 30.0,
  "cached": false,
  "format": {...},
  "streams": [...]
}
```

**與 Register API 的差異**：

| 功能 | Probe API | Register API |
|------|-----------|---------------|
| 計算 UUID | ✓ | ✓ |
| 執行 ffprobe | ✓ | ✓ |
| 儲存 probe.json | ✓ | ✓ |
| 寫入 videos 表 | ✗ | ✓ |
| 建立 monitor_job | ✗ | ✓ |
| 返回 job_id | ✗ | ✓ |
| 適用場景 | 預覽影片資訊 | 註冊並處理影片 |

## 相關檔案

| 檔案 | 說明 |
|------|------|
| `src/core/storage/uuid.rs` | UUID 計算邏輯 |
| `src/api/server.rs` | 註冊與 Probe API 實現 |
| `src/core/probe/ffprobe.rs` | ffprobe 整合 |
| `docs/SFTPGO_DEMO_USER.md` | SFTPgo 用戶設置 |
| `docs/API_ENDPOINTS.md` | API 端點總覽 |


