| 日期 | 2026-06-12 |
| 階段 | 設計(design-only),無 code、無 commit、未部署 |
| branch | feature/oscal-refactor |
| 主產出 | docs/features/FR-037-2606-oscal-schema-gap-audit/oscal-catalog-and-roots-schema.sql(1828 行 / 45 表 / 673 欄,未追蹤) |
| 次產出 | OSCAL skill 補逐欄 outline(~/.claude/skills/oscal-knowledge/,家目錄、非版控) |
| 用途 | user 要把 SQL 匯入 dbdiagram.io 檢視 + 請另一個 AI 審查 |
給審查者/下個 session:這份 handoff 自包含。先讀 §2(鎖定規則)→ §4(判斷點,重點審這裡)→ §5(待決策)。SQL 檔本身每表每欄都有中文 COMMENT。
把 OSCAL v1.2.2 八大 model 從巢狀 JSON 攤平成 PostgreSQL 關聯式 schema,全寫進單一檔 oscal-catalog-and-roots-schema.sql(schema 命名空間 oscal)。45 表涵蓋:共用核心、完整 Catalog 樹、8 root、Profile imports、SSP 完整子樹、Component-Def、AP、AR、POA&M、Mapping。深層宣告式/leaf 結構依判準留 JSONB。必填/選填全部對著官方 v1.2.2 JSON Schema 的 required 陣列逐欄校對(非憑記憶)。
這是純設計產物,沒碰任何產品 code,沒 commit。 不要當成已實作。
docs/features/FR-037-2606-oscal-schema-gap-audit/oscal-catalog-and-roots-schema.sql
docs/reference/oscal_model_schemas/ — 本次補齊到 8 份(新增 component/poam/mapping,從 OSCAL v1.2.2 release 下載)。
~/.claude/skills/oscal-knowledge/,非版控)references/json-schemas/ — 8 份原始 v1.2.2 JSON Schema。references/model-schemas/<model>-outline.md — 8 份逐欄 outline(required/cardinality/說明,程式化從 schema 產出,anyOf/allOf 分支已併入)+ README.md + gen_oscal_outlines.py(可重產)。SKILL.md 頂端新增「⭐ 精確 Schema / 必填欄位」索引段。oscal-relational-schema-shared-and-catalog.sql(同夾,舊版藍本,本次未動)— 設計慣例與新檔不同,以新檔 oscal-catalog-and-roots-schema.sql 為準。id,BIGSERIAL,autoincrement。鐵律。id(NCName,如 ac-2)存成 {model}_id(control_id/group_id/part_id/param_id/role_id)。只有 id 前綴;name/class 等其他欄維持 OSCAL 原名。Root 帶 uuid(非 token)。id(serial PK),不指 token。class → DB "class"(加引號);values/select/end 等保留字改名或加引號(param_values、"end")。OSCAL metadata → ORM attr metadata_,FK 欄 metadata_id。required [1]/[1..*] → 欄位 NOT NULL;選填 → nullable。系統/結構/產品欄(id/FK/sort_order/status/audit)的 NOT NULL 與 OSCAL 無關,註解標明。#uuid)。三種情況:
| Section | Model | 表 | 數 |
|---|---|---|---|
| A | 共用核心 | metadata / roles / parties / resources | 4 |
| B | Catalog | catalogs / catalog_groups / catalog_controls / catalog_control_parts / catalog_control_params | 5 |
| C | 8 root | catalogs(同上) / profiles / component_definitions / system_security_plans / assessment_plans / assessment_results / poams / mapping_collections | 8 |
| C2 | Profile | profile_imports | 1 |
| D | SSP | ssp_system_characteristics / ssp_information_types / ssp_diagrams / ssp_system_implementations / ssp_leveraged_authorizations / ssp_system_users / ssp_components / ssp_inventory_items / ssp_control_implementations / ssp_implemented_requirements / ssp_statements / ssp_by_components | 12 |
| E | Component-Def | cd_components / cd_capabilities / cd_control_implementations / cd_implemented_requirements / cd_statements | 5 |
| F | Assessment Plan | ap_reviewed_controls / ap_local_objectives / ap_assessment_activities / ap_tasks | 4 |
| G | Assessment Results | ar_results | 1 |
| G2 | assessment-common | assessment_observations / assessment_risks / assessment_findings(AR+POA&M 共用) | 3 |
| H | POA&M | poam_items | 1 |
| I | Mapping | mappings / mapping_maps | 2 |
catalogs 同時列在 B 與 C(同一張表),故獨立表數 = 45。
AO(Assessment Object)定案:catalog 層 AO = catalog_control_parts 中 name IN (assessment-objective, assessment-method, assessment-objects, objective) 的列(OSCAL 把 AO 建模為 part,無獨立 assembly)。專案 runtime AO 屬 AP 層(objectives-and-methods,ap_local_objectives)。idx_catalog_parts_ao (catalog_control_id, name) 供快查。
import_*_href NOT NULL + import_*_id nullable(顛倒)→ 改 import_*_id NOT NULL 為真實 anchor、href 整欄移除(關聯式裡關係=FK,href 是序列化概念,匯出時衍生)。POA&M 的 import-ssp OSCAL 選填 → import_ssp_id nullable。anyOf 包欄位,產生器原本跳過 → 已修(collect() 併 anyOf/allOf 分支)並重產 8 outline。這影響過設計依據,審查者若用 skill outline 請確認是修正後版本。catalog_control_parameters→catalog_control_params、part_name→name(規則 2 只前綴 id)。ar_result_id / poam_id 兩個 nullable owner FK(擇一)。替代方案:各開一套(6 表)。status 欄(8 root 的產品生命週期欄):user 說「重新設計、不考慮現行產品」→ 傾向移除(OSCAL 無此欄;要表達放 metadata.props)。尚未移除,等 user 最終確認。provenance 已補(JSONB NOT NULL);mapping 是 OSCAL 實驗性 model,確認是否真要做。psql 跑過。下個 session 若要落地,先在空白 schema 試跑。"class"/"end" 加引號欄、多型 nullable FK 等,dbdiagram 解析行為未驗。cd ~/Projects/Billows/Audit-Manager/compliance-manager-be/docs/features/FR-037-2606-oscal-schema-gap-audit/
f=oscal-catalog-and-roots-schema.sql
# 表數(應 45)
grep -cE '^CREATE TABLE oscal\.' $f
# FK 順序(應無 forward-reference)+ 全欄註解(應 0 缺):見本 arc 用過的 python 檢查
# (或直接 psql 在空白 schema 試跑驗證可建表)
# 對照官方 required:每個 model 的逐欄 outline 在 skill
ls ~/.claude/skills/oscal-knowledge/references/model-schemas/
# 例:某表某欄該不該 NOT NULL → 查對應 <model>-outline.md 的 required 標記審查建議:拿 ~/.claude/skills/oscal-knowledge/references/model-schemas/<model>-outline.md(authoritative,從官方 schema 程式化產出)逐表對 SQL —— 重點查 (a) 每個 OSCAL required [1] 是否 NOT NULL、(b) props/links 是否只在有的物件上、(c) 參照欄是 FK 還是 token(依 §2 規則 8)、(d) JSONB 折衷是否合理。
scripts/extract_claude_sessions.py)。status、定 assessment-common 共用法、補/不補 AP deferred)。<model>-outline.md 逐表複驗 required/props-links/參照(§7)。psql --single-transaction -v ON_ERROR_STOP=1 -f <檔> 試跑驗證可建表;再轉 SQLAlchemy 2.0 model(含 AuditMixin、PartColumnsMixin 之類共用欄 mixin)。本 handoff 自包含。SQL 檔每表每欄有中文 COMMENT,dbdiagram.io 匯入後 hover 可見。