手冊首頁 / 合規稽核 / 範本匯入精靈

範本匯入精靈(ModuleFrame Import — docx / excel)

功能群:合規框架與 SSP|匯入三步式先讀 _overview §4、母頁 module-frame

事實基準:2026-07-05 從 FE / BE code 掃出;endpoint 對 routes.json、schema 對 db_schema.json、error code 開檔驗

1. 功能描述

範本匯入精靈是從 docx / excel 批次匯入合規資源庫(ModuleFrame)內容的精靈(5 條 route 合一 spec)。docx 走三步式(上傳 → 解決差異 → 預覽 / 確認)、excel 走 2 頁式(上傳頁 + 預覽頁)。兩者都是暫存 parse job,confirm 才寫 compliance.module_frames 與其樣板 SSP(見 module-frame_overview §4)。

共用元件:docx 走 SspDocxImportPage.vuesrc/components/grc/ssp-docx-import-v2/),由 modecreate / update-mf)+ source_type='module_frame' 參數化——同一元件也服務 SSP docx 匯入頁(見 project-ssp-import-docx)。

主要使用者:資源庫作者(管理員)。

角色速覽:資源庫作者(管理員);scope=SYSTEM 公版 root 租戶維護。

1.1 功能總覽(本頁全部功能)

# 功能 說明 位置 詳述
1 docx 上傳 (create) 框架 / 版本串接下拉 + .docx 拖放 docx Step1 UC-MFI-01
2 解決差異 update-mf:match / append / skip 決策 docx Step2 UC-MFI-01
3 docx 預覽 / 確認 分節 tab(人員 / 系統特性 / 控制實作 / 外部授權)內嵌決策 docx Step3 UC-MFI-01
4 excel 上傳 框架 / 版本串接 + dropzone + 樣板下載 excel 上傳頁 UC-MFI-02
5 excel 預覽 側欄摘要 + 8 表 TabView(未匹配 / fuzzy 徽章) excel 預覽頁 UC-MFI-02
6 確認匯入 confirm → 寫 module_frame + 樣板 SSP 兩流程 UC-MFI-01 / -02
7 丟棄 DELETE parse job 兩流程 UC-MFI-01 / -02
8 樣板下載 下載空白匯入樣板 excel 上傳 UC-MFI-02
9 整包 / YAML 匯入 /module-frame/import[/template,/verify,/yaml] §6.1

UC(§2)分兩條獨立管線展開:docx 三步式(UC-MFI-01,含解決差異步)、excel 2 頁式(UC-MFI-02,24h TTL parse job)——兩者暫存表 / 服務 / error code 家族各異,故分別成 UC。整包 / YAML 匯入(9)屬常規批次 CRUD,僅列 §6.1 不展開 UC。

2. Use Case

角色速覽:資源庫作者(管理員);scope=SYSTEM 公版 root 租戶維護。

流程圖視覺慣例:菱形 = 判斷、橘底 = 例外 / 擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。

UC-MFI-01 從 docx 匯入資源庫內容(三步式)

項目 內容
角色 資源庫作者
前置條件 已登入;(create) 選框架版本 / (update-mf) 目標資源庫;source_type='module_frame'mode='full'
產出 / 後置條件 confirm 後寫 module_frames + 樣板 SSP 的 ssp_* 子表;清模組快取
uc_mfi_01 start up docx 上傳 .docx POST /ssp-docx-imports/parse (source_type=module_frame, mode=full) start->up val 檔案合法? (.docx / ≤10MB / source_type / mode) up->val err 400 GRC_DOCX_INVALID_FILE / _FILE_TOO_LARGE _SOURCE_TYPE_INVALID / _MODE_FULL_REQUIRES_MODULE_FRAME (400005/6/8/9) val->err mode create 還是 update-mf? val->mode diff update-mf:解決差異 match / append / skip 決策 mode->diff update-mf prev 預覽 GET /ssp-docx-import/{parse_uid} 分節 tab(人員 / 系統特性 / 控制實作 / 外部授權) mode->prev create diff->prev conf POST .../{parse_uid}/confirm (decisions + overrides + metadata) prev->conf drop 丟棄:DELETE /ssp-docx-import/{parse_uid} prev->drop 放棄 done 寫 compliance.module_frames + 樣板 SSP (ssp_* 子表);清模組快取 conf->done
UC-MFI-01 流程:docx 上傳解析→檔案驗證→(update-mf)解決差異→分節 tab 預覽→confirm 寫 module_frame+樣板 SSP

