FR-143 · 設計定案 · 2026-10-17

改善計畫重做:設計定案

左樹只列不符合、稽核缺失文件表單、對原任務逐一設執行人員/改善期限/改善措施、送出即退回第一站重跑、側邊入口表格、Excel 往右延伸一列一任務、OSCAL POA&M 匯出合規

缺失改善頁整個換掉。左樹只列這次判不符合的評估目標;點一條,上半是「稽核缺失」文件表單(稽核發現、風險、稽核建議、稽核人員、查核方法、採用佐證),下半列出這條評估目標底下的原任務,PM 對每個任務設執行人員(可多人)、改善期限、改善措施,不新增任務。只排計畫不追蹤完成,送出就推進:內稽每個任務退回第一站整條重跑、改善期限寫進每一站;外稽進待覆核。側邊選單多一個「改善計畫」表格入口。Excel 與稽核計畫、稽核結果同一份往右延伸,一列一個任務、合併儲存格。資料照 OSCAL POA&M 標準落點,並修 jedi-oscal-v2 四處匯出不合規。本文件寫定案規則、為什麼這樣定、踩到會怎樣。

D1~D12 全部定案(2026-10-17) 六棒六張卡,棒 1 套件修正先做 動兩支套件:jedi-oscal-v2、jedi-compliance-audit 陷阱:現行退卡只重開最新一站,多站流程退錯人 不做報告 Word/PDF、不做舊資料

🔴 這份是設計決策,不是現況。 內文停在 2026-10-17 定稿當時,實作改動不回頭改寫這裡。

狀態:設計定案(2026-10-17)|母卡 CM-2840|子卡 CM-2841~2846|討論稿:discussion.md|雛形:prototype/index.html|範例 Excel:prototype/sample/FR-143-改善計畫範例.xlsx

檔案路徑與行號以 2026-10-17 為準,查不到時以函式名重新定位。路徑慣例:BE 路徑相對 compliance-manager-be/;pkg/<套件>/ 代表 ~/Projects/Jedicogy/module/jedi-python-package/<套件>/<套件底線名>/;FE 路徑相對 compliance-manager-fe/。三個 repo 都在 feature/FR-139(FR-140、141、142 已併入)。

名詞:評估目標=AO,控制項底下的檢查項目,全系統用 part_id 當鍵(<控制項代碼>_obj.N);POA&M=改善計畫(plan of action and milestones),OSCAL 評估層第三個文件;poam-item=一條缺失的封面,引用 finding;risk=風險;response=風險的處置計畫(表 assessment_remediations,程式稱 remediation),lifecycle:recommendation 稽核建議/planned 改善計畫;task=response 底下一筆(表 poam_milestones),本案一筆 task 對一個系統任務;任務=一條工作流程(compliance.workflow_executions),底下可能多站(job_executions,例如證據上傳 → 主管檢核 → 顧問檢核);稽核次=FR-140 的 audit_round_passes,一輪內每做一次稽核一筆,各自一組 AP/AR/POA&M。

§1

變更紀錄

日期 變更 對應
2026-10-17 v1:D1~D12 定案;資料模型與 OSCAL 落點、API、畫面、Excel 契約、退卡規則、六棒六張卡、端到端驗收 母卡 CM-2840
2026-10-17 v1.1:修任務粒度自相矛盾——一塊對一條流程(不是一站一塊),執行人員只改第一站;D3、D5、D10、驗收 2 與 5 改寫 棒 2、5 驗收時發現,決策者裁 A 案
2026-10-17 v1.2:D9 清單改依專案分組展開(與 FR-142 稽核作業同一套),小字「共 N 份改善計畫」;待規劃判準補輪次仍在 remediation 決策者裁;棒 7 CM-2851

§2

分工概述(30 秒版)

整案一句話:缺失改善頁換成左樹只列不符合評估目標、中間上半看稽核缺失、下半對原任務逐一設執行人員/改善期限/改善措施,送出就把任務退回第一站重跑不等改完;側邊選單多一個「改善計畫」表格入口;Excel 與前兩階段同一份往右延伸;POA&M 匯出合規。

