Skip to Content
API 參考規則、觸發器與回呼

規則、觸發器與回呼

驗證寫入、自動化資料表事件、檢視階段性工作,並管理各範圍支援的回呼憑證。

GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/rules

取得資料表規則

用途

回傳資料表已正規化的規則定義(參照以顯示名稱呈現),並附上 `rules_digest`,作為之後 PUT 的前置條件權杖。

適用時機

適合顯示規則編輯器,或在變更資料前檢查實際套用的寫入限制。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/rules
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/rules
  • 公司/private/module/custom_tables/company/tables/{table_id}/rules

範圍

範圍是否提供驗證與權限
聊天室可使用ChatroomTableMetadataReadRequired
部門可使用DepartmentTableMetadataReadRequired
公司可使用CompanyTableMetadataReadRequired

參數

欄位位置型別必填說明
table_idpathuuid是要取得規則的資料表 UUID。

回應結構

TableRulesResponse
欄位型別必填說明
rulesobject[]否未指定
rules_digeststring是Stable digest of the stored normalized rule list, for expected_rules_digest on a later PUT.
table_idstring是未指定
warningsstring[]否Non-fatal notices about the saved rule set — e.g. a content-masking notice when a require_approval rule is saved on a table with column_acl or grant visible_columns restrictions (approval-gate spec §4).

範例

取得資料表的唯一值規則

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  }
}
回應200
{
  "rules_digest": "3b7e9c0d4a1f2e8b6c5d9a0f1e2d3c4b5a69788796a5b4c3d2e1f0a9b8c7d6e5",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "rules": [
    {
      "type": "unique",
      "id": "rule_a1b2c3d4e5f6",
      "name": "訂單編號不可重複",
      "columns": [
        "訂單編號"
      ],
      "case_insensitive": true,
      "when": null,
      "constraint_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
    }
  ],
  "warnings": []
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
404資料表不存在或已在垃圾桶、屬於其他範圍,或你對它沒有任何權利——所有情況都回 `CustomTable Not found`,因此被隱藏的資料表看起來與未知 id 完全相同。其他公司的資料表也回同樣的 404(自後端 5.21.0 起)。
{
  "detail": "CustomTable Not found"
}
PUT
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/rules

取代資料表規則

用途

驗證並以原子方式取代後續資料表寫入所套用的完整規則集。

適用時機

預覽完整的目標規則集後使用;PUT 會在單一交易中取代已儲存的規則清單。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/rules
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/rules
  • 公司/private/module/custom_tables/company/tables/{table_id}/rules

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是要取代規則的資料表 UUID。

請求結構

TableRulesPayload
欄位型別必填說明
expected_rules_digeststring | null否Optional digest from GET rules. A changed stored rules list returns409 with no write; omission preserves unconditional replacement.
rules(AggregateLimitRuleSpec | SameDimensionReferenceRuleSpec | DateIntervalExclusionRuleSpec | PeriodFenceRuleSpec | object)[]是Full rules list (PUT semantics; max 10). Each rule: {"type": "compare" | "unique" | "unique_tuple" | "same_dimension_reference" | "date_interval_exclusion" | "no_overlap" | "exists" | "not_exists" | "count_limit" | "aggregate_limit" | "transition" | "check" | "require" | "require_approval" | "channel" | "invariant" | "immutable_when" | "period_fence", "name"?: str, "id"?: "rule_<hex>", "when"?: [predicates], ...type-specific fields}. An opt-in "unique_tuple" rule takes 1..16 ordered {"column": ref, "null_policy": "forbidden"|"equal"|"distinct"} components, "case_insensitive"?: boolean and "unicode_normalization"?: "none"|"NFC". A "count_limit" rule caps a live-row bucket at {"max": int >= 1}: with "table_id" + "match" it counts the exists-style cross-table bucket; without "table_id" it counts THIS table's rows matching "where" predicates ("$row.<col>" values partition per row, e.g. employee eq $row.employee). A "date_interval_exclusion" rule takes two distinct date columns and 1..2 cardinality-one native-link scopes; a create must supply its end as a date or explicit null, and [start,end) is non-overlapping within the partition. A "no_overlap" rule additionally takes "min_gap"?: number — minimum separation between intervals in the same scope partition (numeric bounds: plain number; datetime: minutes; date: days; touching at exactly min_gap is allowed) — and bounds its intervals EITHER with "start_column"+"end_column" OR with "interval_column" (ONE interval-type column whose {start, end} cell carries both bounds; datetime class, min_gap in minutes) — never both. A "channel" rule (SCP v1.3) takes EITHER {"column", "require_present", "read_op"?: "subset" | "overlaps"} or {"policy": <node tree>}, plus "enforcement": "observe" | "enforce" — see ChannelRuleFlat / ChannelRulePolicy. An "invariant" rule takes {"policy": <node tree>, "enforcement"} and is principal-blind: it holds for every writer on every path — see InvariantRule. An "immutable_when" rule takes {"prior_when": [predicates], "columns": [refs]} and takes no "when": prior_when is the lock condition evaluated against the row's PRE-image (the row before the write); while it matches, the listed columns may not change (400 on violation). Locks stored inline columns only (not computed/link). A "period_fence" rule (ct.calendars) refuses writes whose dated row falls in a closed or missing period — see PeriodFenceRuleSpec; at most 3 per table.

回應結構

TableRulesResponse
欄位型別必填說明
rulesobject[]否未指定
rules_digeststring是Stable digest of the stored normalized rule list, for expected_rules_digest on a later PUT.
table_idstring是未指定
warningsstring[]否Non-fatal notices about the saved rule set — e.g. a content-masking notice when a require_approval rule is saved on a table with column_acl or grant visible_columns restrictions (approval-gate spec §4).

範例

設定不分大小寫的唯一值規則

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "rules": [
      {
        "type": "unique",
        "name": "訂單編號不可重複",
        "columns": [
          "訂單編號"
        ],
        "case_insensitive": true
      }
    ]
  }
}
回應200
{
  "rules_digest": "3b7e9c0d4a1f2e8b6c5d9a0f1e2d3c4b5a69788796a5b4c3d2e1f0a9b8c7d6e5",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "rules": [
    {
      "type": "unique",
      "id": "rule_a1b2c3d4e5f6",
      "name": "訂單編號不可重複",
      "columns": [
        "訂單編號"
      ],
      "case_insensitive": true,
      "when": null,
      "constraint_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
    }
  ],
  "warnings": []
}

列一旦 posted 就凍結數量與單價

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "rules": [
      {
        "type": "immutable_when",
        "name": "posted-locks-qty",
        "prior_when": [
          {
            "column": "狀態",
            "op": "eq",
            "value": "posted"
          }
        ],
        "columns": [
          "數量",
          "單價"
        ]
      }
    ]
  }
}
回應200
{
  "rules_digest": "9f8e7d6c5b4a39281706f5e4d3c2b1a0f9e8d7c6b5a4938271605f4e3d2c1b0a",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "rules": [
    {
      "type": "immutable_when",
      "id": "rule_b2c3d4e5f6a7",
      "name": "posted-locks-qty",
      "prior_when": [
        {
          "column": "狀態",
          "op": "eq",
          "value": "posted"
        }
      ],
      "columns": [
        "數量",
        "單價"
      ],
      "when": null
    }
  ],
  "warnings": []
}

