| 項目 | 內容 |
|---|---|
| 緣由 | Phase 4 完工 + E option ship 後,user 發現 docx import 還是少 parties 資料(「責任單位 / 責任人員」tab 空白);我(前一 session)在 Phase 4 一直把 Bug B 標為「caveat」叫 user 手動 accept,迴避修正。User 點出問題後,因 session 注意力分散,handoff 給下個 fresh session。 |
| Branch | feature/ssp-oscal-alignment(兩 repo 一致) |
| 接手前必讀 | 本文件 → 2026-05-25-phase4-COMPLETE-SUMMARY.md(Phase 4 完工狀態)→ 2026-05-25-phase1-phase2-FINAL-SUMMARY.md §8 L2(Bug B 原始記錄) |
| 預估時間 | 1-2 小時(含 read FE flow + fix + verify + commit) |
| 不在本 handoff scope | L7 以外的 follow-ups(L8 進版 / L9 版號對齊)— 看 phase4-COMPLETE-SUMMARY |
User 在 MF /module-frame/<uid>/template-edit 進 docx import (亞航-CMMC-SSP-20260520-1會議討論版.docx):
oscal.parties + oscal.responsible_parties 對應 SSP shell 261 是空的/template-edit 「責任單位」「責任人員」tab 空白[2026-05-24 23:46:34,183] [ssp-docx-import] _load_current_parties returned EMPTY for module_frame=6492b07a-2039-49e9-86b5-a9334299cfd5
[2026-05-24 23:46:36,539] [ssp-confirm] _filter_parties_for_write parties_decisions count=5 map={
'new-1628102bb960bfc8': 'skip',
'new-66dcffaee4b6081f': 'skip',
'new-689443e94eb4d6c9': 'skip',
'new-925c9cffb607ba86': 'skip',
'new-9500c754dd80a637': 'skip'
}
[2026-05-24 23:46:36,549] [ssp-confirm] annotated party uid=new-1628102bb960bfc8 diff_status=added decision=skip
... (重複 5 次)
[2026-05-24 23:46:36,619] [ssp-confirm] no parties marked use_docx — nothing to write
[2026-05-24 23:46:36,630] [ssp-confirm] skipping strategy.write_parties — parsed_parties=0 hasattr=True
重點觀察:
diff_status=added(全新,不是 conflict / unchanged)結論:BE 行為正確。Root cause 在 FE — diff stepper 預設 decision=skip 而不是 accept。
| 不確定點 | 推測 | 怎麼 verify |
|---|---|---|
| FE diff stepper 預設 decision 的初始值在哪設? | useSspDocxDraft.js composable 或 sspDocxImportStore.js 內,可能在 initDefaultDecisions 之類 function |
grep decision.*skip|use_docx|initDecisions 在 FE src/composables/useSspDocxDraft.js + src/stores/sspDocxImportStore.js |
added / conflict / unchanged 三種 diff_status 各該預設什麼? |
推測:added 該預設 accept(新 party,無風險)/ conflict 預設 skip(user 確認)/ unchanged 預設 skip(不重寫) | 看 FE diff stepper component 對三個 diff_status 是否分流 |
| FE diff stepper UI 是否顯示「電話/職稱/地址」欄位? | 推測:沒顯示,user 看不到完整 party info 所以不敢 accept | grep SspDocxImportPage.vue 內 parties step 欄位列表(電話 / 職稱 / 地址 / address / telephone / job_title) |
| 是否同時要修「parties FE preview 缺欄位」(Issue 1)? | 是,跟 Bug B 同一條 stepper 元件,一起改成本更低 | 改 stepper 時順手加欄位 render |
| 檔 | 為何 read |
|---|---|
domain/oscal/parser/docx_section_extractors.py:255-321(party fields) |
確認 BE 已 extract 5 fields (name/title/address/telephone/email);line 318 extract_party_tables() |
app/oscal/service/ssp_docx_import_app_service.py:847+ 區域(_filter_parties_for_write) |
確認 decision filter logic — fix 後 BE 應正確接 decision='use_docx' 寫入 |
| 檔 | Read 目的 |
|---|---|
src/components/grc/ssp-docx-import-v2/SspDocxImportPage.vue |
主 docx import page,看 parties step 在哪 render + 哪個 stepper component |
src/composables/useSspDocxDraft.js |
docx draft state composable — 推測 default decisions 初始化在這 |
src/stores/sspDocxImportStore.js |
docx import pinia store — initDefaultDecisions 或類似 method 預設 'skip' |
src/service/SspDocxImportService.js |
service 看 confirm payload shape — verify decisions field |
| FE docx import diff stepper 對應 component(從 SspDocxImportPage 內部 import 推) | parties step render — 加電話/職稱/地址欄位 + 改預設 decision |
ba0cdd7a(docx confirm source_type=module_frame 補 ensure_shell)— 跟 Bug B 不相關,但同檔案修過8e8d5624(v2-bundle confirm 套 content_overrides)— 同檔案修過// 在 FE store / composable 內 initDefaultDecisions:
parties.forEach(p => {
decisions[p.uid] = { action: 'use_docx' } // 不管 diff_status 都預設 accept
})parties.forEach(p => {
if (p.diff_status === 'added') {
decisions[p.uid] = { action: 'use_docx' } // 新 party,預設加入
} else if (p.diff_status === 'conflict') {
decisions[p.uid] = { action: 'skip' } // 衝突要 user 確認
} else {
// 'unchanged' 或其他
decisions[p.uid] = { action: 'skip' } // 不動既有
}
})推薦 Option B,跟 BE strategy.write_parties 的「added → write / conflict → skip unless explicit accept」哲學一致。
在 stepper component render parties 表時加:
<Column field="title" :header="t('lang.xxx.col_title')" /> <!-- 職稱 -->
<Column field="address" :header="t('lang.xxx.col_address')" />
<Column field="telephone" :header="t('lang.xxx.col_telephone')" />
BE 已 extract,FE 只是沒 render。i18n key 可放 lang.ssp_docx_import.col.*。
重啟 BE → 重做 docx import → grep log:
tail -300 log/app.log | grep -E "ssp-confirm|_filter_parties|annotated party|strategy.write_parties"預期看到(fix 後):
[ssp-confirm] _filter_parties_for_write parties_decisions count=5 map={
'new-...': 'use_docx', # ← 不再是 'skip'
...
}
[ssp-confirm] annotated party uid=new-... diff_status=added decision=use_docx
... (5 筆)
[ssp-confirm] calling <strategy>.write_parties with ... parties
[ssp-confirm] strategy.write_parties returned parties_written=5
SET app.is_super_admin='t';
SELECT count(*) FROM oscal.parties WHERE created_at > '2026-05-25 開始時間';
-- 預期 ≥ 5
-- responsible_parties (party → SSP/MF context link)
SELECT count(*) FROM oscal.responsible_parties
WHERE context_type='ssp' AND context_id=<新建 SSP shell id>;
-- 預期 ≥ 5099a86bb)/module-frame/<mf_uid>/template-ssp endpoint ship(同 commit)01a51f6)User 該重啟 BE 後 → 進 MF /template-edit 的新「元件清冊」tab 應看到之前 docx import 寫入的 4 components + 1 LA。
design.md §11 補 §11.22 entry 紀錄 Bug B fix(mirror §11.17 Bug A 寫法)docs/features/FR-028-2605-ssp-oscal-alignment/handoff/ 加 Bug B 收尾 SUMMARYfeedback_changelog — 收尾才寫)詳見 2026-05-25-phase4-COMPLETE-SUMMARY.md §5。
你接手 SSP OSCAL Alignment Phase 4 後續 — fix Bug B (docx import 5 parties
全 decision=skip → 0 寫入) + Issue 1 (parties FE preview 缺電話/職稱/地址欄位)。
前一 session 修了 Phase 4 L5/L1a/L2/L3/L6 + E option (E1/E2/E3) 但一直迴避
Bug B,user 點出後 handoff 給你。
按以下順序讀文件:
1. docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-bug-b-and-parties-stepper-handoff.md(本 handoff — 必讀)
2. docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-phase4-COMPLETE-SUMMARY.md(Phase 4 完工狀態)
3. domain/oscal/parser/docx_section_extractors.py:318+(party extractor — 確認 BE 已 extract 5 fields)
4. app/oscal/service/ssp_docx_import_app_service.py:847+(_filter_parties_for_write)
5. ~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/components/grc/ssp-docx-import-v2/SspDocxImportPage.vue(主 page)
6. ~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/stores/sspDocxImportStore.js
7. ~/Projects/Billows/Audit-Manager/compliance-manager-fe/src/composables/useSspDocxDraft.js
開工前 pre-flight:
- 兩 repo branch: feature/ssp-oscal-alignment
- BE working tree: M pyproject.toml only
- FE working tree: clean
- BE 必須先重啟(前 session ship 的 E1/E2 endpoint + clone bug fix)
- BE test smoke: poetry run pytest tests/test_ssp_excel_import_app_service.py — pass
開工順位(看 handoff §3):
1. Read FE store + diff stepper 找預設 decision 初始化
2. 改 Option B 邏輯 (per diff_status 預設 accept/skip)
3. stepper component 加電話/職稱/地址欄位 render
4. FE vite build smoke
5. user 端重新 docx import verify (log + DB)
6. design.md §11 補 §11.22 entry
7. commit (FE 改動 + design.md)