下面整段是給執行 session 的 prompt。前置:Phase 2b 第一波已收(
80514dff等 4 commits)。 本波收完才輪 Phase 2c(收編)。
【接手主題】FR-048 Phase 2b-2 — 完成 2b 交棒單剩餘項(flow_engine 守門復活、participant canonical、4 組端點)+ 2 個跨 phase 縫隙(MF 敏感 GET、D14 補 JWT 批)
必讀:
docs/features/FR-048-2607-unified-auth-guard/endpoint-authz-matrix.md §7.2(2b 交棒單)+ §1 D14 定調 + §3 各模組矩陣docs/analysis/2026-07-07-unified-auth-guard-design.md §2 軸模型common/authz/ 現況(project.py / workflow.py / decorators.py)【branch】fix/v1.8.0-bugs,禁止切 branch。不動 jedi-* 套件。守門一律 common.authz canonical。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 【工作清單(建議照序)】
common/authz/project.py 增 assert_project_participant(前置 canonical)「任一參與者放行」版(軸③,與 assert_project_manager 同族):participant 為 None → ForbiddenError(GRC_NOT_PROJECT_PARTICIPANT)。查法用 project 層 participant 精確查詢或 role_service(跟 assert_project_manager 同查法即可,manager/auditor/reviewer/viewer 任一角色皆過)。登進 __init__.py 決策表。
| 端點 | 守門 | 備註 |
|---|---|---|
grc /jobs/export(GET,Excel) |
參與者 | project 維度從 request 取,resolve 後 assert_project_participant |
grc job-execution comments POST |
參與者 | 留言=協作行為;PUT/DELETE 已有 owner 守門不動 |
| project_summary_report create/update/delete/export/history-revert | 參與者 | spec 明載無角色細分=驗「專案歸屬」;update/delete/export 依 uid,需 domain service 補 report→project 反查(先 grep 有沒有既有反查,禁重複造輪) |
| subtask_status_history POST/PUT/DELETE | 參與者 | 同上,subtask→project 反查 |
run/state、archive:由 run/folder resolve 專案 → assert_project_manager(與已守的 trigger-classify 同軸同級)。ground-truth import(POST /classification-ground-truth):API 無專案維度(per-tenant),user 定調統一 manager → 實作為「該租戶內至少任一專案的 manager」判定(查 participant 表 role=manager 存在即過;RLS 已鎖租戶範圍)。加 docstring 說明此語意;不改 API 契約。此端點無 FE 頁面(維運 runbook 用),收緊零影響。common/authz/workflow.py assert_workflow_project_participant 開頭 return 拔掉,反查鏈改 v2:
task_assignees.project_id(memory 定調:別比對 workflow_execution_uid;v1 的 AP-task mapping 已 dark 不能用)jobs/batch-complete:每 job 走 flow_engine complete_job 隨之受守;其自身入口再補 project 反查(job_uids 可跨專案→逐 job 驗)api/module_frame/ 下含實際資料的 GET 補 @require_super_admin_route(順序:jwt 外、authz 內):template export/download(module_frame_template_import_route.py:66/94)、control-defaults GET list/detail(module_frame_control_default_route.py:50/75)、excel-template / ssp-import-template / ssp-export 類(見矩陣 3.2)。menu/list/detail 一般讀不掛。掛完登記過渡名單(併入 module_frame.manage)。
| 端點 | 處置 |
|---|---|
/module-frame/download/template、/download/yaml-template(module_frame_import_route.py:27/38) |
補 @jwt_required()(靜態範例檔,補認證即可) |
/survey/import-template |
同上 |
/issue/get_members |
補 @jwt_required() |
/task-survey/import-template/<task_uid> |
先查 FE 呼叫方式:axios(interceptor 帶 bearer)→ 補 JWT;<a href>/window.open → 不能盲加,改列 Phase 4 signed-token(矩陣註記)。有 ffa01a78 前科,不確定就查 FE source |
python -m pytest test/ -q --continue-on-collection-errors,comm 比對 FAILED/ERROR 清單,新增失敗必須 0)【FE 影響】本波多為 service 層守門(403 對正常流程不可見);flow_engine 復活影響任務完成/證據增刪——手測 checklist 必含「被指派 auditor 完成任務、增刪證據照常」。