狀態 2026-06-16。本檔是「FE 逐項套到 v2 BE」arc 中資源庫 §5 決策1(適用控制項改走範本 SSP SoA)這條的進度紀錄。 ⚠️ 本輪所有改動都還沒 commit(working tree;
pyproject.tomldev path-dep 不 commit)。這是「進度追蹤」文件,非收尾 — changelog / Notion / 對話歸檔 / 橫向文件都還沒做。
FR-038 把 BE 翻成 jedi_oscal_v2,資源庫範本編輯頁(module-frame/<uid>/template-edit)整套建在舊 jedi_oscal 上、2A 後被 stub/disable。本輪把這頁逐功能接回 v2,原則:換底層、FE 盡量不動、保留原功能。
典範:資源庫 = clone catalog + profile + 範本 SSP 三件組(Model A);「適用控制項」= 編範本 SSP 的 control-implementation(IR)/ AO(statement)SoA。
| # | 項目 | 做法 | 驗證 |
|---|---|---|---|
| 1 | 詳情樹顯示(group→control→AO) | module_frame detail enrich oscal_profile.include_groups(新 resource_library_app_service.get_profile_control_tree,profile→cloned catalog→parts) |
✅ 回 group/control/AO |
| 2 | profile id 對映 | create 把 include_controls 數字 id → control_id 字串(profile resolve 以 control_id 比對、跨 clone 穩定) | ✅ resolved_control_count 正確 |
| 3 | template-ssp 端點 | 從 EXCLUDE_MODULES re-enable + 註冊 + 改走 get_template_ssp_ref |
✅ 回 {ssp_uid,exists} |
| 4 | 控制項層可編(control-defaults) | service 重寫走 v2 ssp_service(IR.props 存 status/desc/role/origination,繞範本 SSP 無 project 的權限層) |
✅ PUT 寫入+讀回+暱稱 |
| 5 | AO 層可編(objective-defaults) | service 重寫走 v2 statement(IR 下 statement.props) | ✅ PUT AO 值+讀回 |
| 6 | AO 初始化基礎 BPMN | create 時每 AO 生 BPMN(Camunda7,含 Evidence upload 任務)+ workflow_template_uid 寫 part.props;樹讀回 | ✅ 6 AO→6 workflow_template |
| 7 | 編輯適用控制項(增減) | update_module_frame 重寫 + update_applicable_controls(更新 profile with-ids + 移除被拔控制項 IR〔statements CASCADE〕+ 新控制項補 AO BPMN);FE dialog 改吃 catalog-tree + 用 control_id pre-select |
BE 邏輯已寫;待 FE 實點增減 |
| 8 | 程序書掛載 control/AO | module_frame_reference_document_service 改走 v2 ssp_service(context_id = IR.id / statement.id) |
✅ FE 實點驗過(2026-06-16) |
| 9 | 程序書 picker 顯示/reload | FE:顯示 fallback file_name、搜尋含 file_name、開啟時 reload pool |
✅ FE hot-reload |
template-edit 頁「批次維護」選單全失效,多個不同根因,需獨立 task:
| 功能 | 根因 |
|---|---|
| Excel 樣板下載 / 匯出現況 / 匯入現況 | DI 炸:module_frame_template_import_service + SspImportTemplateAppService 引用 oscal_container 未定義的 control_implementation_domain_service(di_containers/module_frame/module_frame_containers.py:203-204, 251-252)→ 需 v2 重寫 + DI |
| 從文件匯入(docx)/ 從 Excel 匯入 | ssp_docx_parse_jobs / ssp_excel_parse_jobs 表在 v2 DB 不存在 → 需 DB migration |
| SSP 文件匯出(docx/pdf/odt) | 待確認(log 那兩個錯是 import parse_jobs,非 export 本身) |
這塊是 handoff 早標的「control-defaults 匯入匯出依賴 stubbed → 恐死」+ import parse-job 子系統,非本輪改壞。
把「從文件匯入(docx)」整條打通到「匯入內容顯示在範本編輯頁」。逐項根因都是 v2 換底層後某條路徑沒跟上。
| # | 症狀 | 根因 | 修法 | 狀態 |
|---|---|---|---|---|
| A | docx/excel 匯入 500 | oscal.ssp_docx_parse_jobs / ssp_excel_parse_jobs 表在 v2 DB 不存在(oscal schema DROP 重建時漏掉主專案自有表) |
migration scripts/sql/2026-06-16-restore-ssp-parse-jobs-v2.sql(建 2 表 + RLS + GRANT),已套 DEV |
✅ user 驗過 |
| B | 預覽頁整片空白 | get_parse_result 把資料包進 parsed_result key,但 FE 讀最上層(v1 是 **parsed_result 攤平) |
還原攤平 | ✅ user 驗過 |
| C | 人員/單位 0 筆 | docx 用「修訂模式」填,值在 <w:ins>,python-docx 讀不到;FR-038 P3 重寫 app service 時刪掉了 _normalize_docx_revisions |
還原 _normalize_docx_revisions(接受修訂後再解析) |
✅ user 驗過 |
| D | 新建資源庫「沒勾控制項」誤報 + 建立打到停用端點 | FE 抓 v2 永遠 null 的 catalog_control_uid;且 POST /module-frame(add_module_frame 在 v2 已 return None) |
FE 改抓 control_id + 改打 RESOURCE_LIBRARY_CREATE(對齊 ModuleFrame.vue) |
✅ user 驗過 |
| E | 評估目標 0 / AO 現況沒帶 | parser ao_map 用字母 key (a),v2 candidate.objective_keys 是 part_id ..._obj.1 → key in ao_map 永不命中 |
parser _map_ao_snippets:用 catalog 描述開頭 [a] 把 part_id 橋接回字母 |
✅ user 驗過 |
| F | 發布資源庫「建立專案」灰掉 | list dto 漏回 enable(FE disabled: !rowData.enable) |
dto 補 enable |
✅ user 驗過 |
| G | 匯入內容編輯頁讀不到(控制項/AO 現況空白) | 匯入寫 by-component.description(OSCAL 標準),但編輯頁讀 IR.props 自訂 key | 採 A:匯入也寫 IR.props implementation-description + statement.props(letter key (a) 對齊 aoLetterKey)。by-component 全遷移列大修正延後(見 analysis doc) |
✅ 控制項/AO 現況 user 驗過 |
| H | 實作狀態沒帶出來 | docx 無「狀態」欄,parser 解不出 → soa_props 沒東西寫 | 有現況描述者預設 implemented(之後編輯頁可改) |
✅ user 初步驗過(2026-06-16) |
| I | 既有資源庫重匯報錯 / 變 append | confirm 對既有非空範本送 mode="create" → already-has-a-body 報錯;改 update 後 v3 實體(元件/人員 by title/name)又「只加不刪」累積 |
Replace:套件加 OscalIoService.clear_ssp_body,confirm 既有路徑改 decision-merge → clear → create |
✅ user 初步驗過(2026-06-16) |
docs/analysis/2026-06-16-soa-implementation-storage-ir-props-vs-by-component.md。app/oscal/service/ssp_docx_import_app_service.py(get_parse_result 攤平 / _normalize_docx_revisions 還原 / confirm Replace)、domain/oscal/parser/docx_parser_core.py(_map_ao_snippets)、app/oscal/service/import_adapter/docx_to_oscal_ssp.py(IR.props+statement.props+letter key+status 預設)、app/oscal/service/resource_library_app_service.py(dto enable)OscalIoService.clear_ssp_bodysrc/components/grc/ssp-docx-import-v2/SspDocxImportPage.vuescripts/sql/2026-06-16-restore-ssp-parse-jobs-v2.sql(已套 DEV)BE(12):
app/oscal/service/resource_library_app_service.py(get_profile_control_tree / get_template_ssp_ref / _init_ao_workflows / update_applicable_controls / create id 對映 + 保留 group/version/frequency/provider / list enrich)app/module_frame/service/module_frame_service.py(detail enrich oscal_profile / update_module_frame 重寫)app/module_frame/service/module_frame_control_default_service.py(重寫走 ssp_service)app/module_frame/service/module_frame_control_objective_default_service.py(重寫走 ssp_service statement)app/module_frame/service/module_frame_reference_document_service.py(mapping context 改 v2 IR/statement)api/oscal/__init__.py(註冊 template-ssp)/ api/oscal/routes/module_frame_template_ssp_route.py(改走 resource_library)/ api/oscal/routes/resource_library_route.py(create 收 group/version/frequency/provider)config/di_modules.py(template-ssp route re-enable)di_containers/containers.py(oscal_container 接 workflow_execution_container)/ di_containers/oscal/oscal_containers.py(workflow_execution_container DependenciesContainer + resource_library 注入 workflow_template_service)/ di_containers/module_frame/module_frame_containers.py(control_default / objective_default / reference_document service 改注 ssp_service)FE(4):
src/config/api/api.js(RESOURCE_LIBRARIES_LIST / RESOURCE_LIBRARY_CREATE / RESOURCE_LIBRARY 常數)src/views/module_frame/ModuleFrame.vue(列表/新增改打 resource-library 端點 + 控制項 picker 改 catalog-tree + 框架欄防 null)src/views/module_frame/ModuleFrameTemplateEditView.vue(程序書 picker 顯示/搜尋/reload)src/components/grc/EditIncludeControlsDialog.vue(catalog-tree + control_id pre-select)本輪建的 verify 庫:verify-soa(57f82ee7) / verify-bpmn(f364552b) / 測試匯入合規資料庫(fb1bc3aa,13 程序書) 等;清理時可一併刪。