Skip to Content
核心概念核准流程總覽

審批流程總覽

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 狀態,等決策後再刷新資料列。撤回 process,或由表格 moderator 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 永遠無法投票的情況同樣會被拒絕——使用者不存在、已軟刪、已停用、未驗證、已到期或屬於其他公司。這樣的 template 無法存進規則。

在 IaC 通道上,同一個失敗不是 HTTP 400:executor 會接住它,並把同一則訊息記成該資源行在 200 apply 報告中的 apply 錯誤;其他每一行照常執行。

含有直接使用者 leaf 的 template 同樣是合法的 require_approval 標的。既有的 400 review template '<id>' is not usable. template must exist, be live, and belong to this table's company 與 409 approval_trigger_conflict 不變。

誰能列出 staged changes

三種範圍的 GET .../staged-changes 都受資料表 metadata 閘門保護。資料表不存在或已在垃圾桶、屬於其他範圍、屬於其他公司(自後端 5.21.0 起;過去回 403),或同公司但對資料表沒有任何權利的呼叫者,都會得到同樣的 404 CustomTable Not found——被隱藏的資料表看起來與未知 id 完全相同。有任何權利(讀取、只能新增、只能編輯、moderator)的呼叫者仍可列出;沒有讀取權的人只看得到自己建立的 staged change,且 payload 與 results 不會回傳。Discard 仍只限 moderator。

自 backend 5.21.0 起,列表改為先分頁取 key:先排序並計算呼叫者看得到的 id 數量,再用第二次讀取載入所要求那一頁的 payload,所以 staged change 帶有極大 payload 的資料表也能正常列出,而不是失敗。篩選、排序、total 與上述遮蔽都不變;Command 執行歷史清單(…/commands/{command_id}/executions)同樣先一次讀取排序後的 key,再以每批 100 筆載入 payload。

每一筆都帶有 snapshot_version——暫存時擷取的紀錄版本,create、batch_actions 與 command_plan 則為 null(它們的 record_id 也是 null)——以及 attempts(套用超過五次會以 apply_failed 結束)、兼作套用中心跳的 updated_at,還有只在狀態變成 applied 時才會設定的 applied_at。

指令計畫的摘要改為加上金鑰

對於暫存的 Command 計畫(change_type: "command_plan"),moderator 看到的 payload 與 Review process 的 content 不再露出純 SHA-256:private_plan_sha256、review_manifest_sha256、semantic_sha256 與 review_manifest.command.definition_sha256 都以 tcm1: 金鑰承諾值回傳。相同的計畫仍會得到相同的值,但讀者無法拿猜測的 trigger 機密去比對摘要。儲存的值沒有改變,所以 release 仍會驗證原始計畫。見指令核准。

排隊的 bulk insert 在暫存前會重新檢查權限

非同步的 bulk insert 會在 worker 裡、以即時的成員資格與 grant 重新授權,時間點早於 approval 暫存或任何資料列處理。若送出者在這段期間失去 insert 權限,ticket 會以 failed 結束,error_code 為 custom_table_bulk_insert_authorization_denied(Insert authorization is no longer available.),也不會建立 staged change 或 Review process。

超過 1000 個 action 的受審核佇列式批次新增、更新或刪除也不會暫存:它的 ticket 會以 failed 結束,帶 progress: 0、error: {"error":"gated_batch_too_large","limit":1000} 與 error_message: "gated batch exceeds the approval row limit (1000); split it or narrow the rule"。見其他拒絕與上限。

一列渲染不出來的 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 規則。
  • 完整流程——前置的 template、被暫存的寫入、reviewer decision,然後是 release 或 discard:審批流程指南。
  • Staged change 與規則 endpoints:規則參考。
  • 同步/非同步批次如何呈現 held 狀態:批次操作。

要以合成資料逐步走完規則與暫存寫入,可使用審批設定精靈。

Last updated on