審批流程總覽
require_approval 把「符合條件的寫入」從立即生效改成先暫存、再由 review module 決定是否釋出。它不是寫入後補通知:在核准前,live record 保持原狀。
流程地圖
require_approval rule 命中
↓
寫入被保存為 staged change,live row 不變
↓
建立 review process,依 template 產生 assignment
↓
reviewer approve / reject
↓
approve:套用 staged change reject / discard:不套用一般同步寫入命中規則時會回 409,並提供串接 UI 所需的識別值:
{
"detail": {
"error": "approval_required",
"process_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
"rule_id": "rule_a1111111",
"rule_label": "高額訂單審批",
"staged_change_id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd"
}
}這個 409 代表請求已成功進入審批,而不是讓前端原封不動重試。應導向 process/assignment 狀態,等決策後再刷新資料列。撤回或管理者 discard staged change 都會留下稽核結果,但不修改 live row。
儲存規則時就會驗證範本的 reviewer
儲存 require_approval 規則時會載入所引用的 review template,並執行與建立 template 時完全相同的 gate 驗證。在 PUT /private/module/custom_tables/{scope}/tables/{table_id}/rules 與 POST /private/module/custom_tables/{scope}/tables/{table_id}/rules/preview 上,失敗是 400,其 detail 是單一字串——把 review module 自己的 422 detail 原樣包起來:
review template '66666666-6666-4666-8666-666666666666' has invalid gate groups: review users not found or inactive: ['33333333-3333-4333-8333-333333333333']review groups have no active members: [...] 也以同樣形式出現。真正變的是涵蓋範圍:驗證現在也會擋掉未驗證或已到期的 reviewer,以及 user_id 不存在、已軟刪、已停用、未驗證、已到期或屬於其他公司的直接使用者 leaf。過去只擋得住「群組不存在」與「群組沒有任何未刪除成員」——reviewer 永遠無法認證的 template 會以 200 存檔,之後生出來的流程卡在 in_review,選票沒有人投得下去。
在 IaC 通道上,同一個失敗不是 HTTP 400:executor 會接住它,並把同一則訊息記成該資源行在 200 apply 報告中的 apply 錯誤;其他每一行照常執行。
反向也成立:含有直接使用者 leaf 的 template 是合法的 require_approval 標的。規則存得下去,生出來的流程就指派給那一個人——不需要為此建一個只有一人的 review group。既有的 400 review template '<id>' is not usable 與 409 approval_trigger_conflict 不變。
Review 列表可相對呼叫者分流,不必逐筆抓 detail
GET /private/module/review/processes 接受 role=requested|assigned。requested 表示 caller 送出的流程;assigned 表示 caller 目前或曾持有 ballot。即使 caller 是 manager,這個 filter 仍然只相對於他本人,不會擴成全公司可見集合。省略 role 時,manager 看全公司,其他人看自己 requested 與 assigned 的聯集。
每筆 summary 都獨立回傳 requested_by_me 與 assigned_to_me,因此同一流程可能兩者都是 true。只有 requester_id 仍能在呼叫者的公司內解析成使用者時,requester 才會帶 id、顯示 name、department_id 與 department_name;否則為 null,包括 client/AI 送審,以及送審人已無法在該 tenant 解析的歷史真人流程。若當初有記錄,client/AI 的來源身分仍保留在 process content。前端應直接用這些欄位做 tabs、badges 與送審人標示,不要為列表每列再抓一次 detail。
Process detail 中,已決定的 ballot 可在 signature_blob_id 旁直接帶內嵌 signature_blob。內嵌物件含可渲染 URL 與檔案 metadata;pending/不需簽名或 blob row 已不存在時是 null。顯示時優先用內嵌物件,同時保留 ID 作 durable reference。
一列渲染不出來的 staged row 不再拖垮整頁
payload 損毀、或早於目前格式的 command_plan staged row,以前會讓整份列表 500,於是一列壞資料就讓所有審核者看不到這張表上任何待審變更。現在 GET .../staged-changes 回 200:正常的列照樣帶著自己的 payload,壞的那一列帶的是 {"error": "unrenderable_staged_payload", "message": "This staged command plan is malformed or predates the current payload format and cannot be rendered; it can still be discarded."}。它仍然看得到、也仍然丟得掉——而丟棄本來就是它唯一支援的動作。
往哪裡繼續
- 規則何時命中、支援哪些操作與條件:
require_approval規則。 - 從 review group/template 到 reviewer decision 的完整呼叫順序:審批流程指南。
- Staged change、規則與 review endpoints:規則參考與 Review 參考。
- 同步/非同步批次如何呈現 held 狀態:批次操作。
要以合成資料逐步走完設定與決策,可使用審批設定精靈。