卡 做什麼 產出 完成怎麼判定(決策者親手做什麼、看到什麼)
1 套件 POA&M 匯出合規與守門改法 jedi-oscal-v2 匯出修四處;jedi-compliance-audit 守門改「計畫齊全」、task 對應任務 DEV 一個有不符合的稽核次送出改善計畫後,匯出 OSCAL JSON 用官方 schema 驗證通過,檔內每個 task 有改善期限與執行人員
2 BE 改善計畫端點 新 app service、route、schema、error code Swagger 存一條有兩條流程的評估目標讀回一致;有流程沒填齊送出回 412 列出是哪個;送出後再存回 409
3 FE 改善計畫頁 新頁、子元件、舊頁退役 對照雛形畫面 1 逐頁操作,每個動作對應後端真資料
4 Excel 匯入匯出 workbook 讀寫、預覽 匯出改兩列匯回,預覽標出、確認後畫面更新;寫一個不是成員的名字預覽要求處理
5 退卡改第一站重跑、改善期限寫每一站 新 job_restart_service.py、退卡與覆核輪改接 三站流程全完成後送出改善計畫:第一站回進行中、後兩站回待辦、三站改善期限都是計畫日期、第一站指派人=執行人員、後兩站指派人不變
6 側邊選單「改善計畫」入口 讀模型、端點、FE 表格頁、路由 seed PM 帳號登入,側邊選單「改善計畫」看到待規劃稽核次表格、點列進該輪;只當 auditor 的帳號看不到或為空
7 清單改依專案分組展開 FE 頁改寫、共用分組 composable 「全部」頁籤同專案只一列、點列展開子列由舊到新、「目前」標在最急那次、全部展開/收合、搜稽核次自動展開;稽核作業頁行為不變

依賴:1 先做 →(2、4、5 可平行)→ 3 等 2;6 等 2。

