SSP 匯入與專案啟動完整流程
白話參考文件 — 涵蓋「新增資源庫 → 匯入 Word / Excel → 啟動專案」全 BE 寫入路徑|文件日期:2026-05-25
一、核心概念與名詞對照
系統把 OSCAL 規範對應到三個層次,每個層次有自己的「樣板 (template)」跟「實例 (instance)」。
搞懂這三層,整個匯入流程就好理解。
層次 OSCAL 對應 系統名稱 白話說明
控制項層 Catalog 合規框架 (oscal_frameworks) NIST 800-171 / CMMC L1 / ISO 27001 等控制項全集
樣板層 Profile 合規資源庫 (module_frame) 從 Catalog 挑選一組 controls + 預設「責任單位」「外部利用服務」等「樣板資料」
實作層 SSP 樣板 SSP (template SSP) + 專案 SSP 樣板 SSP 跟 module_frame 1:1,內容是「樣板資料」實體儲存所在;專案啟動時 clone 出新 SSP 給專案用
評估層 AP / AR 評估計畫 (assessment_plan) / 評估結果 (assessment_result) 專案啟動後產生,driving 整個稽核工作流
三段流程的關係(資料流方向)
【Step A】 新增合規資源庫 (module_frame)
│
│ 建立空 profile + 空樣板 SSP shell
▼
【Step B】 匯入 Word / Excel
│
│ 把文件解析後的內容(責任單位 / 人員 / 利用授權 /
│ 元件 / 資產 / 控制項)寫進樣板 SSP(同個 module_frame)
▼
【Step C】 啟動專案
│
│ 以 profile 為基準 clone 新 SSP / 建 AP / 建 AR /
│ per task clone workflow_template / 建 workflow_execution
▼
專案進入 PENDING 狀態,user 可開始稽核任務
二、Step A:新增合規資源庫 (Module Frame)
入口 1:手動建立(FE「合規資源庫 → 新增 → 從合規框架挑選」)
入口 2:從 docx/Excel 自動建立(會走 Step B 內的 superset flow,內部呼叫此方法)
入口 3:YAML import (歷史功能)
核心 service :ModuleFrameService.add_module_frame()(app/module_frame/service/module_frame_service.py:121)
執行步驟(單一 @transaction)
1 檢查名稱不重複 READ
查 public.module_frames WHERE name=?,已存在則 raise ConflictError。
2 取得 OSCAL Framework Version READ
依 payload.oscal_framework_version_uid 查 oscal.oscal_framework_versions,順帶取得對應的 catalog.uid。
這就是「CMMC Level 1」「CMMC Level 2」這類版本選擇實際對應的紀錄。
3 建立 OSCAL Profile INSERT
呼叫
OscalProfileService.add_profile(),寫入兩張表:
oscal.profiles:含 title (= module_frame.name) / catalog_uid / status='draft'
oscal.profile_controls:依 include_controls 從 catalog 挑控制項(空 list = 全納入)— 每筆 control 一 row
4 建立 ModuleFrame 主檔 INSERT
寫入 public.module_frames:name / group / version / description / frequency / provider / oscal_framework_version_uid / oscal_profile_uid(指向 Step 3 建的 profile)。
5 為每個 Assessment 建 Workflow Template INSERT
遍歷 profile 的所有控制項 (
profile_controls),對每個控制項的所有 catalog assessment object 建一個 BPMN workflow template:
workflow_templates(jedi_flow_engine):每個 assessment 一筆 template,含「上傳證據」「Reviewer 審核」等預設 BPMN nodes
oscal.profile_assessment_workflow_mapping:建立「profile_control × catalog_control_assessment × workflow_template」三方關聯
注意 :若控制項沒任何 assessment object(很少見),系統會塞一個預設「Evidence upload」task 進去;確保每個 control 至少有 1 個 workflow。
Step A 完成後 DB 狀態
# Table Schema 寫入動作 每次呼叫筆數
1 oscal.profilesoscal INSERT 1
2 oscal.profile_controlsoscal INSERT N (控制項數)
3 public.module_framespublic INSERT 1
4 public.workflow_templatespublic INSERT M (assessment 數)
5 oscal.profile_assessment_workflow_mappingoscal INSERT M (1:1 對應 workflow_template)
白話總結 :建好 module_frame 後,這個資源庫已經有「控制項清單」+「每控制項對應的 BPMN 流程模板」,但還沒有任何樣板資料 (單位/人員/外部服務/元件/資產)。樣板資料要靠 Step B 匯入 Word/Excel 填,或 user 在 template-edit 頁手動填。
三、Step B:匯入 Word / Excel(兩階段:解析 → 確認)
系統匯入流程拆兩階段:
解析 (parse) :上傳檔案 → BE 抽取內容 → 存 JSONB 暫存 → 跳預覽頁
確認 (confirm) :user 在預覽頁微調 → BE 寫入正式表
Word (docx) 跟 Excel (xlsx) 的「解析」邏輯不同(parser 各一套),但「確認」階段對「外部利用服務 / 元件 / 資產」三類資料共用同一條 path (
SspImportConfirmService) — Bug A/D 修完後完全對齊。
3.1 解析階段(共用:建 parse_job + 寫 parsed_result JSONB)
P1 建 parse_job INSERT
Excel → oscal.ssp_excel_parse_jobs
Docx → oscal.ssp_docx_parse_jobs
兩張表 schema 類似:id / status / source_type / source_uid / framework / template_version / file_path / parsed_result (JSONB) / created_at。
Status 從 parsing → awaiting_review → completed / failed / expired(24h TTL)。
P2 檔案存到 MinIO / 本地 INSERT
透過 jedi-file-upload 套件,原始檔上傳到 storage,parse_job.file_path 存 file_uid (對應 uploaded_files 表)。
P3 Parser 抽取內容 UPDATE
Excel :依 v3.0.0 樣板 8 個 sheet(基本資料 / 受評標的 / 單位 / 參與人員 / 利用授權 / 元件清冊 / 資產清冊 / 控制項與AO / 程序書)抽 row dict → 組 ParsedExcel
Docx :依 CMMC SSP 樣板 section anchor 抽 metadata / parties / Table #6 (FedRAMP 外部服務) / Table #7 (Category 外部服務) / 控制項 narrative
抽完寫進
parsed_result JSONB(schema_version=
v2-bundle);status 改
awaiting_review,FE 跳預覽頁。
3.2 確認階段(依 source_type 分三條 flow)
source_type 是 FE 在「上傳」前選的,決定 confirm 階段寫到「誰」:
framework_version = 從框架建新樣板 (superset flow)— 內部呼叫 Step A 的 add_module_frame()
module_frame = 更新既有資源庫的樣板 (update flow)— 不動 mf 基本欄位 / 寫 entity 樣板資料
ssp = 更新指定 SSP (per-AP SSP 編輯)— 不動 mf / 寫到該 SSP 的 entity 表
Flow B-1:framework_version(從框架建新資源庫,superset flow)
B1a 套 user 在預覽頁的編輯 UPDATE
四個 helper 依序套用:_apply_content_overrides(user 改字串)→ _apply_inline_creates(user 新建 device/user/...)→ _apply_decisions(user 選下拉框)→ _apply_removed_rows(user 標記不匯入的 row)。全在同個 @transaction 內,失敗整段 rollback。
B1b 呼叫 Step A 建立 MF + Profile + Workflow templates INSERT
內部呼叫 ModuleFrameService.add_module_frame()(就是 Step A 那套),所以 Step A 的 5 張表都會建。include_controls 從 controls_with_aos 篩 _target_in_profile=true 那批,限縮 profile 範圍。
B1c 確保 Template SSP shell 存在 INSERT
對 module_frame 來源的匯入,須有一個「樣板 SSP」承載責任單位 / 利用授權 / 元件 / 資產等資料:
oscal.oscal_metadatas:SSP metadata
oscal.system_security_plans:template-level SSP shell(連 profile_id / status=draft)
(Bug A fix 後新增的 path,見
SspShellService.ensure_shell())
B1d 寫責任單位 / 人員(Parties)INSERT
透過
ModuleFrameWriteStrategy.write_parties:
oscal.oscal_parties:每筆 party 一 row(含 name / email / address / telephone / party_type / role)
oscal.oscal_responsible_parties:建立 mf ↔ party 的「責任角色」link(含 role_id / party_uuid / context_type='module_frame' / context_id=mf_id)
Bug B fix :docx 解出來的 person 沒 role 欄位時 fallback default role(org → responsible-organization, person → system-user);否則 _upsert_responsible_party 在空 role 會 silent return,link 表完全沒寫。
B1e 寫利用授權 / 元件 / 資產(v2-bundle dispatch)INSERT
透過
SspImportConfirmService.confirm() 內三 strategy 按序:
LeveragedWriteStrategy.write → oscal.ssp_leveraged_authorizations(overwrite 模式 — 先 delete 既有,再 insert)
ComponentWriteStrategy.write → oscal.ssp_components(含 leveraged_authorization_uid FK resolve)
InventoryItemWriteStrategy.write → oscal.ssp_inventory_items + M2M oscal.ssp_inventory_item_components
順序固定(FK 依賴:inventory → component → LA)。
Bug D fix :docx Table #7 (Category) 行除了 emit Component 之外也 emit LA(用 props JSONB 帶 category / protocol / port_ranges / security_auth 等 non-OSCAL fields),與 Table #6 (CSP/CSO) 對稱。修前 4 筆只寫 1 LA。
B1f 寫控制項 narrative / 受評標的 (SC) INSERT
oscal.system_security_plan_control_implementations:每控制項 narrative
oscal.system_security_plan_control_implementation_objectives:每 AO 的 narrative / impl_status
oscal.system_security_plan_system_characteristic:受評標的(system_name / security_sensitivity_level / status)
B1g 寫 import_summary + parse_job 收尾 UPDATE
parse_job status → completed,summary 寫進 import_summary JSONB;回傳 mf_uid / profile_uid 給 FE。
Flow B-2:module_frame(更新既有資源庫)
跟 B-1 差異:
不建新 MF / Profile — 直接抓現有 mf
呼叫 ModuleFrameService.update_module_frame() 更新 mf 基本欄位 + profile include_controls
B1d~B1f 全跑(樣板 SSP entity overwrite 重寫)
Flow B-3:ssp(per-AP SSP 編輯)
跟 B-1 差異:
不建 / 不動 mf / profile
Parties 寫 context_type='ssp'(連到該 ssp_id,不是 mf)
B1e + B1f 都寫到指定 SSP(job.source_uid = ssp_uid)
3.3 Word 跟 Excel 的差異一覽
項目 Word (docx) Excel (xlsx)
解析方式 section anchor + 內表抽取 固定 sheet 名 / column index
外部利用服務拆 table Table #6 FedRAMP + Table #7 Category(兩 table)Bug D fix 後 兩 table 都 emit LA 單一 利用授權 sheet,每行 1 LA
Parties role 預設值 抽不到 role 時 fallback (Bug B fix 後) SHEET_PERSONS 有 role enum 欄位,user 直接選
樣板版本檢查 有 GRC_DOCX_FRAMEWORK_MISMATCH 守門 有 GRC_EXCEL_TEMPLATE_VERSION_UNSUPPORTED (v2.x 拒絕)
props 欄位 T7 自動帶 category / protocol / security_auth 等 目前 sheet 沒帶 category 欄位 → LA.props 多半 NULL(cross-source 不一致,列 follow-up)
四、Step C:啟動專案(建立 AP / AR / Workflow)
入口:POST /api/1.0/oscal/projects/start → OscalProjectService.start_oscal_project()
整個方法單一 @transaction;除 Step 7 有 try/except 外,任何失敗整段 rollback。
寫入 21 張表 (含某些表多次寫入)。
Request Payload
{
"profile_uid": "required — OSCAL Profile UID (對應 module_frame.oscal_profile_uid)",
"ssp_uid": "optional — 既有 SSP UID;不傳則自動建新 SSP",
"name": "required — 專案名稱",
"description": "optional",
"start_date": "optional — YYYY-MM-DD",
"end_date": "optional — YYYY-MM-DD"
}
執行步驟
1 檢查專案名稱不重複 READ
查 compliance.projects WHERE name=?。
2 取得 Profile READ
查 oscal.profiles WHERE uid=?,找不到 raise NotFound。
3 取得或建立 SSP INSERT (optional)
若無 ssp_uid → 呼叫
SspService.add_empty_ssp(profile_id):
oscal.oscal_metadatas:SSP metadata(每 OSCAL 模型必有 metadata)
oscal.system_security_plans:SSP 主檔(連 profile_id)
4 建立 Assessment Plan (AP) INSERT
oscal.oscal_metadatas:AP metadata
oscal.assessment_plans:AP 主檔(status=ACTIVE,連 profile + ssp)
4.5 建立空白 Assessment Result (AR) INSERT
oscal.oscal_metadatas:AR metadata
oscal.assessment_results:AR 主檔(連 AP)
oscal.assessment_result_datas:初始 run_no=1
5 建立 Project 主檔 INSERT
compliance.projects(status=PENDING)— 走 jedi-project 套件。
6 建立 Project ↔ AP 關聯 INSERT
compliance.project_assessment_plan_mapping。
7 初始化 AP Controls / Groups / Tasks INSERT try/except
從 Profile→Catalog 把控制項清單 clone 到 AP:
oscal.assessment_plan_groups:每 catalog group 一 row
oscal.assessment_plan_controls:每 control snapshot 一 row(凍結 title / control_id)
oscal.assessment_plan_tasks:每 control assessment 一 row(task_code / title / assessment_methods)
oscal.assessment_task_controls:task ↔ control 關聯
⚠️ 風險點 :此 step 被 try/except 包,失敗只 log 不 raise → AP tasks 為空 → Step 8 的 for loop 不執行 → 整個專案沒任何 workflow。但因為其他 step 已 commit,user 看 project 是 PENDING 但無法做任何任務 。詳見「六、流程資料問題檢查」。
8 為每個 AP Task 建立 Workflow(per task loop) INSERT silent continue
每個 task 依序執行:
查 workflow_template mapping :oscal.profile_assessment_workflow_mapping。找不到 → silently continue(該 task 永遠沒 workflow)⚠️
Clone workflow_template (避免之後改 template 影響已啟動的專案):workflow_templates (parent_template_id 指向原始)
建 Workflow Execution :workflow_executions(type=SUB_PROCESS, status=TODO)+ 遞迴處理巢狀 → 為每個 BPMN User Task 建 job_executions + element_variables(PROCESS / TASK 兩種)
建 AP task ↔ Workflow Template 關聯 :oscal.assessment_plan_task_workflow_mapping
建 AP task ↔ Workflow Execution 關聯 :oscal.assessment_plan_task_workflow_execution_mapping
9 創建者加入專案管理員 INSERT UPDATE
compliance.project_participants INSERT(is_admin=True)
oscal.oscal_metadatas UPDATE — 把 user 當 Person party 加進 SSP metadata 的 parties 列表
呼叫鏈視覺化
POST /oscal/projects/start
│
└─ OscalProjectService.start_oscal_project() [@transaction]
│
├─ Step 1: 名稱檢查 → READ compliance.projects
├─ Step 2: Profile 取得 → READ oscal.profiles
├─ Step 3: SSP get/add → INSERT oscal_metadatas, system_security_plans
├─ Step 4: AP add → INSERT oscal_metadatas, assessment_plans
├─ Step 4.5: AR add → INSERT oscal_metadatas, assessment_results,
│ assessment_result_datas
├─ Step 5: Project add → INSERT compliance.projects
├─ Step 6: Project↔AP → INSERT project_assessment_plan_mapping
│
├─ Step 7: init AP controls [try/except]
│ → INSERT ap_groups, ap_controls, ap_tasks, assessment_task_controls
│
└─ Step 8: for task in ap.tasks (若 Step 7 失敗則 0 iter)
├─ READ profile_assessment_workflow_mapping (找不到 → continue)
├─ INSERT workflow_templates (clone 定版)
├─ INSERT workflow_executions + element_variables + job_executions
└─ INSERT assessment_plan_task_workflow_mapping
assessment_plan_task_workflow_execution_mapping
└─ Step 9: add participant → INSERT project_participants
UPDATE oscal_metadatas (SSP parties)
五、所有寫入 Table 總覽表
5.1 Step A:新增合規資源庫
# Table Schema 套件 動作 說明
1 profilesoscal jedi_oscal INSERT 樣板 profile 主檔
2 profile_controlsoscal jedi_oscal INSERT × N 每控制項一 row
3 module_framespublic main INSERT 資源庫主檔
4 workflow_templatespublic jedi_flow_engine INSERT × M 每 assessment 一筆 BPMN template
5 profile_assessment_workflow_mappingoscal main INSERT × M profile_control × assessment × template 三方關聯
5.2 Step B:匯入 Word / Excel(完整 superset / module_frame flow)
# Table Schema 動作 說明
解析階段
P1 ssp_excel_parse_jobs / ssp_docx_parse_jobsoscal INSERT parse_job 主檔
P2 uploaded_files(jedi) INSERT 原始檔 storage record
P3 同上 (parse_job) oscal UPDATE parsed_result JSONB + status=awaiting_review
確認階段 — superset (建新 mf)
C1~C5 同 Step A 的 5 張表 — INSERT 內部呼叫 add_module_frame
C6 oscal_metadatasoscal INSERT 樣板 SSP metadata
C7 system_security_plansoscal INSERT 樣板 SSP shell(Bug A fix 後新增)
確認階段 — entity 樣板資料寫入
C8 oscal_partiesoscal INSERT/UPSERT 每筆 party 一 row
C9 oscal_responsible_partiesoscal INSERT mf ↔ party 角色 link(context_type=module_frame)
C10 ssp_leveraged_authorizationsoscal DELETE + INSERT overwrite 模式
C11 ssp_componentsoscal DELETE + INSERT 每元件一 row,含 leveraged_authorization_uid FK
C12 ssp_inventory_itemsoscal DELETE + INSERT 每資產一 row
C13 ssp_inventory_item_componentsoscal INSERT 資產 ↔ 元件 M2M
C14 system_security_plan_control_implementationsoscal INSERT 控制項 narrative
C15 system_security_plan_control_implementation_objectivesoscal INSERT AO narrative + impl_status
C16 system_security_plan_system_characteristicoscal INSERT 受評標的
C17 module_frame_reference_documentsoscal INSERT 程序書 (若 Excel 有填)
收尾
C18 parse_job (same as P1) oscal UPDATE status=completed + import_summary JSONB
5.3 Step C:啟動專案
# Table Schema 套件 動作 說明
1 oscal_metadatasoscal jedi_oscal INSERT SSP metadata
2 system_security_plansoscal jedi_oscal INSERT SSP 主檔
3 oscal_metadatasoscal jedi_oscal INSERT AP metadata
4 assessment_plansoscal jedi_oscal INSERT AP 主檔
5 oscal_metadatasoscal jedi_oscal INSERT AR metadata
6 assessment_resultsoscal jedi_oscal INSERT AR 主檔
7 assessment_result_datasoscal jedi_oscal INSERT AR 初始 run
8 assessment_plan_groupsoscal jedi_oscal INSERT × N AP 群組 (clone)
9 assessment_plan_controlsoscal jedi_oscal INSERT × N AP 控制項 snapshot
10 assessment_plan_tasksoscal jedi_oscal INSERT × M AP 任務
11 assessment_task_controlsoscal jedi_oscal INSERT task ↔ control
12 projectscompliance jedi_project INSERT 專案主檔 (status=PENDING)
13 project_assessment_plan_mappingcompliance main INSERT Project ↔ AP
14 workflow_templatespublic jedi_flow_engine INSERT × M 複製定版 template
15 workflow_executionspublic jedi_flow_engine INSERT (含巢狀) 子流程 instance
16 element_variablespublic jedi_flow_engine INSERT Workflow / Job 變數
17 job_executionspublic jedi_flow_engine INSERT BPMN User Task instance
18 assessment_plan_task_workflow_mappingoscal main INSERT AP task ↔ template
19 assessment_plan_task_workflow_execution_mappingoscal main INSERT AP task ↔ execution
20 project_participantscompliance main INSERT 創建者 = 管理員
21 oscal_metadatasoscal jedi_oscal UPDATE SSP parties 加 user
六、流程資料問題檢查(潛在風險)
以下列出目前流程已知的「設計潛在風險」+「歷史 bug 教訓」,做為日後 review / 維護重點。
6.1 啟動專案:Step 7 silent failure 可能造成 zombie project 高風險
問題 :
init_ap_controls_from_profile 用 try/except 包,失敗只 log 不 raise。
後果 :
AP tasks 完全沒建
Step 8 的 for loop 0 iter(沒 workflow_templates / workflow_executions / job_executions)
但 Step 5/6 已寫 Project + Mapping → commit
User 看到專案是 PENDING 但點進去發現完全沒任務 — 完全 stuck
建議 :拿掉 try/except,讓失敗整段 rollback;或加 post-condition assertion「AP tasks 數 > 0」+ raise。
6.2 啟動專案:Step 8 找不到 workflow_template silently continue 中風險
問題 :profile_assessment_workflow_mapping 查不到對應 → continue,該 AP task 永遠沒 workflow。
後果 :部分 task 無法執行;user 不知道是「該 task 無流程」還是「流程跑爛」。
發生條件 :Step A 建 mf 時某些 assessment 漏建 template(很少見但可能);或 mf 建好後手動刪了 mapping。
建議 :log.warning + 寫入 AP 的 import_warnings;或在啟動前 pre-flight check(缺幾個 task 沒 workflow 立刻 raise)。
6.3 匯入:「parties_written 計數」會騙人 中風險(已部分 fix)
問題(Bug B 教訓) :write_parties return 的計數只算 oscal_parties 寫成功的 row,不驗 oscal_responsible_parties link 是否真的建。Caller 看到 parties_written=5 以為 OK,實際 link 表 0 筆。
已 fix :Bug B 第二段 fix 補 default role;但底層 silent skip pattern (if not X: return) 還在 jedi-oscal 套件內。
建議 :jedi-oscal 進版時改 log.warning 或 raise;strategy.write 加 post-write verification(兩張表 row count 一致才 return)。
6.4 匯入:跨 source 不一致(Word vs Excel)中風險(已部分 fix)
問題(Bug D 教訓) :Word docx Table #7 加 LA props (category / protocol / security_auth),Excel
利用授權 sheet 沒對應欄位 → Excel 匯入的 LA 全部沒 category。
後果 :跨 source 行為差異;UI 顯示 Excel 來源「印表機」category 是 — (空白),docx 來源是「互連」(interconnection)。
建議 :
短期 — Excel 利用授權 sheet 加 category 欄位(enum: external-service / interconnection / api / fedramp)
長期 — 共用 ParsedLA adapter helper,Excel + docx + 未來 OSCAL JSON 都從同個地方 build ParsedLA
6.5 匯入:source_type 三分支(framework_version / module_frame / ssp)有歷史漏洞 已 fix
問題(Bug A 教訓) :早期 docx confirm path 只處理 project_ssp,module_frame 分支整段缺失 → 樣板 SSP shell 從沒建 → entity 寫入全失敗。
已 fix :SspShellService.ensure_shell() 自動 resolve-or-build;docx + Excel 兩 service 都接通。
6.6 匯入:content_overrides 應用順序 vs v2-bundle dispatch 已 fix
問題(Bug C 教訓) :早期 user 在預覽頁編輯後,_apply_content_overrides 改 v1 keys (devices / leveraged) 但 _run_v2_bundle_confirm 讀 v2-bundle keys → user 編輯 silent loss。
已 fix :confirm 內加 derive_v2_bundle_keys(parsed_result) 在 dispatch 前 re-derive。
6.7 設計級風險:Overwrite vs Append 語意混合 設計面
觀察 :LeveragedWriteStrategy 跟 ComponentWriteStrategy 都採 overwrite (先 delete 既有 → re-insert)。但 oscal_parties 跟 oscal_responsible_parties 是 upsert (不刪舊)。
後果 :重複匯入同一份文件,parties 會累積(雖然 idempotent,但留下舊孤立 parties record);leveraged / components / inventory 每次重整。
建議 :明確標註各 strategy 的 overwrite vs upsert 語意;考慮統一行為(user 可選「重整」vs「增補」)。
6.8 設計級風險:跨 schema FK 沒 constraint 設計面
觀察 :compliance.project_assessment_plan_mapping(compliance schema)參考 oscal.assessment_plans(oscal schema),但這條跨 schema FK 沒在 DB 層建 constraint(per CLAUDE.md DDD 規範 — soft Integer reference)。
後果 :刪 AP 不會 cascade 刪 mapping;orphan row 累積。
緩解 :app service 層做手動 cascade;長期可考慮加 trigger 或 cleanup job。
6.9 設計級風險:project_extensions 不在 Step C 內 設計面
觀察 :compliance.project_extensions(含 module_frame_id / owner_id 等 GRC 專屬欄位)由另一個路由維護,不在 Step C 啟動流程內。
後果 :啟動專案後立刻查 project_extensions 會是空 row;GRC 模組需要 project_extensions 才能顯示完整資訊。
緩解 :FE 在「啟動專案」之後立刻 call POST /grc/projects/{uid}/extensions 補;但沒程式碼保證 user 一定點得到。
6.10 設計級風險:parse_job TTL 24h 已設計
機制 :parse_job 預設 24h 後 expire(status → expired),confirm 會被擋。
清理 :背景 scheduler「framework_parse_job_cleanup」每日 01:00 UTC 跑。
建議 :UI 顯示 TTL 倒數計時(目前 schema 有 ttl_expires_at 欄位但 FE 沒 surface)。
七、相關檔案 / 設計文件索引
類別 路徑 用途
Spec docs/features/FR-028-2605-ssp-oscal-alignment/design.mdSSP OSCAL alignment 完整設計(含 §11 reconciliation)
Phase 4 SUMMARY docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-phase4-COMPLETE-SUMMARY.mdPhase 4 收尾 (Excel preview / inline CRUD / 移舊 tab)
Bug D SUMMARY docs/features/FR-028-2605-ssp-oscal-alignment/handoff/2026-05-25-bug-d-FIXED-SUMMARY.mdBug D / E / F 完整 fix
啟動專案邏輯 prompt/oscal_project_start_flow.mdOscalProjectStartRoute 21 表寫入順序
Excel parser app/oscal/service/excel_parser/parser.py / sheet_handlers.py / v2_bundle.py / types.py
Excel sheet schema app/module_frame/excel_template/sheet_definitions.py8 個 sheet 的欄位定義(含 v3.0.0 OSCAL-aligned 重組)
Excel confirm app/oscal/service/ssp_excel_import_app_service.py3 條 flow (superset / update / ssp_update)
Docx parser domain/oscal/parser/docx_section_extractors.pySection anchor 抽取(Table #6 / #7 / parties)
Docx adapter domain/oscal/adapter/cmmc_ssp_adapter.pyParsedDocx → ParsedSsp + adapt_to_bundle (Bug D fix)
Docx confirm app/oscal/service/ssp_docx_import_app_service.pyconfirm_import + _run_v2_bundle_confirm
共用 confirm service domain/oscal/import_pipeline/confirm_service.pyExcel + Docx 共用 LA / Component / Inventory 寫入
Write strategies domain/oscal/service/write_strategy/leveraged / component / inventory write strategy
jedi-oscal 套件 ~/Projects/Jedicogy/module/jedi-python-package/jedi-oscal/OSCAL entity / service / repo(jedi 系列)
OSCAL knowledge skill ~/.claude/skills/oscal-knowledge/OSCAL 8 model 完整 reference
此文件為 SSP OSCAL Alignment feature 收尾參考 ,配合 design.md §11.25 + Bug D SUMMARY 一起閱讀可獲得完整 context。
若流程或表結構日後變更,請同步更新本文件;亦可作為新成員 onboarding 文件。