級別:小(兩行修改 + sheet 顯示) 依賴:無 被依賴:無 可選性:可不做(C 階段尾聲評估),不做不影響其他 phase
把 v2.0.0(2026-05-21)從 Excel 樣板隱藏的 06_外部利用服務 sheet 恢復,讓 user 能透過 Excel 匯入「外部利用服務 / Leveraged Services」資料到 SSP。
sheet_definitions.py:255-258 註解原文:
v2.0.0 (2026-05-21):06_外部利用服務 暫時從 ALL_SHEETS 隱藏(系統內無對應
資料來源;party / date_authorized picker 拿掉後沒有 user 能填的鉤稽路徑)。
SHEET_LEVERAGED 定義保留 — 未來有需求時加回 ALL_SHEETS + 還原 parser 對應段
即可,不必重寫 SheetDef。
當時 A4/A5 階段決策:
| 檔案 | 改動 |
|---|---|
app/module_frame/excel_template/sheet_definitions.py:259 ALL_SHEETS |
tuple 內加回 SHEET_LEVERAGED(位置:SHEET_INFO_SYSTEMS 後,SHEET_CONTROLS 前) |
app/oscal/service/excel_parser/parser.py:70 |
leveraged=[] 改回呼叫 sh.parse_leveraged_sheet(sh.get_ws(wb, sh.SHEET_NAMES["leveraged"]), validation_errors) |
SHEET_LEVERAGED 欄位調整(沿用 v2.0 精簡版 3 欄:service_name / provider / purpose)sheet_definitions.py改動前:
ALL_SHEETS: tuple[SheetDef, ...] = (
SHEET_METADATA,
SHEET_ORGS,
SHEET_PERSONS,
SHEET_DEVICES,
SHEET_INFO_SYSTEMS,
SHEET_CONTROLS,
SHEET_REF_DOCS,
)改動後:
ALL_SHEETS: tuple[SheetDef, ...] = (
SHEET_METADATA,
SHEET_ORGS,
SHEET_PERSONS,
SHEET_DEVICES,
SHEET_INFO_SYSTEMS,
SHEET_LEVERAGED, # C7 (2026-MM-DD) 恢復:純文字輸入路徑
SHEET_CONTROLS,
SHEET_REF_DOCS,
)parser.py改動前:
# 06_外部利用服務 (SHEET_LEVERAGED) 自 v2.0.0 從 ALL_SHEETS 隱藏 —
# 樣板不產出此 sheet,parser 也跳過讀取以免噴 SHEET_MISSING 警告。
# ParsedExcel.leveraged 留 default_factory=list,下游空 list 安全。
leveraged=[],改動後:
# C7 (2026-MM-DD) 恢復讀取 — 純文字 service_name / provider / purpose
leveraged=sh.parse_leveraged_sheet(
sh.get_ws(wb, sh.SHEET_NAMES["leveraged"]), validation_errors,
),sheet_definitions.py:TEMPLATE_VERSION 或對應位置:
v2.0.0 → v2.1.0(minor bump,因為 sheet 數量改變屬 schema 變動)| 欄位 | 必填 | 寬度 | 說明 |
|---|---|---|---|
service_name |
✅ | 30 | 服務名稱(純文字,如 "AWS S3" / "Microsoft 365") |
provider |
✅ | 30 | 服務提供者(純文字,如 "Amazon Web Services" / "Microsoft") |
purpose |
— | 40 | 用途說明 |
設計選擇:
ssp_system_implementation_items.implementation_type='leveraged-authorization'Excel 06 sheet
↓
parser → ParsedLeveraged(service_name, provider, purpose)
↓
LeveragedWriteStrategy._parsed_to_item_payload
↓
ssp_system_implementation_items (
name=service_name,
title=provider,
purpose=purpose,
implementation_type='leveraged-authorization',
party_uuid=None, # 無 picker
date_authorized=None, # 無 picker
scope_type='ssp' / 'module_frame',
scope_id=...
)
| 情境 | 行為 |
|---|---|
| Excel 06 sheet 完全空白 | parser 回空 list,下游不寫資料 |
service_name 缺 (必填) |
parser 報 validation error,user 修正後重匯 |
| 既有 v2.0.0 樣板被匯入 (無 06 sheet) | parser 容錯:找不到 sheet → validation_errors 加 non-blocking SHEET_MISSING + leveraged=[] |
| Re-import update flow | A5 bugfix 已修「整份覆蓋」語義 (base.py write() delete-before-insert) — leveraged 同 SSP + 同 kind 自動覆蓋 |
| 編號 | 問題 | 我建議 |
|---|---|---|
| C7-D1 | 樣板版本 v2.0.0 → v2.1.0?影響 A2 parser 相容性檢查 | 要 bump,pre-flight 確認 parser 對舊版本 (v2.0.0) 不會強制報錯 |
| C7-D2 | 此 phase 是否要做?或留到 C 階段尾聲再評估 | 建議做,兩行改動成本極低;但你若想先聚焦 C3 也可 defer |
C7 first ship (commit e7f29e3, 2026-05-22) 走「純文字 3 欄」精簡版(service_name / provider / purpose)。Phase C 同期 user 反饋這結構不夠(CMMC / FedRAMP reference doc 有多種 service 類別 + 服務狀態欄位),加上 SSP UI 編輯也需要結構化欄位(不是只有 Excel)。
走「方案 B」:minimal schema extension — 加 2 個新欄位 + 補 2 個既有 OSCAL 欄位 expose 到 UI,不引入 FedRAMP catalog master data。
8de7991)OscalSspSystemImplementationItem 加 2 個 nullable 欄位:
| 欄位 | 型別 | 用途 |
|---|---|---|
provider |
VARCHAR(255) | 供應商名稱(service_name 之外的單獨欄位) |
category |
VARCHAR(50) | 服務類別(6 個 enum) |
對應 entity / mapper 同步擴充。
18a1110)scripts/sql/2026-05-23-add-leveraged-provider-category.sql(cmmgr 跑)SspLeveragedContextService add/update/list/_to_dict 都 wire provider + categorystatus(之前 design §6 列了但沒實作)+ OSCAL purpose(同)SHEET_LEVERAGED 加 category column + 6 個 enum_values + i18n headerSspLeveragedSection.vue 從原 design 的 4 欄位(名稱 / 日期 / 描述 + party_uuid)擴充到 7 欄位:
| # | 欄位 | UI | 對應 OSCAL |
|---|---|---|---|
| 1 | 類別 | Dropdown 6 enum | category (新欄位) |
| 2 | 服務名稱 | InputText | title |
| 3 | 供應商 | InputText | provider (新欄位) |
| 4 | 授權日期 | Calendar | date_authorized |
| 5 | 服務狀態 | Dropdown 3 enum | status (新 expose) |
| 6 | 用途 | Textarea | purpose (新 expose) |
| 7 | 描述 | Textarea | description |
party_uuid 仍隱藏(user 不會知道 UUID 是什麼)— 保留 model + comment 預留未來 picker。
對齊 CMMC + FedRAMP common scenarios:
cloud_infrastructure(雲端基礎設施 - IaaS)cloud_platform(雲端平台 - PaaS)cloud_software(雲端軟體 - SaaS)managed_security(資安託管服務 - MSSP)identity_authentication(身分驗證 / IAM)other(其他)原 design §6 EntityFactory pattern 沿用,但 entity 構建時新欄位(provider / category / status / purpose)跟著一起 build;ssp_id 寫入時走 mapper hasattr guard(避免老 schema ORM model 沒新欄位時硬塞)。
Phase C C7 ship 後(leveraged 結構化欄位進 entity + SSP UI),Excel 端尚未跟上。Track B 補完整個 Excel chain(樣板 / parser / reconciler / write strategy / FE 預覽),詳見 2026-05-23-feat-ssp-excel-system-characteristic-and-leveraged-structured.md。
從 v2.1.0 → v2.4.0 共 3 次 schema bump:
| 版本 | 變更 | 觸發 |
|---|---|---|
| v2.2.0 | leveraged 加 status enum;同 phase 加 受評標的 sheet | 初始 Track B |
| v2.3.0 | sheet 名拿掉「01_」「02_」前綴;parser 加 legacy alias backward compat | user 反饋雜亂 |
| v2.3.1 | SC + leveraged status enum 對齊 Billows convention (active vs operational) |
user 反饋預覽頁狀態無法帶出 |
| v2.4.0 | leveraged 加 date_authorized + description;provider 改 optional | user 反饋對齊 SSP UI edit dialog 欄位 |
原 Phase C 設計:entity 加 provider 後直接從 parsed.provider 寫到 entity.provider。
Track B 發現的 corner case:SSP UI display 讀的是 entity.title,而 LeveragedWriteStrategy 原本只寫 entity.name。Excel 匯入後 SSP UI 看到 bold 「—」+ small「服務名稱」(被誤當 provider 顯示)。
Fix:service_name 同時寫 entity.name + entity.title。BE 兩個欄位都填,UI 端讀 title 為主。
_dict_to_parsed_leveraged 拿掉 provider=provider or service_name cross-fill — user 沒填 provider 就維持空字串(之前 fallback 灌 service_name 到 provider 欄位)。
對齊 Excel v2.4.0 補的 description 欄位。_dict_to_parsed_leveraged 讀 dict.description; LeveragedWriteStrategy payload 帶 description;entity.description 寫入。
03 參與人員 sheet 的 role validator 原本強制 4 個 Billows participant role (manager / reviewer / auditor / viewer),但 MF 內 OSCAL responsible_parties 合法持有 OSCAL 標準角色 (system-owner / system-security-officer 等,OSCAL 文件結構需要)。Filled-mode 寫 OSCAL role 進 Excel,parser self-reject。
Fix:validate_person_role blocking=True → False;code INVALID_ROLE → ROLE_NOT_BILLOWS_PARTICIPANT。Confirm-time 加 _LEGACY_BLOCKING_CODES_NOW_WARNING 過濾名單,舊 parse_job stored blocking=True INVALID_ROLE 也跟著放寬。
User 反饋 Excel 下載 3 個 sheet 全空。Root cause:items 實際存 scope_type='ssp', scope_id=ssp_id(MF template-edit panel 走 ModuleFrameSspResourcesService 寫入時 force scope='ssp',C2.1 commit 設計), 但 _fetch_mf_items 用 scope_type='module_frame' 查 → 永遠空。
Fix:新 _fetch_mf_items_via_ssp(mf) — resolve chain mirror Track B _build_system_characteristic:mf → profile → SSP → items by ssp_id。