手冊首頁 / 專案與任務 / 系統安全計畫編輯器

系統安全計畫編輯器(SSP Editor)

功能群:專案管理|狀態機與共用概念先讀 功能群總覽;OSCAL SSP 領域概念見 oscal-knowledge

事實基準:2026-07-06 從 FE / BE code 掃出;表結構對 db_schema.json、endpoint 對 routes.json 逐條核

1. 功能描述

系統安全計畫編輯器是專案 living SSP 的內容編制面板:受評方在此填寫 OSCAL System Security Plan 的各部分——系統特性(system-characteristics)、參與單位 / 人員(parties)、系統實作的元件(components)、利用授權(leveraged authorizations)、資產清冊(inventory-items)。這是 專案規劃頁Tab1「系統安全計畫」 內容(面板 SspTabPanel.vue);控制項 / AO 的實作現況(control-implementation)不在本頁,那是規劃頁 Tab0 的事(見 規劃頁 UC-PP-01)。

與規劃頁 Tab0 共用同一組可編輯 gate:只有 AP = planning 且使用者為專案 manager 時可寫;launch-audit 後 living SSP 凍結成快照,全面唯讀。

主要使用者:專案 manager(寫)、專案任一參與者(讀)。

角色速覽(完整定義見 _overview §3):

角色 一句話
manager 專案經理 — 唯一能編輯 SSP 各部分者(且需 AP = planning)
參與者 auditor / reviewer / viewer — 可讀不可寫

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

本頁是 hub(概覽 + 共用 gate + Excel 跨子區流程):五個子區各自的 field-level 逐欄規格(表單每欄 / 逐支 API request-response / DB jsonb 結構 / 逐坑)拆成獨立子頁,見「詳述」欄連結。

# 功能 說明 位置 詳述(field-level 子頁)
1 基本資料編輯 系統名稱 / 描述 / 敏感度 / 狀態 / owner / 授權邊界等(system-characteristics,1:1 upsert,8 欄) 子 Tab 基本資料 基本資料
2 參與單位管理 organization 型 party 的增改刪(DataTable + Dialog,含計數) 子 Tab 單位 參與方
3 參與人員管理 person 型 party 的增改刪 子 Tab 參與人員 參與方
4 元件清冊 system-implementation 元件增改刪(type 15 enum、protocol、port 等 9 欄) 子 Tab 元件·授權·資產 › 元件 元件清冊
5 利用授權 leveraged authorization 增改刪(title / provider / 授權日 / 類別 / 狀態) 同上 › 授權 利用授權
6 資產清冊 inventory-items 增改刪;依 asset_type 分「設備資產 / 系統資產」兩表 同上 › 資產 資產清冊
7 SSP Excel 匯出 下載範本(空表 blank / 帶現況 filled) TabView 右上「下載範本」 UC-SE-02
8 SSP Excel 匯入 上傳 .xlsx 解析 → 跳共用預覽頁 → confirm 批次寫入 TabView 右上「匯入」 UC-SE-02
9 唯讀 / 無 SSP 提示 無 sspUid → 提示先啟動稽核計畫;AP 凍結 / 非 manager → 唯讀警告 上層 Message §4

UC(§2)展開兩條核心路徑:各子區共同的內容編輯守門 UC-SE-01(五類 CRUD 的共同 gate 與 M2M 坑總覽,逐欄細節見各子頁)、Excel 批次匯入匯出 UC-SE-02(跨五子區、留在 hub);唯讀 / 提示屬狀態呈現見 §4 / §5。控制項 / AO 現況(control-implementation)與程序書關聯不在本頁,見 規劃頁 Tab0

2. Use Case

角色速覽(同 §1):

角色 一句話
manager 專案經理 — 唯一能編輯者(需 AP = planning)
參與者 auditor / reviewer / viewer — 可讀不可寫

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

UC-SE-01 編輯 SSP 各部分(系統特性 / 單位 / 人員 / 元件 / 授權 / 資產)

