# 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 證據蒐集（接手必跑）

```bash
# 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（必跑）

```bash
# 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（必跑）

```bash
# 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。
