手冊首頁 / 合規稽核 / SSP docx 匯入 / 更新

SSP docx 匯入 / 更新(Project SSP Docx Import)

功能群:合規框架與 SSP|匯入三步式先讀 _overview §4;共用精靈見 module-frame-import

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

1. 功能描述

SSP docx 匯入 / 更新是把 docx 內容匯入更新某專案 living SSP 的頁面。route 掛在專案下(/project/projects/:id/ssp-import-docx),但功能屬匯入家族——用與資源庫匯入相同的共用精靈 SspDocxImportPage.vue,以 mode='update-ssp' + source_type='project_ssp' + mode='statement_only' 參數化。走三步式(上傳 → 解決差異 → 預覽 / 確認),confirm 只寫控制實作的 statement(不動既有控制其他欄位),完成後導回專案規劃。

主要使用者:專案 SSP 維護者(規劃階段)。

角色速覽:專案 SSP 維護者(規劃階段 manager / 有編輯權者,見 專案規劃頁 §3)。

歸屬註:本頁 route 在 project 下,但功能上屬於「匯入」這個家族(與 module-frame-import 共用同一套精靈),因此文件歸類在合規框架與 SSP 群;若日後重整可考慮移專案管理群。

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

# 功能 說明 位置 詳述
1 上傳 docx .docx 拖放上傳解析 Step1 UC-SSI-01
2 解決差異 match / append / skip 決策 Step2 §12
3 預覽 / 確認 分節 tab(控制實作為主)內嵌決策 Step3 §6.2
4 statement_only 寫入 confirm 只更新控制實作 statement 確認 §12
5 丟棄 DELETE parse job Step1/2/3 UC-SSI-02
6 導回規劃 confirm 後帶 ?return_to=ssp 回專案規劃 完成 §10

UC(§2)展開本頁具實質後端邏輯的功能:三步匯入含 confirm 決策驗證閘(UC-SSI-01,涵蓋上傳解析 1 / 解決差異 2 / 預覽確認 3 / statement_only 寫入 4)、丟棄暫存解析 job(UC-SSI-02)。導回規劃(6)為純導覽,見 §10。

2. Use Case

角色速覽:專案 SSP 維護者(規劃階段 manager / 有編輯權者,見 專案規劃頁 §3)。

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

UC-SSI-01 從 docx 匯入更新專案 SSP

