# FR-071 客戶端診斷包（Support Bundle）——遠端可重現分析（需求草稿）

- **日期**：2026-09-02（user 拍板開案）
- **狀態**：Phase 0 白話需求（brainstorm/design 未做）
- **緣起**：落地版裝在客戶端後，系統一出錯原廠人員就得到場——log 在客戶主機、payload 與資料在客戶 DB，遠端拿不到案發現場。

## 白話需求

提供「匯出診斷包」功能：系統出錯時，客戶（或到場人員）一鍵匯出一包 `guidant-diag-<時間戳>.tar.gz`，原廠拿到包就能遠端分析出 root cause——**驗收標準是把包丟給一個乾淨的 AI session（只有包＋源碼 repo，無 DB 無現場）要能指出錯在哪與修法**（user 明確要求：「我把這些東西丟給你，你也要能分析出來」）。

## 包的內容（四層）

1. **環境快照**：版本＋**commit hash**（分析端 checkout 同版對行號的錨）、guidant.env（憑證遮罩）、docker ps/stats、磁碟、license 狀態、migration 水位、套件版本清單。
2. **Log 切片**：app.log 指定時間窗（完整 traceback＋前後脈絡，保留原始格式）＋各容器 docker logs tail。
3. **DB 診斷切片**（不是整庫 dump——客戶資料有合約/個資邊界）：system_logs／api_logs 時間窗切片（含 path/func_name/line_no 與 request/params/response）、各表 row count、**出錯實體與關聯實體的資料切片**（從 payload 解析 id 順藤撈：專案→輪次→任務→指派等），每表一個 JSON/CSV＋schema 註記（AI 可直接讀，不是散文）。
4. **錯誤事件錨點**：BE 全域 error handler 在 5xx 時落一筆錯誤事件——完整 traceback＋request payload＋user context＋關聯實體 id＋**當下關鍵實體序列化快照**（「錯誤瞬間」的資料，與匯出時的現值切片對照——不一致本身就是線索）。

## 三條關鍵設計（AI 可分析的必要條件）

- **request_id 貫穿全鏈**：traceback↔api_log↔錯誤事件↔實體快照綁同一 id，分析端不必靠時間戳猜對應。
- **commit hash 為錨**：包內 file:line 配同版源碼才有意義。
- **manifest.json 開路**：目錄結構／每檔說明／時間窗／錯誤事件清單，分析端（AI 或人）照 manifest 讀起。

## 兩個入口

- **UI**（系統設定→支援→匯出診斷包，admin 限定＋走 platform_admin 守門）：客戶自己點、選時間窗、下載——不用會下指令，這是減少到場的關鍵。
- **CLI**（`guidant diag`，掛進既有維運 CLI）：到場/ssh 的自己人用，可 `--full` 撈更深。

## 隱私/安全

- 遮罩管線：密碼/token/金鑰不進包（guidant.env 遮罩、api_logs request 內密碼欄位過濾）；包附 manifest 讓客戶可審「帶走了什麼」。
- DB 只切片不整 dump。
- 選配（brainstorm 談）：包用原廠公鑰加密（客戶看不到內容、原廠才解得開）。
- **不做 phone-home 自動回傳**——落地版多為隔離內網，動線是「客戶下載→傳給原廠」。

## 分期

- **一期**：CLI＋UI 匯出＋四層打包＋遮罩＋manifest＋request_id 貫穿。已知連帶債：api_logs 錯誤請求 level 全是 INFO（DEV 實查 108,608 筆零 ERROR）要修，否則錯誤列撈不出來。
- **二期**：5xx 錯誤事件錨點（traceback+payload+實體快照同筆落庫）＋「從錯誤記錄一鍵匯出該時間窗診斷包」＋關聯展開深度調優。
- **驗收條款（寫死）**：DEV 故意弄壞一個功能→UI 匯出→丟乾淨 AI session（只有包＋repo）→能指出 root cause 與修法，過了才算完成。

## 未定事項（brainstorm 要談）

- 實體切片的關聯展開深度與白名單（哪些表可進包、展開幾層）
- 遮罩清單的完整盤點（哪些欄位算機密）
- 包加密選配要不要做、金鑰管理
- 錯誤事件表的保留政策（量與清理）
- 現有資產的復用邊界：FR-068 log 轉發鏈、GuardedSystemConfig 遮罩、guidant CLI 架構

## 既有資產（實查 2026-09-02）

- `api_logs`：url/method/params/request/response/duration/user 已在收（payload 已落庫）
- `system_logs`：path/func_name/line_no 已在收（錯在哪一隻已有）
- `guidant` CLI：status/logs/credentials/agent-check 既有，diag 子命令掛進去
- 加密先例：DETECTION_TOOL/DRIVE_TOKEN encryption 兩把金鑰機制
