對應 design:design-C8.md 級別:小 預估工時:BE 0.5 天(含 test fix)
# 1. 確認 _ROLE_LABEL_MAP 仍在預期位置
grep -n "_ROLE_LABEL_MAP" app/oscal/service/export/ssp_docx_generator.py
# 預期:line 32
# 2. 確認 _ROLE_LABEL_PATTERNS 仍在預期位置
grep -n "_ROLE_LABEL_PATTERNS\|_ORGANIZATION_ROLES" domain/oscal/adapter/cmmc_ssp_adapter.py
# 預期:line 49 / 56
# 3. data audit — 既有 SSP 用 'security-officer' 的數量
psql -h 192.168.50.188 -p 25432 -U cmmgr -d guidant_ai_dev -c \
"SELECT role_id, COUNT(*) FROM oscal.oscal_responsible_parties
WHERE role_id IN ('security-officer','manager','auditor','viewer','reviewer')
GROUP BY role_id ORDER BY role_id;"
# 預期:希望全 0(若有需 data fix migration)
# 4. 找出測試會 break 的位置
grep -rn "security-officer\|_ROLE_LABEL_MAP\|_ROLE_LABEL_PATTERNS" tests/ --include="*.py" | head -10ssp_docx_generator.py _ROLE_LABEL_MAP(BE)檔案:app/oscal/service/export/ssp_docx_generator.py:32
改動:對齊 design-C8.md §3.1(9 條 OSCAL 標準角色,移除 manager/auditor/viewer + 修 system-security-officer)
測試:
Commit message:fix(ssp-export): C8 _ROLE_LABEL_MAP 對齊 OSCAL 9 個標準角色,移除誤入專案角色
cmmc_ssp_adapter.py _ROLE_LABEL_PATTERNS(BE)檔案:domain/oscal/adapter/cmmc_ssp_adapter.py:49
改動:對齊 design-C8.md §3.2(9 條 pattern + 補 prepared-for 到 _ORGANIZATION_ROLES)
測試:
tests/test_cmmc_ssp_adapter.py — 加新測試 case:
Commit message:feat(ssp-docx-parser): C8 CMMC adapter 角色 pattern 擴增到 9 個 OSCAL 標準角色
前提:pre-flight Step 3 audit 發現有 broken role_id(security-officer 等)
檔案:scripts/sql/2026-MM-DD-fix-broken-ssp-role-ids.sql
-- Date: 2026-MM-DD
-- Purpose: C8 — 修 oscal_responsible_parties 內 broken role_id
-- 帳號:cmmgr
BEGIN;
-- 1. security-officer → system-security-officer (2026-MM-DD)
UPDATE oscal.oscal_responsible_parties
SET role_id = 'system-security-officer'
WHERE role_id = 'security-officer';
-- 2. 清除誤入的專案角色(這些根本不該在 SSP context)
-- 注意:執行前先 audit 是否真的全為 SSP context 殘留
SELECT role_id, context_type, COUNT(*)
FROM oscal.oscal_responsible_parties
WHERE role_id IN ('manager','reviewer','auditor','viewer')
GROUP BY role_id, context_type;
-- 確認後 (uncomment 才執行)
-- DELETE FROM oscal.oscal_responsible_parties
-- WHERE role_id IN ('manager','reviewer','auditor','viewer');
COMMIT;
-- 驗證
-- SELECT role_id, COUNT(*) FROM oscal.oscal_responsible_parties
-- WHERE role_id IN ('security-officer','manager','reviewer','auditor','viewer')
-- GROUP BY role_id;
-- 預期:0Commit message:chore(sql): C8 修 oscal_responsible_parties broken role_id (security-officer 等)
注意:DELETE 那段預設註解,pre-flight 後 user 確認再開。
可能受影響的測試:
tests/test_cmmc_ssp_adapter.pytests/test_ssp_docx_import_diff_response.pytests/test_ssp_write_strategy_v2_parties.pytests/test_ssp_export*.py(B 階段相關)動作:
pytest tests/ -k "role" 看哪些 breakCommit message:test(ssp): C8 更新 test fixtures 對齊 9 個 OSCAL 角色
檔案:docs/changelog/YYYY-MM-DD-tweak-ssp-role-label-cleanup.md
---
type: tweak
breaking: false
modules: [oscal_export, oscal_docx_import]
---
## 需求說明
C8:清理 _ROLE_LABEL_MAP 內誤入的專案角色 (manager/auditor/viewer),
修 security-officer → system-security-officer 對應,
擴增 CMMC docx adapter pattern 到 9 個 OSCAL 標準角色。
## 變更範圍
### BE
- `app/oscal/service/export/ssp_docx_generator.py`:_ROLE_LABEL_MAP 重寫
- `domain/oscal/adapter/cmmc_ssp_adapter.py`:_ROLE_LABEL_PATTERNS 擴增 + _ORGANIZATION_ROLES 補 prepared-for
- `tests/`:更新 fixture + 新 role 測試 case
- (optional) `scripts/sql/2026-MM-DD-fix-broken-ssp-role-ids.sql`
## 行為差異
- SSP 匯出時不再出現 manager/auditor/viewer 文字(誤入專案角色)
- CMMC docx 匯入可辨識 authorizing-official / prepared-by 等 4 個新角色| 測試 | 內容 |
|---|---|
| Unit | docx_generator 對 9 個 role_id 都能輸出對應 label |
| Unit | cmmc_adapter 對 9 個中英文 pattern 都能 match |
| Unit | unknown role_id fallback 行為(顯示 raw key) |
| Integration | 跑一份 CMMC SSP docx import → 確認新角色被正確解析 |
| Manual | 跑一份 SSP docx 匯出 → 確認 role 顯示正常 |
| 風險 | 緩解 |
|---|---|
既有 SSP 有 security-officer 資料,改 map 後匯出顯示 raw key |
跑 T3 data fix SQL |
| Test fixtures 漏改造成 CI red | 開工前 grep -rn "_ROLE_LABEL" tests/ 確認全找到 |
Rollback:純程式碼改動,git revert 即可