Bug P / Q / R — Parties preview / form 3 個 bug Handoff

項目 內容
緣由 Bug O 收尾 E2E 測試時 user 發現 3 個跟 Bug O scope 無關的 bug — 都集中在 docx import preview UI 的負責單位 / 參與人員 sections
Branch feature/ssp-oscal-alignment(接續 H-N + Bug O arc,這是 H-N arc 第 11~13 個 follow-up)
接手前必讀 本文件自包含 — 按 §0 順序讀本檔 + Bug O FIXED-SUMMARY 確認 Bug O 已收尾即可
預估時間 3-6 小時(3 個 bug,跨 BE + FE,需 trace + reproduce)

0. 接手讀序

  1. 本文件 — 3 個 bug 完整 context
  2. docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-bug-o-FIXED-SUMMARY.md — 確認 Bug O 已收尾(特別是 §5.1 知道你接手的是這 3 個 bug)
  3. FE PartiesSection / PartyLinkDialog 既有實作
    • ~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/components/grc/ssp-docx-import-v2/sections/PartiesSection.vue
    • ~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/components/grc/ssp-docx-import-v2/sections/PartyLinkDialog.vue
  4. 跟 template-edit 的對比(看 template-edit 怎麼處理同樣的 party form):
    • ~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/components/grc/ssp/SspPartiesTab.vue(如有)
    • template-edit 內 負責單位 / 參與人員 兩 tab 的對應元件
  5. BE confirm 後 parties 寫入路徑
    • app/oscal/service/ssp_docx_import_app_service.py _filter_parties_for_write (~line 996) + 後續 strategy.write_parties
    • 確認寫完 DB 真的有更新 → 確認 FE template-edit page 是 cache 沒 invalidate
  6. FE 跨 repo 必讀~/Projects/Billows/Audit-Manager/compliance-manager-fe/CLAUDE.md

讀完後跑 §6 Pre-flight + §7 Verify Bug O close → §3 開工順位。


1. 症狀

1.1 Bug P:負責單位 (Organization Party) 預覽畫面點「連結帳號」跳 Error,且應該連到「組織單位」非「帳號」

