_ROLE_LABEL_MAP 清理 + Role ID 修正級別:小 依賴:C1(system_menus 已 seed,提供權威 role list) 被依賴:B 階段匯出 + C2 SSP party endpoint
清理 SSP 匯出 generator 內 hardcoded 的 role label map,移除錯誤混入的專案角色(manager/auditor/viewer),修正 security-officer vs system-security-officer 對不上的 bug。
| 檔案 | 修正項 |
|---|---|
app/oscal/service/export/ssp_docx_generator.py:32 _ROLE_LABEL_MAP |
移除 manager / auditor / viewer;修 security-officer → system-security-officer;補齊 C1 9 個角色 |
domain/oscal/adapter/cmmc_ssp_adapter.py:49 _ROLE_LABEL_PATTERNS |
擴增到 9 個角色對應的中/英文 regex pattern |
system_menus master data(已在 C1 處理)sheet_definitions.py:138 role enum(屬 C2/C5 整合改造)ssp_docx_generator.py — _ROLE_LABEL_MAP改動前(10 條,含 3 條錯誤):
_ROLE_LABEL_MAP: dict[str, str] = {
"responsible-organization": "Responsible Organization",
"information-owner": "Information Owner",
"information-provider": "Information Provider",
"information-receiver": "Information Receiver",
"system-owner": "System Owner",
"security-officer": "Security Officer", # ⚠️ ID 對不上 adapter
"manager": "Manager", # ⚠️ 專案角色不該出現
"auditor": "Auditor", # ⚠️ 專案角色不該出現
"viewer": "Viewer", # ⚠️ 專案角色不該出現
}改動後(9 條,與 C1 master 對齊):
# 對齊 C1 system_menus group='ssp_party_role' 9 個 OSCAL 標準角色
# 此 map 僅用於 SSP docx 匯出時將 role_id 轉成英文 label(OSCAL 文件慣例)
_ROLE_LABEL_MAP: dict[str, str] = {
"responsible-organization": "Responsible Organization",
"system-owner": "System Owner",
"system-security-officer": "System Security Officer",
"authorizing-official": "Authorizing Official",
"information-owner": "Information Owner",
"information-provider": "Information Provider",
"information-receiver": "Information Receiver",
"prepared-by": "Prepared By",
"prepared-for": "Prepared For",
}Fallback 行為:未在 map 內的 role_id 仍直接用 role_id 當 label 顯示(既有行為不變)。
cmmc_ssp_adapter.py — _ROLE_LABEL_PATTERNS改動前(5 條):
_ROLE_LABEL_PATTERNS = [
("responsible-organization", re.compile(r"Responsible Organization|專案負責單位", re.I)),
("information-provider", re.compile(r"Information provider|資料提供者|上游廠商", re.I)),
("information-receiver", re.compile(r"Information receiver|資料接收者|專案窗口", re.I)),
("system-owner", re.compile(r"System Owner|系統所有者", re.I)),
("system-security-officer", re.compile(r"System Security Officer|系統安全官", re.I)),
]改動後(9 條,含新增 4 個 OSCAL 標準角色 pattern):
_ROLE_LABEL_PATTERNS = [
("responsible-organization", re.compile(r"Responsible Organization|專案負責單位", re.I)),
("system-owner", re.compile(r"System Owner|系統所有者", re.I)),
("system-security-officer", re.compile(r"System Security Officer|ISSO|系統安全官", re.I)),
("authorizing-official", re.compile(r"Authorizing Official|授權機關|AO", re.I)),
("information-owner", re.compile(r"Information Owner|資料所有者", re.I)),
("information-provider", re.compile(r"Information Provider|資料提供者|上游廠商", re.I)),
("information-receiver", re.compile(r"Information Receiver|資料接收者|專案窗口", re.I)),
("prepared-by", re.compile(r"Prepared By|文件撰寫者", re.I)),
("prepared-for", re.compile(r"Prepared For|文件對象", re.I)),
]
_ORGANIZATION_ROLES = {"responsible-organization", "prepared-for"} # 補 prepared-for注意:
re.I (case-insensitive)_ORGANIZATION_ROLES 補 prepared-for(亞航文件慣例下這個是組織單位)role_id='security-officer' 的歷史資料 → 不再有對應 label,匯出時直接顯示 security-officer 字串SELECT DISTINCT role_id, COUNT(*)
FROM oscal.oscal_responsible_parties
WHERE role_id = 'security-officer'
GROUP BY role_id;security-officer → system-security-officer(design 預設此 case 為零,pre-flight 驗證後再決定)tests/test_cmmc_ssp_adapter.py 可能有 hardcoded role list assertion,需同步更新tests/test_ssp_docx_import_diff_response.py 同上tests/test_ssp_write_strategy_v2_parties.py 同上| 情境 | 行為 |
|---|---|
既有 SSP 用 security-officer 角色 |
匯出顯示 raw key(不會 fall through 到舊 label) |
| docx 內出現未識別的中英文 role pattern | 解析時 role=None(既有 fallback 不變) |
| 同一個 party 在 docx 內被標記多個 role | 沿用 adapter 既有行為(取第一個) |
| 編號 | 問題 | 我建議 |
|---|---|---|
| C8-D1 | DB 內若有 role_id='security-officer' 的歷史資料,要不要寫一次性 SQL 改成 system-security-officer? |
要(不留 broken role_id),但 pre-flight 先 audit 數量 |
| C8-D2 | _ORGANIZATION_ROLES 是否確定 prepared-for 算 organization?亞航文件用法是 person 還是 org? |
看亞航 reference docx 內 prepared-for 區塊,pre-flight 驗證 |
_ROLE_LABEL_MAP 9 條乾淨對齊 OSCAL 標準_ROLE_LABEL_PATTERNS 擴增到 9 個角色