FR-047 全站已知坑處理 — 交接(最後一桶 UX,2026-07-08)

✅ FIXED — 2026-07-09 UX 桶收口,整個 508 arc 完結。 U-1~U-6 全修 + 收尾前逐族複核 no-action 衍生三批(OTP 節流 / 六項設計調整 / 專案狀態機 B 案)+ jedi-auth 0.1.26 / jedi-mfa 0.0.12 發版。完整收尾見 2026-07-09-UX-bucket-and-arc-completion-SUMMARY.md。逐條真相見 tracker。本交接檔任務已完成,勿再當 pending 接手。

項目 內容
緣由 508 條「已知坑」逐桶處理 arc。七桶已收,只剩 ③ UX(47 條)未動。本棒交接 UX 桶給下一棒。
branch fix/v1.8.0-bugs(不要切;不對就停下問 user)
唯一進度真相 🔴 docs/analysis/2026-07-07-known-pits-remediation-tracker.md —— 只有這一份追蹤表。一切定調/銷帳/桶狀態看它、寫它。絕對不要另建第二份清單/checklist(前棒教訓,勿重蹈)。
母清單 docs/analysis/2026-07-07-spec-known-pits-inventory.md(508 條原文,只讀不改分類
前一份交接 docs/features/FR-047-2607-feature-spec-handbook/handoff/2026-07-08-known-pits-remaining-buckets-handoff.md(UX/STATE/REPLACE 三桶原始交接,STATE/REPLACE 已完成)
預估 UX 47 條,但照塌縮率實際動手估 一二十個決策點(~85% 是告知類 no-action)

🧭 這個 arc 在解決什麼(WHY,先讀再動手)

FR-047 spec 手冊全站 67 頁的 §12「邊界情況與已知坑」被彙整成 508 條清單關鍵認知:這 508 條不是 508 個待辦——§12 是寫給工程師的「邊界情況告知」,混了三種東西:

  1. 可修 bug / 缺口(安全守門、真 bug、死碼)
  2. 刻意設計、只是提醒(full-replace、best-effort、date-only 時區慣例)—— 知道就好,不是要改
  3. 文件/schema 澄清

arc 的目標=逐桶把「①可修」挑出來修,②③ 一律 no-action(維持現狀)。 已收七桶實證:真正動手的遠少於總數(STATE 33 條真修 10、REPLACE 34 條真修 4 群、其他 204 條 ~25、ECODE 39 條真缺陷 7)。UX 桶同理——大部分會是 no-action,別把每條當 bug 修。


§0 接手讀序(按順序,讀完才動手)

  1. 🔒 本文件全讀(懂 WHY + 現況 + SOP)
  2. 🔒 docs/analysis/2026-07-07-known-pits-remediation-tracker.md 全讀(唯一進度真相;特別看已收的 §STATE / §REPLACE 桶的定調模式——UX 照同一套寫)
  3. CLAUDE.md 權限/DDD/DB transaction/error code/jedi 套件異動規範 + 跨 FE repo 必讀 FE 的 CLAUDE.md(UX 桶大宗在 FE)
  4. 母清單 2026-07-07-spec-known-pits-inventory.md(抽 UX 桶時查原文,只讀)

冷接自檢(答不出回去讀,別碰 code)

  1. 508 條的核心認知是什麼?→(§12 是邊界告知非待辦,~85% no-action,只挑①可修)
  2. 進度真相在哪一份文件?可以另開清單嗎?→(唯一 tracker,絕不另開第二份
  3. 接一個桶的 SOP 五步是什麼?→(見 §3)
  4. 動手前對每條坑要先做什麼?→(live 驗證真實碼/DB/FE,spec 文字常過時誤報)
  5. 你在哪個 branch?發版/merge/push 能自己做嗎?→(fix/v1.8.0-bugs,發版/push/merge 全等 user 明示)

§1 現況:508 條桶層總帳

狀態
① SEC (75) ✅ 收口(→ FR-048)
② SCHEMA (60) ✅ 收口(DDL 5 項 DEV+STG 已套;告知類 no-action)
④ ECODE (39) ✅ 收口(真缺陷 7 條已修+發版)
⑤ STATE (33) 收口(2026-07-08 手測通過)——SSP phase guard 重建 + 問卷狀態機 + bulletin 時間窗;不要重做
⑥ REPLACE (34) 收口(2026-07-08 手測通過)——刪除級聯守門 + 快速配置不洗關聯 + 批次匯入單一交易 + 刪資料夾擋非空;不要重做
⑦ DEAD (30) ✅ 收口
⑧ 其他 (204) ✅ 三次複核
③ UX (47) 待抽桶(本棒任務)

已收的七桶不要重做。 若懷疑某條狀態,查 tracker 那一列(不是重新調查)。


§2 前棒教訓(別重蹈)

  • 絕不建第二份追蹤表:只用 docs/analysis/ 那份,定調一律寫它。
  • 動手/升級前一律 live 驗證:spec 文字常過時。本 arc 抓到多條誤報(system_owner comment 早修好、info-system#4 route 早回 404、update_task_survey 其實進不了 status)。先 grep 真碼 / 查 DB / 讀 FE 再定調。
  • 改套件 ≠ 授權發版:發版(bump + 推 Nexus)不可逆,一律等 user 明示。
  • 不甩 caveat:坑內文標「刻意不檢查 / 設計如此 / RLS 類」要當真——盲改會打爆(FR-048 有 2 次盲加 auth 打爆下載的前科)。
  • UX 桶特有:很多是「顯示層沒標明歸屬 / 沒 gate」的體驗題,不是安全題——別把 UX 摩擦誤判成資安 bug。REPLACE 桶手測時 user 一度以為「看到別租戶資料」是外洩,實查是多租戶階層設計(父租戶看得到子租戶),非漏洞。UX 桶類似觀感題要先 live 分清「設計 vs 缺陷」。

§3 接一個桶的 SOP(五步,每桶照做)

  1. 抽桶:跑下方腳本把 UX 條目 + 內文全撈出來。
  2. 逐條讀內文分性質:真缺陷 / 設計告知 no-action / 同 root pattern 重複 / 屬別桶。每條可行動的先 live 驗證(grep 真碼、查 DB、讀 FE view)。
  3. 同 root pattern 合併談:例如「date-only 時區 08:00 ×多頁」(同 root)、「status 欄有值無 UI ×N 頁」——合併後塌縮成幾個決策點。
  4. 寫進 tracker(唯一那份):開 §UX 段,逐族定調(比照已收的 §STATE / §REPLACE 寫法)。
  5. 跟 user 討論定調 → 才動手絕不自己開修——本 arc 全程「先定調、user 拍板、才派工」(用 Opus subagent 派工,指定 model: opus,別讓執行者吃主 session 的 model)。

抽桶腳本

cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
python3 - <<'PY'
import re
lines=open("docs/analysis/2026-07-07-spec-known-pits-inventory.md",encoding="utf-8").read().split("\n")
n=0
for i,l in enumerate(lines):
    m=re.match(r'- \*\*\[([^\]]+)\]\*\*\s+(\S+)\s+(.*)$', l)
    if m and m.group(3).strip().startswith("`UX`"):
        n+=1
        body=[]
        for j in range(i+1,len(lines)):
            if re.match(r'- \*\*\[', lines[j]) or lines[j].startswith('#'): break
            if lines[j].strip(): body.append(lines[j].strip())
        print(f'=== {n:2d}. [{m.group(1)}] {m.group(2)}')
        for b in body: print(f'    {b}')
print(f"\nTOTAL = {n}")
PY

UX 桶預收方向(抽桶後才有細節;這裡只給定位):

  • date-only 時區 ×多頁(同 root):date-only 字串顯示成 08:00(吐本地 datetime 無 tz)。合併一次談。SCHEMA ⑤ 段已標「date-only 時區 ×3 → UX」。
  • i18n 漏譯:做全 namespace 稽核(memory feedback_i18n_audit_against_index_loaded_files)。
  • toast / 分頁 / 即時刷新:互動體驗類。
  • 歸入項user-profile#1(TOTP 未驗證就啟用會自鎖,嚴重度較高、優先)、device#5 / department#5(status 欄有值無 UI)、information-system-manage#2(軟刪除確認框文案沒說明「停用 vs 刪除」,REPLACE 桶已標「→UX 桶尾備查」)。
  • 跨 FE repo~/Projects/Billows/Audit-Manager/compliance-manager-fe/(改前讀其 CLAUDE.md;改完提醒 user 重 build)。

§4 開工順位

  1. 跑 §6 pre-flight(確認 branch / working tree / BE listener)。
  2. 跑 §3 抽桶腳本,把 47 條撈出來。
  3. 逐條 live 驗分性質(真缺陷的先 grep 真碼 / 讀 FE view / 查 DB)。
  4. 同 root 合併 → 寫 tracker §UX 段 → 給 user 定調表。
  5. user 拍板後才派 Opus subagent 修(BE / FE 分 repo,各自 commit、顯式 git add、禁 -am)。
  6. 修完給 user 一句話 status + 手測 checklist,,等 user 下令收尾。

§5 該讀的檔案 / 預期改動範圍

  • FE(UX 桶大宗)~/Projects/Billows/Audit-Manager/compliance-manager-fe/ — date 顯示元件、i18n src/config/locales/i18n/{zh-tw,en}/*.json、各管理頁 view。先讀 FE CLAUDE.md + docs/claude/frontend-overview.md(BE 視角速查)。
  • BE:少數(date-only 回傳格式若在 BE 決定、status 欄 enrich)。
  • jedi 套件:若某坑在套件層(如 device/information-system 的 status 欄),走 path dependency 開發、發版等 user 明示。

§6 Pre-flight(開工前必跑)

cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
git branch --show-current          # 應為 fix/v1.8.0-bugs,不是就停下問 user
git status --short | grep -v '^??'  # working tree 應乾淨(?? untracked 的 docx/zip 是 user 的別動)
git rev-list --count @{u}..HEAD     # 領先 upstream 數
lsof -i :8000 | grep LISTEN         # BE 是否在跑(BE 由 user 起)

§7 Verify 前面七桶確實 close(不要走回頭路)

STATE / REPLACE 的 fix 都已 landed + user 手測通過 + jedi 套件已發版(Nexus pin 0.1.25/0.0.25)。不要回頭追已修的坑。若懷疑某條狀態,查 tracker §STATE / §REPLACE 段(不是重新調查)。已修清單見 tracker 各桶「修復銷帳」段。


§8 行為規範重要提醒(本 arc 適用)

  • 不切 branch(已在 fix/v1.8.0-bugs);push / 發版 / merge to main / 主專案進版 全等 user 明示,不自動做。commit 顯式 git add 檔名、禁 -am
  • 絕不建第二份追蹤表。定調一律寫 docs/analysis/ 那份。
  • 每條可行動坑先 live 驗證再定調(spec 常過時誤報)。
  • 跨 FE repo 先讀 FE CLAUDE.md;改 FE 提醒 user 重 build;不晶晶體。
  • 改 BE service code 提醒 user 重啟(無 hot reload);BE 異常先自己看 log/app.log
  • 不甩坑內 caveat(刻意不檢查/設計如此/RLS 類要當真)。
  • 派工用 Opus subagentmodel: opus),先定調 user 拍板才派;subagent prompt 必寫「顯式 git add 禁 -am / 不切 branch / 不發版」。
  • 收尾(spec/SUMMARY/Notion/memory)等 user 明確下令,plan approve ≠ 自動收尾。

§9 收尾流程(UX 桶定調完 / fix 完)

  • 桶定調完 → 寫 tracker §UX 段(不另開檔)→ 跟 user 討論。
  • fix 完 → 給 user 一句話 status + 手測 checklist,,等 user 下令才做 SUMMARY / Notion / spec / memory。
  • UX 桶收完 = 整個 508 條 arc 完結 → 屆時走 closing-and-handoff skill 的完整收尾(arc 級 SUMMARY + memory 教訓 + Notion)。

§10 不在本期 scope(別順手做,會 scope creep)

  • 不做主專案進版 / merge to main——等 user 決定。
  • 不重推發版 / 不 push——jedi 0.1.25/0.0.25 已發版;三 repo commit 未 push(user 自己 push)。
  • 不套 POC migration——user 明確按住。
  • 不重做已收七桶
  • 不碰 RLS 權限模型 case——已獨立歸檔 Notion(見 §零星 loose ends),狀態「討論」等 user 排,非 UX 桶主線。

§零星 loose ends(桶外 / 未定調,user 排,非 UX 主線)

  • RLS 權限模型三缺口(Notion case 397346da-4cd0-81e8-a60d-fde2f4468e57,狀態「討論」):① org_units INSERT 政策 scope 到部門成員(非租戶)、無 super_admin 後門 → 租戶 admin 能刪部門卻不能在它底下加子部門;② RLS super_admin 只認租戶 path 單層、不認 users.is_super_admin 欄;③ users.is_super_admin(欄位)vs role.is_admin(角色屬性)兩旗標語意矛盾。現場繞法:建部門時上層選自己掛載的部門(如 System Administration Department 98)即可 nest。
  • GRC_403060 BE 訊息寫死「合規框架」common/code/grc_error_code.py:137 但該碼被框架/租戶/通知多處共用,用在刪租戶時文字對不上。FE 已用通用 i18n 蓋過(e7dd8cc),BE 訊息建議之後改通用。
  • otp-resend type/mfa_type 未修api/auth/routes/otp_route.py:148kwargs.get("mfa_type") 但 serializer 宣告 type → TOTP 使用者靜默走 email。Notion case 61db 維持 Not started。
  • PUT /task-survey route bug(STATE 桶手測前撈到):task_survey_route.py:55 位置參數傳法已修(BE 5cc31915),已 landed。
  • AUTH_401009 文件漂移:ECODE#4 改碼後舊碼殘在 8 檔 → 應 AUTH_401009AUTH_400003。純文件 spec-sync。
  • DEAD B 族 topt_secret drop:DEV 查乾淨,待 STG/POC 確認 + user 拍板(跟 POC 一起等)。
  • locale 對稱輕量驗證:可翻譯欄位 update 路徑是否都有傳 locale(SCHEMA ⑤ 列的待辦,非 bump)。
  • FR-048 e2e ×2(test repo):QR 顯示 / 框架下載前科件 + 負向案。

§11 本 arc 近期 commits(對照用;三 repo 皆未 push,等 user)

主 repo compliance-manager-befix/v1.8.0-bugs,領先 origin):

  • be628759 docs:標記發版完成
  • 59bb5eb8 chore(deps):pin jedi-auth 0.1.25 / jedi-survey 0.0.25 + survey DI wiring
  • 9c8fd6f0 docs(REPLACE):REPLACE 桶收口銷帳
  • 4e1c4e81 fix(REPLACE):批次匯入單一交易 + 設備引用計數端點
  • 7b45bd2a docs(STATE):STATE 桶收口
  • 5cc31915 fix(STATE):問卷狀態機守門 + bulletin 時間窗 + PUT task-survey route bug
  • 158d7c8b fix(STATE):SSP 寫入 phase guard 重建
  • (更早還有 FR-048 全批等,整條 branch 未 merge origin/main)

jedi monorepo(領先 origin 4):

  • b0422fb chore(release):bump jedi-auth 0.1.25 / jedi-survey 0.0.25
  • 5414ce7 fix(jedi-auth):add_user send_email 參數
  • 6f6244d fix(jedi-survey):刪資料夾擋非空
  • 1ad088a fix(jedi-auth):org_units/tenants 刪除守門
  • poetry publish 到 Nexus(0.1.25 / 0.0.25),BE 已 pin 新版並驗證

FE compliance-manager-fe(領先 origin 4):

  • 675c71f fix(survey-v2):刪資料夾去重複 toast
  • e7dd8cc fix(i18n):GRC_403060
  • c8279cc fix(i18n):REPLACE 刪除守門 6 碼 + AUTH_409009
  • ea93921 fix(device):快速配置 + 刪設備警示

§12 給下個 session 的超短 prompt

接手 FR-047 已知坑 arc 最後一桶(③ UX,47 條)。先讀交接文件全文:
docs/features/FR-047-2607-feature-spec-handbook/handoff/2026-07-08-UX-bucket-handoff.md
再讀唯一追蹤表 docs/analysis/2026-07-07-known-pits-remediation-tracker.md(進度真相,絕不另開第二份清單)。
答完交接檔 §0 冷接自檢 5 題再動手。branch fix/v1.8.0-bugs 不切、push/發版/merge 等我明示。
照 §3 SOP「抽桶→逐條 live 驗分性質(UX 桶大宗在 FE,先讀 FE CLAUDE.md)→同 root 合併→寫追蹤表→跟我定調」,別自己開修。
已收七桶(含 STATE/REPLACE 手測通過)不要重做;桶外 loose ends(RLS 權限 Notion case 等)非本桶主線。