UC-MFI-02 從 excel 匯入資源庫內容(2 頁式)

項目 內容
角色 資源庫作者
前置條件 已登入;source_typeframework_version / module_frame + source_uid;parse job 須 awaiting_review 且未過 24h TTL 才可 confirm
產出 / 後置條件 僅無阻斷級錯誤時可 confirm,寫 module_frames + 樣板 SSP 的 ssp_* 子表;清模組快取
uc_mfi_02 start tmpl 下載樣板 GET /module-frame/download/template start->tmpl 可選 up excel 上傳頁:上傳 .xlsx POST /ssp-excel-imports/parse (source_type=framework_version | module_frame) start->up fill 離線填寫 8 表 tmpl->fill fill->up val 檔案合法? (.xlsx / ≤10MB / source_type / source_uid) up->val err 400 GRC_EXCEL_INVALID_FILE / _FILE_TOO_LARGE _SOURCE_TYPE_INVALID / _SOURCE_UID_REQUIRED (400065/6/7/8) val->err prev 預覽頁 GET /ssp-excel-import/{parse_uid} 側欄摘要 + 8 表 TabView(未匹配 / fuzzy 徽章) val->prev gate job = awaiting_review 且未過 24h TTL? prev->gate drop 丟棄:DELETE /ssp-excel-import/{parse_uid} prev->drop 放棄 gerr 412 GRC_EXCEL_PARSE_JOB_NOT_AWAITING(412013) / _TTL_EXPIRED(412014)→ 需重新上傳 gate->gerr block 有阻斷級錯誤? gate->block berr 400 GRC_EXCEL_VALIDATION_ERRORS_BLOCKING(400070) block->berr 是(擋 confirm) conf POST /ssp-excel-import/{parse_uid}/confirm block->conf done 寫 compliance.module_frames + 樣板 SSP (ssp_* 子表);清模組快取 conf->done
UC-MFI-02 流程:(可選下載樣板)→excel 上傳頁解析→檔案驗證→預覽頁 8 表 + 未匹配徽章→TTL/awaiting 與阻斷級錯誤 gate→confirm 寫 module_frame+樣板 SSP

3. 權限矩陣

操作 FE 判定 BE 強制 BE 檢查位置
進匯入精靈 選單能力(作者) @jwt_required() + org_unit-scoped 授權 api/oscal/routes/ssp/ssp_docx_import_route.py / ssp_excel_import_route.py
上傳 / confirm / 丟棄 同上 同上 app/oscal/service/ssp_docx_import_app_service.py / ssp_excel_import_app_service.py

本頁多為 JWT + 選單能力守門(無 platform-admin 限制,資源庫非全域資源);細粒度前置以 error code 表達(§4)。

4. 狀態機與前置條件

匯入三步式見 _overview §4。error code:

