SSP 基本資料(System Characteristics)
功能群:專案管理|上層見 系統安全計畫編輯器(本頁=其 Tab「基本資料」子區)
事實基準:2026-07-06 從 FE / BE code 掃出;表結構對
db_schema.json、endpoint 對routes.json、欄位對 marshmallow serializer + mapper 組裝碼逐條核
1. 功能描述
基本資料是 SSP
的系統特性(system-characteristics)編制區:登錄受評範圍(受評標的)的身分與整體屬性——範圍名稱、識別碼、FIPS-199
安全分類、範圍類型、運行狀態、範圍負責人、授權邊界描述與描述。對應 OSCAL
SSP 的 system-characteristics 物件,與 SSP 為
1:1(一份 SSP 一列
oscal.ssp_system_characteristics,ssp_id
UNIQUE),寫入採 upsert(首次 PUT 自動建列)。
掛在 SSP 編輯器 的第一個子
Tab「基本資料」(FE SspBasicSection.vue)。與 SSP
其餘子區共用同一組可編輯 gate(manager +
AP=planning),launch-audit
凍結後唯讀。同一支元件亦被範本編輯(module-frame)復用,差別只在
apiBase prop(ssp vs
module-frame)與權限守門。
主要使用者:專案 manager(寫)、專案任一參與者(讀)。
角色速覽(完整定義見 _overview §3):
| 角色 | 一句話 |
|---|---|
| manager | 專案經理 — 唯一能編輯基本資料者(需 AP=planning) |
| 參與者 | auditor / reviewer / viewer — 可讀不可寫 |
1.1 功能總覽(本頁全部功能)
| # | 功能 | 說明 | 位置 | 詳述 |
|---|---|---|---|---|
| 1 | 讀取系統特性 | 載入既有 8 欄;無列時回空 placeholder(安全分類預設 high) | 進子 Tab 即載 | §6.2 GET |
| 2 | 編輯 / 儲存系統特性 | 8 欄一次 PUT(1:1 upsert,首次自動建列) | 表單 + 「儲存」鈕 | UC-SB-01 |
本頁無 DataTable / Dialog,是單一表單 1:1 upsert,故 §1.1 只有讀 + 寫兩項;UC(§2)展開唯一核心路徑 UC-SB-01(編輯系統特性),涵蓋名稱必填(FE 擋)、權限守門、首次自動建列、8 欄映射四個關鍵分支。
2. Use Case
角色速覽(同 §1)。流程圖視覺慣例:菱形 = 判斷、橘底 = 例外/擋下、紅框 = 錯誤(標 error code)、綠框 = 成功終點、虛線 = 可選路徑。
UC-SB-01 編輯系統特性(1:1 upsert)
| 項目 | 內容 |
|---|---|
| 角色 | 專案 manager(讀:任一參與者) |
| 前置條件 | 已載入 living
SSP(sspUid);AP=planning(否則唯讀) |
| 產出 / 後置條件 | upsert oscal.ssp_system_characteristics(1:1,首次 PUT
auto-create);8 欄映射到核心欄 + system_ids jsonb +
props jsonb;回傳完整 DTO 供前端重載 |
3. 權限矩陣
| 操作 | FE 判定 | BE 強制 | BE 檢查位置 |
|---|---|---|---|
| 讀系統特性 | 參與者即可 | require_participant(SSP → project → 任一
participant) |
app/oscal/service/ssp_system_characteristic_app_service.py:46(get) |
| 編輯 / 儲存 | readonly prop(非 manager 或 AP 非 planning 時父層傳入
→ 欄位 disabled、隱藏「儲存」鈕) |
require_manager(manager + AP 可編輯,否則
GRC_403051 / GRC_412028) |
同檔 update:54 |
route 層僅
@jwt_required()(ssp_system_characteristic_route.py:24,39),實際角色守門在 app service 的SspPermissionChecker.require_participant/require_manager——與 SSP 群其他頁一致。改權限以 service 層為準。
4. 狀態機與前置條件
承接 SSP 可編輯 gate(見 SSP 編輯器
§4):AP=planning 且 manager
才可寫,凍結後唯讀。額外前置:
| 條件 | 效果 | 出處 |
|---|---|---|
| ssp 尚無 system_characteristic 列 | GET 回空
placeholder(security_sensitivity_level='high'、其餘
null);首次 PUT 自動建列(NN 欄給空預設) |
module_frame_system_characteristic_service.py:_empty_placeholder:139
/ app service update:60-64 |
readonly(非 manager / AP 非 planning) |
欄位 disabled、無「儲存」鈕 | SspBasicSection.vue:48,301 |
5. UI 設計
版面骨架與區塊職責(單一直式系統特性表單,無 DataTable / Dialog;彩色區塊可點跳本頁小節錨點,API 僅標代表性):
📸 截圖待補(亮色模式):基本資料表單整頁(含頂部受評標的說明 block)
sspbasic-form.png。
單一直式表單(無 DataTable / Dialog),頂部一則 info block
說明「這頁要填什麼」(audit_subject_intro_body)。8
個表單欄位(SspBasicSection.vue template):
| # | i18n label | 型別 | 必填 | 列舉 / 來源 | 儲存欄位 | 備註 |
|---|---|---|---|---|---|---|
| 1 | label_system_name 範圍名稱 |
InputText | 是 | — | system_name |
空 → FE toast warn name_required(純前端擋,無
BE 守門) |
| 2 | label_system_identifier 範圍識別碼 |
InputText | 否 | — | system_ids[0].id(jsonb;空字串 →
[]) |
OSCAL system-ids,FE 只用單一值 |
| 3 | label_fips199 安全分類等級 |
Dropdown(showClear) |
否 | low / moderate / high |
security_sensitivity_level |
預設 high(FIPS-199 從嚴);空值載入時 fallback
high |
| 4 | label_target_type 範圍類型 |
InputText | 否 | — | props['target-type'] |
OSCAL 無核心欄,走 props 擴充 |
| 5 | label_operational_status 運行狀態 |
Dropdown | 否 | value active(label 卻是 operational)/
under-development / disposition /
other |
status_state |
FE 只 4 種、value active≠DB 慣用
operational、缺
under-major-modification(見 §12) |
| 6 | label_owner_uid 範圍負責人 |
Dropdown(filter 可搜尋、showClear) |
否 | menuStore.userMenu(label=nickname (login_name)、value=user
uid) |
props['owner-uid'] |
OSCAL 無核心欄,走 props 擴充 |
| 7 | label_boundary 授權邊界描述 |
Textarea(autoResize) | 否 | — | authorization_boundary_description |
|
| 8 | common.description 描述 |
Textarea(autoResize) | 否 | — | description |
系統摘要 |
狀態呈現:無 socket、無徽章;載入時顯示
ProgressSpinner;儲存成功 toast、失敗 toast(讀
e.response.data.msg)。readonly 時整組欄位
disabled、無「儲存」鈕。
6. API 規格
Envelope:成功 {"status": true, "data": …}、失敗
{"error_code": "…", "msg": "…"}。
6.1 總清單
| 分類 | Method + Path | 說明 | 完整規格 |
|---|---|---|---|
| 基本資料 | GET /ssp/{ssp_uid}/system-characteristic |
讀系統特性(無列回空 placeholder) | §6.2 |
| 基本資料 | PUT /ssp/{ssp_uid}/system-characteristic |
儲存系統特性(1:1 upsert,strip None) | §6.2 |
| picker | GET
/system/menu/user(menuStore.userMenu) |
範圍負責人下拉來源 | GAI-SD-02 |
6.2 核心 endpoint
[PUT] /ssp/{ssp_uid}/system-characteristic
系統特性 1:1 upsert。所有欄位選填(allow_none)、route
層 strip None(只送有值欄位視為更新,缺欄位=不變)。Request body:
{
"name": "受評系統範圍名稱",
"description": "系統摘要",
"system_identifier": "SYS-001",
"security_sensitivity_level": "high",
"target_type": "資訊系統",
"scope_description": "授權邊界描述",
"status": "active",
"owner_uid": "<user uid>"
}| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
| name | string | 否* | 範圍名稱 → system_name(*FE 端擋空,BE
無必填檢查) |
| description | string | 否 | 系統摘要 → description |
| system_identifier | string | 否 | → system_ids[0].id(jsonb;strip 後空 →
[]) |
| security_sensitivity_level | string | 否 | low / moderate / high →
同名欄 |
| target_type | string | 否 | → props['target-type'](非破壞性合併) |
| scope_description | string | 否 | 授權邊界 → authorization_boundary_description |
| status | string | 否 | 運行狀態 → status_state |
| owner_uid | string | 否 | 範圍負責人 → props['owner-uid'] |
映射與 upsert:_apply_payload 只動 payload
帶到的鍵、props 走 {name,value}
非破壞性合併;ssp 無列時 auto-create(NN 欄
system_name/description/status_state/authorization_boundary_description/system_ids
給空預設)。出處:app/oscal/service/ssp_system_characteristic_app_service.py:52-68、mapper
app/module_frame/service/module_frame_system_characteristic_service.py:_apply_payload:91-113
[GET] /ssp/{ssp_uid}/system-characteristic
Response
data(SspSystemCharacteristicResponseSchema +
audit nickname enrich):
| 欄位 | 型別 | 說明 |
|---|---|---|
| uid | string|null | 恆為 null(v2
ssp_system_characteristics 無 OSCAL uuid 欄) |
| name | string|null | ← system_name |
| description | string|null | ← description |
| system_identifier | string|null | ← system_ids[0].id |
| security_sensitivity_level | string|null | ← 同名欄(空列 placeholder 回 high) |
| target_type | string|null | ← props['target-type'] |
| scope_description | string|null | ← authorization_boundary_description |
| status | string|null | ← status_state |
| owner_uid | string|null | ← props['owner-uid'] |
| created_user / updated_user | string|null | login_name |
| created_user_name / updated_user_name | string|null | nickname(enrich_audit_nickname_one 補) |
出處:module_frame_system_characteristic_service.py:_to_dict:121-136、serializer
api/oscal/serializers/ssp/ssp_system_characteristic_inproject.py
7. 前端檔案地圖(compliance-manager-fe/)
| 檔案 | 角色 |
|---|---|
src/components/grc/ssp/SspBasicSection.vue |
本子區表單(8 欄、name 必填擋、apiBase 區別
SSP/MF、readonly gate) |
src/composables/useSspSystemCharacteristic.js |
load / invalidate(cache
包裝,apiBase 參數) |
src/service/SspService.js |
updateSystemCharacteristic(uid, payload, apiBase) |
src/stores/menuStore.ts |
userMenu(範圍負責人 dropdown
來源,fetchUserMenu 一次性 cache) |
8. 後端檔案地圖(本頁核心鏈路)
| 鏈路 | Route | App Service | 底層 |
|---|---|---|---|
| 系統特性 CRUD | api/oscal/routes/ssp/ssp_system_characteristic_route.py |
SspSystemCharacteristicAppService(require_participant
讀 / require_manager 寫;經
SspPermissionChecker) |
oscal.ssp_system_characteristics(1:1);純 mapping
共用 ModuleFrameSystemCharacteristicService(單一真相,MF
與 SSP 同表同契約) |
DDD 提醒:app service 不自寫 mapping,直接複用範本版
ModuleFrameSystemCharacteristicService的靜態_apply_payload/_to_dict,確保 MF 與 SSP 兩端欄位映射單一真相。
9. DB
9.1 資料表總清單(本頁讀寫的全部表)
| 表 | 讀寫 | 說明 | 詳述 |
|---|---|---|---|
| oscal.ssp_system_characteristics | 讀 / 寫 | 系統特性(1:1 per SSP,ssp_id UNIQUE) |
§9.3 |
| oscal.system_security_plans | 讀 | containment 父(ssp_uid → ssp.id) |
GAI-SD-03 |
9.2 ER 圖
系統特性以 ssp_id(UNIQUE 1:1)隸屬
system_security_plans,見 SSP
編輯器 §9.2 ER;本頁不另繪。
9.3 核心表欄位(取自 DEV DB dump,含 DB comment)
oscal.ssp_system_characteristics(本頁只寫下列 8 欄映射的欄位;其餘 v2 補欄 CRUD 未觸及)
| 欄位 | 型別 | 說明 |
|---|---|---|
| ssp_id | bigint | containment FK → system_security_plans.id(1:1
UNIQUE) |
| system_name | text | [必填] 系統全名 ← name |
| system_name_short | text | [選填](本頁 UI 未用) |
| description | text | [必填] 系統摘要 ← description |
| security_sensitivity_level | text | [選填] FIPS-199 整體分類(low/moderate/high) |
| system_ids | jsonb | [必填] [{id, identifier-type}];本頁只寫
[{id}] ← system_identifier |
| status_state | varchar(40) | [必填] operational / under-development / under-major-modification /
disposition / other ← status |
| authorization_boundary_description | text | [必填] 授權邊界描述 ← scope_description |
| props | jsonb | [選填] [{name,value}];本頁保留鍵
target-type / owner-uid(OSCAL 無核心欄,走
props 擴充) |
| created_user / updated_user | varchar(255) | Audit:login_name(response enrich nickname) |
⚠️ schema 註:欄位一律取自
db_schema.json。target_type/owner_uid不是獨立欄位,是存在props的保留鍵(target-type/owner-uid);system_identifier是system_idsjsonb 陣列第一項的id,非獨立欄位。表另有 network-architecture / data-flow / security-objective 等多組 v2 補欄,本頁 8 欄 UI 未觸及。
10. 頁面邏輯與資料對應
進子 Tab 由
useSspSystemCharacteristic.load(uid, {apiBase}) GET
載入,寫入 form(8 欄)。欄位對應:
| 畫面元素 | FE state | API 欄位 → DB |
|---|---|---|
| 範圍名稱 | form.name |
name → system_name |
| 範圍識別碼 | form.system_identifier |
system_identifier → system_ids[0].id |
| 安全分類 | form.security_sensitivity_level |
同名 → security_sensitivity_level |
| 範圍類型 | form.target_type |
target_type → props['target-type'] |
| 運行狀態 | form.status |
status → status_state |
| 範圍負責人 | form.owner_uid |
owner_uid → props['owner-uid'] |
| 授權邊界 | form.scope_description |
scope_description →
authorization_boundary_description |
| 描述 | form.description |
description → description |
儲存流程:onSave 先 client 檢查
name.trim() 非空(空 → toast warn 不送)→ 全 8 欄一次
PUT(name trim、其餘 || '')→
invalidate cache → toast success → emit
saved。載入
fallback:security_sensitivity_level 空 →
high、status 空 → active(避免
dropdown
顯示空白)。錯誤對應:GRC_403051(非
manager)/ GRC_412028(AP 關閉/封存)→ toast(讀
msg)。
11. 背景行為與外部依賴
| 類型 | 內容 |
|---|---|
| socket | 無(儲存後 invalidate + 重載) |
| store | menuStore.userMenu(範圍負責人
master,fetchUserMenu 一次性 cache) |
| 共用 | 同一元件被 module-frame
範本編輯復用(apiBase='module-frame',走
/module-frame/{uid}/system-characteristic,無權限
gate) |
| 凍結 | launch-audit 後 living SSP 凍結成快照,本頁轉唯讀(見
_overview §4) |
12. 邊界情況與已知坑
- name 必填只有 FE 擋、BE
無守門:
SspBasicSection.onSaveclient 端檢查name.trim()非空(toast warn 不送);但SspSystemCharacteristicUpdateSchema全欄allow_none、route strip None、mapperpayload.get('name') or ''——直接打 API 送空 name 不會被拒(與 inventory 的GRC_400074BE 守門不同,此頁無等價碼)。 - 運行狀態 FE 4 值 / value
active對不上 DB 慣用:FEstatusOptions只 4 項(valueactive/under-development/disposition/other),且第一項 label 是status_operational但 value 存active;DBstatus_statecomment 列的是operational / under-development / under-major-modification / disposition / other(5 種、用operational)。故 DB 實際存進active而非operational,且under-major-modificationFE 選不到。維護 OSCAL round-trip 時留意此 value 不一致。 uid恆為 null:v2ssp_system_characteristics無 OSCAL uuid 欄,_to_dict硬回uid: None;前端不可拿此頁uid當識別鍵(1:1 對 SSP,用ssp_uid即可)。- 空 placeholder 的 sensitivity 預設 high:無列時 GET
回
security_sensitivity_level='high'(非 DB 值,是 placeholder 常數);FE 載入亦有|| 'high'fallback——兩層預設一致,改預設要同步兩處。 - props 保留鍵非 DB 欄:
target-type/owner-uid存在propsjsonb、非獨立欄位;改鍵名要同步 mapper_PROP_TARGET_TYPE/_PROP_OWNER_UID(module_frame_system_characteristic_service.py:35-36)。 - SSP 寫入無 phase guard(BE):唯讀由 FE
readonlyprop 鎖;凍結後直接打 PUT 仍會改 living SSP——同 SSP 編輯器 §12。
13. 開發與驗證
- 跑起來:起 BE + FE;登入見
.env/ 部署文件測試帳號(需該專案 manager) - 導航:規劃頁 Tab1「系統安全計畫」→ 子
Tab「基本資料」(
SspBasicSection) - 前置資料:需有 living SSP 的專案(AP=planning);測首次 upsert(空 SSP 進來按儲存自動建列)+ 既有列更新;備幾個 user 測範圍負責人 dropdown
- 相關:其餘 SSP 子區見 參與方 / 元件 / 利用授權 / 資產清冊;範本版同欄位見 module-frame 系統特性;OSCAL system-characteristics 概念見 oscal-knowledge skill