FR-135 · 第二期 design-cra · 2026-10-12(D1~D17 已裁)
P2-B 表單設定、P2-C 產品版本與風險評估、P2-D CRA 內容(建庫帶預設、評估目標調整、證據來源、文件範本)
第〇步拿自家材料走完 CRA 31 條,露出 CRA 本身要補的內容:受評標的沒地方填用途、分級、支援期;沒有製造商與通報聯絡人;沒有風險評估;7 條一條包多件事;有些證據客戶在系統別頁填完就有、卻要他再上傳。本文件把已裁的 D 項展開到「照做就能交」:資源庫第四件「表單設定」決定 CRA 專案多出哪些欄位與頁籤、製造商與通報聯絡人用 OSCAL 的 Party 與角色、風險評估開新表並對齊 OSCAL 風險物件、顧問從畫面新增 CRA 資源庫時由建庫程式依框架帶入預設內容、評估目標(AO)全面調整為 4 群 34 條 49 個、AO 帶「證據來源」屬性直接連到系統內的頁面。CMMC 專案畫面一點都不變。
狀態:設計定案(D1~D17 已裁,本文件展開 D1 D2 D3 D5 D6 D7 D9 D10 D11 D13 D14 D15 D16 D17)|日期:2026-10-12|平台層(規劃頁條文、無 AO 開工、覆核輪、收證據範本)見
design-platform.md
🔴 這份是設計決策,不是現況。 內文行號是 2026-10-12 的位置,會隨程式漂移;上線後的現況看 SPEC 頁。
| 日期 | 變更 | 對應 |
|---|---|---|
| 2026-10-11 | v1:P2-B/C/D 設計定案 | 母卡 CM-2675 |
| 2026-10-12 | v2:對齊已落地的實作與決策者裁示——建庫帶預設內容機制、程序書與證據分兩套、風險評估「依據標準」、AO 全面調整、AO 證據來源機制;十三張卡附實際 Case No | CM-2705 |
CRA(歐盟網路韌性法,Regulation (EU) 2024/2847)要求製造商回答「你為什麼這樣做、依據是什麼」,不只是逐條打勾。一個 CRA 專案要能留下:圈範圍(用途、誤用、環境、角色、八題適用判定、產品分級)、Annex II 使用者資訊(製造商、漏洞通報窗口、揭露政策網址、產品識別、支援期結束日)、風險評估(威脅、依據標準、資產、衝擊、可能性、既有控制、措施、對應控制項)、產品版本與支援期、評估目標拆分(一條控制項底下要查的幾件具體事情)、證據來源(系統內已有的資料直接當證據,客戶自有的檔才上傳)。
顧問視角:從畫面新增資源庫、框架選 CRA,建庫程式依框架代號 CRA_2024 自動帶入表單設定、Annex II 預設說明、製造商與通報聯絡人兩個空殼、五份文件範本。用這個資源庫建專案,規劃頁就多出 CRA 專用欄位與「風險評估」頁籤,參與單位頁已有兩個空位,程序書池已有範本並掛好控制項。CMMC 資源庫沒有這些預設內容,專案完全不受影響。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
subgraph RL["新增 CRA 資源庫(module_frames)"]
P["① 控制項選集<br/>catalog+profile<br/>(4 群 34 條 49 AO)"]
S["② SSP 範本<br/>Party 空殼/A2.x 預設說明"]
F["③ 稽核流程範本"]
FS["④ 表單設定<br/>form_settings"]
POOL["程序書池<br/>文件範本 5 份"]
end
DEF["framework_library_defaults/<br/>cra_2024.py(建庫時依框架 code 查表)"]
subgraph PJ["CRA 專案"]
SC["受評標的<br/>SC.props ext:cra-*"]
PARTY["參與單位<br/>製造商/通報聯絡人"]
RISK["風險評估表<br/>ssp_risks"]
PLAN["規劃頁<br/>依 sections 開頁籤"]
AOP["AO 面板<br/>證據來源或上傳"]
end
IS["資訊系統盤點<br/>+版本子表"]
DEF -.-> S
DEF -.-> FS
DEF -.-> POOL
P -->|建專案複製| PLAN
S -->|深拷貝| SC
S -->|深拷貝 metadata| PARTY
POOL -->|整池複製+對應| PLAN
F --> PLAN
FS -->|專案讀資源庫設定| PLAN
FS -->|宣告欄位| SC
PLAN -->|頁籤開關| RISK
IS -->|版本與支援期| SC
P -->|AO 屬性 evidence-source| AOP
RISK --> AOP
SC --> AOP
PARTY --> AOP
IS --> AOP
本文件只管 CRA 層;平台層兩項(規劃頁看條文、無 AO 開工)見 design-platform.md,兩份可平行施工。
整案一句話:CRA 專案多出一套 CRA 專用的欄位、角色與風險評估頁,AO 調整為 49 個並可直接連到系統內的證據來源;CMMC 專案一個像素都不變。
| 卡 | Case No | 做什麼 | 規模 | 決策者檢查法 |
|---|---|---|---|---|
| F1 表單設定落點 | CM-2690 | module_frames 加 form_settings 欄、程式驗結構 |
S | DEV 查 CRA 資源庫 form_settings 有值、CMMC 資源庫是 NULL |
| F2 專案取設定端點 | CM-2693 | 兩支 GET 端點:資源庫取、專案 SSP 取 | S | Swagger 打 GET /ssp/<CRA 專案 SSP uid>/form-settings 回欄位清單;打 CMMC 專案回 null |
| F3 前端動態欄位與頁籤開關 | CM-2699 | 受評標的頁依設定渲染擴充欄位;BE 收送 ext_fields/ext_links |
M | CRA 專案受評標的頁多四段、填完重整還在;CMMC 專案畫面不變 |
| F4 建庫帶 CRA 預設 | CM-2700 | create_resource_library 依框架 code 帶表單設定 22 欄、A2.1~A2.9 預設說明、兩個 Party 空殼 |
S~M | 畫面新增 CRA 資源庫:表單設定、預設說明、兩個空角色都在;新增 CMMC 資源庫什麼都沒多 |
| V1 資訊系統版本子表 | CM-2694 | jedi-asset 新子表+CRUD+盤點頁子表格 | M | 盤點任一筆底下新增 v1.0/v1.1,各有上市日與支援期結束日 |
| R1-a 風險評估本體 | CM-2701 | 新表 oscal.ssp_risks、DDD 四層、端點、手填表格 |
M | CRA 專案新增兩筆風險、勾對應控制項、重整還在 |
| R1-b 頁籤開關與依據標準 | CM-2702 | 頁籤依表單設定顯示;「依據標準」下拉讀 system_menus |
S | CMMC 專案看不到頁籤;風險編輯的依據標準有 10 項下拉 |
| C1 AO 拆分範本 | CM-2691 | 首版 AO 拆分文件與套件 seed 004 | S | 打開 md 看拆點與依據 |
| C1b AO 全面調整 | CM-2696 | 新群組、拆條、改句、建議證據三段式掛各 AO、套件 seed 005 | M~L | 框架 4 群 34 條 49 AO;每個 AO 有自己的建議證據 |
| C2 收舊套掛檔+刪舊 clone | CM-2695 | 控制項層舊上傳路徑刪除、詳情改讀程序書池;刪舊 clone 端點 | M | POST /module-frame/clone 回 404;控制項詳情 reference_documents 回池資料 |
| C2b 撤回程序書 locator | CM-2697 | 拔掉加錯層的 locator 欄與前後端帶欄 |
S~M | oscal.ssp_reference_document_mappings 無 locator 欄 |
| C3 文件範本骨架 | CM-2703 | 五份 docx 骨架,建庫時上傳進程序書池並預掛 | S | 新 CRA 資源庫程序書頁有五份、15 條控制項共 16 筆掛載 |
| E1 AO 證據來源機制 | CM-2704 | AO 屬性 evidence-source、解析端點、規劃頁與判定頁依屬性切顯示 |
M | 風險評估那條 AO 面板顯示「證據來源:風險評估頁,已登錄 N 筆」並可跳轉,不顯示上傳區 |
依賴:F1 → F2 → F3 → R1-b;R1-a 與 F3 合流後 R1-b;F4 依賴 F1,畫面等 F3;C3 依賴 F4(共用建庫機制);C1 → C1b → E1;C2 → C2b;V1 隨時可派。
| 項 | 裁示 | 被排除的方案與原因 |
|---|---|---|
| D1 複製資源庫 | 本期範圍外;專案直接讀資源庫的表單設定 | 新做複製服務:要連 catalog、profile、SSP 範本、流程範本、程序書池一起處理,L 級工程,第二期用不到 |
| D2 表單設定落點 | compliance.module_frames 加 JSONB 欄 form_settings,結構檢查在應用層 |
新表 module_frame_form_settings:多 repo、mapper、RLS 政策,最小版用不到每欄一列的約束 |
| D3 專案取設定 | 主專案新端點,不改 jedi-compliance-audit DTO | 改套件 DTO 加欄:要為一個欄位發套件版本、碰其他 consumer |
| D5 公版資源庫 | 公版機制裁撤:不隨安裝出貨 CRA 資源庫、不用 seed CLI;驗收由決策者從畫面新建 CRA 資源庫與專案 | 出貨公版並提供 --rebuild:資源庫是顧問的事,出貨公版要連帶處理既有專案引用 |
| D6 AO 拆分 | 不等顧問;依 ENISA 底稿、第〇步拆點、法條原文自產,標「AI 拆分待顧問確認」,經套件 seed 進框架;範圍由矛盾掃描報告與決策者裁示擴大為全面調整(§6.7) | 等顧問先拆:卡住第二期驗收 |
| D7 兩套程序書掛法 | 收掉控制項層舊上傳路徑,詳情 API 改讀程序書池;程序書不加 locator(程序書是公司 SOP,掛控制項證明有規定,不指章節) |
在程序書對應加 locator:加錯層,「證據指到檔內某節」屬證據那條 |
| D9 風險評估存哪 | 新表,掛專案 SSP,欄位對齊 OSCAL 風險物件;與改善計畫(POA&M)分開 | 借 AR 殼(主體錯、要先造評估計畫);借 POA&M(與「改善計畫=結案才有」的心智模型衝突);SC.props JSON 陣列(多人覆寫、無外鍵、統計要拆 JSON) |
| D10 文件範本 | 顧問主筆;runner 只做格式,本期放骨架佔位;骨架放 repo,建庫時走 F4 機制上傳並預掛 | AI 起稿直接出貨:對外法律文件需有人負責內容 |
| D11 舊 clone 端點 | 刪,FE 常數一起刪 | 保留:無人呼叫,讓人誤以為已有「複製資源庫」 |
| D13 製造商與通報窗口 | 製造商與漏洞通報聯絡人是 SSP metadata 的 Party,以角色掛上;揭露政策網址、安全通告頁、聲明取得位置是 SSP link;支援期結束日、產品識別等單值走 SC.props ext: 前綴 |
全放 SC.props:通報模組要讀「人」與聯絡方式,props 存不了結構;放資訊系統主檔:改 jedi-asset 主表且所有框架都看得到 |
| D14 自家 SBOM 成證據 | 本期範圍外 | — |
| D15 證據來源機制 | AO 多「證據來源」屬性,指向系統內已有的資料;規劃頁與判定頁依屬性切顯示(§6.11) | 全部要客戶匯出再上傳:同一件事兩份真相;為每個來源各做獨立頁:重複造輪子 |
| D16 下拉選項進字典表 | 畫面下拉、單選、分類標籤的選項一律存 public.system_menus,由主線 phase=seed migration 寫入,FE 走既有選單讀取 |
選項寫進 FE 元件或框架預設內容:管理員想加一項要改程式 |
| D17 風險評估不做威脅清單與精靈 | 系統不出威脅清單、不自動帶入;顧問填威脅時選「依據標準」(下拉)並自填條號 | 內建威脅庫:系統不是有公信力的單位;全自由文字:沒有人會填 |
| 編號 | 決定 | 理由 |
|---|---|---|
| C-P1 | form_settings JSON 結構固定三鍵:version(整數,現為 1)、sections(物件,布林開關)、groups(陣列,每組 key/title/fields[]);欄位物件 key/label/type/required/options/help/reason。type 限 text/textarea/url/date/select/boolean |
textarea、url 是 text 的顯示變體,型別檢查仍歸四型;reason: true 讓布林題自帶「理由」文字欄,八題適用判定不必拆 16 個欄位 |
| C-P2 | 欄位值存受評標的 SC.props,鍵一律 ext:cra-*;理由欄鍵為 <key>-reason |
避開既有 target-type/owner-uid;ext: 前綴讓 OSCAL 匯出時一眼看出是產品擴充 |
| C-P3 | 新端點只讀:GET /module-frame/<uid>/form-settings、GET /ssp/<uid>/form-settings;SSP 版只服務專案 SSP(經 ctx.project.module_frame_id 取資源庫),資源庫範本編輯頁用資源庫 uid 那支 |
規劃頁手上只有專案 SSP uid;資源庫範本編輯頁手上只有資源庫 uid |
| C-P4 | Party 角色 id:manufacturer、vulnerability-contact,登記進 system_menus 群組 ssp_party_role;現行 DEV 沒有 oscal.oscal_roles 表,不寫該表 |
沿用既有 9 個角色的 kebab-case 命名;FE 下拉自動多兩項 |
| C-P5 | 角色掛法沿用產品既有做法:party 本體的 props.responsible-role,不寫 metadata.responsible_parties |
建專案時 party uuid 會重產(jedi-oscal-v2 metadata_clone_service.py),metadata.responsible_parties 照原樣複製會指到舊 uuid |
| C-P6 | link 存受評標的 SC.links(OSCAL [{href, rel, text}]),rel 用 ext:cra-disclosure-policy/ext:cra-advisories/ext:cra-doc-location |
SC.links 已有欄且建專案深拷貝自然帶過;oscal.metadata.links DEV 0 筆使用、無服務寫入入口 |
| C-P7 | 風險表名 oscal.ssp_risks;租戶隔離比照 compliance.source_scans(tenant_id+org_unit_id+RLS FOR ALL,ENABLE+FORCE) |
oscal.* 既有表沒有租戶欄、RLS 擋不到;新表一開始就補上 |
| C-P9 | AO 的 part_id 為 <control_id>_obj.<N>,N 從 3 起算(1=_smt、2=_gdn 已佔);sort_order 與 N 相同;props 不帶 workflow-template-uid |
對齊 CMMC 的 _obj.N 與 sort_order 一致慣例;流程範本 uid 由建庫時 _init_ao_workflows 補,seed 寫死會指到不存在的範本 |
| C-P10 | 建庫預設內容放 app/oscal/service/framework_library_defaults/<框架 code>.py(純資料),由 __init__.py 的 REGISTRY 以框架 code 查表;查無=什麼都不寫 |
一框架一檔,新增框架只加一檔一列;CMMC 沒有檔,行為不變 |
| C-P11 | AO 證據來源存 AO part 的 props,名 evidence-source;狀態不隨控制項樹回傳,另打端點取 |
控制項樹已很重;先例是 workflow-template-uid 同樣存 AO props |
| 項目 | 落點 | 做法 |
|---|---|---|
| 資源庫表 | compliance.module_frames;ORM infra/module_frame/models/module_frame.py、mapper module_frame_mapper.py、entity module_frame_entity.py |
form_settings JSONB 欄,三處帶欄 |
| 建庫入口 | app/oscal/service/resource_library_app_service.py 的 create_resource_library |
建庫尾端兩行呼叫 apply_framework_defaults,同一交易 |
| 建庫預設內容 | app/oscal/service/framework_library_defaults/(__init__.py 查表套用、cra_2024.py 純資料) |
表單設定、A2.x 預設說明、Party 空殼、文件範本清單 |
| 受評標的 props | module_frame_system_characteristic_service.py(資源庫端)、ssp_system_characteristic_app_service.py(專案端,讀 require_participant、寫 require_manager) |
擴充鍵走同一合併工具,收送 ext_fields/ext_links |
| Party | 資源庫 module_frame_party_service.py、專案 ssp_party_app_service.py;角色存 props.responsible-role;FE ModuleFramePartiesPanel.vue 讀 system_menus ssp_party_role |
兩個角色進字典表;建庫預建兩筆空殼 |
| 風險 | 新表 oscal.ssp_risks;稽核結果層 oscal.assessment_risks 不動 |
四層+頁籤 |
| 下拉字典 | public.system_menus(group/key/value/sort/enable/public) |
角色、風險依據標準都在這 |
| 資訊系統 | compliance.information_systems(jedi-asset,有 tenant_id/org_unit_id、RLS 已開) |
版本子表+套件 migration 006+子表格元件 |
| 程序書池 | oscal.ssp_reference_document_mappings 與資源庫程序書池服務 module_frame_reference_document_service.py |
建庫時上傳範本並預掛;詳情 API 讀池資料 |
| AO | oscal.catalog_control_parts name=assessment-objective,底下的 guidance 子段落放該 AO 的建議證據;建庫補流程範本 _init_ao_workflows |
套件 seed 005;讀法 app/oscal/service/control_part_prose.py 的 ao_guidance_map |
體積:ProjectPlanningView.vue、ssp_control_implementation_service.py、RoundAuditReviewView.vue 已超標,本期在這幾檔只准刪與少數幾行(一行 v-if、字典補欄),新邏輯一律新開檔;InformationSystemManage.vue 797 行貼線,子表格必須新開元件。
資料庫:migration scripts/sql/2026-10-11-fr135-module-frame-form-settings.sql
ALTER TABLE compliance.module_frames ADD COLUMN IF NOT EXISTS form_settings JSONB;
COMMENT ON COLUMN compliance.module_frames.form_settings IS '表單設定:專案受評標的多顯示哪些欄位、哪些 SSP 子頁籤;結構由應用層驗';NULL=照固定畫面(CMMC 不受影響)。不新建表,既有 GRANT 與 RLS 照舊。manifest.tsv 登記 active *,出貨基線待重產。
三層帶欄:ORM form_settings: Mapped[Optional[dict]] = mapped_column(JSONB, nullable=True);mapper 兩向帶;entity 建構子加參數。
結構驗證:app/module_frame/service/form_settings_schema.py 的 validate_form_settings(dict) -> dict,檢查三鍵、type 白名單、key 必為 ext: 開頭且不重複、select 必有 options。不合格拋 BadRequestError(ModuleFrameErrorCode.MODULE_FRAME_FORM_SETTINGS_INVALID)(MODULE_FRAME_400013)。唯一寫入者是建庫預設(§6.9),寫入前驗一次;讀取端不再驗。
組的兩個選填鍵:collapsed(布林,前端預設折疊該組)與 gate({when_any_true, when_any_false, message_key},兩個陣列只能列本組的布林欄位;任一題命中即判「不在範圍」,前端收起其餘組並顯示 message_key 的提示,使用者仍可手動展開)。CRA 的「適用判定」排第一組並帶 gate,其餘四組 collapsed: true;沒有這兩鍵的設定照舊全部展開。sections.nist_fields: false(CRA 預設)讓共用基本欄位藏起 FIPS 199 與授權邊界兩欄與頂部 NIST 導向說明;有表單設定時共用欄位也包成同樣的可折疊組「系統基本資料(各框架共用)」,預設展開。
端點(api/module_frame/routes/form_settings_route.py,app service app/module_frame/service/form_settings_app_service.py):
| 端點 | 守門 | 回傳 |
|---|---|---|
GET /module-frame/<uid>/form-settings |
verify_module_frame_exists_by_uid(uid)(讀) |
{"data": <form_settings 或 null>} |
GET /ssp/<ssp_uid>/form-settings |
SspPermissionChecker.require_read_access(ssp_uid) |
專案 SSP:ctx.project.module_frame_id → 資源庫設定 |
兩支都只讀。
前端(FE repo):
src/composables/useFormSettings.js:依 apiBase 打兩支端點之一、快取。src/components/grc/ssp/SspExtFieldsSection.vue:吃 groups,各型別對應 PrimeVue 元件(InputText/Textarea/Calendar/Dropdown/InputSwitch),reason: true 的欄位下方多一個理由框;送出走既有 system-characteristic PUT,多帶 ext_fields: {<key>: <value>}。SspBasicSection.vue 底部一行掛 <SspExtFieldsSection v-if="settings?.groups?.length">。SspTabPanel.vue:「風險評估」子頁籤 v-if="settings?.sections?.risk_assessment",其他子頁籤不動。_apply_payload 多收 ext_fields:只接受 ext: 開頭的鍵,逐鍵 _set_prop;_to_dict 回傳 ext_fields(把 props 中 ext: 開頭者攤平)。資源庫與專案共用此對應,兩頁同時生效。CMMC 不變的條件:form_settings 為 NULL 時,端點回 null、前端兩個 v-if 都不成立,DOM 與 CMMC 現況相同。
CRA 資源庫的表單設定內容(cra_2024.py 的 FORM_SETTINGS;label 為繁中、help 簡述法源;5 群 22 欄):
{
"version": 1,
"sections": {"risk_assessment": true},
"groups": [
{ "key": "scope", "title": "產品用途與環境", "fields": [
{"key": "ext:cra-intended-purpose", "label": "預期用途", "type": "textarea", "required": true, "help": "Art. 3(12);技術文件第 1 項"},
{"key": "ext:cra-foreseeable-misuse", "label": "可合理預見的誤用", "type": "textarea", "required": true, "help": "Art. 13(3) 風險評估要涵蓋"},
{"key": "ext:cra-operational-environment", "label": "預期使用環境", "type": "textarea", "required": true, "help": "Annex II 第 4 項"},
{"key": "ext:cra-operator-role", "label": "客戶在 CRA 的角色", "type": "select", "required": true, "options": ["manufacturer", "importer", "distributor", "authorised-representative", "open-source-steward"], "help": "Art. 3(13)~(18)"}
]},
{ "key": "applicability", "title": "適用判定", "fields": [
{"key": "ext:cra-q-eu-market", "label": "會在歐盟市場上市或提供", "type": "boolean", "reason": true, "help": "Art. 2(1)"},
{"key": "ext:cra-q-digital-elements", "label": "產品含數位元素(軟體或含軟體的硬體)", "type": "boolean", "reason": true, "help": "Art. 3(1)"},
{"key": "ext:cra-q-data-connection", "label": "預期用途包含與裝置或網路的資料連線", "type": "boolean", "reason": true, "help": "Art. 2(1)"},
{"key": "ext:cra-q-pure-saas", "label": "是純 SaaS(無製造商設計的遠端處理以外的產品部分)", "type": "boolean", "reason": true, "help": "前言 (12);純 SaaS 不在範圍"},
{"key": "ext:cra-q-spare-part", "label": "是同規格替換用的備品", "type": "boolean", "reason": true, "help": "Art. 2(6)"},
{"key": "ext:cra-q-open-source-non-commercial", "label": "是非商業活動提供的開源軟體", "type": "boolean", "reason": true, "help": "前言 (18)~(19)、Art. 24"},
{"key": "ext:cra-q-sector-exempt", "label": "已受專法規範(醫療器材、汽車、民航、船舶等)", "type": "boolean", "reason": true, "help": "Art. 2(2)~(4)"},
{"key": "ext:cra-q-defence-security", "label": "專為國安或國防目的開發", "type": "boolean", "reason": true, "help": "Art. 2(7)~(8)"}
]},
{ "key": "classification", "title": "產品分級與支援期", "fields": [
{"key": "ext:cra-product-class", "label": "產品分級", "type": "select", "required": true, "options": ["default", "important-class-i", "important-class-ii", "critical"], "help": "Art. 7~8、Annex III/IV;細節見 (EU) 2025/2392"},
{"key": "ext:cra-product-class-reason", "label": "分級理由(對到 Annex III/IV 哪一類)", "type": "textarea"},
{"key": "ext:cra-support-end-date", "label": "支援期結束日", "type": "date", "required": true, "help": "Art. 13(8)、Annex II 第 7 項"},
{"key": "ext:cra-support-end-reason", "label": "支援期長度的理由", "type": "textarea", "required": true, "help": "Art. 13(8):至少 5 年,短於預期使用期需說明"}
]},
{ "key": "annex2", "title": "Annex II 產品識別", "fields": [
{"key": "ext:cra-product-name", "label": "產品名稱與型號", "type": "text", "required": true, "help": "Annex II 第 3 項"},
{"key": "ext:cra-product-identifier", "label": "產品識別(類型、批號、序號或版本)", "type": "text", "required": true, "help": "Annex II 第 3 項"},
{"key": "ext:cra-sbom-access", "label": "SBOM 取得方式(若對使用者提供)", "type": "textarea", "help": "Annex II 第 9 項(選擇性)"}
]},
{ "key": "links", "title": "公開資訊網址", "fields": [
{"key": "ext:cra-disclosure-policy", "label": "漏洞揭露政策網址", "type": "url", "help": "Annex II 第 2 項"},
{"key": "ext:cra-advisories", "label": "安全通告頁網址", "type": "url", "help": "CRA.II.4/II.8 引用"},
{"key": "ext:cra-doc-location", "label": "EU 符合性聲明取得位置", "type": "url", "help": "Annex II 第 6 項"}
]}
]
}欄位數:scope 4、applicability 8、classification 4、annex2 3、links 3,共 22 個;8 題適用判定各帶理由欄,3 個網址欄存 links、其餘 19 欄加 8 個理由欄,props 最多 27 鍵。八題的「理由」對應 Art. 2 範圍判斷,是技術文件要寫的「為什麼適用/不適用」。欄位 key 是 SC.props 的鍵,有專案填過值就是資料契約,不可改名。
Annex II 九項按 D13 分三類:
| Annex II 項 | 控制項 | 落點 | 鍵或角色 |
|---|---|---|---|
| 1 製造商名稱、地址、聯絡方式 | CRA.A2.1 | Party(§6.3) | 角色 manufacturer |
| 2 漏洞通報單一聯絡點、揭露政策位置 | CRA.A2.2 | Party+link | 角色 vulnerability-contact;rel=ext:cra-disclosure-policy |
| 3 產品名稱、類型、識別 | CRA.A2.3 | SC.props | ext:cra-product-name、ext:cra-product-identifier |
| 4 預期用途、安全環境、功能 | CRA.A2.4 | SC.props | ext:cra-intended-purpose、ext:cra-operational-environment |
| 5 已知或可預見的風險情境 | CRA.A2.5 | 風險評估表(§6.4) | — |
| 6 EU 符合性聲明取得位置 | CRA.A2.6 | link | rel=ext:cra-doc-location |
| 7 技術支援方式、支援期結束日 | CRA.A2.7 | SC.props | ext:cra-support-end-date、ext:cra-support-end-reason |
| 8 安全安裝、更新、停用等說明 (a)~(f) | CRA.A2.8 | 拆 AO(§6.7)+證據 | — |
| 9 SBOM 取得方式 | CRA.A2.9 | SC.props | ext:cra-sbom-access |
安全通告頁網址另以 rel=ext:cra-advisories 存,供 CRA.II.4/II.8 引用。
link 怎麼編輯:受評標的服務 _apply_payload 多收 ext_links: [{rel, href, text}],只接受 ext:cra- 開頭的 rel,同 rel 覆寫、其他 link 保留;_to_dict 回傳 ext_links。表單設定的 links 群組宣告三種 rel 的標籤,SspExtFieldsSection 以文字框渲染網址,型別 url。欄位 key 要 ext:cra- 開頭才存得進 links。
預設說明文字:A2.1~A2.9 九條的 implementation-description 寫進資源庫範本 SSP 的實作需求 props(module_frame_control_default_service.py 的 _P_DESC),建專案隨範本 SSP 複製。文字放 cra_2024.py 的 A2_DEFAULT_DESCRIPTIONS,英文、每條 2~4 句,說明「這段資訊放在使用者資訊的哪一章、對應受評標的哪個欄位」,標 [AI draft – consultant to confirm]。只寫入該資源庫 profile 內的控制項。
角色登記(migration scripts/sql/2026-10-12-fr135-cra-party-roles.sql,manifest.tsv 登記 seed *):
INSERT INTO system_menus ("group", key, value, sort, enable, public) VALUES
('ssp_party_role', 'manufacturer', 'manufacturer', 100, 1, 1),
('ssp_party_role', 'vulnerability-contact', 'vulnerability-contact', 110, 1, 1)
ON CONFLICT DO NOTHING;只寫 system_menus;DEV 沒有 oscal.oscal_roles 表。冪等,資料類不進出貨基線。FE ModuleFramePartiesPanel.vue 從 system_menus 讀,下拉自動多兩項,所有框架都看得到這兩個選項——這是可接受的副作用(選項存在不影響 CMMC 既有資料)。i18n 標籤走 lang.oscal_role.ssp_party_role.<key>.label,roleLabel() 查不到時退回顯示 key,不會壞。
角色怎麼掛:沿用產品既有做法(C-P5)——party 本體 props.responsible-role。同一角色允許多人(例如通報聯絡人有主要與備援),由現有參與單位頁增刪。
CRA 資源庫預建空殼:建庫預設(§6.9)呼叫既有 ModuleFramePartyService.add_party 兩次:
| party_type | name | role | 說明 |
|---|---|---|---|
| organization | Manufacturer (to be filled) |
manufacturer |
客戶在專案參與單位頁改名、填地址、email |
| organization | Vulnerability contact (to be filled) |
vulnerability-contact |
填通報信箱或網頁表單網址 |
名稱帶 (to be filled) 讓顧問一眼看出還沒填。建專案時 clone_metadata_with_party_map 整批複製 party,專案端由 ssp_party_app_service.py 讀寫,FE 參與單位頁不用改。
第三期接點:通報模組讀專案 SSP metadata 下 props.responsible-role in ('manufacturer','vulnerability-contact') 的 party,取 name/email_addresses/props.address。
表:oscal.ssp_risks(migration scripts/sql/2026-10-12-fr135-ssp-risks.sql)
| 欄 | 型別 | 對齊 assessment_risks |
說明 |
|---|---|---|---|
id |
BIGSERIAL PK | 同 | |
uid |
UUID NOT NULL UNIQUE | — | 對外識別 |
tenant_id |
BIGINT NOT NULL | — | RLS 依此隔離(C-P7) |
org_unit_id |
BIGINT | — | 租戶表必含 |
ssp_id |
BIGINT NOT NULL FK → oscal.system_security_plans.id ON DELETE CASCADE |
取代 ar_result_id/poam_id |
專案 SSP |
sort_order |
INT NOT NULL DEFAULT 0 | 同 | |
uuid |
UUID NOT NULL | 同 | OSCAL risk uuid,匯出用 |
title |
TEXT NOT NULL | 同 | 威脅(一句話) |
description |
TEXT | 同(原為必填) | 威脅情境說明 |
statement |
TEXT | 同(原為必填) | 受影響資產 |
status |
VARCHAR(40) NOT NULL DEFAULT 'open' | 同 | open/investigating/remediating/deviation-approved/closed(OSCAL risk-status,有 CHECK) |
threat_ids |
JSONB | 同 | 依據標準:[{key, system, id, href}],畫面開放讀寫(見下) |
characterizations |
JSONB | 同 | 衝擊與可能性:[{facets:[{name:"impact",value:"high"},{name:"likelihood",value:"moderate"}]}] |
mitigating_factors |
JSONB | 同 | 既有控制:[{description}] |
remediations |
JSONB | 同 | 處理措施:[{lifecycle:"planned", title, description}] |
related_control_ids |
JSONB | 新 | 對應控制項 ["CRA.I.2.d", …] |
component_uuids |
JSONB | 新 | 元件連結預留:SSP 元件 uuid 陣列;畫面不出現 |
props/links |
JSONB | 同 | OSCAL 擴充 |
remarks |
TEXT | — | 備註 |
created_user/updated_user |
VARCHAR(255) | 同 | 審計 |
created_at/updated_at |
TIMESTAMPTZ NOT NULL DEFAULT now() | 同 |
不帶 origins/deadline/risk_log/related_observations(屬稽核發現,風險評估期沒有)。description/statement 可空,讓顧問先記一句威脅再補。衝擊與可能性用 OSCAL characterizations.facets 存,值域 low/moderate/high,風險等級在畫面算(衝擊與可能性取較高者),不存欄。
migration 登記 active *(出貨基線待重產):ENABLE+FORCE ROW LEVEL SECURITY、POLICY ... FOR ALL(超管放行或 app_tenant_allowed_for_session(tenant_id))、GRANT ... TO cm_app 含 sequence、索引 (ssp_id)、(tenant_id)。
依據標準:風險編輯對話框的「依據標準(選填)」每列三格:標準名(下拉)、條號(自由文字)、網址(選填)。
public.system_menus 群組 risk_reference_standard(D16;migration scripts/sql/2026-10-12-fr135-risk-reference-standards.sql,seed *,十列:etsi-en-303-645、iec-62443-4-2、iec-62443-4-1、en-18031、iso-iec-27005、capec、attack、owasp-iot-top10、enisa-threat-landscape、other)。管理員可在系統選單維護頁增刪;顯示名優先走 i18n lang.risk_reference_standard.<key>。threat_ids 的 key 是 system_menus.key(程式用)、system 是顯示名;選 other 時標準名變文字框自填。value 當提示。href 鍵;網址只有 http://、https:// 開頭才渲染成連結。DDD 四層(主專案,不進套件——SSP 層風險是產品概念):
| 層 | 檔 |
|---|---|
| domain | domain/oscal/entity/ssp_risk_entity.py、domain/oscal/repository/i_ssp_risk_repo.py(介面)、domain/oscal/service/ssp_risk_domain_service.py |
| infra | infra/oscal/model/ssp_risk.py、infra/oscal/mapper/ssp_risk_mapper.py、infra/oscal/repository/ssp_risk_repo_impl.py(繼承 BaseRepositoryImpl) |
| app | app/oscal/service/ssp_risk_app_service.py:讀 require_participant、寫 require_manager;tenant_id/org_unit_id 取自專案;審計欄暱稱以 enrich_audit_nickname_objs 補 *_user_name |
| api | api/oscal/routes/ssp/ssp_risk_route.py、api/oscal/serializers/ssp/ssp_risk.py;DI 進 di_containers/oscal/ |
端點:GET/POST /ssp/<ssp_uid>/risks、PUT/DELETE /ssp/<ssp_uid>/risk/<risk_uid>。related_control_ids 寫入時驗證每個 id 在該專案的控制項範圍內(查法與控制項導航樹同一個 profile 解析),不在拋 GRC_400140;刪改時同時比對風險屬於該 SSP,找不到拋 GRC_404051(common/code/flow_control_error_code.py),同步 FE i18n。
前端:src/components/grc/ssp/SspRiskAssessmentSection.vue(DataTable+編輯對話框;衝擊、可能性兩個下拉,風險等級顯示徽章、依據標準多列、對應控制項多選),掛在 SspTabPanel.vue 子頁籤,v-if="settings?.sections?.risk_assessment"。
與 POA&M 不互動:不讀、不寫 assessment_risks;稽核結果頁不顯示。GRC 期再決定是否合併(§後續)。
套件 migration jedi-asset/jedi_asset/migrations/006-information-system-versions.sql:
| 欄 | 型別 | 說明 |
|---|---|---|
id |
SERIAL PK | |
uid |
VARCHAR(50) NOT NULL UNIQUE | 比照母表 |
information_system_id |
INTEGER NOT NULL FK → compliance.information_systems.id ON DELETE CASCADE |
|
version |
VARCHAR(100) NOT NULL | 版號,同母表唯一 (information_system_id, version) |
release_date |
DATE | 上市日 |
support_end_date |
DATE | 支援期結束日 |
support_end_reason |
TEXT | 支援期長度理由 |
remarks |
TEXT | |
tenant_id |
INTEGER NOT NULL | 比照母表 |
org_unit_id |
INTEGER | |
created_user/updated_user |
VARCHAR(50) | |
created_at/updated_at |
TIMESTAMPTZ NOT NULL DEFAULT now() |
RLS 四支政策照母表寫法(select/insert/update/delete 各一)、GRANT cm_app 含 sequence。build 期自動同步到主專案 scripts/sql/packages/jedi_asset/ 與 packages/manifest.tsv。
套件四層:infra/models/information_system_version.py、mapper、repo;domain/entity+domain/repository;app/service/information_system_version_service.py(新檔,不塞進母服務);api/routes/information_system_version_route.py:
| 端點 | 守門 |
|---|---|
GET/POST /information-system/<uid>/versions |
讀/寫各套母表的 information_system_read_capability/information_system_update_capability |
PUT/DELETE /information-system/<uid>/version/<version_uid> |
update_capability |
FROZEN_URLS(routing.py)同步加兩條;能力點沿用母表,不新增。jedi-asset 版號 1.2.4,發版等決策者明示。
前端:src/views/information-system/InformationSystemVersionTable.vue,InformationSystemManage.vue 的編輯對話框底部一行掛上(該檔 797 行,只准加一行)。
SSP 端不動:受評標的以 inventory_items.props 的 ref-type/ref-id 軟連到資訊系統。「專案選定某個版本」本期不做;受評標的的 ext:cra-product-identifier 由顧問手填版本字串。
🔴 概念鐵則:程序書 ≠ 證據,兩套路、兩種畫面,不可混
程序書=公司的 SOP/流程文件(CMMC、ISO 都有),掛在控制項上,證明「公司有這個規定」,不指檔內章節。證據=證明達到控制項要求的附件,掛在準備期工作(job evidence)底下。
程序書的對應表 oscal.ssp_reference_document_mappings 只有「哪份檔掛哪個控制項/AO」,沒有出處欄。第〇步缺口「證據指不到檔內某一節」屬證據那條,是否在證據上加出處另案討論,不在本文件範圍。
舊路已收掉:控制項層舊上傳與刪除(add_reference_documents、delete_reference_document)、AO 層舊讀寫與其 route 已刪,FE 對應呼叫一併刪除;控制項詳情 API 的 reference_documents 讀程序書池對應。ssp_control_implementation_service.py 超標,這塊只刪不加。
結果:CRA 框架為 4 群組、34 條控制項、49 個 AO,每個 AO 可獨立判定「有/沒有」,句型比照 CMMC(句首 [a]、[b] 字母配合分類器解析)。依據是 cra-ao-contradiction-scan-2026-10-12.md 的矛盾掃描與決策者裁示。
| 動作 | 內容 |
|---|---|
| 新群組 Articles 13 and 14 | 三條:CRA.ART.13.RA 風險評估(3 AO)、CRA.ART.13.SP 支援期(3 AO)、CRA.ART.14.RP 通報(3 AO)。三件製造商義務的法源在 Article 13/14,不在 Annex I |
| 搬移 | CRA.I.1 底下三個屬 Article 13 的 AO 搬到 CRA.ART.13.RA;搬移是改掛(保留原列 id、換控制項與 part_id),不是刪掉重建 |
| 拆 6 條 | CRA.I.2.c、CRA.I.2.f、CRA.I.2.m、CRA.II.1、CRA.II.4、CRA.II.8;CRA.II.6 不拆 |
| 改句 | 既有 AO 依矛盾掃描改寫,消除互相重疊與一句多件事 |
| 建議證據 | 每個 AO 底下掛一個 guidance 子段落,內容為三段式:Deliverable(交什麼檔或紀錄)、Must show(審閱者要在裡面看到什麼)、Evidence(upload|system — <頁面>|template — <範本>);不帶 [obj.N] 與 [beyond ENISA] 之類內部標記 |
內容單一來源:scripts/cra_ao_content.py,產生器 scripts/gen_cra_ao_restructure.py 一次產出 cra-assessment-objectives.md、cra-suggested-evidence.md 的建議證據段與套件 seed 005。AO 句與證據依 docs/reference/CRA/ 法條原文自寫,不抄 ENISA 或 EN 40000 條文;Basis(依據)欄只進 md,不進 seed。md 頁首標「AI 依 ENISA 子要求拆分,待顧問確認」。
套件 seed 005 jedi-oscal-v2/jedi_oscal_v2/migrations/005-cra-2024-ao-restructure.sql(套件版號 2.5.4,發版推 Nexus 等決策者明示):
INSERT ... WHERE NOT EXISTS (part_id),重跑計數不變;catalog_id 以 CRA catalog 固定 uuid 定位。name='assessment-objective'、parent_id=NULL(CMMC 也是平鋪)、part_id='<control_id>_obj.<N>'、N 從 3 起(C-P9)。parent_id 指向該 AO。讀法陷阱:AO 底下的 guidance sort_order=1 會排在控制項層 _gdn 前面。控制項層的 statement/guidance 只取 parent_id 為空的列,AO 層建議證據走 control_part_prose.py 的 ao_guidance_map;framework_version_edit_service 的 _guidance_prose/_upsert_part 同樣加此過濾,否則瀏覽對話框與編輯會被子段落干擾。
生效範圍:只對之後新建的資源庫與專案(建庫整份複製 catalog)。
本期只做骨架佔位(D10):五份 docx,每份有封面、法源、版本紀錄表、目錄,每節一句「此節要寫什麼、依據哪條」與紅字 [Consultant to complete] 佔位,內容由顧問日後替換。
| 檔 | 掛的控制項 |
|---|---|
CRA-CVD-Policy-Template.docx(協調漏洞揭露政策) |
II.5、II.6、A2.2 |
CRA-Security-Advisory-Template.docx(安全通告) |
II.4、II.8 |
CRA-Support-Period-Statement-Template.docx(支援期聲明) |
A2.7、I.2.c |
CRA-User-Information-Template.docx(Annex II 使用者資訊) |
A2.1、A2.3、A2.4、A2.5、A2.8 |
CRA-Update-and-Decommission-Procedure-Template.docx(更新與停用程序) |
I.2.m、II.2、II.7、A2.8 |
合計 15 條控制項、16 筆掛載(A2.8 同時掛兩份)。
scripts/generate_cra_doc_templates.py(python-docx 手寫,可重跑覆蓋),產物放 app/oscal/templates/cra/——打包腳本只帶清單內的資料夾,此路徑已在清單內。project_start_app_service.py 的 _clone_reference_documents)。三份法定文件匯出:與上面五份骨架是兩回事——骨架是空白章節給顧問主筆,匯出是從專案已填資料直接組出內容的 docx(D4 只出 docx),顧問下載後可再改字。
| 匯出 | format 值 |
範本 |
|---|---|---|
| Annex VII 技術文件 | cra-annex7 |
CRA-Annex-VII-Technical-Documentation-Export.docx |
| Annex II 使用者資訊 | cra-annex2 |
CRA-Annex-II-User-Information-Export.docx |
| EU 符合性聲明(Annex V) | cra-doc |
CRA-EU-Declaration-of-Conformity-Export.docx |
GET /ssp/<uid>/export?format=…,同一顆 oscal.ssp.export 能力點、同樣只限專案參與者;非 CRA 專案(表單設定沒開風險評估段)回 412 GRC_412059。app/oscal/service/export/cra_legal_docs_export_service.py,每份一支 context 組裝;內容來源:受評標的 ext:cra-* 欄與連結、風險評估(含依據標準,歸併成「採用標準」表)、資訊系統版本(支援期以最新版本為準,沒建版本才讀 ext:cra-support-end-date)、參與單位 manufacturer/vulnerability-contact(名字仍是建庫佔位的不算填了)、控制項實作說明(Annex VII 列全部控制項)。(not provided);符合性聲明的簽署人、地點日期與簽名留底線空白給製造商親簽。scripts/generate_cra_doc_templates.py 產(docxtpl {{ }} 佔位,變數名與 service context 鍵對應);重跑會順手重寫五份骨架的檔案時間戳,只改匯出範本時記得還原那五份。顧問從畫面新增資源庫、框架選 CRA 時,create_resource_library(app/oscal/service/resource_library_app_service.py)在建庫尾端兩行呼叫 FrameworkLibraryDefaultsService.apply_framework_defaults(rl_uid, framework_id, user),與建庫同一交易,任一步失敗整個建庫回滾。
流程:由 framework_id 反查 oscal.frameworks.code(CRA 是 CRA_2024)→ 以 REGISTRY 查 framework_library_defaults/<code>.py → 依序寫入:
validate_form_settings,再設到 module_frames.form_settings)查無該框架 code=什麼都不寫,CMMC 行為不變。預設內容寫在資源庫層即可:建專案時 party、SC props、範本 SSP 的控制項預設值、程序書池都會整批複製。
陷阱:
resolve_profile 過濾。update 會把 entity 所有非空欄位寫回,entity 的 enable 預設 0。自己 new 一個 entity 去 update 會把新庫打回草稿;要讀回完整 entity 再改 form_settings。clone_module_frame service、route(註冊於 api/module_frame/__init__.py)、schema、FE src/config/api/api.js 的 MODULE_FRAME_CLONE 已刪(D11)。刪前 grep BE/FE/test 三處確認無呼叫端;刪後端點少一條,route guard inventory 守衛清單同步。
問題:CRA 有一批證據是客戶在系統其他頁填完就有的——風險評估頁籤、每條控制項的適用/不適用與理由、受評標的的支援期結束日與產品識別、參與單位的製造商與通報聯絡人、資訊系統版本、FR-134 的 SBOM 與弱點掃描。只有「上傳檔案」一種掛法,客戶得把系統裡的東西匯出再傳回來,同一件事兩份真相。矛盾掃描報告標出 116 點建議證據中 15 點主要來源是系統內、另 10 點混合。
做法:AO part 的 props 多一個 evidence-source:
{"name": "evidence-source", "value": "<type>", "ns": "guidant"}值由 §6.7 三段式第三段 Evidence: system — <頁面> 轉出,由框架 seed 以冪等 UPDATE 寫入。六種 type:
| type | 讀哪裡 | 狀態句例 |
|---|---|---|
risk-assessment |
oscal.ssp_risks 筆數與最後更新 |
已登錄 6 筆,最後更新 10/12 |
applicability |
該專案控制項的適用/不適用判定數 | 已判定 28/34 |
system-characteristic:<ext-key> |
受評標的 props 該鍵的值 | 已填:2031-12 |
party:<role> |
有無該角色 party 且名稱不是 (to be filled) |
尚未填寫 |
information-system-version |
受評標的所連資訊系統的版本數 | 已登錄 2 個版本 |
source-scan |
該專案最近一次原始碼掃描 | 最近掃描 10/10 |
BE:
app/oscal/service/ao_evidence_source.py:一支 resolve(ssp_id, source),六個 type 各一小函式,回統一形狀 {type, label_key, status: 'filled'|'empty'|'partial', count, summary, link: {route, params}};各物件的讀取走既有 service,不另寫查詢,不新增表。evidence_source: {type, ref}(只帶 type 與 ref;ssp_control_implementation_service.py 超標,只加幾行,解析放新檔)。GET /ssp/<ssp_uid>/ao/<part_id>/evidence-source(參與者可讀)取狀態,lazy 打,避免控制項樹變重。FE:
src/components/grc/planning/AoEvidenceSourcePanel.vue:顯示「證據來源:<白話名稱>」、狀態一行、「前往」按鈕(router 到對應頁籤)。ProjectPlanningView.vue):evidence_source 有值 → 掛 AoEvidenceSourcePanel、隱藏關聯程序書與上傳區;無值 → 照舊。一行 v-if。RoundAuditReviewView.vue、AuditControlRef.vue):有值顯示來源狀態與「前往」,稽核員看那頁判定。稽核判定邏輯不改:稽核員仍手動判定,本機制只改「看證據的入口」。
收證據任務:evidence-source-only 為 true 的 AO(沒 AO 的控制項看 catalog_controls.props)啟動稽核與覆核輪都不產收證據任務,統計卡也就不算它;混合型(有 evidence-source 但 only 不是 true)照常產。判斷在 prep_job_generation_service.py,與規劃頁藏上傳區同一旗標。
CMMC 不變:CMMC 所有 AO 無此屬性,畫面與現況完全相同。
共通鐵則(每張卡都適用,開卡照抄):只動 DEV;不切 branch、不 push;顯式 git add;動到已超標檔只准刪或一行呼叫;migration 照 sql-migration skill(日期註解、GRANT、schema_migrations、manifest.tsv,active * 要回報出貨基線待重產);套件走 path dependency、發版等令;commit 前跑 test/test_module_boundaries.py 與 RLS 形狀守衛;做完 commit+Notion 回寫+子卡改「修正待驗證」。
| 卡 | Case No | 依賴 | 規模 | 重點 |
|---|---|---|---|---|
| F1 表單設定落點 | CM-2690 | 無 | S | §6.1 資料庫、三層帶欄、validate_form_settings;本卡需單元測試(結構守門屬共用邏輯) |
| F2 專案取設定端點 | CM-2693 | F1 | S | §6.1 兩支 GET;SSP 版只服務專案 SSP |
| F3 前端動態欄位與頁籤開關 | CM-2699 | F2 | M | BE ext_fields/ext_links 收送;FE useFormSettings.js、SspExtFieldsSection.vue;驗收專查 target-type/owner-uid 未被清掉 |
| F4 建庫帶 CRA 預設 | CM-2700 | F1 | S~M | §6.9 機制+cra_2024.py 內容+角色 migration;FE i18n 兩個角色標籤;畫面等 F3 |
| V1 資訊系統版本子表 | CM-2694 | 無 | M | §6.5;套件異動,發版等令 |
| R1-a 風險評估本體 | CM-2701 | 無 | M | §6.4 新表+四層+端點+FE 表格;新租戶表,RLS 形狀守衛要綠,本卡含 repo 層 RLS 測試 |
| R1-b 頁籤開關與依據標準 | CM-2702 | F3、R1-a | S | 頁籤 v-if+依據標準下拉(讀 system_menus,seed migration 一支) |
| C1 AO 拆分範本 | CM-2691 | 無 | S | 首版 AO 拆分文件與 seed 004 |
| C1b AO 全面調整 | CM-2696 | C1 | M~L | §6.7;套件 seed 005、BE/FE 讀 AO 自己的建議證據 |
| C2 收舊套掛檔+刪舊 clone | CM-2695 | 無 | M | §6.6 收舊路、§6.10 刪 clone;套件異動等令 |
| C2b 撤回程序書 locator | CM-2697 | C2 | S~M | 拔掉 locator 欄與前後端帶欄;保留 C2 收舊路 |
| C3 文件範本骨架 | CM-2703 | F4 | S | §6.8;產生腳本+五份 docx+建庫預掛 |
| E1 AO 證據來源機制 | CM-2704 | C1b | M | §6.11;resolve 六個 type 各一 case 的測試,突變拿掉任一分支要紅;FE 新 v-can 掛點要重跑權限矩陣 |
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#E2F0F1','primaryTextColor':'#14201F','primaryBorderColor':'#0E7C86','secondaryColor':'#EEF2F3','secondaryTextColor':'#14201F','tertiaryColor':'#FBFCFC','tertiaryTextColor':'#14201F','lineColor':'#4A5A5C','textColor':'#14201F','mainBkg':'#E2F0F1','nodeBorder':'#0E7C86','nodeTextColor':'#14201F','edgeLabelBackground':'#FBFCFC','titleColor':'#14201F','clusterBkg':'#FBFCFC','clusterBorder':'#E4EAEB','actorBkg':'#E2F0F1','actorTextColor':'#14201F','actorBorder':'#0E7C86','actorLineColor':'#C7D1D2','signalColor':'#4A5A5C','signalTextColor':'#14201F','labelBoxBkgColor':'#EEF2F3','labelBoxBorderColor':'#C7D1D2','labelTextColor':'#14201F','loopTextColor':'#14201F','noteBkgColor':'#F6EBD5','noteTextColor':'#14201F','noteBorderColor':'#9C6B12','activationBkgColor':'#EEF2F3','activationBorderColor':'#C7D1D2','sequenceNumberColor':'#FFFFFF'}}}%%
flowchart LR
F1 --> F2 --> F3 --> R1b["R1-b"]
R1a["R1-a"] --> R1b
F1 --> F4
F3 -.畫面.-> F4
F4 --> C3
C1 --> C1b --> E1
C2 --> C2b
V1
用非 102 租戶的帳號,從畫面新增一個 CRA 資源庫、再用它建驗收專案,逐項做(批次跑完再一次回報):
SC.props 只多 ext:cra-*,target-type/owner-uid 仍在。[obj.N] 標記。🔴 預設內容只在建庫當下寫入,任何 seed 或預設內容對既有資源庫無效
AO、guidance、表單設定、預設說明、party 空殼、文件範本全部只對建庫之後的新資源庫生效。驗收一律用新建的資源庫與專案,不拿第〇步測資驗。
| 陷阱 | 後果 | 對策 |
|---|---|---|
| 建專案時 party uuid 重產 | 用 uuid 指 party 的寫法(metadata.responsible_parties)在專案端斷鏈 |
只用 party 本體 props.responsible-role;第三期通報模組照此讀 |
| 受評標的整包覆寫 | 清掉固定 8 欄或 target-type/owner-uid |
ext_fields 逐鍵 _set_prop;F3 驗收專查 |
照抄 oscal.assessment_risks 欄位 |
該表 RLS 未開,新表沒隔離 | ssp_risks 必含 tenant_id+org_unit_id+RLS FOR ALL |
| 兩個新角色進全域下拉 | CMMC 專案參與單位也看得到「製造商」 | 無害、不過濾;要只在 CRA 出現需新機制,本期外 |
| docx 範本是資料檔 | Nuitka 不自動帶,客戶端建庫時上傳失敗 | 範本放 app/oscal/templates/cra/(打包清單內);出包後確認 image 內有五份 |
建庫預設的 repo update 寫回 entity 全部非空欄位 |
新庫被打回草稿(enable 預設 0) |
讀回完整 entity 再改欄位 |
AO 底下的 guidance 排在控制項層 _gdn 前面 |
控制項層取到 AO 的證據 | 控制項層只取 parent_id 為空的列 |
ProjectPlanningView.vue、ssp_control_implementation_service.py、RoundAuditReviewView.vue 超標 |
往裡加會被 reviewer 判阻斷 | 只准刪與少數幾行,邏輯進新檔 |
| 項目 | 去向 |
|---|---|
| 複製資源庫(連表單設定一起帶) | D1,GRC 期 |
| 自家 SBOM 掃描結果轉控制項證據、定期執行證明 | D14,FR-134 後續或 GRC |
| 證據(job evidence)指到檔內某一節的出處欄 | 另案討論 |
| 專案選定資訊系統的某個版本 | 第三期三份文件需要時再做;本期以 ext:cra-product-identifier 手填 |
| 畫面上的表單設定編輯器、條件顯示、驗證規則 | GRC 期 |
| 風險評估與改善計畫(POA&M)合併、組織層風險登錄、依元件建議威脅 | GRC 期;component_uuids 已預留 |
| 框架版本瀏覽對話框列出 AO 層建議證據 | 小卡,未開 |
| 文件範本正式內容、Annex II 預設說明、AO 拆法 | 顧問確認後以框架新版本或補灌修正 |
| 「填欄位自動產出」三份法定文件 | 第三期 |
ext:cra-*、link;版本子表供支援期到期排程。source-scan 證據來源讀其掃描紀錄;SBOM 轉證據本期不接(D14)。