在 expected_rules_digest 前置條件下新增 unique_tuple 規則

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "expected_rules_digest": "3b7e9c0d4a1f2e8b6c5d9a0f1e2d3c4b5a69788796a5b4c3d2e1f0a9b8c7d6e5",
    "rules": [
      {
        "type": "unique",
        "id": "rule_a1b2c3d4e5f6",
        "name": "訂單編號不可重複",
        "columns": [
          "訂單編號"
        ],
        "case_insensitive": true,
        "when": null,
        "constraint_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
      },
      {
        "type": "unique_tuple",
        "name": "每年度發票號碼不可重複",
        "components": [
          {
            "column": "會計年度",
            "null_policy": "forbidden"
          },
          {
            "column": "發票號碼",
            "null_policy": "equal"
          }
        ],
        "case_insensitive": true,
        "unicode_normalization": "NFC"
      }
    ]
  }
}
回應200
{
  "rules_digest": "9f8e7d6c5b4a39281706f5e4d3c2b1a0f9e8d7c6b5a4938271605f4e3d2c1b0a",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "rules": [
    {
      "type": "unique",
      "id": "rule_a1b2c3d4e5f6",
      "name": "訂單編號不可重複",
      "columns": [
        "訂單編號"
      ],
      "case_insensitive": true,
      "when": null,
      "constraint_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
    },
    {
      "id": "rule_c3d4e5f6a7b8",
      "type": "unique_tuple",
      "name": "每年度發票號碼不可重複",
      "when": null,
      "components": [
        {
          "column": "會計年度",
          "null_policy": "forbidden"
        },
        {
          "column": "發票號碼",
          "null_policy": "equal"
        }
      ],
      "case_insensitive": true,
      "unicode_normalization": "NFC",
      "constraint_id": "cccccccc-cccc-4ccc-8ccc-cccccccccccc"
    }
  ],
  "warnings": []
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
400至少一筆規則的類型、欄位參照、運算式或選項無效。
{
  "detail": "rules[0]: invalid rule type 'unknown'. valid types: compare, unique, unique_tuple, same_dimension_reference, date_interval_exclusion, no_overlap, exists, not_exists, count_limit, transition, check, require, require_approval, channel, invariant, immutable_when, period_fence"
}
400immutable_when 規則缺少 prior_when 或 columns、帶了一般的 when、被鎖欄位超過 20 個,或鎖到計算欄/link 欄。detail 是純字串,有 hint 時會在句點後併入。
{
  "detail": "immutable_when requires a non-empty prior_when predicate list (the lock condition, evaluated against the row's pre-image). e.g. [{\"column\": \"status\", \"op\": \"eq\", \"value\": \"posted\"}]"
}
409仍有未解決的階段性變更依賴 require_approval 規則,因此不能變更該規則。
{
  "detail": {
    "error": "approval_rule_locked",
    "pending_count": 2
  }
}
403你看得到這張資料表,但不是它的 moderator。訊息內容依資料表範圍而定:這是你自己部門內聊天室資料表的回應;其他部門的聊天室資料表會是 `…or management rights.`,部門資料表是 `…table moderator, department manager, or company management rights.` 或 `…table moderator or department management rights.`,公司資料表則是 `…table moderator or company management rights.`
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
404部門或公司路徑:資料表存在、你也是它的 moderator,但它屬於路徑以外的範圍(`Table not found in this department`/`… in this company`)。因為公司管理者是公司內每張資料表的 moderator,這個情況確實可能發生。在聊天室路徑上,同樣的情況會回 `CustomTable Not found`。
{
  "detail": "Table not found in this department"
}
409`expected_rules_digest` 與已儲存的規則不符:期間有其他編輯者存檔。沒有寫入任何東西(規則與 history 都沒有)。請重新載入、重新套用你的修改,並送出新的摘要。
{
  "detail": {
    "error": "rules_changed",
    "message": "Table rules changed; reload before saving."
  }
}
409新增或修改的 `unique` 規則無法啟用,因為既有的 live 列已經重複。Body 會把最多五組碰撞樣本與其紀錄 id 列給讀得到每個 component 與每筆碰撞列的呼叫者(其他人只拿到衝突中繼資料);不會儲存任何東西。
{
  "detail": {
    "message": "cannot enable unique rule '訂單編號不可重複': existing records collide (1 sample conflict shown)",
    "columns": [
      "訂單編號"
    ],
    "conflicts": [
      {
        "key_tuple": [
          "ord-1001"
        ],
        "records": [
          "33333333-3333-4333-8333-333333333333",
          "dddddddd-dddd-4ddd-8ddd-dddddddddddd"
        ]
      }
    ]
  }
}
409新增或修改的 `unique_tuple` 規則無法啟用,因為既有的 live 列已經重複。Body 不含任何值——只點名約束與欄位,不列出資料列——且不會儲存任何東西。
{
  "detail": {
    "error": "unique_tuple_conflict",
    "constraint": "每年度發票號碼不可重複",
    "columns": [
      "會計年度",
      "發票號碼"
    ]
  }
}
409既有的 live 列已經違反新的 `same_dimension_reference` 規則(參照或維度缺少、不是 live,或沒有共用)。不會儲存任何東西。
{
  "detail": {
    "error": "same_dimension_reference_violation",
    "message": "Reference must share a live required dimension."
  }
}
409既有的存活資料列已經違反新的 `date_interval_exclusion` 規則:沒有合法期間的資料列(起始日缺漏、結束日缺漏或不晚於起始日,或 scope link 沒有剛好指向一個目標)是 `date_interval_exclusion_invalid_period`,同一分割內期間重疊的兩列是 `date_interval_exclusion_overlap`。什麼都不會儲存。body 只有固定訊息,絕不指出資料列、日期或 scope 值;`rules.preview` 不會執行這項檢查。
{
  "detail": {
    "error": "date_interval_exclusion_overlap",
    "message": "Date period overlaps another period in this partition."
  }
}
409這份清單替某張資料表加上 `require_approval` 規則,但有 trigger action 會寫入這張表(create_record/update_record 的目標、自身表的 delete_record、materialize_slots 的目標,或所引用指令會寫入它的 invoke_command)。請先移除或改寫那個 action 的目標。
{
  "detail": {
    "error": "approval_trigger_conflict",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "trigger_table_id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
    "trigger_table_name": "訂單",
    "trigger_id": "trg_666666666666",
    "trigger_name": "同步出貨",
    "action_type": "create_record"
  }
}
422Request 驗證失敗:超過 10 條規則、`unique_tuple`、`same_dimension_reference` 或 `date_interval_exclusion` 的 shape 錯誤(例如 17 個 component、缺少 `null_policy`、參照或期間規則帶非空的 `when`)、`channel` 或 `invariant` 規則的 shape 錯誤、policy 超過上限,或 `expected_rules_digest` 不是 64 個小寫 hex 字元。
{
  "detail": [
    {
      "type": "string_pattern_mismatch",
      "loc": [
        "body",
        "expected_rules_digest"
      ],
      "msg": "String should match pattern '^[a-f0-9]{64}$'",
      "input": "stale",
      "ctx": {
        "pattern": "^[a-f0-9]{64}$"
      }
    }
  ]
}
423資料表目前被結構遷移鎖定。
{
  "detail": "Table is currently locked for operation: add_column"
}
409Rules transaction 中遇到 MySQL 1205 lock-wait timeout 或 1213 deadlock。所有變更都已回滾;請重試請求。
{
  "detail": "Concurrent write conflict (lock); please retry the request."
}
500其他資料庫錯誤讓整個 transaction 回滾;detail 是淨化後的 flat 字串 Database operation failed.。
{
  "detail": "Database operation failed."
}
400儲存時發生非預期、非資料庫錯誤的兜底回應(前綴之後是錯誤文字)。不會儲存任何東西。
{
  "detail": "Failed to update rules: <exception text>"
}
POST
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/rules/preview

預覽資料表規則

用途

驗證候選規則集,並在有上限的樣本上評估,不儲存規則。

適用時機

取代正式規則前使用,特別是 `channel`/`invariant` 規則(抽樣的資料列影響)與 `same_dimension_reference` 規則(既有列准入檢查)。它不會把 `exists`/`not_exists`/`count_limit`/`check` 或 unique 碰撞套到既有列上。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/rules/preview
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/rules/preview
  • 公司/private/module/custom_tables/company/tables/{table_id}/rules/preview

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是要評估候選規則的資料表 UUID。

請求結構

TableRulesPreviewPayload
欄位型別必填說明
expected_rules_digeststring | null否Optional digest from GET rules. A changed stored rules list returns409 with no write; omission preserves unconditional replacement.
rules(AggregateLimitRuleSpec | SameDimensionReferenceRuleSpec | DateIntervalExclusionRuleSpec | PeriodFenceRuleSpec | object)[]是Full rules list (PUT semantics; max 10). Each rule: {"type": "compare" | "unique" | "unique_tuple" | "same_dimension_reference" | "date_interval_exclusion" | "no_overlap" | "exists" | "not_exists" | "count_limit" | "aggregate_limit" | "transition" | "check" | "require" | "require_approval" | "channel" | "invariant" | "immutable_when" | "period_fence", "name"?: str, "id"?: "rule_<hex>", "when"?: [predicates], ...type-specific fields}. An opt-in "unique_tuple" rule takes 1..16 ordered {"column": ref, "null_policy": "forbidden"|"equal"|"distinct"} components, "case_insensitive"?: boolean and "unicode_normalization"?: "none"|"NFC". A "count_limit" rule caps a live-row bucket at {"max": int >= 1}: with "table_id" + "match" it counts the exists-style cross-table bucket; without "table_id" it counts THIS table's rows matching "where" predicates ("$row.<col>" values partition per row, e.g. employee eq $row.employee). A "date_interval_exclusion" rule takes two distinct date columns and 1..2 cardinality-one native-link scopes; a create must supply its end as a date or explicit null, and [start,end) is non-overlapping within the partition. A "no_overlap" rule additionally takes "min_gap"?: number — minimum separation between intervals in the same scope partition (numeric bounds: plain number; datetime: minutes; date: days; touching at exactly min_gap is allowed) — and bounds its intervals EITHER with "start_column"+"end_column" OR with "interval_column" (ONE interval-type column whose {start, end} cell carries both bounds; datetime class, min_gap in minutes) — never both. A "channel" rule (SCP v1.3) takes EITHER {"column", "require_present", "read_op"?: "subset" | "overlaps"} or {"policy": <node tree>}, plus "enforcement": "observe" | "enforce" — see ChannelRuleFlat / ChannelRulePolicy. An "invariant" rule takes {"policy": <node tree>, "enforcement"} and is principal-blind: it holds for every writer on every path — see InvariantRule. An "immutable_when" rule takes {"prior_when": [predicates], "columns": [refs]} and takes no "when": prior_when is the lock condition evaluated against the row's PRE-image (the row before the write); while it matches, the listed columns may not change (400 on violation). Locks stored inline columns only (not computed/link). A "period_fence" rule (ct.calendars) refuses writes whose dated row falls in a closed or missing period — see PeriodFenceRuleSpec; at most 3 per table.

回應結構

RulesPreviewResponse
欄位型別必填說明
aggregate_violationsinteger否Violating aggregate groups in the full live population; includes exact current sums.
invariant_violationsinteger否Sampled rows that already fail the candidate INVARIANT rules. Reported once, not per room: an invariant has no principal. Such rows stay readable but become uneditable until repaired.
roomsRulesPreviewRoomImpact[]否Per acting room, for the CHANNEL rules. Empty when the candidate carries no channel rule or the table has no chatroom grants.
sample_capinteger是The sampling cap applied.
sampled_rowsinteger是Live rows actually evaluated (the first N by sort_order). EVERY count below is out of this number, not out of total_rows.
table_idstring是The table previewed.
total_rowsinteger是Live rows in the table. Greater than sampled_rows ⇒ the preview was truncated and says so in warnings.
warningsstring[]否Truncation notices and lockout alarms, in plain language.

範例

預覽唯一值規則

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "rules": [
      {
        "type": "unique",
        "name": "訂單編號不可重複",
        "columns": [
          "訂單編號"
        ],
        "case_insensitive": true
      }
    ]
  }
}
回應200
{
  "table_id": "22222222-2222-4222-8222-222222222222",
  "sampled_rows": 1,
  "total_rows": 1,
  "sample_cap": 200,
  "rooms": [],
  "invariant_violations": 0,
  "warnings": []
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
400候選規則的結構或語意不合法。
{
  "detail": "rules[0]: invalid rule type 'unknown'. valid types: compare, unique, unique_tuple, same_dimension_reference, date_interval_exclusion, no_overlap, exists, not_exists, count_limit, transition, check, require, require_approval, channel, invariant, immutable_when, period_fence"
}
403你看得到這張資料表,但不是它的 moderator。訊息內容依資料表範圍而定:這是你自己部門內聊天室資料表的回應;其他部門的聊天室資料表會是 `…or management rights.`,部門資料表是 `…table moderator, department manager, or company management rights.` 或 `…table moderator or department management rights.`,公司資料表則是 `…table moderator or company management rights.`
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
404部門或公司路徑:資料表存在、你也是它的 moderator,但它屬於路徑以外的範圍(`Table not found in this department`/`… in this company`)。因為公司管理者是公司內每張資料表的 moderator,這個情況確實可能發生。在聊天室路徑上,同樣的情況會回 `CustomTable Not found`。
{
  "detail": "Table not found in this department"
}
422Request 驗證,與 PUT 相同:規則過多;unique_tuple、same_dimension_reference、date_interval_exclusion、channel 或 invariant 的 shape 錯誤;policy 超過上限;或 expected_rules_digest 不是 64 位小寫 hex——雖然 preview 不使用它的值,格式仍會被驗證。
{
  "detail": [
    {
      "type": "string_pattern_mismatch",
      "loc": [
        "body",
        "expected_rules_digest"
      ],
      "msg": "String should match pattern '^[a-f0-9]{64}$'",
      "input": "stale",
      "ctx": {
        "pattern": "^[a-f0-9]{64}$"
      }
    }
  ]
}
409候選清單中的 `same_dimension_reference` 規則已被既有資料違反。Preview 會執行與 PUT 相同的既有列檢查(在會回滾的 guard 下進行),所以回相同的 409。
{
  "detail": {
    "error": "same_dimension_reference_violation",
    "message": "Reference must share a live required dimension."
  }
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/triggers

取得資料表觸發器

用途

回傳資料表的 trigger(事件與排程),參照以顯示名稱呈現,只有表格 moderator 能讀。每個 webhook/api_call 機密 slot 都顯示 "__SECRET__",並由型別化的 `secrets` 清單標出位置;絕不回傳儲存的值。

適用時機

以表格 moderator 身分顯示自動化設定,或在整批取代前取得目前的 triggers、action id 與機密佔位符。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/triggers
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/triggers
  • 公司/private/module/custom_tables/company/tables/{table_id}/triggers

範圍

範圍是否提供驗證與權限
聊天室可使用ChatroomTableTriggerConfigReadRequired
部門可使用DepartmentTableTriggerConfigReadRequired
公司可使用CompanyTableTriggerConfigReadRequired

參數

欄位位置型別必填說明
table_idpathuuid是要取得觸發器的資料表 UUID。

回應結構

TableTriggersResponse
欄位型別必填說明
secretsTriggerSecretSlot[]否One entry per masked slot, locating each "__SECRET__" and whether a value is stored.
table_idstring是未指定
triggersobject[]否Trigger configuration with every webhook/api_call secret slot replaced by "__SECRET__" (for every reader, moderators included; the stored values are used only to fire).

範例

取得資料列建立通知觸發器

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  }
}
回應200
{
  "table_id": "22222222-2222-4222-8222-222222222222",
  "triggers": [
    {
      "id": "trg_666666666666",
      "name": "通知新訂單",
      "on": "created",
      "created_by": "44444444-4444-4444-8444-444444444444",
      "when": null,
      "transition": null,
      "schedule": null,
      "actions": [
        {
          "id": "act_111111111111",
          "type": "notify",
          "chatroom_id": "11111111-1111-4111-8111-111111111111",
          "message": "已建立訂單:$row.訂單編號"
        }
      ]
    }
  ],
  "secrets": []
}

