FR-038 收尾弧 — 稽核 + POA&M 階段完成 + AR 溯源(implementation plan)

2026-06-17。範圍:把生命週期最後兩階段(audit / poam)的 FE 遷到 v2 round-scoped, 並補上 AP → AR 溯源(assessment-subjects / tasks),依 OSCAL Assessment Results 模型。 user 拍板:全部一次做完;AR subjects 比照 OSCAL(result 層 child table)。

§1

現況(agent 盤點結論)

階段 BE FE
audit ✅ v2 round-scoped 全 alive(`/audit-round//ar/findings finding
poam ✅ v2 round-scoped alive(/audit-rounds/<uid>/poam-itemsrisks/<uid>/remediationsremediations/<uid>/milestones、close_round 強制 all_items_closed) PoamView.vue AP-centric 打舊 GRC_POAM_LIST,無 round route

AR 溯源缺口:add_result 只收 reviewed-controls;result 層 assessment-subjects; observation.subjects / ar_results.assessment_log JSONB 欄存在但沒寫。

§2

OSCAL 對照(依據)

result 下平行陣列:reviewed-controls / assessment-subjects[] / assessment-assets / attestations / assessment-log(entry 可帶 related-tasks)/ observations[](每筆有 subjects[])/ risks[] / findings[]。本專案 findings/observations/risks 已是 FK→ar_results 的 child table → assessment-subjects 比照建 child table 即 OSCAL-faithful。


§3

Phase C1 — jedi-oscal-v2:AR assessment-subjects child table(dev 走 path dependency)

新增(mirror ar/oscal_ar_observation.* 的 FK→ar_results 結構 + ap/oscal_ap_assessment_subjects.* 的欄位):

  • infra/model/ar/oscal_ar_assessment_subjects.py — 表 oscal.ar_assessment_subjectsid PK / ar_result_id FK→oscal.ar_results.id NN CASCADE / sort_order / subject_type / subject_uuid / include bool / title / props JSONB / 審計欄
  • domain/entity/ar/oscal_ar_assessment_subjects_entity.py + ..._query_entity.py
  • infra/mapper/ar/ar_assessment_subjects_mapper.py
  • domain/repository/ar/ar_assessment_subjects.py(interface)+ infra/repository/ar/ar_assessment_subjects_repo_impl.pyget_by_ar_result(ar_result_id) + wholesale replace_for_result
  • AR app service(jedi-oscal-v2 assessment_result_service):add_resultassessment_subjects 參數, 寫入 child table;新增 list_result_subjects(ar_result_id)
§4

Phase C2 — 主專案 BE:echo + observation.subjects + assessment-log + migration

  • assessment_result_app_service.init_ar_matrix_for_round:建 result 時,把 AP 的 assessment-subjects(ApAssessmentSubjectsRepoImpl.get_by_ap)map 成 AR subjects 傳給 add_result
  • 判定/觀察:add_observation 路徑允許帶 subjects(observation.subjects JSONB),FE 傳「這條查了哪些對象」。
  • assessment-log:start_auditing 或 finalize 時把 AP tasks 摘要寫 ar_results.assessment_log (entry: title/timing/methods/related-task uuid)。最小:echo 一份 task 清單當 log。
  • get_findings response 補回 result-level subjects(供 FE 顯示)。
  • SQL migration scripts/sql/2026-06-17-ar-assessment-subjects.sql:建表 + GRANT ... cm_app + seq 權限 + INSERT schema_migrations。DEV 先套。
§5

Phase A — FE:稽核頁 v2 round-scoped

  • router 加 project-audit-review-round = /project/projects/:id/round/:roundUid/audit
  • 新(或改)AuditReviewView:吃 roundUid;資料改 GET /audit-round/<roundUid>/ar/findings(AO 矩陣, control→AO findings + stats);判定 PUT .../ar/finding/<uid>;觀察 POST .../ar/observations (可選 subjects);風險 GET/POST .../ar/risks + PUT .../ar/risk/<uid>/findingsPOST .../ar/finalize
  • 顯示 result-level 受評對象(從 get_findings 帶回)。
  • FlowPhaseBanner 傳 :round-uid;總覽稽核按鈕改 isRoundRoute 派發到 -round。
  • i18n:沿用既有 audit-review 命名,補缺。
§6

Phase B — FE:POA&M 頁 v2 round-scoped

  • router 加 project-poam-round = /project/projects/:id/round/:roundUid/poam
  • 新(或改)PoamView:吃 roundUid;列表 GET /audit-rounds/<roundUid>/poam-items; detail .../poam-items/<uid>;三層編輯:風險→POST risks/<uid>/remediationsPOST remediations/<uid>/milestonesPUT milestones/<uid>(status/assignee/target_date)。
  • close_round 走 banner 推進(precondition all_items_closed 由 close_round 強制)。
  • 總覽 POA&M 按鈕改 isRoundRoute 派發到 -round。
§7

驗證

  • BE:migration 套 DEV;import smoke;start_auditing 後查 oscal.ar_assessment_subjects 有列。
  • 整條:planning→ap_authoring→audit(判定+觀察記對象+風險→finalize 生 POA&M)→poam(remediation+milestone→close)→closed。
  • FE build:DEV 綠。
§8

行為規範

  • jedi-oscal-v2 dev 走 path dependency(pyproject 改 path,dev-only 不 commit);發版等 user。
  • 不切 branch;各 repo 分開 commit、顯式 git add;push 等 user。
  • 收尾(changelog/SUMMARY/Notion)等 user 下令。