User-facing

  • 對既有 mf 跑 docx import → 到 Step 3 預覽 → 「參與人員與單位」tab → 「負責單位」(organization) row → 點該 row 的「連結帳號」按鈕
  • 預期:應該開「連結組織單位 dialog」(organization 是組織,應連到 org_unit_id
  • 實際:開了「連結帳號 dialog」(user link dialog),且 dialog 跳 Error

推測 root cause

  • FE PartiesSection 對 organization vs person party_type 沒分流 — 都用同個「連結帳號」button
  • 或 button label 寫死「連結帳號」沒 i18n 條件
  • Error 可能是 user link dialog API call 帶錯 entity context

1.2 Bug Q:參與人員 (Person Party) 少了「角色」下拉選單

User-facing

  • 同 Step 3 「參與人員與單位」tab → 「參與人員」(person) row → 應該有「角色」下拉(role: cisa_poc / system_engineer / etc)但找不到
  • User 提示「原本好像有」— 可能是 H-N 期被 refactor 掉
  • 預設可不選(OSCAL party.role 是 optional)

推測 root cause

  • PartiesSection 內 person row template 缺 role dropdown
  • 或 role 在 H-N parties Card→Table refactor 時被移除沒補回
  • Reference: 應該有 OSCAL role enum dropdown 元件

1.3 Bug R:確認匯入後負責單位 / 參與人員沒更新成新的資料

User-facing

  • 完成 Step 3 「確認匯入」→ 顯示成功
  • 回 template-edit page 看「負責單位」/「參與人員」 tab → 資料還是舊的(沒看到 docx 帶來的新 parties)
  • 預期:confirm 後重 GET 拿到新 parties

推測 root cause (待 trace):

  • (a) BE 沒真寫:confirm 走 strategy.write_parties 但因為某個 condition fall through 沒寫
  • (b) FE template-edit page cache 沒 invalidate:confirm 成功後 store 沒 reset / 沒重 GET module_frame detail
  • (c) Bug O regression:Bug O _apply_v3_decisions 改動可能影響 parties write path(雖然 parties 不在 _V3_LIST_KEYS 內,但 confirm 流程改動可能 side effect)
  • (d) 用戶看的是別的 mf 版本(SSP versioning 可能影響)

1.4 DB / log 證據蒐集(接手必跑)

# 1. 找最近的 confirm import job
PGPASSWORD='jedi@123!' psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -A -c "
SET app.is_super_admin='t';
SELECT id, source_uid, status, import_summary, updated_at
  FROM oscal.ssp_docx_parse_jobs WHERE status='completed' ORDER BY id DESC LIMIT 3;
"

# 2. 看 import_summary 裡的 parties_written count
# 預期:若 BE 真寫,count > 0;若 0 → bug R 是 BE 沒寫

# 3. 對應 mf → template SSP → parties
PGPASSWORD='jedi@123!' psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -A -c "
SET app.is_super_admin='t';
SELECT p.uid AS party_uid, p.name, p.party_type, p.created_at, p.created_user
  FROM oscal.oscal_parties p
  JOIN oscal.system_security_plans s ON s.id = p.ssp_id
  JOIN oscal.profiles pr ON pr.id = s.profile_id
  JOIN public.module_frames mf ON mf.oscal_profile_uid = pr.uid::text
 WHERE mf.uid = '<MF_UID>'
 ORDER BY p.created_at DESC LIMIT 10;
"
# 看 created_at 是否在 confirm 之後 — 是 → 真寫了 (bug R = FE cache)
#                                     否 → 沒寫 (bug R = BE)

# 4. BE log
grep -A 20 "write_parties\|parties_written" log/app.log | tail -50

2. 前次教訓(Bug O 收尾累積,避免重蹈)

  1. Annotated entry vs raw shape 不能共用 dict key — 本期 P/Q/R 若需動 annotated payload shape,記得用獨立 <key>_diff suffix
  2. 同一 function 多個 call site 必須全部 wire 同樣 param — Bug O 改 annotate_parse_result 時漏 wire GET 那條,本期改 BE 任何方法時 grep 所有 call site
  3. FE store 命名三處(state init / getter / setter)要 1:1 對齊 — 改 key 時三段同步
  4. tab name / button wording 對齊既有 UI 結構優先於 spec naming — 本期動 PartiesSection UI 時對齊 template-edit 既有 wording

3. 開工順位(建議按此順序)

  1. 跑 §6 Pre-flight + §7 Verify Bug O close(10 分鐘)
  2. Bug R 先驗 BE 真假(5 分鐘)— 看 import_summary.parties_written + DB created_at;確認是 BE 沒寫 / FE cache / Bug O regression 哪一條
  3. Bug Q 比較簡單(30~60 分鐘)— 只在 PartiesSection 補 role dropdown;確認 OSCAL role enum 來源;確認 default null OK
  4. Bug P 中等(1~2 小時)— FE PartiesSection 對 party_type 分流 button label + dialog 類型;trace org link API 確認 Error 來源
  5. Bug R 修補(取決 root cause):
    • BE → 加 trace + 修 write path
    • FE → confirm 成功後 reset store + 重 GET module_frame detail
    • Bug O regression → patch
  6. 跑 pytest + 跑 e2e (playwright) verify 全 3 bug
  7. Phase R 收尾:design.md 加 §11.35~37(每 bug 一段)+ changelog + FIXED-SUMMARY

4. 該讀的檔案 / 預期改動範圍

4.1 BE 端(Bug R 用)

檔案 為何 read / 改
app/oscal/service/ssp_docx_import_app_service.py (_filter_parties_for_write / confirm_import parties path) trace parties 寫入;確認 Bug O 改動沒 side effect
domain/oscal/service/write_strategy/...party*write* (若有) parties write strategy 邏輯
app/oscal/service/party_context_service.py 既有 party 寫入/更新 path
tests/test_ssp_docx_import_app_service.py (parties_written / unlinked test cases) regression test reference

4.2 FE 端(Bug P / Q 用)

檔案 為何 read / 改
~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/components/grc/ssp-docx-import-v2/sections/PartiesSection.vue Bug Q 補 role dropdown / Bug P 對 party_type 分流 button
~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/components/grc/ssp-docx-import-v2/sections/PartyLinkDialog.vue Bug P dialog 邏輯 — 確認 org / user 分開
~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/components/grc/ssp/SspPartiesTab.vue (template-edit 端) 對比 template-edit 怎麼處理 — wording / role dropdown / org link 都對齊
~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/components/grc/ssp-docx-import-v2/SspDocxImportPage.vue (confirm 後 reset 邏輯) Bug R FE cache invalidate path
~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/stores/sspDocxImportStore.js reset() confirm 成功後 reset 是否真的清掉 / 重 GET

4.3 跨 repo 必做

  • 改 FE 前必 read ~/Projects/Billows/Audit-Manager/compliance-manager-fe/CLAUDE.md
  • 對齊 template-edit Parties tab 既有 wording / role dropdown / org link 邏輯

5. Pre-flight Command(必跑)

# 1. 兩 repo branch + working tree
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be branch --show-current
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-fe branch --show-current
# 預期:兩個都 feature/ssp-oscal-alignment

git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be status --short
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-fe status --short
# 預期:clean (Bug O 已 commit 完)

# 2. local vs origin
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-be log origin/feature/ssp-oscal-alignment..HEAD --oneline
git -C ~/Projects/Billows/Audit-Manager/compliance-manager-fe log origin/feature/ssp-oscal-alignment..HEAD --oneline
# 預期 BE 9+ commits ahead;FE 4 commits ahead — 看 user 是否已 push

# 3. BE / FE listener
lsof -t -i:8000 && echo "BE up" || echo "BE down — restart needed"
lsof -t -i:5180 && echo "FE up" || echo "FE down"

# 4. BE pytest smoke
cd ~/Projects/Billows/Audit-Manager/compliance-manager-be
poetry run pytest tests/test_ssp_docx_import_app_service.py \
  tests/test_ssp_docx_diff_service.py \
  tests/test_ssp_write_strategy.py -q
# 預期 ~210+ passed

6. Verify Bug O + H-6 確實 close(必跑)

# 6.1 H-6 cleanup verify — 4 OSCAL 表 org_unit_id 應全 NULL
PGPASSWORD='jedi@123!' psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -A -c "
SET app.is_super_admin='t';
SELECT 'parties' AS tbl, count(*) AS bad FROM oscal.oscal_parties WHERE org_unit_id IS NOT NULL
UNION ALL SELECT 'leveraged', count(*) FROM oscal.ssp_leveraged_authorizations WHERE org_unit_id IS NOT NULL
UNION ALL SELECT 'components', count(*) FROM oscal.ssp_components WHERE org_unit_id IS NOT NULL
UNION ALL SELECT 'inventory', count(*) FROM oscal.ssp_inventory_items WHERE org_unit_id IS NOT NULL;
"
# 預期 4 row all bad=0

# 6.2 Bug O annotate 對 v3 4 key 真有套 — 看最近 awaiting_review job
PGPASSWORD='jedi@123!' psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -A -c "
SET app.is_super_admin='t';
SELECT id, jsonb_object_keys(parsed_result) FROM oscal.ssp_docx_parse_jobs
 WHERE status='awaiting_review' ORDER BY id DESC LIMIT 1;
"
# 預期 keys 含:components / components_diff / leveraged_authorizations / leveraged_authorizations_diff
#              / inventory_items / inventory_items_diff / system_characteristic / system_characteristic_diff
# 若 _diff key 缺 = Bug O regression 跑回去了

7. 行為規範重要提醒(per CLAUDE.md + memory)

  • 永不切 branch
  • 可自行 commit,不自動 push
  • 跨 repo 改 FE 前必 read FE CLAUDE.md
  • 改 BE service 層後必提醒 user 重啟
  • PrimeVue 3.53 quirks — Dropdown 對 null value 有 bug(用 sentinel string + v-model wrapper),SelectButton 預設 unselectable=true
  • DB 兩張表都 verify 才算 done — Bug R 修完必驗 (a) BE 寫 DB OK (b) FE 重 GET OK
  • 不要把 bug 標 caveat 甩給 user
  • changelog 收尾 batch 寫
  • 不要晶晶體(per memory feedback_no_chinglish
  • plan 假設先 verify(per memory feedback_plan_vs_reality_verify_first)— Bug Q「原本好像有」是 user 記憶,先 git log 確認 H-N refactor 是否真移除過

8. 收尾流程(fix 完後)

  1. design.md 加 §11.35~37(每 bug 一段,含 root cause / 修補 / 教訓)
  2. design.md §11 index 加新段標
  3. changelog 寫(type=fix 或 tweak,按性質)
  4. handoff/2026-05-XX-bug-pqr-FIXED-SUMMARY.md 短收尾報告
  5. commit + 問 user 確認 push 規模
  6. 對話歷史歸檔到 docs/conversation-history/<YYYY-MM-DD>/bug-pqr/

9. 不在 scope

  • Bug O 已 close — 不要回去碰 diff stepper / 4 key annotation / TabView
  • jedi-* 套件進版(本期不動套件)
  • Excel import 對應 bug(如有)— Excel 走自己 path,本期只修 docx
  • BE/FE 版號對齊(user 拍板)

10. 給 fresh session 的超短 prompt

請閱讀交接文件,了解現況,並接手 Bug P / Q / R 開發。

交接文件路徑:
docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-bug-p-q-r-parties-form-handoff.md

按本檔 §0 接手讀序執行 — 必跑 §6 Pre-flight + §7 Verify Bug O close →
§3 開工順位。注意 §2 前次教訓 + §7 行為規範。

3 個 bug 摘要:
- Bug P: 負責單位點「連結帳號」跳 Error 且應連 org_unit 非 user (FE PartiesSection)
- Bug Q: 參與人員少了「角色」下拉 (FE PartiesSection refactor regression?)
- Bug R: 確認匯入後 parties 沒更新(trace BE write OK 還是 FE cache 沒 invalidate)

依 §3 順序,第 2 步 enter plan mode 寫 implementation plan 給 user approve 才開工。
Bug R 先驗 root cause (5 分鐘 DB SQL + log grep)再決定怎修。

11. 跟 Bug O + H-N arc 的關聯

Bug P / Q / R 是 H-N arc 第 11~13 個 follow-up,跟 Bug O 改動 scope 解耦(負責單位連結 / 角色下拉 / confirm 後 reload — 都不是 diff stepper 也不是 4 key annotation 直接相關)。

Bug O 已 closed(diff stepper 6-tab + 4 key annotation + confirm filter 全 ship),但 user E2E 測試時發現 docx import preview UI 的 parties form 還有 3 個獨立 bug。

本期 P/Q/R 是 H-N arc「user-facing complete」前的最後幾步 — 完成後 docx import update mode 整段才算 v1 stable。