條件 效果 出處
docx 檔非 .docx / 超 10MB GRC_DOCX_INVALID_FILE(400005)/ GRC_DOCX_FILE_TOO_LARGE(400006) grc_error_code.py:156-157
docx source_type 非法 GRC_DOCX_SOURCE_TYPE_INVALID(400008,只允 project_ssp / module_frame) :159
docx mode=full 非 module_frame GRC_DOCX_MODE_FULL_REQUIRES_MODULE_FRAME(400009) :160
excel 檔格式 / 超 10MB GRC_EXCEL_INVALID_FILE(400065)/ GRC_EXCEL_FILE_TOO_LARGE(400066) :104-105
excel source_type 非法 / source_uid 缺 GRC_EXCEL_SOURCE_TYPE_INVALID(400067)/ GRC_EXCEL_SOURCE_UID_REQUIRED(400068) :106-107
excel 阻斷級錯誤 GRC_EXCEL_VALIDATION_ERRORS_BLOCKING(400070) :109
parse job 不存在 / 非 awaiting / 過期(24h) GRC_EXCEL_PARSE_JOB_NOT_FOUND(404033)/ _NOT_AWAITING(412013)/ _TTL_EXPIRED(412014) :110-112

5. UI 設計

版面骨架:

範本匯入精靈 — docx 三步式 / excel 2 頁式(共用暫存 parse job,confirm 才落地) docx 精靈(ImportDocxPage → 共用 SspDocxImportPage) 開啟:UC-MFI-01 從 docx 匯入資源庫內容(三步式) Step1 上傳 (create) 框架/版本串接下拉 + .docx 拖放 POST /ssp-docx-imports/parse 開啟:UC-MFI-01 從 docx 匯入資源庫內容(三步式) Step2 解決差異(update-mf) DiffResolutionStep:match/append/skip 決策 GET /ssp-docx-import/{parse_uid} 開啟:UC-MFI-01 從 docx 匯入資源庫內容(三步式) Step3 預覽/確認 分節 tab:人員/系統特性/控制實作/外部授權 POST …/{parse_uid}/confirm 左 40% PDF(有內嵌才顯示)|右 60% Step3 TabView 內嵌 match/append/skip 開啟:§6 API 規格 confirm → 寫 module_frames + 樣板 SSP 子表;清模組快取 DELETE /ssp-docx-import/{parse_uid}(丟棄) → #6-api-規格(點我開啟) excel 精靈(ImportExcelPage + ImportExcelPreviewPage,2 route) 開啟:UC-MFI-02 從 excel 匯入資源庫內容(2 頁式) 上傳頁 框架/版本串接 + dropzone + 樣板下載 POST /ssp-excel-imports/parse GET /module-frame/download/template 開啟:UC-MFI-02 從 excel 匯入資源庫內容(2 頁式) 預覽頁:左側欄摘要 + 右 8 表 TabView(未匹配/fuzzy 徽章) basic/system_characteristic/components/leveraged/inventory/system_assets/parties/controls GET /ssp-excel-import/{parse_uid}(24h TTL、awaiting_review 才可 confirm) POST …/{parse_uid}/confirm 開啟:§6 API 規格 confirm 僅無阻斷級錯誤時可行 → 寫 module_frames + 樣板 SSP;清模組快取 DELETE /ssp-excel-import/{parse_uid}(丟棄) → #6-api-規格(點我開啟) 彩色=可點跳本頁 §6/UC,灰=本頁結構|虛線=wizard step 分組框 API 僅列代表性 2~3 條,完整規格見 §6
範本匯入版面:docx 三步(上傳/解決差異/預覽確認)+ excel 2 頁(上傳/預覽 8 表),confirm 寫 module_frame + 樣板 SSP;可點跳 UC-MFI-01/02

實機截圖(STG,亮色模式,2026-07-05,帳號 blsadmin):

docx 上傳 Step 1:合規框架 + 版本兩層下拉(框架/版本串接)

② docx 解決差異步驟、③ excel 預覽頁(8 表 + 未匹配徽章)截圖從缺:需實際上傳檔案觸發解析 job 才能進入 Step 2,屬寫入動作(會在 STG 建立 parse job / 暫存檔),不在本次唯讀截圖範圍內;待專案安排實測資料時再補。

狀態呈現:docx 用 SspDocxImportPage 分步;excel 上傳與預覽分屬兩 route(reload 可復原);決策持久化在 Pinia store + localStorage。

6. API 規格

