# Bug Report: /api/v1/file/:uuid/chunks 500 Error

**發現者**：M4  
**日期**：2026-05-06  

---

## 現象

`GET /api/v1/file/:uuid/chunks` 回傳 **500 Internal Server Error**，response body 為空。

## Root Cause

Handler `list_pre_chunks()` 內使用 `chrono::DateTime<chrono::Utc>` 對應 PG `created_at` 欄位（型別：`timestamp without time zone`），導致 sqlx `query_as` tuple 反序列化失敗。

```rust
// ❌ DateTime<Utc> 不能對應 timestamp without time zone
chrono::DateTime<chrono::Utc>,
```

## 影響

所有對 `pre_chunks` 有資料的 UUID 都會觸發這個 500 error。空的 UUID（count=0）不受影響。

## M4 暫修驗證

M4 已將 `query_as` tuple 改為 `sqlx::query` + `Row::try_get` 手動 mapping，驗證通過：

```
✅ PASS: count=360, items=20
```

## 建議解法

1. 使用 `sqlx::query` 搭配 `Row::try_get`（M4 已驗證）
2. 或將 `created_at` cast 為 text：`created_at::text`，以 String 取出
3. 或確認 schema 可改為 `timestamptz`，則可沿用 `DateTime<Utc>`

---

## 附：完整 diff

```diff
-    use sqlx::query_as;
+    use sqlx::Row;

-    let rows: Vec<(i64, String, String, i64, ... chrono::DateTime<chrono::Utc>)> 
-        = sqlx::query_as(&data_query)
-        .bind(&uuid)
-        .fetch_all(state.db.pool())
-        .await
-        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

-    let pre_chunks = rows.iter().map(|row| PreChunkItem { ... created_at: row.10.to_rfc3339() }).collect();

+    let rows = sqlx::query(&data_query)
+        .bind(&uuid)
+        .fetch_all(state.db.pool())
+        .await
+        .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

+    let pre_chunks = rows.iter().map(|row| {
+        PreChunkItem {
+            ...
+            created_at: row.try_get::<String, _>("created_at").unwrap_or_default(),
+        }
+    }).collect();
```