%%{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
    C1[1 套件修正] --> C2[2 BE 端點]
    C1 --> C4[4 Excel]
    C1 --> C5[5 退卡重跑]
    C2 --> C3[3 FE 頁面]
    C2 --> C6[6 入口清單]
圖 1 — 卡片依賴

§3

決策定案

全部由決策者 2026-10-17 拍板,討論過程見討論稿。

D1 粒度=逐不符合評估目標;控制項只是分組 左樹到評估目標,每條各自規劃;控制項總覽只是彙總。OSCAL poam-item 對 finding(FR-142 起 finding 已是評估目標層)。排除:控制項層一筆(第 2 次內稽縮範圍是評估目標層,對不上)。

D2 只排計畫不追蹤完成 沒有打勾、沒有進度條;改好沒有=下一次稽核判定。poam_milestones.status/completed_at 停用不刪。排除:保留打勾但不當守門(兩套真相)。

D3 不新增任務;對評估目標底下的原任務逐一設執行人員、改善期限、改善措施;守門=每個任務三欄齊;送出後鎖定 「任務」=一條工作流程(workflow_execution_control_mapping 掛的那一層),一條流程底下可能多站(證據上傳 → 主管檢核 → 顧問檢核);畫面一塊對一條流程,不是一站一塊。站只唯讀顯示名稱與狀態。一條評估目標底下有幾條流程就列幾塊,有缺失就都要退回,沒有「納不納入」。每塊:執行人員(可多人,預設第一站原指派人)、改善期限(即里程碑)、改善措施(可一鍵帶入稽核建議)。有任務沒填齊就擋送出並列出「任務名 未填:X」;送出後整份唯讀。排除:一站一塊(檢核站的人是流程範本定的,不該在改善計畫頁換;PM 要填三倍);PM 自建改善任務清單;一個任務多個里程碑;任務可勾不納入;送出後仍可改改善期限。

D4 改善期限逐任務設定、寫回該任務;一個任務對多條評估目標時共用執行人員與改善期限 畫面上同一任務在第二條評估目標出現時顯示「此任務同時對應 X,執行人員與改善期限一併套用」。排除:一條評估目標一個改善期限套全部任務;取最早或最晚。

D5 執行人員=流程第一站的指派人,可多人,預設帶第一站原指派人,PM 可加減;送出時只改寫第一站的 task_assignees,後續站維持原人 DEV 實查三站流程每站各有其人(執行者/主管/顧問);改善計畫的執行人員是「誰去改」,檢核站的人不因排計畫而換。送出確認表註明相較原指派人增減了誰。排除:三站都換成執行人員(執行人員自己檢核自己);計畫上另記負責人、任務指派人不動。

D6 Excel=與稽核計畫、稽核結果同一份往右延伸;一列一個任務;同評估目標的灰底欄合併儲存格 契約見「Excel 契約」。決策者原則「每階段往右加欄,最後是完整軌跡」(FR-142 D9 已定);一格換行 user 一定填錯、往右長一組 user 不會用。排除:一格多值換行;每任務往右長一組;砍計畫欄只留重點;執行人員拆三欄。

D7 匯出兩個:Excel 工作表、OSCAL POA&M JSON;不做 Word/PDF 報告 OSCAL POA&M 頂層沒有文件正文欄位(AP 有 terms-and-conditions,POA&M 只有 metadata/remarks),硬放等於自創欄位;業界 POA&M 交付物就是表格(FedRAMP 官方範本是 Excel)。排除:報告 docx/pdf;概要頁籤;併進稽核報告。

D8 舊資料不管 既有輪次的改善計畫不遷移、不處理。新頁只服務本案上線後結案的稽核次。排除:寫遷移;新頁唯讀顯示舊資料。

D9 側邊選單加「改善計畫」入口(不加「我的」),表格依專案分組展開,列出我是專案經理的輪次 與 FR-142 稽核作業同一套:一專案一列,專案列的值取「目前這一次」(待規劃 > 已送出 > 覆核中 > 已結束,同狀態取最晚期限最近);專案名下小字「共 N 份改善計畫 · 第 R 輪 · 標準」(N=該專案有改善計畫的稽核次數,決策者裁 A 案)。點專案列展開子列:該專案每一份改善計畫依結案日由舊到新,「目前」加粗標 tag;只有一份的不展開、小字直接寫稽核次、點列直接進。預設展開有待規劃的專案;工具列「全部展開/收合」。欄位:狀態、已規劃/不符合、退回任務數、最晚期限(30 天內橘、過期紅)、稽核結案、送出日。狀態頁籤仍算稽核次、預設「待規劃」,篩選後子列只剩符合的並加「(符合篩選 M 次)」;可篩稽核性質與標準、搜專案名與稽核次(命中子列自動展開並標黃)。排序、分頁以專案為單位,每頁 10 個專案。前端一次撈全部稽核次後分組;分組 composable 與稽核作業頁共用(useAuditWorkGroups,注入預設展開規則與專案列額外欄位)。登入者判準只看「是該專案 manager」;待規劃=輪次仍在 remediation 且為目前稽核次且改善計畫未送出。理由:排計畫的人是 PM,入口藏在專案三層內是「不知道怎麼用」的原因之一;同專案多次稽核平列時看不出卡在哪。排除:卡片式;平列一稽核次一列(第一版,決策者改判分組);進度條;小字寫「共 N 次稽核」(B 案,子列只列有改善計畫的那幾次,數字對不上);併進「我的稽核」當分頁。

D10 退卡=每個任務退回第一站整條重跑 現行內稽退卡只把最新那一站改回進行中(not_met_job_redo_service._redo_one 用 pick_latest),三站流程全完成時重開的是顧問檢核,補證據的人改不到;DEV 現有 6 筆退卡紀錄全是單站流程,沒被測出來。定案:第一站改回進行中、通知第一站指派人(=執行人員);後續站改回待辦、保留原指派人,前一站完成才依序往下。改善措施照舊寫成任務上的系統留言。外稽覆核輪產新任務同理從第一站開始。排除:只重開最新站;讓 PM 選退到哪一站。

D11 不設「暫行緩解措施」欄 改好之前先做的臨時防護本來就該寫進該任務的改善措施。OSCAL risk.mitigating-factors 匯出留空。

D12 改善期限寫進該任務的每一站,不加欄位、不動 jedi-flow-engine 期限欄 job_executions.due_at 已存在(FR-140),但只在每一站上,流程主表沒有;complete_job 推出下一站不帶期限。定案:退卡時把 PM 設的改善期限寫進該任務全部站的 due_at(due_at_manual=false)。排除:流程主表加欄(動套件);流程變數;只壓第一站。


§4

現況接入點

① POA&M 資料模型(套件 jedi-oscal-v2,schema oscal)

三層既有,不加表:assessment_risks(status、deadline、mitigating_factors)→ assessment_remediations(lifecycle、title、description)→ poam_milestones(task_type、title、description、assignee_user_id、assignee_org_unit_id、target_date、status、completed_at、props)。poams(status)、poam_items(related_findings)。產生:pkg/jedi-oscal-v2/app/service/poam/poam_service.py:54 generate_from_findings,FR-142 結案 finalize_assessment 呼叫,每筆 not_met finding 一個 item(finding 已是評估目標層,粒度自然對)。

② 匯出(pkg/jedi-oscal-v2/app/service/io/oscal_io_service.py,1,697 行超標)

_risk_to_json(:1538)、_remediation_to_json(:1564)、_milestone_to_task_json(:1584)、_export_poam(:1600)、_poam_item_to_json(:1685)。四個不合規見「OSCAL 落點」。超標檔只准新開 poam_export_parts.py 再從原檔一行呼叫。

③ 套件服務與主專案端點

  • pkg/jedi-compliance-audit/app/service/poam_app_service.py(493 行):list_items、get_item、add_remediation、add_milestone、update_milestone、all_items_closed(:421)、earliest_milestone_dates(:434)、milestones_by_control(:449)。
  • pkg/jedi-compliance-audit/app/service/audit_round_pass_transitions.py:96 _close_on_pass:all_items_closed 不成立拋 GRC_POAM_NOT_ALL_CLOSED(GRC_412005)——這就是「要等改完才能走」的根。
  • pkg/jedi-compliance-audit/app/service/audit_round_app_service.py(918 行超標):finalize_audit(:470)、close_round(:522)、launch_reverify(:543)。
  • 主專案 api/project/__init__.py:109-114 掛 /audit-round/<round_uid>/poam-items、poam-item/<item_uid>、remediation/<uid>、poam-milestone/<uid>;route 在 api/project/routes/audit_round_route.py:380-485,守門 @require_capability("grc.audit.read")(讀)、grc.audit.create/grc.audit.update(寫)。
  • 退卡:app/flow_control/service/not_met_job_redo_service.py(126 行)redo_not_met_jobs → _redo_one → app/flow_engine/service/job_reopen.py reopen_job_execution;期限 job_due_date_service.due_at_from_milestone_date(台北 23:59:59)。
  • 流程退回:app/flow_engine/service/workflow_execution_service.py:787 revert_job(目標站重開、後續站改 TODO;帶 assert_job_operator 與輪次凍結守門,系統退卡不可直接呼叫)。
  • 錯誤碼:common/code/flow_control_error_code.py:100-109、285-286(GRC_POAM_*)。

④ FE 現況

src/views/project/RoundPoamView.vue(890 行超標)掛 /project/projects/:id/round/:roundUid/poam(router index.js:1130);端點常數 api.js:296-298;i18n round-audit-poam.json。本案整頁退役,只改一行導向新頁。「我的稽核」入口:MyAuditsView.vue(320 行)、/project/audit-manage、BE app/readmodel/service/auditor_dashboard_service.py+infra/readmodel/audit/auditor_dashboard_query.py(162 行);路由 seed 先例 scripts/sql/2026-04-27-add-audit-and-cloud-integration-permissions.sql:31-47。

⑤ 可沿用

FR-142 的頁面骨架、Excel 四頁(ap_workbook_*/ar_workbook_*)、匯入預覽模式;任務指派人 task_assignees(多人);退卡系統留言 not_met_redo_comment.build_redo_comment;任務到期提醒(FR-140 P4)不動。


§5

詳細設計

OSCAL 落點(POA&M,v1.2.2)

畫面 OSCAL DB
一條不符合評估目標 poam-items[]:title/description 抄 finding、related-findings[{finding-uuid}]、related-risks[{risk-uuid}] oscal.poam_items(既有產生)
稽核缺失(唯讀) 從 AR 讀 finding、observation、risk、remediation lifecycle=recommendation;匯出時內嵌進 POA&M 檔 不重存
改善計畫(整組) risk.remediations[] 一筆 lifecycle=planned、title=「改善計畫」 oscal.assessment_remediations
一個任務的設定 response.tasks[] 一筆:type=action、title=任務名、description=改善措施、timing.on-date.date=改善期限、responsible-roles[{role-id:'remediation-owner', party-uuids:[…]}]=執行人員、props[name=job-uid]=任務流程 uid oscal.poam_milestones:task_type=action、title、description、target_date、props.job_uid、props.assignee_user_ids[](多人全部進 props,assignee_user_id 存第一人向後相容)
送出 risk.status=remediating、risk.deadline=該項最晚改善期限;poams.status=submitted;同時寫回任務指派人、各站 due_at、系統留言 assessment_risks.status/deadline、oscal.poams.status、compliance.task_assignees、compliance.job_executions.due_at
鎖定 以 poams.status 判 —

官方必填:poam-item(title/description)、response(uuid/lifecycle/title/description)、task(uuid/type/title)、risk(uuid/title/description/statement/status)。執行人員對 party-uuid:專案參與者在 SSP metadata.parties 有對應 party(既有 matched_user_id),查不到的只寫 props(name)不寫 responsible-roles,不造假 uuid。mitigating-factors 留空(D11)。

匯出四處修正(棒 1):

# 現況 修法
1 _milestone_to_task_json 沒帶 timing/responsible-roles 補 timing.on-date.date=target_date、responsible-roles 反查 party-uuid
2 related-findings 塞私有鍵 finding-id(官方 additionalProperties:false) 匯出剝掉;DB 繼續存
3 POA&M 檔 findings[]/risks[]/observations[] 空,poam-item 引用懸空 匯出時把被引用的 finding、risk(含 remediations)、observation 寫進 POA&M 檔(同 uuid,組裝不複製 DB)
4 task 自創 status/completed_at 不匯出;DB 欄不刪

讀寫 API(棒 2)

掛在既有 /audit-round/<round_uid> 下,讀取以 FR-140「目前稽核次」取 POA&M(GET 可帶 pass)。新邏輯一律新檔 app/flow_control/service/poam_objective_app_service.py,不往套件 493 行的 poam_app_service.py 加。

方法 路徑 用途
GET …/poam/objectives 只列不符合的控制項樹(族群→控制項→評估目標)、每條的稽核缺失(finding、risk、recommendation、稽核人員、查核方法、採用佐證)、底下的任務(流程 uid、名稱、原指派人、站數與狀態、目前設定:執行人員/改善期限/改善措施)、計畫狀態、統計六格、鎖定旗標
PUT …/poam/objective/<part_id> 存一條評估目標底下全部任務的設定(陣列:job_uid、assignee_user_uids[]、due_date、advice);同一任務在別條評估目標也存在時一併套用;回傳該控制項最新狀態與統計
POST …/poam/submit 守門(每個任務三欄齊,412 列「任務名 未填:X」)→ risk.status=remediating、deadline、poams.status=submitted → 寫回任務指派人與各站改善期限、系統留言 → 呼叫既有 close_round(內稽退卡走棒 5 的第一站重跑;外稽進待覆核)→ 鎖定
GET …/poam/export?format=xlsx|oscal 匯出二選一
POST …/poam-xlsx/parse、/poam-xlsx/<parse_uid>/confirm Excel 匯入預覽與確認(棒 4)

鎖定:送出後所有寫入端點回 409(新 error code GRC_POAM_SUBMITTED_LOCKED(「改善計畫已送出,內容不可修改」),GRC_409042(現有最大 409041))。權限:route 掛 grc.audit.read(讀)/grc.audit.update(寫,同既有 PoamMilestoneRoute);app service 內再以 common/authz 資源域守門要求專案 manager 才可寫,auditor 可讀。守門改法(棒 1):_close_on_pass 的 all_items_closed 改成 all_items_planned(每個 item 的每個 task 都有 target_date、assignee、description);GRC_POAM_NOT_ALL_CLOSED 文案改「尚有任務未完成規劃」。

任務對應:一條評估目標底下的任務=workflow_execution_control_mapping 對到該控制項(control_id)的流程;FR-141/142 已逐評估目標對應者取 ao_part_id,否則控制項層全部任務都算(與 FR-142 D8 佐證候選同源)。

畫面(棒 3)

照雛形 prototype/poam-authoring.html。FE 新檔 src/views/project/RoundPoamPlanView.vue+src/components/grc/poam/:PoamObjectiveTree.vue(左樹只列不符合、燈號已規劃/部分規劃/未規劃)、PoamControlOverview.vue、PoamObjectiveForm.vue(稽核缺失文件表單+任務區塊)、PoamTaskCard.vue(執行人員 chip 多選、改善期限、改善措施、帶入稽核建議)、PoamSubmitDialog.vue(守門清單/確認表)、PoamImportPreview.vue(預覽模式)。舊 RoundPoamView.vue 改一行導向新頁後退役。表單用語照雛形(稽核缺失、執行人員、改善期限、改善措施、已規劃/未規劃/待規劃),不放說明句(FR-142 D12 同)。禁 border-left ≥3px。

Excel 契約(延伸 FR-141、FR-142,棒 4)

「改善計畫」頁只列判不符合的評估目標,一列一個任務;同一條評估目標的灰底欄合併儲存格、垂直置中,評估目標之間粗上框;凍結窗格在 S 欄:

欄 內容 匯入
A(隱藏) part_id 比對鍵
B~J(灰,合併) FR-141 計畫欄:序號、控制項、實務要求、執行說明、評估目標、查核方法、受評人員、受評元件、稽核人員;D~J 群組預設收合 不讀
K~Q(灰,合併) FR-142 結果欄:稽核結果、佐證檔案、其他佐證、稽核發現、風險等級、風險說明、稽核建議 不讀
R(隱藏) job_uid 比對鍵
S~T(淺藍) 任務、原指派人 不讀
U(黃) 執行人員:一格,多人以 ; 分隔;預設原指派人;必須是專案成員 讀
V(黃) 改善期限:YYYY-MM-DD,日期驗證;必填 讀
W(黃) 改善措施;必填 讀

「可選清單」頁只留「執行人員(專案成員)」。匯入預覽:異動列標黃、原值劃掉;執行人員對不到成員、日期格式不對、同一任務多列執行人員或改善期限不一致 → 標紅「待確認」就地處理;全部處理完才能確認。匯出名「改善計畫工作表(Excel)」。範例:prototype/sample/FR-143-改善計畫範例.xlsx(產生腳本 make_sample_xlsx.py)。

退卡與覆核輪(棒 5)

新檔 app/flow_control/service/job_restart_service.py:restart_from_first_station(workflow_execution_id, due_date, assignee_user_ids, curr_user):

  1. 取該流程全部站(get_latest_station_jobs),依 BPMN 順序找第一站。
  2. 第一站 reopen_job_execution(進行中、清 end_time、通知);其餘站 status 改 TODO、清 end_time;流程 status 改 PROCESSING。
  3. 每一站 due_at=due_at_from_milestone_date(due_date)、due_at_manual=false。
  4. 第一站的 task_assignees 改成執行人員清單(保留 is_approver 既有值);後續站不動。
  5. 寫 job_execution_redo_log(每站一筆)與系統留言(build_redo_comment,內容=改善措施)。

not_met_job_redo_service.redo_not_met_jobs 改成逐 task 呼叫上式(來源從 earliest_milestone_dates 改讀 task 的 props.job_uid+target_date+props.assignee_user_ids)。launch_reverify 新任務:從第一站開始,due_at 與指派人同上。到期提醒(FR-140 P4)不動。

入口清單(棒 6)

BE 新讀模型 app/readmodel/service/poam_dashboard_service.py+infra/readmodel/audit/poam_dashboard_query.py(照 auditor_dashboard_* 寫法):條件=登入者是該專案 manager、稽核次已結案且 POA&M 有 item;欄位見 D9;分頁、排序、篩選(狀態、稽核性質、標準、關鍵字)走後端。端點 POST /grc/poams/my/list(RequestMetaSchema)。FE 新頁 src/views/project/MyPoamsView.vue(表格,照 MyTasksView 的 lazy DataTable),路由 /project/poam-manage,名稱 poam-manage。路由 seed:scripts/sql/<日期>-fr143-poam-manage-route.sql(phase=seed:ui_routes 一列、route_capabilities 綁 grc.audit.* read=ALL,照 2026-04-27 先例);守衛 test/test_fr132_route_entry_registered.py 要過。


§6

端到端流程

%%{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'}}}%%
sequenceDiagram
    participant PM
    participant FE as 改善計畫頁
    participant BE as BE/套件
    participant Job as 任務流程
    PM->>FE: 側邊選單「改善計畫」→ 點輪次
    FE->>BE: GET /poam/objectives
    BE-->>FE: 不符合評估目標:稽核缺失+底下任務
    PM->>FE: 逐任務設執行人員、改善期限、改善措施,儲存
    FE->>BE: PUT /poam/objective/<part_id>
    PM->>FE: 送出改善計畫
    FE->>BE: POST /poam/submit
    BE->>BE: 守門:有任務沒填齊 → 412 列原因
    BE->>BE: risk.status=remediating、poams.status=submitted、鎖定
    BE->>Job: 每條流程:第一站回進行中且指派人=執行人員、後續站回待辦、每站 due_at=改善期限、系統留言、通知
    BE->>BE: close_round(內部缺失改善站推進)
    BE-->>FE: 已送出
圖 2 — 內稽:規劃 → 送出 → 退回第一站

外稽同前半段;送出後 close_round 走「母輪→pending_reverify」;launch_reverify 新任務從第一站開始、改善期限與指派人照計畫。


§7

端到端驗收

  1. 入口:PM 帳號登入,側邊選單「改善計畫」,表格一專案一列(小字「共 N 份改善計畫 · 第 R 輪」),預設頁籤「待規劃」帶筆數、有待規劃的專案預設展開;點多份專案展開子列由舊到新、「目前」標在最急那次;搜稽核次文字命中自動展開標黃;只當 auditor 的帳號看不到或為空。
  2. 規劃:點一輪進改善計畫頁,左樹只有不符合的評估目標;點 AC.L1-b.1.iv [c],上半文件表單顯示稽核發現、風險等級、稽核建議、查核方法、採用佐證;下半列出底下的流程各一塊(一條三站流程只有一塊,站名與狀態唯讀列在塊內);加一位執行人員、設改善期限、按帶入稽核建議;儲存重整還在;左樹燈號部分規劃。
  3. 共用:同一任務在另一條評估目標出現時顯示共用提示,改改善期限兩處同步。
  4. 守門:還有任務沒填齊時按送出被擋,列出「主管檢核 未填:改善措施、改善期限」;補完後確認表列出每個任務、執行人員(註明新增誰)、改善期限;送出成功頁面唯讀,再呼叫寫入 API 回 409。
  5. 退卡:三站流程全完成後送出:第一站回進行中、後兩站回待辦、三站 due_at 都是計畫日期(台北 23:59:59)、第一站 task_assignees 等於執行人員、主管檢核與顧問檢核的指派人不變、第一站有系統留言寫改善措施、執行人員收到通知;「我的任務」看到第一站帶改善期限。
  6. Excel:匯出 Excel,改善計畫頁一列一任務、計畫欄收合、評估目標欄合併;改兩列執行人員與改善期限、寫一個不是成員的名字匯回,預覽標黃與待確認,就地修正後確認,畫面更新。
  7. OSCAL:匯出 OSCAL POA&M JSON,用 ~/.claude/skills/oscal-knowledge/references/json-schemas/oscal_poam_schema.json 驗證通過;每個 task 有 timing.on-date 與 responsible-roles;related-findings 沒有 finding-id;findings[]/risks[] 非空。
  8. 外稽:外稽送出後輪次進待覆核;發起覆核輪,新任務從第一站開始、改善期限與指派人照計畫。

§8

拆分表

Notion:母卡 CM-2840;子卡 1=CM-2841、2=CM-2842、3=CM-2843、4=CM-2844、5=CM-2845、6=CM-2846、7=CM-2851。

卡 做什麼 碰哪裡 套件 依賴 驗收
1 匯出四處修正;all_items_closed→all_items_planned;task 存 props.job_uid/assignee_user_ids;earliest_milestone_dates/milestones_by_control 改回傳逐 task(job_uid、date、assignees、advice) pkg/jedi-oscal-v2/app/service/io/ 新 poam_export_parts.py;pkg/jedi-compliance-audit/app/service/poam_app_service.py(493)、audit_round_pass_transitions.py:96 兩支 — 驗收 7
2 poam_objective_app_service.py+API、守門、鎖定、寫回任務、推進 app/flow_control/service/、api/project/routes/、api/project/__init__.py、common/code/ — 1 驗收 2、3、4 的 API 部分
3 FE 改善計畫頁 FE src/views/project/RoundPoamPlanView.vue、src/components/grc/poam/、router、api.js、i18n — 2 驗收 2、3、4 畫面部分
4 Excel 一列一任務讀寫(合併、群組)、執行人員比對、預覽;FE 預覽模式 app/flow_control/service/poam_workbook_*.py(新);FE PoamImportPreview.vue — 1(FE 部分等 3) 驗收 6
5 job_restart_service.py;退卡改逐 task 第一站重跑、每站 due_at、指派人;覆核輪同 app/flow_control/service/not_met_job_redo_service.py(126)、新檔;pkg/jedi-compliance-audit/.../audit_round_app_service.py:543 launch_reverify jedi-compliance-audit 1 驗收 5、8
6 入口清單讀模型、端點、FE 表格頁、路由 seed app/readmodel/、infra/readmodel/audit/、api/、FE MyPoamsView.vue、scripts/sql/ — 2 驗收 1
7 清單改依專案分組展開;useAuditWorkGroups 泛用化與稽核作業頁共用 FE MyPoamsView.vue、useAuditWorkGroups.js、my-poams.json — 6 驗收 1

§9

坑與陷阱

# 坑 影響 對策
1 現行退卡 pick_latest 只重開最新一站 多站流程退錯人;DEV 6 筆退卡紀錄全單站,測不出 棒 5 新 service 退第一站;驗收 5 用三站流程
2 期限只在站層,推出下一站不帶 後續站沒期限 D12:退卡時全部站一次寫
3 revert_job 帶操作者與輪次凍結守門 系統退卡直接呼叫會被擋 棒 5 另包,不呼叫 revert_job
4 oscal_io_service.py 1,697 行、audit_round_app_service.py 918 行、RoundPoamView.vue 890 行皆超標 不能往裡加 新開檔;原檔只加一行呼叫或退役
5 task assignee_user_id 單值 多執行人員存不下 props 存全部、欄位存第一人;匯出 responsible-roles 讀 props
12 「任務」與「站」混用 雛形曾把三站畫成三塊,規格跟著寫錯 本文件「任務」一律指流程;站只唯讀顯示
6 執行人員對 party-uuid 查不到 匯出造假 uuid 不合規 查不到只寫 props 不寫 responsible-roles
7 同一任務對多條評估目標 兩邊設定不一致 PUT 時一併套用;Excel 多列不一致標待確認
8 related-findings 私有鍵 finding-id 官方 schema 驗證失敗 匯出剝掉,DB 留
9 送出後 PM 在抽屜改改善期限(FR-140 P5) 計畫與任務漂移 維持 P5:手改標 manual、不回寫 POA&M;計畫鎖定不改
10 路由 seed 是 phase=seed,不是主線 active 不需重產出貨基線 紀律段照實寫,runner 不要誤報
11 守門文案 GRC_POAM_NOT_ALL_CLOSED 被 FE i18n 引用 改文案要同步 FE 棒 1 改 BE 文案、棒 3 同步 i18n