Envelope:成功 {"status": true, "data": …}、失敗 {"error_code": "…", "msg": "…"}

6.1 總清單(本頁呼叫的全部 endpoint)

分類 Method + Path 說明 完整規格
docx 解析 POST /ssp-docx-imports/parse 上傳解析(source_type=module_frame, mode=full) §6.2
docx 預覽 / 確認 / 丟棄 GET /ssp-docx-import/{parse_uid}、POST .../confirm、DELETE .../{parse_uid} 三步式 §6.2
excel 解析 POST /ssp-excel-imports/parse 上傳解析(source_type=framework_version|module_frame) §6.2
excel 預覽 / 確認 / 丟棄 GET /ssp-excel-import/{parse_uid}、POST .../confirm、DELETE .../{parse_uid} 2 頁式 §6.2
控制預設匯入 POST /module-frame/{uid}/control-defaults/import[/template,/validate,/verify] 控制預設 Excel 匯入三步 GAI-SD-02
整包 / YAML POST /module-frame/import[/template,/verify,/yaml] 整包 / YAML 匯入 GAI-SD-02
樣板 GET /module-frame/download/{template,yaml-template}/module-frame/{uid}/ssp-import-template 下載匯入樣板 GAI-SD-02

6.2 核心 endpoint

[POST] /ssp-docx-imports/parse

Request(multipart):

欄位 型別 必填 說明
file raw .docx
framework string
source_type string 'module_frame'
source_uid string 目標 mf uid
mode string 'full'
oscal_framework_version_uid string

Response data{parse_uid, status}。出處:api/oscal/routes/ssp/ssp_docx_import_route.py::SspDocxImportParseRoute

[GET] /ssp-docx-import/{parse_uid} ・ [POST] .../confirm

GET 回 {status, parsed_result}statusawaiting_review / failed / confirmed)。confirm body:

欄位 型別 必填 說明
decisions[] array 差異決策
overrides object 分節 / 各表覆寫
metadata object

confirm → 寫 module_frames + 樣板 SSP。出處:app/oscal/service/ssp_docx_import_app_service.py

[POST] /ssp-excel-imports/parse

Request(multipart):

欄位 型別 必填 說明
file raw .xlsx
source_type string 'framework_version' | 'module_frame'
source_uid string
metadata object JSON

Response data{parse_uid, status};預覽 GET 回各表 row 資料 + 未匹配 / fuzzy 標記。出處:api/oscal/routes/ssp/ssp_excel_import_route.py

7. 前端檔案地圖(compliance-manager-fe/)

