system_security_plan_system_implementations 表擴充Phase:A0(基礎建設) 級別:重型 狀態:design draft,等 raymond review brainstorm 來源:requirement-understanding.md §2(10 個問題已 resolved) 依賴:無(Phase 2 的最前置) 後續依賴本 phase:A1, A2, A3, A4, A5(Track A 全部)+ B2, B5(Track B 內容組裝與 OSCAL 匯出)
擴充既有 oscal.system_security_plan_system_implementations 表,使其能同時承載:
public.devices / compliance.information_systems 鉤稽(既有只存純文字 name)完成後,Phase 2 後續所有匯入流程(A1~A5)寫入此表、所有匯出流程(B2 / B5)讀取此表,無需新建任何 OSCAL mirror 表。
oscal.system_security_plan_system_implementations
├── id (PK)
├── uid (UUID, unique, default uuid4)
├── system_security_plan_id (FK → oscal.system_security_plans.id, NOT NULL, ON DELETE CASCADE)
├── name (varchar(255), NOT NULL)
├── description (text)
├── implementation_type (varchar(50), NOT NULL)
├── responsible_party (varchar(100))
└── audit: created_at / updated_at / created_user / updated_user
SystemImplementationType(jedi-oscal common/enum/code_enum.py):
class SystemImplementationType(StrEnum):
SYSTEM = "system"
SUBSYSTEM = "subsystem"
SERVICE = "service"
COMPONENT = "component"
HARDWARE = "hardware"
SOFTWARE = "software"DB 內 140 筆,全部 implementation_type='hardware'(= devices 鏡像,由 project_device_mapping_service 寫入)。
| 模組 | 行為 |
|---|---|
app/associations/service/project_device_mapping_service.py |
寫 hardware 紀錄 |
app/oscal/service/ssp_versioning_service.py |
SSP 版本複製時複製 system_implementations |
| 層 | 檔案 |
|---|---|
| ORM | jedi_oscal/infra/model/ssp/ssp_system_implementation.py |
| Entity | jedi_oscal/domain/entity/ssp/ssp_system_implementation_*.py |
| Repo interface | jedi_oscal/domain/repository/ssp/system_implementation_repo.py |
| Repo impl | jedi_oscal/infra/repository/ssp/ssp_system_implementation_repo_impl.py |
| Mapper | jedi_oscal/infra/mapper/ssp/system_implementation_mapper.py |
| OSCAL YAML mapper | jedi_oscal/infra/mapper/ssp/ssp_yaml_mapper.py |
| DTO | jedi_oscal/app/dto/ssp/ssp_system_implementation_dto.py |
| Enum | jedi_oscal/common/enum/code_enum.py → SystemImplementationType |
| 欄位 | 型別 | nullable | 用途 |
|---|---|---|---|
scope_type |
varchar(20) |
NOT NULL(既有資料 migration 為 'ssp') |
'ssp' 或 'module_frame' |
scope_id |
integer |
NOT NULL(既有資料 migration 為 system_security_plan_id) |
對應 scope 表 id(soft FK,無 DB constraint) |
device_id |
integer |
nullable | soft FK → public.devices.id(鉤稽既有 device 時填) |
information_system_id |
integer |
nullable | soft FK → compliance.information_systems.id(鉤稽既有 system 時填) |
title |
varchar(255) |
nullable | OSCAL component.title 人類可讀標題(與 name 區分) |
purpose |
text |
nullable | OSCAL component.purpose 用途說明 |
status |
varchar(50) |
nullable | OSCAL component.status(under-development / operational / disposition / other) |
party_uuid |
varchar(36) |
nullable | OSCAL leveraged-authorization.party-uuid(型別對齊既有 oscal_responsible_parties.party_uuid) |
date_authorized |
date |
nullable | OSCAL leveraged-authorization.date-authorized |
| 欄位 | 變更 | 理由 |
|---|---|---|
system_security_plan_id |
NOT NULL → nullable,CASCADE FK 保留 | scope_type='module_frame' 時此欄為 null |
responsible_party |
不動,標 deprecated(docstring) | 不破壞既有 140 筆資料的寫入;新功能改用 oscal_responsible_parties (polymorphic with context_type='system_implementation')。後續優化資料遷移列入「最後統整優化清單」 |
SystemImplementationType 加 1 個值:
LEVERAGED_AUTHORIZATION = "leveraged-authorization"不加
inventory-item:既有hardware已 cover device 鏡像用途,加inventory-item會兩個 enum 值意義重疊。OSCAL 匯出時由 mapper 把hardware翻譯成 OSCALinventory-item結構,不動 DB enum。
| Index | 欄位 | 用途 |
|---|---|---|
ix_ssp_sys_impl_scope |
(scope_type, scope_id) | 依 scope 查詢 |
ix_ssp_sys_impl_device_id |
device_id | 依 device 反查 |
ix_ssp_sys_impl_info_system_id |
information_system_id | 依 information_system 反查 |
COMMENT ON TABLE oscal.system_security_plan_system_implementations IS
'OSCAL system-implementation 多型鏡像表(v4 擴充:scope_type 區分 ssp / module_frame)。
implementation_type 區分 hardware (device 鏡像) / component (information_system 鏡像) /
leveraged-authorization / system / subsystem / service / software。';GRANT SELECT, INSERT, UPDATE, DELETE ON oscal.system_security_plan_system_implementations TO cm_app;
-- sequence 既有,不需要重複 GRANTUPDATE oscal.system_security_plan_system_implementations
SET scope_type = 'ssp',
scope_id = system_security_plan_id
WHERE scope_type IS NULL; -- ADD COLUMN 後既有 row 此欄為 null
-- 驗證
SELECT COUNT(*) FROM oscal.system_security_plan_system_implementations
WHERE scope_type = 'ssp' AND scope_id IS NOT NULL;
-- 預期 140implementation_type 維持 hardware(不轉 inventory-item)responsible_party 既有純文字保留system_security_plan_id 既有資料維持指向原 SSP(CASCADE FK 保留)dev 期間走 poetry path dependency(主專案
pyproject.toml改 path 指本地 source),Phase 2 完成後一次性 bump 版本推 Nexus。
jedi_oscal/infra/model/ssp/ssp_system_implementation.py:
加 9 個 Mapped[] column 對應 §3.1;system_security_plan_id 改 nullable=True;補 3 個 Index。
jedi_oscal/domain/entity/ssp/:
SspSystemImplementationEntity 加 9 個 attributeSspSystemImplementationQueryEntity 加 scope_type / scope_id / device_id / information_system_id 篩選欄位jedi_oscal/infra/repository/ssp/ssp_system_implementation_repo_impl.py:
list_by_scope(scope_type, scope_id) / find_by_device_id(device_id) / find_by_information_system_id(info_system_id)jedi_oscal/infra/mapper/ssp/system_implementation_mapper.py:
entity ↔︎ model 對應 9 個新欄位的雙向 mapping
jedi_oscal/infra/mapper/ssp/ssp_yaml_mapper.py:
依 implementation_type 分支序列化:
hardware → OSCAL inventory-items[*](含 uuid / description / props(補 device_id soft ref))component / software / service 等 → OSCAL components[*](含 type / title / description / purpose / status)leveraged-authorization → OSCAL leveraged-authorizations[*](含 title / party-uuid / date-authorized)jedi_oscal/app/dto/ssp/ssp_system_implementation_dto.py:加 9 個欄位。
jedi_oscal/common/enum/code_enum.py:SystemImplementationType 加 LEVERAGED_AUTHORIZATION = "leveraged-authorization"。
A0 不改變既有 caller 的寫入行為(既有 caller 不寫新增的 9 欄,全部 nullable 預設 null)。但要驗證:
project_device_mapping_servicehardware row 流程不變ssp_versioning_servicesystem_security_plan_id 改 nullable 後不影響既有複製邏輯grep 全 repo 確認沒有 hard-code 假設 system_security_plan_id 為 NOT NULL 的 query。
| 測試類別 | 範圍 |
|---|---|
| Migration test | 跑 migration → 驗證既有 140 筆 scope 已補;驗證新欄位為 null;驗證 enum 已加 leveraged-authorization |
| ORM CRUD | 新欄位讀寫測試(scope / device_id / information_system_id / title / purpose / status / party_uuid / date_authorized) |
| Repository query | list_by_scope / find_by_device_id / find_by_information_system_id 三個新 method |
| Mapper round-trip | entity ↔︎ model 雙向 mapping 完整性 |
| OSCAL YAML serialize | implementation_type 三分支(hardware / component / leveraged-authorization)序列化正確 |
| 既有 caller regression | project_device_mapping_service + ssp_versioning_service 既有測試跑通 |
| 不做 | 理由 / 何時做 |
|---|---|
| Excel parser / 匯入流程 | A2 |
| 鉤稽(match)演算法 | A3 / A4 |
| Confirm 寫入 service(含 inline 新建 device) | A5 |
| docx generator | B1 / B2 |
| OSCAL JSON / XML serialize(YAML 以外) | B5 — A0 只擴充 yaml_mapper,JSON/XML 另案 |
responsible_party 既有純字串資料遷移到 oscal_responsible_parties |
列入「最後統整優化清單」 |
既有 hardware 是否完全淘汰改 inventory-item |
列入「最後統整優化清單」 |
| Frontend 改動 | A5 / B6 |
實作開工前需 verify:
A0 視為 shipped 的條件:
project_device_mapping_service + ssp_versioning_service) integration 測試通過