項目 內容
角色 專案 manager(讀:任一參與者)
前置條件 已載入 living SSP(sspUid);AP = planning(否則唯讀)
產出 / 後置條件 對應 oscal.ssp_* 表 upsert / insert / delete;基本資料 1:1,其餘為清單項;面板計數徽章更新
sspedit_uc_01 start tab 選子區:基本資料 / 單位 / 參與人員 / 元件 · 授權 · 資產 start->tab gate 有編輯權? (FE canEdit = manager 且 AP=planning; BE require_manager + AP 可編輯) tab->gate ro 唯讀(非 manager 或 AP 已凍結) 表單 disabled、隱藏新增/編輯/刪除 gate->ro act 動作? gate->act basic 基本資料:PUT .../system-characteristic (1:1 upsert) act->basic 存基本資料 crud 單位/人員/元件/授權/資產: POST 新增 · PUT 改 · DELETE 刪 (.../parties · /components · /leveraged · /inventory-items) act->crud 增/改/刪清單項 done 寫入對應 oscal.ssp_* 表 → 面板重載、計數徽章更新 basic->done m2m 改的是資產的 implemented_components(M2M)? crud->m2m m2mno PUT 無法改 M2M(FK 限制) FE 於編輯時 disable 該欄 → 需 delete + 重建 m2m->m2mno 是(編輯既有) m2m->done
UC-SE-01 流程:選子區→檢編輯權(manager+AP planning,否則唯讀)→基本資料 PUT system-characteristic 或 清單項 POST/PUT/DELETE→改資產 M2M implemented_components 需 delete+重建(PUT 改不了)→寫 oscal.ssp_* 表→重載

UC-SE-02 SSP Excel 批次匯出 / 匯入

項目 內容
角色 專案 manager
前置條件 AP = planning(匯入鈕 canEdit 才顯示)
產出 / 後置條件 匯出 = 下載 xlsx 範本;匯入 = 解析後跳共用預覽頁,confirm 才批次寫入 SSP 各子表
sspedit_uc_02 start dl TabView 右上「下載範本」 GET .../excel-template?mode=blank|filled (blank 空表 / filled 帶現況) start->dl fill 離線填寫 Excel dl->fill open 「匯入」開 Dialog(限 canEdit)→ 選 .xlsx fill->open upload POST .../excel-import/upload (解析,source_type='ssp') open->upload jump 跳轉共用預覽頁 (route: module-frame-import-excel-preview) upload->jump preview 預覽差異 → confirm 批次寫入 (三步式,與範本匯入共用管線) jump->preview done 寫回 SSP 各子表 → 回面板重載 preview->done
UC-SE-02 流程:下載範本(blank/filled)→離線填寫→匯入 Dialog 選 xlsx→POST excel-import/upload 解析(source_type=ssp)→跳共用預覽頁→confirm 批次寫入→回面板重載

3. 權限矩陣