Moderator 讀取 api_call trigger:機密 slot 已遮罩

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  }
}
回應200
{
  "table_id": "22222222-2222-4222-8222-222222222222",
  "triggers": [
    {
      "id": "trg_999999999999",
      "name": "同步 ERP",
      "on": "created",
      "created_by": "44444444-4444-4444-8444-444444444444",
      "when": null,
      "transition": null,
      "schedule": null,
      "actions": [
        {
          "id": "act_444444444444",
          "type": "api_call",
          "method": "POST",
          "url": "https://erp.example/orders?api_key=__SECRET__",
          "headers": {
            "Authorization": "__SECRET__"
          },
          "body": {
            "order_no": "$row.訂單編號",
            "source": "__SECRET__"
          }
        }
      ]
    }
  ],
  "secrets": [
    {
      "trigger_id": "trg_999999999999",
      "action_id": "act_444444444444",
      "action_index": 0,
      "location": "url_query",
      "name": "api_key",
      "occurrence": 0,
      "path": null,
      "has_value": true
    },
    {
      "trigger_id": "trg_999999999999",
      "action_id": "act_444444444444",
      "action_index": 0,
      "location": "header",
      "name": "Authorization",
      "occurrence": null,
      "path": null,
      "has_value": true
    },
    {
      "trigger_id": "trg_999999999999",
      "action_id": "act_444444444444",
      "action_index": 0,
      "location": "body",
      "name": null,
      "occurrence": null,
      "path": [
        "source"
      ],
      "has_value": true
    }
  ]
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
403你對這張資料表有權利(可讀、可新增或可編輯),但不是表格 moderator。Trigger 設定只限 moderator 讀取;確切訊息依資料表範圍與你的部門而定,與其他 moderator 閘門路由相同。
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404資料表不存在或已在垃圾桶、屬於其他範圍或(自後端 5.21.0 起)其他公司,或你對它沒有任何權利——所有情況都回同樣的 `CustomTable Not found`,因此被隱藏的資料表看起來與未知 id 完全相同。
{
  "detail": "CustomTable Not found"
}
PUT
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/triggers

取代資料表觸發器

用途

驗證並以原子方式取代事件驅動通知、API/資料表動作、通道附件投遞與 Sandbox 工作提交。

適用時機

要發佈資料表的完整目標觸發器設定時使用。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/triggers
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/triggers
  • 公司/private/module/custom_tables/company/tables/{table_id}/triggers

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是要取代觸發器的資料表 UUID。

請求結構

TableTriggersPayload
欄位型別必填說明
triggersobject[]是Full triggers list (PUT replace semantics; at most 50 triggers). Each trigger authors 1 to 5 actions from the ten supported types: webhook, api_call, create_record, update_record, notify, send_channel_message, invoke_command, delete_record, materialize_slots, and submit_sandbox_job. Saved configs preserve exactly one stable identity per action; server-minted values use act_<12 hex>. GET echoes it as action.id, which clients must round-trip when replacing the list. materialize_slots fails closed before any slot insert when more than 1000 live source rows are scanned; truncating slot inserts at 1000 per tick remains success.

回應結構

TableTriggersResponse
欄位型別必填說明
secretsTriggerSecretSlot[]否One entry per masked slot, locating each "__SECRET__" and whether a value is stored.
table_idstring是未指定
triggersobject[]否Trigger configuration with every webhook/api_call secret slot replaced by "__SECRET__" (for every reader, moderators included; the stored values are used only to fire).

範例

建立資料列時通知聊天室

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "triggers": [
      {
        "name": "通知新訂單",
        "on": "created",
        "actions": [
          {
            "type": "notify",
            "chatroom_id": "11111111-1111-4111-8111-111111111111",
            "message": "已建立訂單:$row.訂單編號"
          }
        ]
      }
    ]
  }
}
回應200
{
  "table_id": "22222222-2222-4222-8222-222222222222",
  "triggers": [
    {
      "id": "trg_666666666666",
      "name": "通知新訂單",
      "on": "created",
      "created_by": "44444444-4444-4444-8444-444444444444",
      "when": null,
      "transition": null,
      "schedule": null,
      "actions": [
        {
          "id": "act_111111111111",
          "type": "notify",
          "chatroom_id": "11111111-1111-4111-8111-111111111111",
          "message": "已建立訂單:$row.訂單編號"
        }
      ]
    }
  ],
  "secrets": []
}

