# FR-047 全站已知坑處理 — 現況交接（2026-07-07）

| 項目 | 內容 |
|------|------|
| 緣由 | FR-047 全站終驗完成後，把散在各頁 §12 的「已知坑」**全站彙整成一份清單（508 條，分類 + 可修徽章）**。本棒接手**處理這整份清單**——逐類 / 逐條跟 user 討論「修 / 不修 / 怎麼修」。**user 指定第一個處理的桶＝授權守門（SEC）**，其餘類別接續。 |
| branch | **`fix/v1.8.0-bugs`**（user 已建好的 bugfix branch，目前 = `main` 頂點）。**在這個 branch 上工作，不要切 branch**；branch 不對就停下問 user。 |
| 接手前必讀 | 本檔全文 → **坑清單 `docs/analysis/2026-07-07-spec-known-pits-inventory.md`（全檔，尤其檔頭「性質提醒」＋分類表）** → 專案根 `CLAUDE.md` 的「權限檢查」與「DDD 層級規範」段 |
| **這棒要幹嘛** | **處理整份 508 條坑清單**（不只 SEC）：跟 user 一起把每類 / 每條定調成「可修 bug / 刻意設計只告知 / 文件澄清」，可修的排優先級 + 規劃解法。**先讀現況、別自己先分類或開修——分類方式與解法由 user 跟你討論後才定。** |

## 🧭 原始需求（WHY，先懂再動）

FR-047 spec 手冊逐頁 code-read 期間，把每頁掃到的邊界情況 / 缺口 / 技術債記進各頁 §12「已知坑」（當時政策：**只記錄不修**）。全站累積後，散在 67 頁 + 8 個 `_overview`，難以總覽。終驗收尾時 user 要求**彙整成一份總表**，好做「總整理、分類分析、看怎麼解決」。

於是產出 `docs/analysis/2026-07-07-spec-known-pits-inventory.md`：**508 條坑**，每條標 `群/頁#N` id、頁功能、第一版 keyword 粗分類、可修性啟發式徽章。

**本棒的任務＝把這 508 條「處理掉」**——但「處理」不等於「全修」。§12 混了三種東西：
1. **可修的 bug / 缺口**（安全守門缺失、真 bug、死碼）→ 要修，排優先級；
2. **刻意設計、只是提醒**（full-replace 全量覆寫、best-effort 不阻塞、owner 只在 BE 保護、date-only 時區慣例）→ 多半 **no-action**（維持現狀，確認 spec 已講清楚）；
3. **文件 / schema 澄清** → 多數已在終驗修掉。

所以「怎麼解決」＝**先跟 user 把每條定調（①/②/③），把①挑出來排序 + 規劃**。這是**跨模組決策**，不是機械全補。

**本棒在大圖的位置**：坑清單處理的**第 0 步——理解現況、跟 user 定分類與範圍、從 SEC 開始**。

## 處理順序（user 拍板）

**先做「授權守門（SEC）」**（見下方 SEC 段），再依 user 意願接續其餘類別。**每一類都先跟 user 討論再動手**，不要自作主張把整份 508 條一次分完 / 開修。

分類表（清單檔內，primary 單標，sum=508）：

| 主類別 | 條數 | 啟發式「可修」 | 順序 |
|------|------|----------|------|
| 🔴 SEC 安全/授權守門 | 67 | 38 | **① 本棒先做** |
| SCHEMA 表名/欄位/命名 drift | 60 | 11 | 待 user 排 |
| UX FE/顯示/i18n/時區 | 47 | 4 | 待 user 排 |
| ECODE error code 型別/碼 | 39 | 7 | 待 user 排 |
| STATE 狀態機/前置條件 | 33 | 4 | 待 user 排 |
| REPLACE full-replace/cascade/trigger | 33 | 4 | 待 user 排 |
| DEAD 死碼/預留/vestigial | 25 | 13 | 待 user 排 |
| 其他（多為行為告知） | 204 | 26 | 待 user 排 |

> 註：分類是 **keyword 第一版粗分**，會犯錯（primary 單標犧牲細節、204 條沒被 keyword 抓到）。**真正定調待人工**。可修徽章（🔧/📗/❓）也是啟發式，逐條要人看。

## ① SEC 授權守門（第一個處理的桶）

**共同 root pattern**：大量「寫入 / 狀態轉換」API 端點只有 `@jwt_required()`，**沒有 BE 角色 / 能力守門**，全靠 FE 隱藏入口或 `canEdit` 擋——任何已登入者知道 path + uid、繞過 FE 就能執行本該限 manager / auditor / admin 的操作。違反 `CLAUDE.md`「寫入 API 必須有角色權限檢查（manager / auditor）」「權限檢查在 service 層透過 domain service」。

- 抓 SEC 段：`grep -nE "\`SEC\`" docs/analysis/2026-07-07-spec-known-pits-inventory.md`（每條下一行是內文）。
- 67 條裡**三種性質、不能盲補**：
  1. 真守門缺口（絕大多數）；
  2. **刻意不做角色檢查**（例 `evidence/cloud-integrations#4` `trigger_init_project_folders` docstring 明載「避免 is_admin 誤擋專案 manager」）；
  3. RLS / 跨租戶可見性類（`user-log#4` api_logs 無 tenant_id、不受 RLS）。