項目 內容
角色 專案 SSP 維護者
前置條件 已登入;專案有 living SSP(sspUid
產出 / 後置條件 confirm 只更新控制實作 statement;導回規劃
uc_ssi_01 start entry 從專案規劃 / 總覽進入 /project/projects/:id/ssp-import-docx start->entry up Step1:上傳 .docx POST /ssp-docx-imports/parse (source_type=project_ssp, mode=statement_only, source_uid=sspUid) entry->up val 檔案合法? up->val err 400 GRC_DOCX_INVALID_FILE / TOO_LARGE (400005 / 400006) val->err diff Step2:解決差異 match / append / skip val->diff prev Step3:預覽(分節 tab) GET /ssp-docx-import/{parse_uid} diff->prev conf POST .../{parse_uid}/confirm (decisions[] / overrides) prev->conf dchk decisions 完整 且 control_id / party_uid 合法? conf->dchk derr 400 GRC_DOCX_DECISIONS_INCOMPLETE(400013) / INVALID_CONTROL_ID(400022) / INVALID_PARTY_UID(400023) dchk->derr done statement_only:只寫控制實作 statement 更新專案 living SSP(不動既有控制其他欄位) → 導回規劃(?return_to=ssp) dchk->done
UC-SSI-01 流程:進頁→上傳docx解析(project_ssp/statement_only)→驗證→解決差異→預覽→confirm 檢查 decisions 完整+control_id/party_uid 合法→只寫 statement→導回規劃

UC-SSI-02 丟棄解析 job

項目 內容
角色 專案 SSP 維護者
前置條件 精靈任一步(Step1 / 2 / 3)已有解析 job(parse_uid
產出 / 後置條件 刪除暫存解析 job;living SSP 未變動;解析 job 不存在 → GRC_DOCX_PARSE_JOB_NOT_FOUND(404023)
uc_ssi_02 start any 精靈任一步(Step1 / 2 / 3) 已有解析 job(parse_uid) start->any click 點「丟棄」 any->click del DELETE /ssp-docx-import/{parse_uid} (刪除暫存解析 job) click->del chk 解析 job 存在? del->chk err 404 GRC_DOCX_PARSE_JOB_NOT_FOUND (404023) chk->err done 暫存資料清除 (living SSP 未變動)→ 回精靈起點 chk->done
UC-SSI-02 流程:精靈任一步點丟棄→DELETE /ssp-docx-import/{parse_uid} 刪暫存 job→清除暫存資料回精靈起點

3. 權限矩陣

操作 FE 判定 BE 強制 BE 檢查位置
進頁 / 上傳 / confirm 專案編輯權(規劃階段) @jwt_required() + 專案權限(require_manager per project_planning auth) api/oscal/routes/ssp/ssp_docx_import_route.py

權限比照專案規劃頁的 SSP 寫入(見 專案規劃頁 §3);docx 匯入路徑是否同等 phase / 角色檢查需個案確認(規劃頁 §12 坑 7 同款注意)。

4. 狀態機與前置條件

匯入三步式見 _overview §4。error code(docx 系):

條件 效果 出處
檔非 .docx / 超 10MB GRC_DOCX_INVALID_FILE(400005)/ _FILE_TOO_LARGE(400006) grc_error_code.py:156-157
source_type 非法 GRC_DOCX_SOURCE_TYPE_INVALID(400008,只允 project_ssp / module_frame) :159
缺 framework 參數 GRC_DOCX_FRAMEWORK_REQUIRED(400007) :158
decisions 缺漏 / 未知 control_id / party_uid GRC_DOCX_DECISIONS_INCOMPLETE(400013)/ _INVALID_CONTROL_ID(400022)/ _INVALID_PARTY_UID(400023) :162-164
來源 / 解析 job 不存在 GRC_DOCX_SOURCE_NOT_FOUND(404022)/ _PARSE_JOB_NOT_FOUND(404023) :193-194

5. UI 設計

版面骨架:與資源庫 docx 精靈相同(共用 SspDocxImportPage),見 module-frame-import §5——差異僅 mode='update-ssp' / source_type='project_ssp' / statement_only

SSP docx 匯入 / 更新(route /project/projects/:id/ssp-import-docx) 與資源庫共用精靈 SspDocxImportPage(mode=update-ssp/source_type=project_ssp/statement_only) 三步式精靈(同一 route,Step 依 parse_uid 狀態切換) 開啟:UC-SSI-01 從 docx 匯入更新專案 SSP Step1 上傳 .docx 拖放上傳解析 POST /ssp-docx-imports/parse (source_type=project_ssp, mode=statement_only) 開啟:UC-SSI-01 從 docx 匯入更新專案 SSP Step2 解決差異 match/append/skip 決策 GET /ssp-docx-import/{parse_uid} decisions 必完整(否則 GRC_400013) 開啟:UC-SSI-01 從 docx 匯入更新專案 SSP Step3 預覽/確認 分節 tab(以控制實作為主) POST …/{parse_uid}/confirm statement_only:只寫 statement 不動既有控制其他欄位 開啟:UC-SSI-02 丟棄解析 job 丟棄(精靈任一步)+ confirm 後導回規劃(?return_to=ssp) DELETE /ssp-docx-import/{parse_uid} → GRC_DOCX_PARSE_JOB_NOT_FOUND(404023)若已不存在 → UC-SSI-02(點我開啟) 彩色=可點跳本頁 §6/UC,灰/紫=本頁結構|虛線=wizard step 分組框 API 僅列代表性 2~3 條,完整規格見 §6;版面與資源庫 docx 精靈相同(見 module-frame-import.md §5)
SSP docx 匯入版面:三步式(上傳/解決差異/預覽確認,statement_only 只寫 statement)+ 丟棄 job;可點跳 UC-SSI-01/02

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

上傳 docx Step 1:三步精靈(上傳檔案 → 解決差異 → 預覽與確認)+ 拖放上傳區,僅支援 .docx

② 解決差異、③ 預覽 / 確認兩張截圖從缺:需實際上傳 docx 觸發解析 job 才能進入後續步驟,屬寫入動作(會在 STG 建立 parse job / 暫存資料),不在本次唯讀截圖範圍內;待專案安排實測資料時再補。

狀態呈現:三步(上傳 / 解決差異 / 預覽);決策持久化 Pinia + localStorage;confirm 導回規劃帶 ?return_to=ssp / ?project_uid / ?ap_uid

6. API 規格

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

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

分類 Method + Path 說明 完整規格
docx 解析 POST /ssp-docx-imports/parse 上傳解析(source_type=project_ssp, mode=statement_only) §6.2
docx 預覽 / 確認 / 丟棄 GET /ssp-docx-import/{parse_uid}、POST .../confirm、DELETE .../{parse_uid} 三步式 §6.2
SSP 控制實作匯入 POST /ssp/{ssp_uid}/control-implementations/import[/validate,/confirm] 控制實作 Excel 匯入三步(規劃頁批次維護亦用) GAI-SD-02
樣板 GET /ssp-import-template 下載 SSP 匯入樣板 GAI-SD-02

6.2 核心 endpoint

[POST] /ssp-docx-imports/parse

Request(multipart):

欄位 型別 必填 說明
file raw .docx 檔
source_type string 固定 project_ssp
source_uid string ssp_uid
mode string 固定 statement_only
framework 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};confirm body decisions[] / overrides只更新控制實作 statement(statement_only:不動既有控制其他欄位)。出處:app/oscal/service/ssp_docx_import_app_service.py

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

檔案 角色
src/views/project/ImportDocxPage.vue wrapper(mode=update-ssp;props: sspUid / project_id / framework)
src/components/grc/ssp-docx-import-v2/SspDocxImportPage.vue 共用 docx 精靈元件(同 module-frame-import)
src/config/router/index.js:792-796 route project-ssp-import-docx/project/projects/:id/ssp-import-docx
src/config/api/api.js endpoint 常數

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

鏈路 Route App Service 底層
docx 解析 / confirm api/oscal/routes/ssp/ssp_docx_import_route.py(source_type=project_ssp) app/oscal/service/ssp_docx_import_app_service.py(statement_only confirm) oscal.ssp_docx_parse_jobs → 專案 living SSP

DDD 提醒:與資源庫 docx 匯入共用 route / service,靠 source_type 分流;statement_only 只寫 statement。

9. DB

9.1 資料表總清單

讀/寫 說明 欄位詳述
oscal.ssp_docx_parse_jobs (暫存) docx 解析暫存 job(source_type=project_ssp) module-frame-import §9.3
oscal.system_security_plans 目標 living SSP GAI-SD-03
oscal.ssp_statements (confirm) 控制實作 statement(statement_only) 規劃頁 §9.3
oscal.ssp_implemented_requirements 讀 / 控制實作(依 decisions match/append) 規劃頁 §9.3
oscal.parties (decisions 含 party) 人員(如 docx 帶 parties) GAI-SD-03

9.2 ER 圖

SSP 子表結構見 規劃頁 §9.2;本頁寫暫存 ssp_docx_parse_jobs(confirm 後只落地 statement)。

9.3 核心表

oscal.ssp_docx_parse_jobs 結構見 module-frame-import §9.3(共用暫存表,source_type=project_ssp 區分)。

10. 頁面邏輯與資料對應

載入 / 儲存流程:進頁 → 上傳 parse(source_type=project_ssp)→ 解決差異 → 預覽 → confirm(statement_only)→ 導回規劃(?return_to=ssp)。

關鍵欄位對應

畫面元素 API 欄位
差異決策 confirm decisions[](match/append/skip)
控制實作 statement confirm 只更新 statement(不動其他欄位)

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

11. 背景行為與外部依賴

類型 內容
解析 docx 解析成暫存 job;confirm 只寫 statement
Socket 本頁 socket
jedi-* 套件 jedi-oscal-v2(SSP 解析寫入)
系統參數 無 feature flag

12. 邊界情況與已知坑

  1. 共用精靈 source_type 分流:與 module-frame-import 共用 SspDocxImportPage 與 route / service,靠 source_type=project_ssp 走 SSP 路徑;改共用元件 / service 兩頁都受影響
  2. statement_only 只寫 statement:confirm 只更新控制實作的 statement,不動既有控制其他欄位(與資源庫 mode=full 寫全欄位不同)——避免覆蓋專案已填的實作狀態
  3. 權限比照規劃頁 SSP 寫入:docx 匯入是否同等 phase / 角色檢查需個案確認(同規劃頁 §12 坑 7)
  4. decisions 必完整:所有匹配控制項要做選擇(否則 GRC_400013);未知 control_id / party_uid 擋(400022 / 400023
  5. 導回帶 context:confirm 後 ?return_to=ssp / ?project_uid / ?ap_uid 帶回規劃頁上下文

13. 開發與驗證

  • 跑起來:BE python main_socketio.py(port 8000,log 在 log/app.log);FE Vite dev server。BE 改 service code 必重啟
  • 測試帳號:專案 SSP 維護者(規劃階段 manager);密碼見 .env / 部署文件
  • 導航路徑:專案規劃 / 總覽 → SSP docx 匯入(/project/projects/:id/ssp-import-docx
  • 前置資料:專案有 living SSP;一份 docx 檔
  • E2Ecompliance-manager-test/ repo;以 SSP 匯入 / ssp-import-docx 搜尋
  • 相關文件:共用精靈 module-frame-import、專案規劃頁 project-planning、匯入三步式 _overview §4;SSP 匯入匯出 Phase 2 見 memory project_ssp_import_export_phase2