傳送附件欄位並提交 pinned Sandbox task version

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "triggers": [
      {
        "name": "傳送附件並建立 Sandbox 工作",
        "on": "created",
        "actions": [
          {
            "type": "send_channel_message",
            "recipient": "created_by_client",
            "message": "訂單附件:$row.訂單編號",
            "attachments": [
              {
                "column": "col_a1111111_1111_4111_8111_111111111111"
              }
            ]
          },
          {
            "type": "submit_sandbox_job",
            "chatroom_id": "11111111-1111-4111-8111-111111111111",
            "task_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
            "timeout_seconds": 900,
            "input": {
              "order_id": "$row.訂單編號"
            }
          }
        ]
      }
    ]
  }
}
回應200
{
  "table_id": "22222222-2222-4222-8222-222222222222",
  "triggers": [
    {
      "id": "trg_777777777777",
      "name": "傳送附件並建立 Sandbox 工作",
      "on": "created",
      "actions": [
        {
          "type": "send_channel_message",
          "recipient": "created_by_client",
          "message": "訂單附件:$row.訂單編號",
          "attachments": [
            {
              "column": "附件"
            }
          ],
          "id": "act_222222222222"
        },
        {
          "type": "submit_sandbox_job",
          "chatroom_id": "11111111-1111-4111-8111-111111111111",
          "task_version_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
          "timeout_seconds": 900,
          "input": {
            "order_id": "$row.訂單編號"
          },
          "id": "act_333333333333"
        }
      ],
      "created_by": "44444444-4444-4444-8444-444444444444",
      "when": null,
      "transition": null,
      "schedule": null
    }
  ],
  "secrets": []
}

