公開回呼
先為指定資料表鑄造回呼憑證,再以只顯示一次的密鑰送出外部新增或更新;整合結束後應撤銷該憑證。
請求的 idempotency_key 會記錄在與資料列一起寫入的 durable receipt:在 receipt 視窗(預設 24 小時)內重複送出,會 replay 原本的結果並設 replayed: true;相同 key 搭配不同 body 則是 409 idempotency_key_reuse(詳情)。
同一份憑證也能讀取目標資料表的可寫欄位,讓公開表單自行產生欄位,而不必寫死一組會隨版主改名而失效的名稱。
POST
路由範本
/public/module/custom_tables/callback/{token_id}用途
讓外部系統使用綁定單一資料表的回呼憑證新增或更新資料列。
適用時機
ERP、表單或其他無 TeamSync 帳號的系統需要把事件寫入指定資料表時使用。
實際掛載路徑
- 完整路由
/public/module/custom_tables/callback/{token_id}
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 完整路由 | 可使用 | callback token (minted) |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
token_id | path | uuid | 是 | 鑄造回呼憑證時取得的 token_id;它是 URL 憑證的一半。 |
請求結構
CallbackRequestOpenAPI 快照中沒有此模型的頂層元件欄位。
回應結構
CallbackResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
ok | boolean | 否 | Always true on a 2xx response (the submission was accepted) |
op | "create" | "update" | 是 | The operation the request asked for |
process_id | string | null | 否 | ReviewProcess now holding the write (held_for_approval / already_pending) |
record_id | string | null | 否 | Id of the created/updated record; null when status is held_for_approval or already_pending (no row exists until a reviewer approves) |
replayed | boolean | 否 | True when idempotency_key matched a previous accepted request — no new write or staged change happened. Created/updated and held/already-pending outcomes are replayable for 24 hours. |
rule_label | string | null | 否 | Human label of the require_approval rule that held the write — safe to show the submitter (held_for_approval only) |
staged_change_id | string | null | 否 | Staged change holding the write (held_for_approval / already_pending) |
status | "created" | "updated" | "held_for_approval" | "already_pending" | 是 | Outcome discriminator. created/updated: the write landed and record_id is set. held_for_approval: a require_approval rule matched — the write is staged and now awaits review (process_id/staged_change_id set, record_id null); this is a terminal success, do NOT resubmit. already_pending: an identical submission (same approval match column value) or the target record is already held by the returned process — no second change was staged. |
範例
以具冪等鍵的回呼新增訂單
請求
{
"pathParams": {
"token_id": "11111111-1111-4111-8111-111111111111"
},
"body": {
"op": "create",
"data": {
"訂單編號": "ORD-1042",
"數量": 3
},
"idempotency_key": "event-1042"
}
}回應200
{
"ok": true,
"op": "create",
"status": "created",
"record_id": "22222222-2222-4222-8222-222222222222",
"process_id": null,
"staged_change_id": null,
"rule_label": null,
"replayed": false
}在 receipt 視窗內重複送出同一個帶 key 的建立:會回傳原本的結果與 replayed=true,且不會寫入第二列
請求
{
"pathParams": {
"token_id": "11111111-1111-4111-8111-111111111111"
},
"body": {
"op": "create",
"data": {
"訂單編號": "ORD-1042",
"數量": 3
},
"idempotency_key": "event-1042"
}
}回應200
{
"ok": true,
"op": "create",
"status": "created",
"record_id": "22222222-2222-4222-8222-222222222222",
"process_id": null,
"staged_change_id": null,
"rule_label": null,
"replayed": true
}被暫存待核准的 update(2xx,尚未落地)
請求
{
"pathParams": {
"token_id": "11111111-1111-4111-8111-111111111111"
},
"body": {
"op": "update",
"record_id": "22222222-2222-4222-8222-222222222222",
"data": {
"數量": 5
},
"idempotency_key": "event-1043"
}
}回應200
{
"ok": true,
"op": "update",
"status": "held_for_approval",
"record_id": null,
"process_id": "33333333-3333-4333-8333-333333333333",
"staged_change_id": "44444444-4444-4444-8444-444444444444",
"rule_label": "大量訂單變更",
"replayed": false
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 403 | 資料表的 `write_policy` 是 `commands_only`:任何不在 Command 之內的主體所做的資料列寫入,都會在任何東西被暫存、排入佇列或 commit 之前,以 typed 的 `governed_context_required` 被拒絕(不會產生版本、history、receipt、token 或 Review process)。`operation` 指出是哪種寫入,若該通道有名稱則以 `surface` 指出;請改用被允許寫入該資料表的 Command。讀取不受影響。 | |
| 409 | `date_interval_exclusion` 規則拒絕此次寫入:`date_interval_exclusion_invalid_period`(建立時省略 end key、結束日為空字串或不晚於起始日,或 scope link 沒有恰好一個目標)、`date_interval_exclusion_overlap`(另一筆 live 資料列涵蓋了這段期間的一部分),或 `date_interval_exclusion_retry`(寫入等待期間資料表的規則被改變;沒有寫入任何東西,請重送)。body 是固定訊息,絕不會指出資料列、日期或 scope 值。 | |
| 409 | 排除送審者(`exclude_requester`)之後,某個必要的審批 gate 沒有任何可核准者。送出會在任何 review process 出現之前就被拒絕;`gate_order` 指出該 gate。對於不管理每一張被引用資料表的 `authority: definition` command 呼叫者,只會回傳安全的 key,所以沒有 `gate_order`。 | |
| 409 | 這筆寫入需要排除送審者,但呼叫的主體沒有已驗證的人類身分(例如 service account),無法歸屬。不會暫存任何東西。 | |
| 400 | 請求格式、允許操作、資料規則或欄位內容不合法。 | |
| 400 | Body 的 `op` 不在 token 的 `allowed_ops` 內(用只能 create 的 token 做 update)。 | |
| 400 | Update 指定的欄位 key 既不是綁定資料表已知的顯示名稱,也不是內部 `col_<hex>` 鍵。(Create 則會靜默略過未知的 key。) | |
| 403 | 綁定的資料表帶有 enforcing 的 `channel` 規則,而 callback(沒有 acting chatroom)永遠無法滿足它;違反 invariant 會以同樣方式回 `scp_invariant_violation`。Minting 使用者無法讀取的 link 目標是 `404 linked record not found`,不是 403。 | |
| 404 | token 不存在、已撤銷、已過期,或所提供的密鑰驗證失敗。 | |
| 404 | Update 目標不存在、在垃圾桶中,或屬於其他資料表。只有 `Not found` 才是 token/auth 的一致回應。 | |
| 404 | 綁定的資料表在垃圾桶中。資料表丟進垃圾桶時會保留它的 token(永久清除才會刪除),查找垃圾桶中的資料表會回這個 body,而不是統一的 `Not found`;還原資料表即可恢復。 | |
| 409 | 使用這個 idempotency_key 的第一個請求仍在執行,或它的 receipt 尚未定案;稍候後用同一個 key 重試。 | |
| 409 | 在 receipt 視窗內,相同的 idempotency_key 搭配不同的 op、record_id 或 data。不寫入任何東西;一個事件請用一個 key。 | |
| 409 | 寫入在 `unique_tuple` 規則下碰撞(body 只點名約束與欄位,不含任何值;呼叫者讀不到某個 component 時,只列出讀得到的欄位、以不透明的 `rule_<hex>` id 稱呼規則,並加上 `message`)。舊式 `unique` 衝突只有在該列與整個鍵都讀得到時才帶 `conflicting_record_id` 與 `key_tuple`,違反 `same_dimension_reference` 則回 `same_dimension_reference_violation`,`date_interval_exclusion` 拒絕則回 `date_interval_exclusion_invalid_period`、`date_interval_exclusion_overlap` 或 `date_interval_exclusion_retry`。 | |
| 413 | 原始請求本文超過 64 KB。 | |
| 423 | 資料表正被遷移鎖定。 | |
| 429 | 單一 token 超過每分鐘 60 次,或待覆核暫存變更已達上限。 | |
| 429 | 待核准的暫存額度已滿:這個 token 在該表已有 500 筆待審變更(`scope: "actor"`),或該表已有 50 筆待審的新增(`scope: "table"`、`limit: 50`)。請暫停 producer,等 reviewer 消化佇列。 | |
GET
路由範本
/public/module/custom_tables/callback/{token_id}/form-schema用途
回傳目標資料表的顯示名稱與可寫欄位(名稱與型別),讓外部表單在送出回呼寫入前先自行產生欄位。
適用時機
當公開表單應該依資料表動態產生欄位,而不是寫死一組會隨版主改名而失效的欄位名稱時使用。
實際掛載路徑
- 完整路由
/public/module/custom_tables/callback/{token_id}/form-schema
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 完整路由 | 可使用 | callback token (Bearer secret or HMAC signature — same credential as the write route) |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
token_id | path | uuid | 是 | 回呼(寫入)token 的 token_id——與你送出寫入請求時使用的網址是同一半憑證。 |
回應結構
CallbackFormSchemaResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
columns | PublicColumnInfo[] | 是 | Writable columns (name + type). Computed columns omitted. |
table_name | string | 是 | Display name of the target table. |
範例
依 token 的目標資料表產生表單
請求
{
"pathParams": {
"token_id": "11111111-1111-4111-8111-111111111111"
}
}回應200
{
"table_name": "訂單回報",
"columns": [
{
"name": "訂單編號",
"type": "string"
},
{
"name": "數量",
"type": "integer"
},
{
"name": "狀態",
"type": "select"
},
{
"name": "備註",
"type": "text"
},
{
"name": "回報時間",
"type": "datetime"
}
]
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 404 | token 不存在、已撤銷、已過期,憑證驗證失敗,資料表已被永久清除(token 會一併刪除),或 sandbox run token 的使用者已不存在——這些都回傳完全相同的 404。綁定的資料表在垃圾桶中時則改回 `CustomTable Not found`。 | |
| 404 | 綁定的資料表在垃圾桶中。資料表丟進垃圾桶時會保留它的 token(永久清除才會刪除),查找垃圾桶中的資料表會回這個 body,而不是統一的 `Not found`;還原資料表即可恢復。 | |
Last updated on