檔案 角色
src/views/module_frame/ImportDocxPage.vue docx 精靈 wrapper(mode create/update-mf)
src/components/grc/ssp-docx-import-v2/SspDocxImportPage.vue 共用 docx 精靈元件(含 DiffResolutionStep)
src/views/module_frame/ImportExcelPage.vue / ImportExcelPreviewPage.vue excel 上傳頁 / 預覽頁
src/config/router/index.js:458-507 5 routes(import-docx / -docx-update / -excel / -excel-update / -excel-preview)
src/stores/*SspDocxImportStore* / *SspExcelImportStore* 決策持久化 store
src/config/api/api.js endpoint 常數

8. 後端檔案地圖(本頁核心鏈路)

鏈路 Route App Service 底層
docx 解析 / confirm api/oscal/routes/ssp/ssp_docx_import_route.py(Parse/Get/Confirm Route) app/oscal/service/ssp_docx_import_app_service.py oscal.ssp_docx_parse_jobs → module_frames + 樣板 SSP
excel 解析 / confirm api/oscal/routes/ssp/ssp_excel_import_route.py app/oscal/service/ssp_excel_import_app_service.py oscal.ssp_excel_parse_jobs → 同上

DDD 提醒:匯入三步式(暫存 parse job → confirm 才落地);source_type 驅動 confirm 寫入目標。

9. DB

9.1 資料表總清單

讀/寫 說明 欄位詳述
oscal.ssp_docx_parse_jobs (暫存) docx 解析暫存 job §9.3
oscal.ssp_excel_parse_jobs (暫存) excel 解析暫存 job §9.3
compliance.module_frames (confirm) 資源庫主檔 module-frame §9.3
oscal.system_security_plans (confirm) 樣板 SSP GAI-SD-03
oscal.ssp_implemented_requirements / ssp_statements / ssp_components / ssp_leveraged_authorizations / ssp_inventory_items / parties / ssp_system_characteristics (confirm) 樣板 SSP 子資源 GAI-SD-03

9.2 ER 圖

樣板 SSP 子表結構見 module-frame §9.2;本頁另寫暫存 ssp_docx_parse_jobs / ssp_excel_parse_jobs(confirm 後落地)。

9.3 核心表

oscal.ssp_docx_parse_jobs / ssp_excel_parse_jobs — 匯入解析暫存 job

共用結構:uid / statusawaiting_review / failed / confirmed)/ parsed_result(JSON)/ source_type / source_uid / created_at / created_user / org_unit_id。excel job 有 24h TTL(GRC_EXCEL_PARSE_JOB_TTL_EXPIRED)。

10. 頁面邏輯與資料對應

載入 / 儲存流程:docx 見 §2 UC-MFI-01(上傳 → (update) 解決差異 → 預覽 → confirm);excel 見 UC-MFI-02(上傳頁 → 預覽頁 → confirm)。決策存 Pinia + localStorage,confirm 後清模組快取(避免 router.push 回去讀到 stale)。

關鍵欄位對應

畫面元素 API 欄位
差異決策 confirm decisions[](match/append/skip)
分節 / 各表覆寫 confirm overrides
excel 未匹配徽章 parsed_result 各表 unmatched / fuzzy

錯誤對應:見 §4 error code 表。

11. 背景行為與外部依賴

類型 內容
解析 docx / excel 解析成暫存 job;confirm 落地
快取 confirm 後清 useModuleFrameParties 等模組快取
Socket 本頁 socket
jedi-* 套件 jedi-oscal-v2(SSP / catalog 解析寫入)
系統參數 excel parse job 24h TTL

12. 邊界情況與已知坑

  1. 共用元件 mode/source_type 參數化SspDocxImportPage 同時服務資源庫(source_type=module_frame)與專案 SSP(source_type=project_ssp,見 project-ssp-import-docx)——改這元件兩頁都受影響
  2. docx 三步 vs excel 兩頁:docx 有「解決差異」步(update-mf);excel 無 diff 步、改用 2 route(上傳頁 + 預覽頁)
  3. mode=full 僅 module_frame:docx mode=full 寫全欄位,只適用 module_frame 來源(否則 GRC_400009);SSP 來源用 statement_only
  4. excel parse job 24h TTL:過期 GRC_412014 需重新上傳;awaiting_review 才可 confirm(否則 GRC_412013
  5. 決策持久化 localStorage:中途離開可續,但跨裝置 / 清快取會丟決策
  6. confirm 後清模組快取:避免 router.push 回資源庫讀到 stale(useModuleFrameParties 等)
  7. 8 表 excel:basic / system_characteristic / components / leveraged / inventory / system_assets / parties / controls——各表獨立匹配決策

13. 開發與驗證

  • 跑起來:BE python main_socketio.py(port 8000,log 在 log/app.log);FE Vite dev server。BE 改 service code 必重啟
  • 測試帳號:資源庫作者 / 管理員;密碼見 .env / 部署文件
  • 導航路徑:範本管理 → 建立(docx / excel)或既有資源庫 → 匯入更新
  • 前置資料:docx / excel 檔(可先下載樣板);(create) 需框架版本
  • E2Ecompliance-manager-test/ repo;以 範本匯入 / module-frame-import 搜尋
  • 相關文件:母頁 module-frame、SSP docx 匯入(共用元件)project-ssp-import-docx、匯入三步式 _overview §4