把 GET 的回傳原封不動送回——每個佔位符都保留已儲存的值

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "triggers": [
      {
        "id": "trg_999999999999",
        "name": "同步 ERP",
        "on": "created",
        "created_by": "44444444-4444-4444-8444-444444444444",
        "when": null,
        "transition": null,
        "schedule": null,
        "actions": [
          {
            "id": "act_444444444444",
            "type": "api_call",
            "method": "POST",
            "url": "https://erp.example/orders?api_key=__SECRET__",
            "headers": {
              "Authorization": "__SECRET__"
            },
            "body": {
              "order_no": "$row.訂單編號",
              "source": "__SECRET__"
            }
          }
        ]
      }
    ]
  }
}
回應200
{
  "table_id": "22222222-2222-4222-8222-222222222222",
  "triggers": [
    {
      "id": "trg_999999999999",
      "name": "同步 ERP",
      "on": "created",
      "created_by": "44444444-4444-4444-8444-444444444444",
      "when": null,
      "transition": null,
      "schedule": null,
      "actions": [
        {
          "id": "act_444444444444",
          "type": "api_call",
          "method": "POST",
          "url": "https://erp.example/orders?api_key=__SECRET__",
          "headers": {
            "Authorization": "__SECRET__"
          },
          "body": {
            "order_no": "$row.訂單編號",
            "source": "__SECRET__"
          }
        }
      ]
    }
  ],
  "secrets": [
    {
      "trigger_id": "trg_999999999999",
      "action_id": "act_444444444444",
      "action_index": 0,
      "location": "url_query",
      "name": "api_key",
      "occurrence": 0,
      "path": null,
      "has_value": true
    },
    {
      "trigger_id": "trg_999999999999",
      "action_id": "act_444444444444",
      "action_index": 0,
      "location": "header",
      "name": "Authorization",
      "occurrence": null,
      "path": null,
      "has_value": true
    },
    {
      "trigger_id": "trg_999999999999",
      "action_id": "act_444444444444",
      "action_index": 0,
      "location": "body",
      "name": null,
      "occurrence": null,
      "path": [
        "source"
      ],
      "has_value": true
    }
  ]
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
400觸發事件、條件或動作無效,或動作數量超出支援範圍。
{
  "detail": "triggers[0]: actions must be a list of 1..5"
}
400資料表帶有通道範圍限制政策,無法與觸發器併用。
{
  "detail": "this table carries a channel-scoped constraint policy; triggers are not supported on channel-governed tables. a trigger has no acting chatroom, so it cannot satisfy the channel floor (deferred to SCP Phase 2)"
}
400某個 trigger 保留原 id 卻更改了 schedule.type;schedule identity 依 kind 區分,請讓舊 id 退役,並用新 id 建立新 kind。
{
  "detail": "schedule_kind_change_requires_new_trigger_id: trigger 'trg_666666666666' changes its schedule type in place. retire the old trigger id and create the new schedule kind under a new trigger id"
}
400寫入想保留一個無法綁定的已儲存機密;不會儲存任何東西。`code` 說明原因:`unknown_action_id`、`action_id_reused`、`trigger_id_reused`、`ambiguous_keep`、`no_stored_twin`、`type_changed`、`destination_changed`(URL 的 scheme/host/port 或 `Host` header 改變)、`nothing_to_keep` 或 `duplicate_header`。訊息只點名 slot,不含任何值。
{
  "detail": {
    "error": "trigger_secret_keep_refused",
    "code": "destination_changed",
    "message": "triggers[0] action 1: the url's scheme, host or port, or its Host header, changed, so its stored secrets cannot be kept — re-enter every header, query, userinfo and body value for the new destination (or clear them)"
  }
}
400有一個 `"__SECRET__"` 佔位符沒有被任何保留綁定解析,例如夾在較長的值裡(`"Bearer __SECRET__"`)。佔位符永遠不會被當成憑證儲存。
{
  "detail": "'__SECRET__' is the masked placeholder of a stored api_call secret and cannot be saved as a value. send the real value, or keep a stored one by sending the placeholder in its own slot of the same stored action"
}
409`create_record`/`update_record` action 的目標表帶有 `require_approval` 規則(同一個 409 也擋下在自身表上的 `delete_record`、`materialize_slots` 的目標表,以及所引用指令會寫入受核准閘門資料表的 `invoke_command`)。
{
  "detail": {
    "error": "approval_trigger_conflict",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "target_table_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
    "target_table_name": "出貨單",
    "action_type": "create_record",
    "rule_id": "rule_3f9a1c2b7d4e"
  }
}
409Locked-graph 重新驗證或非資料庫的 compile/refresh failure,使伺服器無法安全更新所有先前仍有效的相依 commands。這個結構化錯誤與下方 flat-detail database errors 不同;trigger JSON、schema history 紀錄與所有 command definition 更新會在同一個交易中一起回滾。
{
  "detail": {
    "error": "command_dependency_refresh_failed",
    "message": "a dependent Custom Table command cannot accept the candidate triggers"
  }
}
409Trigger-update transaction 中遇到 MySQL 1205 lock-wait timeout 或 1213 deadlock。完整 transaction 已回滾;這個可重試 409 使用 flat string detail,不是 command_dependency_refresh_failed。
{
  "detail": "Concurrent write conflict (lock); please retry the request."
}
422Body 未通過 request 驗證,例如超過 50 個 trigger。這條路由屬於機密寫入路徑,所以每筆錯誤只有 `loc`、`type` 與 `msg: "validation_error:<type>"`,絕不回顯送出的值。
{
  "detail": [
    {
      "loc": [
        "body",
        "triggers"
      ],
      "type": "too_long",
      "msg": "validation_error:too_long"
    }
  ]
}
403你看得到這張資料表,但不是它的 moderator。訊息內容依資料表範圍而定:這是你自己部門內聊天室資料表的回應;其他部門的聊天室資料表會是 `…or management rights.`,部門資料表是 `…table moderator, department manager, or company management rights.` 或 `…table moderator or department management rights.`,公司資料表則是 `…table moderator or company management rights.`
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
404部門或公司路徑:資料表存在、你也是它的 moderator,但它屬於路徑以外的範圍(`Table not found in this department`/`… in this company`)。因為公司管理者是公司內每張資料表的 moderator,這個情況確實可能發生。在聊天室路徑上,同樣的情況會回 `CustomTable Not found`。
{
  "detail": "Table not found in this department"
}
500發生其他資料庫失敗——lock 衝突以外的 operational error,或 integrity/data error——整個 transaction 已回滾;detail 是淨化後的 flat 字串 Database operation failed.。
{
  "detail": "Database operation failed."
}
500非資料庫的失敗——例如伺服器沒有設定加上金鑰的摘要所需的金鑰——讓整個 transaction 回滾;detail 是純文字 Internal Server Error。
{
  "detail": "Internal Server Error"
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/triggers/schedule-preview
用途

以 scheduler 自己的 evaluator 唯讀地評估這張表上每一個 schedule trigger,回傳每個 trigger 的機器可讀原因計數與時鐘狀態。

適用時機

當 scheduler tick 健康卻一直回報零筆 run,而你需要知道資料列是缺日期、仍在未來、被 when 排除、已經消耗,還是真的到期時使用。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/triggers/schedule-preview
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/triggers/schedule-preview
  • 公司/private/module/custom_tables/company/tables/{table_id}/triggers/schedule-preview

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是要評估其 schedule triggers 的資料表 UUID。

回應結構

TableSchedulePreviewResponse
欄位型別必填說明
evaluated_atstring (date-time)是未指定
live_recordsinteger是未指定
record_limitinteger否未指定
table_idstring是未指定
triggers(InvalidSchedulePreview | DateColumnReachedSchedulePreview | IntervalSchedulePreview | DailySchedulePreview | CronSchedulePreview)[]否未指定

範例

預覽一張含 date trigger、interval trigger 與一個損毀儲存 trigger 的表

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  }
}
回應200
{
  "table_id": "22222222-2222-4222-8222-222222222222",
  "evaluated_at": "2026-08-27T05:02:13",
  "live_records": 2,
  "record_limit": 1000,
  "triggers": [
    {
      "kind": "date_column_reached",
      "trigger_id": "trg_666666666666",
      "config_status": "valid",
      "already_fired": 1,
      "records_scanned": 2,
      "missing_schedule_value": 0,
      "invalid_schedule_value": 0,
      "scheduled_for_future": 1,
      "when_filter_mismatch": 0,
      "due_now": 0,
      "unscanned": 0,
      "truncated": false,
      "warnings": []
    },
    {
      "kind": "interval",
      "trigger_id": "trg_777777777777",
      "config_status": "valid",
      "last_consumed_window_at": "2026-08-27T05:00:00",
      "due_at": null,
      "due_now": false,
      "active_run": false,
      "warnings": [
        "when_ignored_for_recordless_schedule"
      ]
    },
    {
      "kind": "invalid",
      "trigger_id": "trg_888888888888",
      "stored_schedule_type": "monthly",
      "config_status": "invalid",
      "error_codes": [
        "unsupported_schedule_type"
      ],
      "warnings": []
    }
  ]
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
403你看得到這張資料表,但不是它的 moderator。訊息內容依資料表範圍而定:這是你自己部門內聊天室資料表的回應;其他部門的聊天室資料表會是 `…or management rights.`,部門資料表是 `…table moderator, department manager, or company management rights.` 或 `…table moderator or department management rights.`,公司資料表則是 `…table moderator or company management rights.`
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
404部門或公司路徑:資料表存在、你也是它的 moderator,但它屬於路徑以外的範圍(`Table not found in this department`/`… in this company`)。在聊天室路徑上,同樣的情況會和不存在或在垃圾桶的 id 一樣回 `CustomTable Not found`。
{
  "detail": "Table not found in this department"
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/trigger-runs

列出觸發器執行記錄

用途

回傳資料表非同步觸發動作的分頁執行記錄。

適用時機

適合監測自動化健康狀態、檢查失敗,或在重試前找到執行記錄。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/trigger-runs
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/trigger-runs
  • 公司/private/module/custom_tables/company/tables/{table_id}/trigger-runs

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是要列出觸發器執行記錄的資料表 UUID。
statusqueryenum:pending|running|done|failed|stuck否選填的執行狀態:pending、running、done、failed 或 stuck。
skipqueryint >= 0否略過前幾筆符合條件的執行記錄,預設為 0。
limitqueryint 1..200否最多回傳幾筆執行記錄,可填 1 到 200。

回應結構

TriggerRunListResponse
欄位型別必填說明
runsTriggerRunResponse[]是未指定
totalinteger是未指定

範例

列出失敗的觸發器執行記錄

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "query": {
    "status": "failed",
    "skip": "0",
    "limit": "50"
  }
}
回應200
{
  "runs": [
    {
      "id": "55555555-5555-4555-8555-555555555555",
      "table_id": "22222222-2222-4222-8222-222222222222",
      "trigger_id": "trg_999999999999",
      "record_id": "33333333-3333-4333-8333-333333333333",
      "record_version": 1,
      "event": "created",
      "status": "failed",
      "attempts": 1,
      "error": "api_call failed: HTTP 500",
      "chain_id": "55555555-5555-4555-8555-555555555555",
      "depth": 0,
      "payload": {
        "event": "created",
        "table_id": "22222222-2222-4222-8222-222222222222",
        "record_id": "33333333-3333-4333-8333-333333333333",
        "record_version": 1,
        "data": {
          "col_b2222222_2222_4222_8222_222222222222": "ORD-1001"
        },
        "diff": null,
        "fired_at": "2026-07-19T03:00:00.412000",
        "trigger": {
          "id": "trg_999999999999",
          "name": "同步 ERP",
          "created_by": "44444444-4444-4444-8444-444444444444"
        },
        "actor": {
          "user_id": "44444444-4444-4444-8444-444444444444",
          "client_id": null
        },
        "source_permission_context": {
          "kind": "unroomed",
          "principal_user_id": "44444444-4444-4444-8444-444444444444",
          "principal_client_id": null
        },
        "chain_id": "55555555-5555-4555-8555-555555555555",
        "depth": 0
      },
      "action_results": [
        {
          "type": "api_call",
          "ok": false,
          "detail": "HTTP 500",
          "action_id": "act_444444444444"
        }
      ],
      "created_at": "2026-07-19T03:00:00",
      "updated_at": "2026-07-19T03:05:00"
    }
  ],
  "total": 1
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
403你看得到這張資料表,但不是它的 moderator。訊息內容依資料表範圍而定:這是你自己部門內聊天室資料表的回應;其他部門的聊天室資料表會是 `…or management rights.`,部門資料表是 `…table moderator, department manager, or company management rights.` 或 `…table moderator or department management rights.`,公司資料表則是 `…table moderator or company management rights.`
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
404部門或公司路徑:資料表存在、你也是它的 moderator,但它屬於路徑以外的範圍(`Table not found in this department`/`… in this company`)。在聊天室路徑上,同樣的情況會和不存在或在垃圾桶的 id 一樣回 `CustomTable Not found`。
{
  "detail": "Table not found in this department"
}
POST
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/trigger-runs/{run_id}/retry

重試觸發器執行

用途

將符合條件的失敗、待執行或過期執行記錄重新放回觸發器佇列。

適用時機

排除下游錯誤後,重排 failed、pending 或逾時 running 執行;已完成的 run 不能重試。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/trigger-runs/{run_id}/retry
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/trigger-runs/{run_id}/retry
  • 公司/private/module/custom_tables/company/tables/{table_id}/trigger-runs/{run_id}/retry

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是擁有觸發器執行記錄的資料表 UUID。
run_idpathuuid是要重試的觸發器執行 UUID。

回應結構

TriggerRunResponse
欄位型別必填說明
action_resultsobject[] | null否Per-action results written by the worker
attemptsinteger是未指定
chain_idstring是未指定
created_atstring (date-time)是未指定
depthinteger是未指定
errorstring | null是未指定
eventstring是未指定
idstring是未指定
payloadobject | null否Trigger-time row snapshot + change metadata (the webhook payload)
record_idstring | null是未指定
record_versioninteger是未指定
statusstring是pending | running | done | failed
table_idstring是未指定
trigger_idstring是未指定
updated_atstring (date-time)是未指定

範例

將失敗的觸發器執行重新排入佇列

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "run_id": "55555555-5555-4555-8555-555555555555"
  }
}
回應200
{
  "id": "55555555-5555-4555-8555-555555555555",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "trigger_id": "trg_999999999999",
  "record_id": "33333333-3333-4333-8333-333333333333",
  "record_version": 1,
  "event": "created",
  "status": "pending",
  "attempts": 1,
  "error": null,
  "chain_id": "55555555-5555-4555-8555-555555555555",
  "depth": 0,
  "payload": {
    "event": "created",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "record_id": "33333333-3333-4333-8333-333333333333",
    "record_version": 1,
    "data": {
      "col_b2222222_2222_4222_8222_222222222222": "ORD-1001"
    },
    "diff": null,
    "fired_at": "2026-07-19T03:00:00.412000",
    "trigger": {
      "id": "trg_999999999999",
      "name": "同步 ERP",
      "created_by": "44444444-4444-4444-8444-444444444444"
    },
    "actor": {
      "user_id": "44444444-4444-4444-8444-444444444444",
      "client_id": null
    },
    "source_permission_context": {
      "kind": "unroomed",
      "principal_user_id": "44444444-4444-4444-8444-444444444444",
      "principal_client_id": null
    },
    "chain_id": "55555555-5555-4555-8555-555555555555",
    "depth": 0
  },
  "action_results": [
    {
      "type": "api_call",
      "ok": false,
      "detail": "HTTP 500",
      "action_id": "act_444444444444"
    }
  ],
  "created_at": "2026-07-19T03:00:00",
  "updated_at": "2026-07-19T03:05:00"
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
404這張資料表沒有指定觸發器執行記錄。
{
  "detail": "Trigger run not found"
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
409執行已完成,或處於其他不可重試的狀態。
{
  "detail": "run is done; only failed/pending (or stale-running) runs can be retried"
}
409重試 interval、daily 或 cron run 會重新武裝該 trigger 的「同時只有一個 run」fence;這個 409 表示同一 trigger 的另一個 run 仍在 pending 或 running。請等它完成後再重試。
{
  "detail": "another run is active for this schedule trigger; retry after it completes"
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/staged-changes

列出階段性變更

用途

列出被 require_approval 規則暫緩的寫入,以及審核與套用狀態。

適用時機

適合監測需核准的寫入,或調查為何資料列被待審狀態擋住。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/staged-changes
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/staged-changes
  • 公司/private/module/custom_tables/company/tables/{table_id}/staged-changes

範圍

範圍是否提供驗證與權限
聊天室可使用ChatroomTableMetadataReadRequired
部門可使用DepartmentTableMetadataReadRequired
公司可使用CompanyTableMetadataReadRequired

參數

欄位位置型別必填說明
table_idpathuuid是要列出階段性變更的資料表 UUID。
statusqueryenum:pending|applying|applied|apply_failed|discarded否選填的進程狀態:pending、applying、applied、apply_failed 或 discarded。
change_typequeryenum:create|update|delete|restore|revert|batch_actions|command_plan否選填的暫緩操作類型:create、update、delete、restore、revert、batch_actions 或 command_plan。
skipqueryint >= 0否略過前幾筆符合條件的階段性變更,預設為 0。
limitqueryint 1..200否最多回傳幾筆階段性變更,可填 1 到 200;預設 50。

回應結構

StagedChangeListResponse
欄位型別必填說明
staged_changesStagedChangeResponse[]是Visible staged changes, newest first
totalinteger是Total visible staged changes matching the filters (before pagination)

範例

列出待審階段性變更

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "query": {
    "status": "pending",
    "skip": "0",
    "limit": "50"
  }
}
回應200
{
  "staged_changes": [
    {
      "id": "88888888-8888-4888-8888-888888888888",
      "table_id": "22222222-2222-4222-8222-222222222222",
      "record_id": "33333333-3333-4333-8333-333333333333",
      "process_id": "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
      "rule_id": "rule_5e6f7a8b9c0d",
      "change_type": "update",
      "status": "pending",
      "snapshot_version": 3,
      "attempts": 0,
      "error": null,
      "created_by": "44444444-4444-4444-8444-444444444444",
      "created_at": "2026-07-19T03:00:00",
      "updated_at": "2026-07-19T03:00:00",
      "applied_at": null,
      "payload": null,
      "results": null
    }
  ],
  "total": 1
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
404資料表不存在或已在垃圾桶、屬於其他範圍,或你對它沒有任何權利——所有情況都回 `CustomTable Not found`,因此被隱藏的資料表看起來與未知 id 完全相同。其他公司的資料表也回同樣的 404(自後端 5.21.0 起)。
{
  "detail": "CustomTable Not found"
}
POST
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/staged-changes/discard

捨棄階段性變更

用途

嘗試將指定的未解決核准寫入標記為已捨棄。

適用時機

被暫緩的寫入應直接作廢,而不是核准並套用時使用。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/staged-changes/discard
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/staged-changes/discard
  • 公司/private/module/custom_tables/company/tables/{table_id}/staged-changes/discard

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是擁有階段性變更的資料表 UUID。

請求結構

StagedChangeDiscardRequest
欄位型別必填說明
staged_change_idsstring[]是Staged change ids to discard (1..50); each is looked up anchored to the path table_id

回應結構

StagedChangeDiscardResponse
欄位型別必填說明
discardedinteger是How many ids were discarded this call
resultsStagedChangeDiscardResult[]是One result per requested id, in request order

範例

捨棄一個階段性變更 ID

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "staged_change_ids": [
      "88888888-8888-4888-8888-888888888888"
    ]
  }
}
回應200
{
  "results": [
    {
      "staged_change_id": "88888888-8888-4888-8888-888888888888",
      "ok": false,
      "outcome": "not_found",
      "status": null
    }
  ],
  "discarded": 0
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
403你看得到這張資料表,但不是它的 moderator。訊息內容依資料表範圍而定:這是你自己部門內聊天室資料表的回應;其他部門的聊天室資料表會是 `…or management rights.`,部門資料表是 `…table moderator, department manager, or company management rights.` 或 `…table moderator or department management rights.`,公司資料表則是 `…table moderator or company management rights.`
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
404部門或公司路徑:資料表存在、你也是它的 moderator,但它屬於路徑以外的範圍(`Table not found in this department`/`… in this company`)。在聊天室路徑上,同樣的情況會和不存在或在垃圾桶的 id 一樣回 `CustomTable Not found`。
{
  "detail": "Table not found in this department"
}
422`staged_change_ids` 是空的,或超過 50 個 id。
{
  "detail": [
    {
      "type": "too_short",
      "loc": [
        "body",
        "staged_change_ids"
      ],
      "msg": "List should have at least 1 item after validation, not 0",
      "input": [],
      "ctx": {
        "field_type": "List",
        "min_length": 1,
        "actual_length": 0
      }
    }
  ]
}
POST
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/callback-tokens

簽發回呼 token

用途

建立綁定資料表的 token,供已驗證的公開回呼寫入,並只回傳一次密鑰。

適用時機

要為外部回呼程式配置新增,或新增與更新能力時使用。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/callback-tokens
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/callback-tokens
  • 公司/private/module/custom_tables/company/tables/{table_id}/callback-tokens

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是要綁定回呼 token 的資料表 UUID。

請求結構

CallbackTokenMintPayload
欄位型別必填說明
allowed_ops"create" | "create,update"否Operations the token may perform
namestring | null否Label shown in listings
valid_untilstring (date-time) | null否Expiry (UTC); null = no expiry. Expired tokens answer the uniform 404.

回應結構

CallbackTokenMintResponse
欄位型別必填說明
allowed_opsstring是未指定
secretstring是Bearer secret — shown ONCE, never retrievable again
table_idstring是未指定
token_idstring是The URL path segment: POST /public/module/custom_tables/callback/{token_id}
valid_untilstring (date-time) | null是未指定

範例

簽發可新增與更新的回呼 token

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "name": "訂單系統回呼",
    "allowed_ops": "create,update",
    "valid_until": null
  }
}
回應201
{
  "token_id": "99999999-9999-4999-8999-999999999999",
  "secret": "catalog_example_only_0000000000000000000000",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "allowed_ops": "create,update",
  "valid_until": null
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
403你看得到這張資料表,但不是它的 moderator。訊息內容依資料表範圍而定:這是你自己部門內聊天室資料表的回應;其他部門的聊天室資料表會是 `…or management rights.`,部門資料表是 `…table moderator, department manager, or company management rights.` 或 `…table moderator or department management rights.`,公司資料表則是 `…table moderator or company management rights.`
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
404部門或公司路徑:資料表存在、你也是它的 moderator,但它屬於路徑以外的範圍(`Table not found in this department`/`… in this company`)。在聊天室路徑上,同樣的情況會和不存在或在垃圾桶的 id 一樣回 `CustomTable Not found`。
{
  "detail": "Table not found in this department"
}
422token 名稱、允許的操作集合或到期時間不合法。
{
  "detail": [
    {
      "type": "literal_error",
      "loc": [
        "body",
        "allowed_ops"
      ],
      "msg": "Input should be 'create' or 'create,update'",
      "input": "update",
      "ctx": {
        "expected": "'create' or 'create,update'"
      }
    }
  ]
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/callback-tokens

列出回呼 token

用途

回傳資料表回呼 token 的基本資訊、能力、到期時間與撤銷狀態。

適用時機

適合稽核整合,或在撤銷前找到 token ID。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/callback-tokens
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/callback-tokens
  • 公司/private/module/custom_tables/company/tables/{table_id}/callback-tokens

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是要列出回呼 token 的資料表 UUID。

回應結構

CallbackTokenListResponse
欄位型別必填說明
tokensCallbackTokenInfo[]是未指定

範例

列出回呼 token 基本資訊

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  }
}
回應200
{
  "tokens": [
    {
      "id": "99999999-9999-4999-8999-999999999999",
      "name": "訂單系統回呼",
      "table_id": "22222222-2222-4222-8222-222222222222",
      "allowed_ops": "create,update",
      "valid_until": null,
      "revoked": false,
      "created_by": "44444444-4444-4444-8444-444444444444",
      "created_at": "2026-07-19T03:00:00"
    }
  ]
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
403你看得到這張資料表,但不是它的 moderator。訊息內容依資料表範圍而定:這是你自己部門內聊天室資料表的回應;其他部門的聊天室資料表會是 `…or management rights.`,部門資料表是 `…table moderator, department manager, or company management rights.` 或 `…table moderator or department management rights.`,公司資料表則是 `…table moderator or company management rights.`
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
404部門或公司路徑:資料表存在、你也是它的 moderator,但它屬於路徑以外的範圍(`Table not found in this department`/`… in this company`)。在聊天室路徑上,同樣的情況會和不存在或在垃圾桶的 id 一樣回 `CustomTable Not found`。
{
  "detail": "Table not found in this department"
}
DELETE
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/callback-tokens/{token_id}

撤銷回呼 token

用途

永久停用一組資料表專屬憑證,使後續 public callback 寫入回傳與無效驗證相同的隱蔽 404。

適用時機

輪替憑證、停用整合,或懷疑憑證外洩時使用。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/callback-tokens/{token_id}
  • 部門/private/module/custom_tables/department/{department_id}/tables/{table_id}/callback-tokens/{token_id}
  • 公司/private/module/custom_tables/company/tables/{table_id}/callback-tokens/{token_id}

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableModeratorRequired
部門可使用CustomTableModeratorRequired
公司可使用CustomTableModeratorRequired

參數

欄位位置型別必填說明
table_idpathuuid是擁有回呼 token 的資料表 UUID。
token_idpathuuid是要撤銷的回呼 token UUID。

回應結構

SuccessResponse
欄位型別必填說明
messagestring否未指定

範例

撤銷一組回呼 token

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "token_id": "99999999-9999-4999-8999-999999999999"
  }
}
回應200
{
  "message": "Callback token revoked"
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。

狀態發生條件錯誤本文
403你看得到這張資料表,但不是它的 moderator。訊息內容依資料表範圍而定:這是你自己部門內聊天室資料表的回應;其他部門的聊天室資料表會是 `…or management rights.`,部門資料表是 `…table moderator, department manager, or company management rights.` 或 `…table moderator or department management rights.`,公司資料表則是 `…table moderator or company management rights.`
{
  "detail": "Insufficient permissions. Required: table moderator, chatroom creator, or department management rights."
}
404這張資料表沒有該 id 的 token——包括其實屬於另一張資料表的 token。資料表不在指定範圍內時則回 `Table not found in this <scope>`。
{
  "detail": "Callback token not found"
}
404部門或公司路徑:資料表存在、你也是它的 moderator,但它屬於路徑以外的範圍(`Table not found in this department`/`… in this company`)。在聊天室路徑上,同樣的情況會回 `CustomTable Not found`。
{
  "detail": "Table not found in this department"
}
404沒有這個 id 的 live 資料表:它從未存在、已被永久清除,或正在垃圾桶中。其他公司的資料表也回同樣的結果(自後端 5.21.0 起,不再是 403)。在聊天室路徑上,屬於其他聊天室的資料表也回同樣的結果。
{
  "detail": "CustomTable Not found"
}
404資料表所屬的聊天室已被刪除。聊天室被軟刪除後,它自己的資料表仍是 live,但 moderator 閘門在每一種路徑(聊天室、部門或公司)都會拒絕它們——時間點在查到資料表與公司檢查之後(其他公司的資料表改為回 `CustomTable Not found`)、moderator 檢查之前。
{
  "detail": "Chatroom Not found"
}
409撤銷在鎖競爭中落敗,「沒有」發生——token 仍然存活、仍接受 callback 寫入。重試直到拿到 200;只有 200 才確認撤銷完成。
{
  "detail": "Concurrent write conflict (lock); please retry the request."
}

aggregate_limit 是第 18 種規則,支援精確群組 sum/count 與 Command 最終狀態檢查。

Last updated on