對應 design:design-C7.md 級別:小 預估工時:BE 0.5 天(含 smoke + 樣板版本確認)
# 1. 確認 SHEET_LEVERAGED 定義仍在
grep -n "SHEET_LEVERAGED" app/module_frame/excel_template/sheet_definitions.py
# 預期:line 184
# 2. 確認 parse_leveraged_sheet handler 仍在
grep -n "parse_leveraged_sheet" app/oscal/service/excel_parser/sheet_handlers.py
# 預期:line 139
# 3. 確認 LeveragedWriteStrategy 仍存活
grep -rn "LeveragedWriteStrategy\b" app/oscal/service/ --include="*.py" | head -3
# 預期:被 ssp_excel_import_app_service.py 注入
# 4. 樣板版本目前值
grep -n "TEMPLATE_VERSION\b" app/module_frame/excel_template/sheet_definitions.py
# 預期:v2.0.0
# 5. A2 parser 相容性檢查邏輯
grep -rn "template_version" app/oscal/service/excel_parser/ --include="*.py" | head -5
# → 確認對 v2.0.0 / v2.1.0 容錯處理sheet_definitions.py ALL_SHEETS 加回 SHEET_LEVERAGED(BE)檔案:app/module_frame/excel_template/sheet_definitions.py:259
改動:對齊 design-C7.md §5.1(tuple 內加 SHEET_LEVERAGED 在 SHEET_INFO_SYSTEMS 後 / SHEET_CONTROLS 前)
附帶:移除 line 255-258 註解(解釋 v2.0.0 隱藏的歷史脈絡),改成 C7 註解說明恢復理由
Commit message:feat(ssp-excel-template): C7 恢復 06_外部利用服務 sheet
parser.py 改回讀取(BE)檔案:app/oscal/service/excel_parser/parser.py:70
改動:對齊 design-C7.md §5.2(呼叫 sh.parse_leveraged_sheet)
Commit message:合併到 T1 同個 commit(連動改動)
檔案:app/module_frame/excel_template/sheet_definitions.py(或對應位置)
改動:
TEMPLATE_VERSION = "v2.1.0" # C7 (2026-MM-DD): 恢復 06_外部利用服務 sheet相容性檢查:
Commit message:合併到 T1
檔案:tests/test_excel_template_generator_blank.py / test_excel_template_generator_filled.py
新測試 case:
檔案:tests/test_excel_parser.py
新測試 case:
ParsedExcel(leveraged=[...]) 非空leveraged=[] 且 validation_errors 加 non-blocking warningservice_name 缺 → validation error檔案:tests/test_a4_write_strategy_leveraged.py 已存在,沿用
Commit message:test(ssp-excel): C7 加 06_外部利用服務 sheet 匯入流程測試
步驟:
GET /api/1.0/module-frame/<uid>/ssp-import-template?mode=blank 下載樣板ssp_system_implementation_items 內有 implementation_type='leveraged-authorization' 對應 2 筆SQL 驗證:
SELECT name, title, purpose, implementation_type
FROM oscal.ssp_system_implementation_items
WHERE implementation_type = 'leveraged-authorization'
AND scope_type = 'ssp'
AND scope_id = <test_ssp_id>
ORDER BY created_at DESC LIMIT 5;檔案:docs/changelog/YYYY-MM-DD-feat-ssp-excel-leveraged-sheet-restore.md
---
type: feat
breaking: false
modules: [module_frame, oscal]
---
## 需求說明
C7:恢復 v2.0.0 隱藏的 06_外部利用服務 sheet。Phase C 走向 SSP 直接編輯後,
純文字輸入到 SSP 變得合理,重啟此 sheet 的匯入路徑。
## 變更範圍
### BE
- `app/module_frame/excel_template/sheet_definitions.py`:ALL_SHEETS 加回 SHEET_LEVERAGED
- `app/oscal/service/excel_parser/parser.py`:leveraged=[] 改回呼叫 parse_leveraged_sheet
- TEMPLATE_VERSION v2.0.0 → v2.1.0
- `tests/`:新增 06 sheet round-trip 測試
## 行為差異
- Excel 樣板下載多一頁 06_外部利用服務(3 欄純文字:service_name / provider / purpose)
- 匯入流程處理 06 sheet 資料 → ssp_system_implementation_items (type='leveraged-authorization')
- v2.0.0 舊樣板仍可匯入(向後相容,無 06 sheet 視為空)| 風險 | 緩解 |
|---|---|
| v2.1.0 樣板 user 用舊 parser 匯入 break | 已驗證 parser 對缺 sheet 是 non-blocking warning |
| LeveragedWriteStrategy 已 stale 不能用 | A4 階段已有測試,無 stale 風險 |
| 寫入時撞 A5 bugfix「整份覆蓋」邏輯 | 此 fix 對 leveraged 已生效(write_strategy base.py) |
Rollback:純樣板改動,git revert 即可。已匯入的 leveraged 資料維持在 SSP items 表內,不會被影響。