- **最嚴重**：`system-admin/user-log#1`——`GET /log/api-logs/export` 的 `@jwt_required()` 被註解掉（SEC-001），**未登入者**知道 URL 即可下載全部 api_logs，已有 regression test。這條幾乎確定要優先修。
- 很多端點在 **jedi-auth 套件內**（user/role/tenant）——動套件前依 CLAUDE.md「外部套件異動規範」先提醒 user 決策。

## ⚠️ 分類 / 解法先別自己定（user 明確指示）

user 說：**「先不用分析，你只要跟他說現況就好，我會跟他討論狀況。」** 所以整份清單（含 SEC）：
- **不要**自己把坑分桶定調、排優先級、寫解法計畫。
- **要**：讀懂現況（本檔 + 坑清單 + CLAUDE.md 權限/DDD 規範），然後**跟 user 討論怎麼切**（先攻哪類？一次全補還是逐群？統一 decorator 還是逐 service？哪些判 no-action？）。

## 冷接自檢（動手前先答，答不出回去讀）

1. 本棒要處理的範圍是什麼？→（**整份 508 條坑清單**，不只 SEC；SEC 是 user 指定的第一個桶）
2. 「處理」是不是「全修」？→（不是。逐條定調 ①可修 / ②刻意設計只告知 / ③文件澄清；只有①要修）
3. 你被授權做到哪？→（讀現況 + 跟 user 討論分類與範圍；**不是**直接開修任何一條）
4. SEC 的共同 root pattern？角色檢查放哪層、什麼 error code？→（寫入端點僅 `@jwt_required`；service 層透過 domain service；`GRC_403xxx`）
5. 你在哪個 branch？→（`fix/v1.8.0-bugs`，不切）

## Pre-flight（開工前必跑）

```bash
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
git branch --show-current          # 應為 fix/v1.8.0-bugs；不對停下問 user
git status --short                 # 應乾淨（untracked docs/specs/v1.8.0/html.zip = user 的，別動別 commit）
git log --oneline -3               # 頂點應為本交接 commit
# BE 出錯先看 log：tail -200 log/app.log | grep -A30 -i 'Traceback\|ERROR'
```

## 行為規範重要提醒（本棒適用）

- **不切 branch**（已在 `fix/v1.8.0-bugs`）；**push 永遠等 user 明示**；commit 顯式 `git add` 檔名、禁 `-am`。
- **權限檢查放 service 層**（透過 domain service 查 participant / role），route 層不碰 DB；error code 走 `GRC_403xxx`（如 `GRC_403002` / `GRC_NOT_MANAGER`；平台層 `GRC_NOT_PLATFORM_ADMIN` / 403060）。
- **改 jedi-auth 等套件前先提醒 user 決策**；dev 走 poetry path dependency、path 改動不 commit。
- **改 BE service code 必提醒 user 重啟**（無 hot reload）；BE 行為異常先自己看 `log/app.log`。
- **不甩 caveat**：坑內文標的「刻意不檢查 / RLS 類 / 只記錄不修 / 設計如此」要當真，別一律當缺口。
- **spec = code 真相**：修掉某條坑後，對應頁面 §12 該條的敘述要更新（走 `writing-feature-specs` skill，收尾時做、等 user 令）。

## Notion 去重（做成 case 前必查）

量產期已在 Notion「[GuidantAI] Issue 任務清單」開過幾條 SEC / bug case（`notion-search` 搜「守門 / 僅 JWT / 無角色 / 密碼政策 / TOTP / GITLAB / MAIL_SEND_FAILED」）。**要 spin 成 case 前先搜、有相符就 update 別重開**。座標見 `docs/claude/notion-issue-tracker.md`；作業人員 Claude 做的填「小弟」。

## 本次遺留（loose ends，非本棒核心但要知道）

- **未 push**：`e7fc9230`（坑清單）+ 本交接 commit 還在本地（origin/main 停在 `f707bf1d`）。要 push 到 main、還是留在 `fix/v1.8.0-bugs` 隨處理工作一起走，等 user 定。
- **POC rsync 未完成**：spec 手冊 html 站待部署到 `jedi@192.168.50.189:/var/www/html/docs/specs/v1.8.0/`，但該目錄 `root:root`、`jedi` 需 sudo 密碼——待 user 一次性 `sudo chown -R jedi:jedi` 後才能 rsync。
- **is_template drift**：背景 task `task_c5e7ff0b`（BE code cleanup，樣板 SSP 靠 `template_ssp_id` 非 `is_template` 欄），與本棒無關。

## §給 fresh session 的超短 prompt（user 複製貼）

```
請接手 FR-047 全站已知坑處理。先讀 docs/features/FR-047-2607-feature-spec-handbook/handoff/2026-07-07-known-pits-remediation-handoff.md
全文 + 坑清單 docs/analysis/2026-07-07-spec-known-pits-inventory.md（尤其檔頭性質提醒 + 分類表）+ CLAUDE.md 權限/DDD 規範，
答完冷接自檢 5 題。branch 是 fix/v1.8.0-bugs、不要切。第一個處理的桶是「授權守門(SEC)」。
【重要】先讀現況、別自己分類或開修——分類方式與解法我會跟你討論後才定。讀完跟我對話。
```