操作 FE 判定 BE 強制 BE 檢查位置
讀各子區 參與者即可 require_participant(SSP → project → 任一 participant) common/middleware/permission/ssp_permission.py
編輯任一子區(POST/PUT/DELETE) canEdit = apStatus==='planning'currentUserRole==='manager' require_manager = manager 角色 + AP 可編輯 各 service(如 app/oscal/service/ssp_components_service.pyrequire_manager @ :63
Excel 匯入 confirm 同上 require_manager app/oscal/service/ssp_excel_import_app_service.py(confirm :124-125

⚠️ 部分 SSP endpoint(如 system-characteristic)route 層僅 @jwt_required(),實際角色守門在 service 層——與本群其他頁一致(讀 require_participant / 寫 require_manager)。改權限以 service 層檢查為準。

4. 狀態機與前置條件

本頁無獨立狀態機,承接 living SSP 的可編輯 gate(與 規劃頁 §4 同源):

條件 效果 出處
!sspUid 上層 Message「請先啟動稽核計畫,再回來編輯 SSP」 SspTabPanel.vuereadonlyHint:88-98
apStatus === 'planning' 且 role=manager canEdit=true:各子區可增改刪 同檔 :84-86
apStatus !== 'planning'(含 closed) living SSP 凍結為快照,全面唯讀 同上
非 manager 唯讀警告 同上

5. UI 設計

📸 實際畫面截圖待補(一律亮色模式拍攝):預計補 SSP 編輯器整頁(四子 Tab)sspedit-overview.png、元件/授權/資產子區 sspedit-components.png、Excel 匯入 Dialog sspedit-excel.png

版面骨架與子區職責(本頁為 hub:四子 Tab 分屬五個 field-level 子頁,Excel 匯入跨子區留在 hub;彩色區塊可點跳對應子頁,API 僅標代表性):

上層 Message:無 sspUid → 「先啟動稽核計畫」;AP 凍結/非 manager → 唯讀警告 共用可編輯 gate:canEdit = apStatus==='planning' 且 role=manager(否則全面唯讀) [0] 基本資料 [1] 單位/參與人員 [2] 元件・授權・資產 右上:下載範本/匯入 開啟:SSP 基本資料(system-characteristics)子頁 Tab[0] 基本資料(system-characteristics) 系統名稱/描述/敏感度/狀態/owner/授權邊界(1:1 upsert,8 欄) GET/PUT /ssp/{ssp_uid}/system-characteristic → project-ssp-basic.md(點我開啟) 開啟:SSP 參與方(organization/person party)子頁 Tab[1] 單位/參與人員(parties) organization/person 型 party 增改刪(DataTable+Dialog,含計數) GET/POST /ssp/{ssp_uid}/parties ・ PUT/DELETE …/parties/{party_uid} → project-ssp-parties.md(點我開啟) Tab[2] 元件・授權・資產(整合 tab;舊 key scope/leveraged 自動 redirect 至此)— 三子區各有獨立子頁 開啟:SSP 元件清冊(system-implementation components)子頁 › 元件清冊 元件增改刪 type 15 enum/protocol/port(9 欄) GET/POST /ssp/{uid}/components PUT/DELETE …/components/{uid} → project-ssp-components.md 開啟:SSP 利用授權(leveraged authorization)子頁 › 利用授權 leveraged authorization 增改刪 title/provider/授權日/類別/狀態 GET/POST /ssp/{uid}/leveraged PUT/DELETE …/leveraged/{uid} → project-ssp-leveraged.md 開啟:SSP 資產清冊(inventory-items)子頁 › 資產清冊 inventory-items 增改刪 依 asset_type 分設備/系統兩表 GET/POST /ssp/{uid}/inventory-items PUT/DELETE …/inventory-items/{uid} → project-ssp-inventory.md Excel 匯入 Dialog(跨五子區批次,留在 hub §6.2) GET /ssp/{uid}/excel-template?mode=blank|filled POST …/excel-import/upload → /{parse_uid} → /confirm(三步式) 彩色=有獨立子頁的區塊,整塊可點擊跳轉(框內標檔名+代表性 API)|灰=hub 本頁描述|虛線框=依操作才出現的 Dialog/整合 tab 容器 API 僅列代表性 2~3 條,完整規格見各子頁 §6;共用可編輯 gate:AP=planning 且 manager(launch-audit 後凍結唯讀)
SSP 編輯器版面 wireframe:上層唯讀/無 SSP 提示、子 TabView(基本資料→basic、單位/參與人員→parties、元件·授權·資產→components/leveraged/inventory 三子頁)、右上下載範本/匯入、Excel 匯入 Dialog

狀態呈現:子 Tab header 帶計數徽章(由各子面板 emit);SECTION_TAB_MAP 支援 ?section=<key> 深連結(舊 key scope/scope_devices/scope_info_systems/leveraged 自動 redirect 到整合後的元件·授權·資產 tab,維持書籤相容);無 socket,寫入後前端本地更新 + 重載。

6. API 規格

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

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

分類 Method + Path 說明 完整規格
基本資料 GET / PUT /ssp/{ssp_uid}/system-characteristic 系統特性讀取 / 儲存(1:1 upsert,8 欄) 基本資料 §6
單位 / 人員 GET / POST /ssp/{ssp_uid}/parties、PUT / DELETE .../parties/{party_uid} party 增改刪(organization / person 依 type 過濾) 參與方 §6
元件 GET / POST /ssp/{ssp_uid}/components、PUT / DELETE .../components/{uid} 元件清冊增改刪 元件清冊 §6
授權 GET / POST /ssp/{ssp_uid}/leveraged、PUT / DELETE .../leveraged/{uid} 利用授權增改刪 利用授權 §6
資產 GET / POST /ssp/{ssp_uid}/inventory-items、PUT / DELETE .../inventory-items/{uid} 資產清冊增改刪 資產清冊 §6
Excel GET /ssp/{ssp_uid}/excel-template?mode=blank|filled 下載匯入範本 GAI-SD-02
Excel POST /ssp/{ssp_uid}/excel-import/upload/{parse_uid}/confirm 匯入解析 → 預覽 → 批次寫入(三步式) §6.2

五個子區的逐欄 request / response 表在各自子頁 §6;以下 §6.2 只留跨子區的 Excel 匯入(本 hub 專屬)。

6.2 核心 endpoint(跨子區)

[POST] /ssp/{ssp_uid}/excel-import/upload

上傳 .xlsx 解析(source_type='ssp', source_uid=ssp_uid),成功後 FE 跳轉共用預覽頁(route module-frame-import-excel-preview),走與範本匯入相同的 parse → preview → confirm 三步式管線。出處:api/oscal/routes/ssp/ssp_scoped_excel_import_route.py:32-68app/oscal/service/ssp_excel_import_app_service.py

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

檔案 角色
src/components/grc/ssp/SspTabPanel.vue 本面板(四子 Tab 容器 + Excel 動作)
src/components/grc/ssp/SspBasicSection.vue 子 Tab 基本資料
src/components/grc/ModuleFramePartiesPanel.vue 子 Tab 單位 / 參與人員(party-type 過濾;SSP 與範本共用)
src/components/grc/ssp/SspComponentsLeveragedInventoryTab.vue 子 Tab 元件 · 授權 · 資產
src/views/project/ProjectPlanningView.vue 掛載點:規劃頁 Tab1
src/service/SspService.js 各子資源 CRUD service
src/service/SspExcelImportService.js Excel 匯入(uploadSspScoped
src/stores/menuStore.ts sspPartyRoleMenu(party role dropdown 來源)

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

鏈路 Route App Service 底層
系統特性 api/oscal/routes/ssp/ssp_system_characteristic_route.py SspSystemCharacteristicAppService oscal.ssp_system_characteristics(1:1)
party api/oscal/routes/ssp/ssp_party_route.py SspPartyAppService oscal.parties(透過 SSP metadata_id 掛接)
元件 / 授權 / 資產 ssp_components_route.py / ssp_leveraged_route.py / ssp_inventory_items_route.py SspComponentsAppService 等(require_participant 讀 / require_manager 寫) ssp_system_implementations containment → 三張子表
Excel 匯入 ssp_scoped_excel_import_route.py SspExcelImportAppService(parse / confirm,共用範本匯入管線) parse job 暫存 → 批次寫各子表

9. DB

9.1 資料表總清單(本頁讀寫的全部表)

讀寫 說明 詳述
oscal.system_security_plans SSP 主檔(uuid / metadata_id / status) §9.3
oscal.ssp_system_characteristics 讀 / 系統特性(1:1) §9.3
oscal.ssp_system_implementations 元件 / 授權 / 資產的 containment 父 GAI-SD-03
oscal.ssp_components 讀 / 系統元件清冊 §9.3
oscal.ssp_leveraged_authorizations 讀 / 利用授權 §9.3
oscal.ssp_inventory_items 讀 / 資產清冊(設備 / 系統) §9.3
oscal.parties 讀 / 參與單位 / 人員(透過 SSP metadata 掛接) §9.3

9.2 ER 圖(本頁讀寫範圍)

sspedit_er ssp oscal.system_security_plans id (PK) · uuid metadata_id · import_profile_id · status sc oscal.ssp_system_characteristics(1:1) ssp_id → SSP system_name / description / security_sensitivity_level status_state / authorization_boundary_* sc->ssp ssp_id si oscal.ssp_system_implementations id (PK) · ssp_id → SSP (containment 點:元件 / 授權 / 資產) si->ssp ssp_id comp ssp_components / ssp_leveraged_authorizations / ssp_inventory_items system_implementation_id → 上表 uuid · title · type / party_uuid / implemented_components(jsonb) comp->si system_implementation_id parties oscal.parties uuid · type(person / organization)· name metadata_id → SSP.metadata(單位/人員來源) comp->parties party_uuid 軟式參照 parties->ssp metadata_id(軟掛)
SSP 編輯器讀寫範圍:system_security_plans ← system_characteristics(1:1) / system_implementations ← 元件·授權·資產三子表;parties 透過 metadata_id 軟掛、授權以 party_uuid 軟式參照

9.3 核心表欄位

各子表的完整欄位卡(含 DB comment、jsonb 內部結構、props 保留鍵)在各子頁 §9.3:

逐欄詳述
oscal.ssp_system_characteristics 基本資料 §9.3
oscal.parties 參與方 §9.3
oscal.ssp_components 元件清冊 §9.3
oscal.ssp_leveraged_authorizations 利用授權 §9.3
oscal.ssp_inventory_items 資產清冊 §9.3

共通提醒:五張子表的產品擴充欄一律走各自 props jsonb([{name,value}])而非 OSCAL 核心欄;party_uuid / component-uuid 等跨表關聯皆軟式參照(無 FK)。細節見各子頁。

10. 頁面邏輯與資料對應

各子面板獨立 GET 載入(useSspSystemCharacteristic / useSspParties / useSspLeveraged 等 composable 包裝 cache)。

畫面元素 FE state / composable API 欄位
基本資料表單 useSspSystemCharacteristic system-characteristic 各欄
單位 / 人員 DataTable useSspPartiesload/invalidate parties[]type 過濾)
party role dropdown menuStore.sspPartyRoleMenu 9 個 C1 master role
元件 / 授權 / 資產清單 各自 GET components / leveraged / inventory-items

儲存流程:基本資料 = PUT 1:1;清單項 = POST/PUT/DELETE 單筆 → 對應 composable invalidate → 重載。Deep link?section=<key> 進頁自動切子 Tab。

11. 背景行為與外部依賴

類型 內容
socket (寫入後本地更新 + 重載)
store menuStore.sspPartyRoleMenu(party role master data,一次性 cache)
共用管線 Excel 匯入跳共用預覽頁(與範本匯入 module-frame-import-excel-preview 同一頁),走 parse → preview → confirm 三步式
凍結 launch-audit 後 living SSP 凍結成該輪快照(round.ssp_id),本頁轉唯讀(見 _overview §4

12. 邊界情況與已知坑

  1. 資產 implemented_components 是 M2M,PUT 改不了:BE update path 受 FK 限制無法改資產與元件的多對多關聯;FE 在編輯既有資產時 disable 該欄並提示「需 delete + 重建」,新增時可正常填。
  2. 資產分流(FR-032)asset_type='information_system' → 系統資產(infoSystemOptions picker);其餘 / 預設 → 設備資產(deviceOptions picker)——同一 inventory-items 表、UI 分兩張。
  3. party 無獨立 mapping 表:單位 / 人員掛在 SSP 的 metadataparties.metadata_id),type 分 person / organization;授權 / 資產以 party_uuid 軟式參照(無 FK),刪 party 前留意被參照。
  4. 舊 section key 相容?section=scope/scope_devices/scope_info_systems/leveraged 會 redirect 到整合後的「元件·授權·資產」子 Tab(Phase 4 L3 清理併 tab,書籤仍可用)。
  5. SSP 寫入無 phase guard(BE):唯讀是 FE 鎖的,凍結後直接打 API 仍會改 living SSP——同 規劃頁 §12 坑 3
  6. 無 socket:多人同編互不可見,後儲存者覆蓋。

13. 開發與驗證

  • 跑起來:起 BE + FE;登入見 .env / 部署文件測試帳號(需該專案 manager)
  • 導航:專案規劃頁 → Tab1「系統安全計畫」(/project/projects/:id/planning?tab=1);或帶 ?section=<key> 深連結
  • 前置資料:需一個有 living SSP 的專案(AP = planning);建幾筆元件 / 授權 / 資產測 CRUD 與 M2M 坑;下載 filled 範本測 Excel round-trip
  • 相關:控制項 / AO 現況見 規劃頁 UC-PP-01;OSCAL SSP 領域概念見 oscal-knowledge skill;Excel 匯入共用管線見 範本匯入