| 項目 | 內容 |
|---|---|
| 目標 | 讓 table 欄位名直接等於 OSCAL 規範名,後人零 mapping 表即可對應 |
| 原則 | additive only——保留既有 FK / soft-ref 欄位(內部 join 用),新增 OSCAL 同名欄位(規範對應 + 匯出用) |
| 命名規則 | OSCAL 連字號欄位名 → snake_case(import-profile → import_profile) |
| 來源 | 官方 sample github.com/usnistgov/oscal-content/examples/*/json/(已爬,欄位名見 §1) |
| 影響 | jedi-oscal(ORM + DDL)+ 3 DB 環境(dev/stg/poc);POA&M 部分在 BE compliance.poams |
| 規範 | 套件異動前 user 點頭、path-dep dev、user 明示才發版;migration 用 cmmgr、加日期註解、INSERT schema_migrations |
⚠️ ORM 欄位與 migration 必須同時上:SQLAlchemy 查詢帶所有 mapped column,只加 model 不加 DB 欄會讓該表所有查詢炸。故每個欄位 = model 改動 + migration + 套 3 環境,綁定執行。
跨文件參照(import 類,本計畫主體):
| 模型 | OSCAL 欄位 | sample 實值 | 指向 |
|---|---|---|---|
| SSP | import-profile.href |
"#b78aa3ec-915d-…" |
Profile(經 back-matter resource rlink 到 catalog/profile) |
| AP | import-ssp.href |
"../../ssp/xml/ifa_ssp.xml" |
SSP |
| AR | import-ap.href |
"../../ap/xml/ifa_assessment-plan.xml" |
AP |
| POA&M | import-ssp.href |
"../../ssp/xml/ifa_ssp.xml" |
SSP |
文件內參照(intra-doc,OSCAL 同名 key,供 §3 廣域對齊參考):
| OSCAL key | 出現處 | 我們現況 |
|---|---|---|
component-uuid |
implemented-component / by-component | 未建模 by-component;implemented-component 以 int component_id join |
party-uuid / party-uuids |
leveraged-authorization / responsible-party | party_uuid ✅ 已同名 |
role-id / role-ids |
responsible-role / user | role_id ✅ 已同名 |
control-id |
implemented-requirement / reviewed-controls | control_identifier(SSP)/ control_id(AP/AR ✅) |
statement-id |
statement | statement_identifier |
param-id |
set-parameter | 未建模 set-parameter |
observation-uuid / risk-uuid / finding-uuid |
related-* | 未建模 observation/risk;ar_finding_id(int) |
命名啟示:我們有些欄位早已與 OSCAL 同名(
party_uuid/role_id/control_id);落差主要在 import 類(存內部 id)與尚未建模的結構(by-component / observation / risk,屬 FR-037 §0 Tier C)。
每欄存「被參照文件的 UUID」(非 int id),匯出時合成 href="#<uuid>";既有 FK / soft-ref 保留不動。
oscal.ssps.import_profile(user 指定的 worked example)# jedi_oscal/infra/model/ssp/ssp.py — 新增於 profile_id 之後
import_profile: Mapped[Optional[uuid.UUID]] = mapped_column(
UUID(as_uuid=True),
nullable=True,
comment="OSCAL import-profile.href 指向的 Profile UUID(規範同名欄位;href 合成為 #<uuid>)",
)uid(= profiles.uid,可由現有 profile_id 解析回填)。profile_id(FK,內部 join)。兩者並存——profile_id 內部用、import_profile 規範/匯出用。UPDATE oscal.ssps s SET import_profile = p.uid FROM oscal.profiles p WHERE p.id = s.profile_id;oscal.assessment_plans.import_sspimport_ssp: Mapped[Optional[uuid.UUID]] = mapped_column(
UUID(as_uuid=True), nullable=True,
comment="OSCAL import-ssp.href 指向的 SSP UUID(規範同名欄位)",
)ssps.uid。保留 ssp_id(現存 stringified int,僅追溯)。ssp_id 是 stringified int → UPDATE … SET import_ssp = s.uid FROM oscal.ssps s WHERE s.id = CAST(ap.ssp_id AS INTEGER)(注意空值 / 非數字防呆)。oscal.assessment_results.import_apimport_ap: Mapped[Optional[uuid.UUID]] = mapped_column(
UUID(as_uuid=True), nullable=True,
comment="OSCAL import-ap.href 指向的 AP UUID(規範同名欄位)",
)assessment_plans.uid。保留 assessment_plan_id(FK)。UPDATE … SET import_ap = ap.uid FROM oscal.assessment_plans ap WHERE ap.id = ar.assessment_plan_id。compliance.poams.import_sspPOA&M 在 BE 不在 jedi-oscal,且為扁平 per-finding 表。若要對齊可加 import_ssp(SSP uuid)。建議獨立評估,不綁本批。
若要連 intra-doc 參照也對齊,多數綁在「尚未建模的結構」上(FR-037 §0 Tier C),應與那批一起做,而非單純改名:
component_uuid:須先有 by-component 表。observation_uuid / risk_uuid / finding_uuid:須先有 observation / risk 表(AR)。statement_identifier → 是否補一個 statement_id 同名欄、control_identifier → control_id:純改名 additive,可做但效益低(語意已清楚)。scripts/sql/2026-06-10-oscal-import-ref-columns.sql:ALTER TABLE ADD COLUMN ×3 + 回填 UPDATE + GRANT(新欄不需額外 grant,但確認)+ INSERT schema_migrations。psql --single-transaction -v ON_ERROR_STOP=1)。#uuid)。若需支援匯入「外部 OSCAL 文件」(target 不在我們 DB,href 是外部 URL),另需 import_*_href(String) 存原始 href——是否納入?