Skip to Content
API 參考JSONL IaC

JSONL IaC

規劃、套用、檢視狀態、匯出宣告式 JSONL,並取得其 typed authored contract,同時掌握命名空間與破壞性變更。

iac.contract 是三種 scope 各自經驗證的 GET .../tables/iac/contract 路由:

  • /private/module/custom_tables/chatroom/{chatroom_id}/tables/iac/contract
  • /private/module/custom_tables/department/{department_id}/tables/iac/contract
  • /private/module/custom_tables/company/tables/iac/contract

它回傳 IacDocumentContractResponse,欄位為 version、kinds、resource_types 與 line。Runtime line 是一條合法的 header 範例;OpenAPI response schema 則帶出完整的 discriminated IacLine union,補上原始 JSONL plan/apply request body 無法呈現的型別契約。

GET
路由範本/private/module/custom_tables/{scope}/tables/iac/contract
用途

回傳 authored kind、managed resource 清單與 typed IacLine carrier,讓 OpenAPI 暴露完整 discriminated union。

適用時機

建立 raw JSONL plan/apply body 的 editor、validator 或 client 時使用。

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

範圍

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

回應結構

IacDocumentContractResponse
欄位型別必填說明
kinds("header" | "table" | "column" | "rule" | "trigger" | "view" | "grant" | "client_access" | "record" | "command" | "insight_selection" | "public_read")[]是未指定
lineIacHeaderLine | IacTableLine | IacColumnLine | IacRuleLine | IacTriggerLine | IacViewLine | IacGrantLine | IacClientAccessLine | IacRecordLine | IacCommandLine | IacInsightSelectionLine | IacPublicReadLine是Optional first line of a JSONL doc: version + state namespace (spec §3.1).
resource_types("table" | "column" | "rule" | "trigger" | "view" | "grant" | "client_access" | "command" | "insight_selection" | "public_read")[]是未指定
versioninteger否未指定

範例

讀取 IaC union carrier

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111"
  }
}
回應200
{
  "version": 1,
  "kinds": [
    "header",
    "table",
    "column",
    "rule",
    "trigger",
    "view",
    "grant",
    "client_access",
    "record",
    "command",
    "insight_selection",
    "public_read"
  ],
  "resource_types": [
    "table",
    "column",
    "rule",
    "trigger",
    "view",
    "grant",
    "client_access",
    "command",
    "insight_selection",
    "public_read"
  ],
  "line": {
    "kind": "header",
    "version": 1,
    "system": "",
    "description": ""
  }
}

錯誤

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

狀態發生條件錯誤本文
403呼叫者未通過該 scope 的存取檢查。聊天室 route 允許聊天室的建立者、該聊天室所屬部門的部門管理者(角色 ≥ `CAN_MANAGE_DEPARTMENT`,預設 2),或公司管理者(角色 ≥ `CAN_MANAGE_COMPANY`,預設 3)。拒絕訊息為 `Insufficient permissions, not the creator. (Required department manager)`、`Insufficient permissions, not at the same department. (Required company manager)`;自後端 5.21.0 起,其他公司的聊天室與不存在的聊天室一樣回 `404 Chatroom Not found`。部門 route 允許該部門的管理者或公司管理者(`Insufficient permissions for department-level access.`);公司 route 允許公司管理者(`Insufficient permissions for company-level access.`)。
{
  "detail": "Insufficient permissions, not the creator. (Required department manager)"
}
404Route 無法解析指定的 scope,因此什麼都不會執行:不存在或已刪除的聊天室回 `Chatroom Not found`,不屬於你公司的部門回 `Department not found`。公司 route 沒有 scope 404。
{
  "detail": "Chatroom Not found"
}
POST
路由範本/private/module/custom_tables/{scope}/tables/iac/plan

規劃 JSONL IaC 文件

用途

解析並驗證宣告式 JSONL 文件,和現行資源比對差異,再回傳逐行動作與計畫雜湊。

適用時機

每次套用前都先執行,讓人員或自動化流程檢查建立、更新、改名、刪除、漂移與警告。

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

範圍

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

回應結構

IacPlanResponse
欄位型別必填說明
actionsIacPlanAction[]否Per-line planned actions.
errorsIacLineError[]否Doc-level parse/validate errors.
plan_hashstring是Server-keyed sha256 fingerprint (HMAC) pinning apply to this reviewed plan (spec §6); only the server can recompute it, so it reveals nothing about write-only secrets.
summaryIacPlanSummary是Counts per action type.

範例

規劃一張資料表與其自然鍵欄位

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111"
  },
  "body": "{\"kind\":\"header\",\"version\":1,\"system\":\"catalog-demo\",\"description\":\"Catalog example\"}\n{\"kind\":\"table\",\"ref\":\"orders\",\"spec\":{\"name\":\"IaC orders\",\"description\":\"Orders managed from JSONL\",\"key\":\"order_no\"}}\n{\"kind\":\"column\",\"table\":\"orders\",\"ref\":\"order_no\",\"spec\":{\"name\":\"Order number\",\"type\":\"string\",\"required\":true}}"
}
回應200
{
  "plan_hash": "9a1b2c3d4e5f60718293a4b5c6d7e8f90123456789abcdef0123456789abcdef",
  "summary": {
    "create": 2,
    "adopt": 0,
    "move": 0,
    "update": 0,
    "noop": 0,
    "delete": 0,
    "orphaned": 0,
    "insert": 0,
    "skip": 0
  },
  "actions": [
    {
      "line": 2,
      "kind": "table",
      "ref": "orders",
      "action": "create",
      "adopted": false,
      "changes": [
        {
          "field": "name",
          "from": null,
          "to": "IaC orders",
          "secrets": null
        },
        {
          "field": "description",
          "from": null,
          "to": "Orders managed from JSONL",
          "secrets": null
        }
      ],
      "drifted_fields": [],
      "warnings": [],
      "errors": []
    },
    {
      "line": 3,
      "kind": "column",
      "ref": "orders.order_no",
      "action": "create",
      "adopted": false,
      "changes": [
        {
          "field": "name",
          "from": null,
          "to": "Order number",
          "secrets": null
        },
        {
          "field": "type",
          "from": null,
          "to": "string",
          "secrets": null
        },
        {
          "field": "required",
          "from": null,
          "to": true,
          "secrets": null
        }
      ],
      "drifted_fields": [],
      "warnings": [],
      "errors": []
    }
  ],
  "errors": []
}

錯誤

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

狀態發生條件錯誤本文
400文件空白或格式錯誤,或超過位元組、行數、資料表或資料列上限。IaC 無條件可用,不存在 feature-disabled 分支。
{
  "detail": "line 2: invalid JSON: Expecting value"
}
400某一實體 JSONL 行的 `[`/`{` 巢狀超過 128 層。量測涵蓋整行(含 line envelope),字串字面值內的括號不計;比較是嚴格大於,因此 128 通過、129 中止。這個上限寫死在程式裡,不是 `CUSTOM_TABLE_IAC_MAX_*` 那組環境變數之一。
{
  "detail": "line 2: excessively nested JSON structure (max depth 128)"
}
400整數字面值超過 4300 位數(不計負號),或超過 Python 啟用的更嚴格限制。Plan、apply 都在寫入前中止 parse,以不含值的 line error 回報;引號內的小數字串不是整數字面值。
{
  "detail": "line 3: [{\"type\": \"json_integer_too_long\", \"loc\": [], \"msg\": \"JSON integer exceeds the safe digit limit\"}]"
}
400IaC grant 的 can_read 或 can_edit 使用 list/object。Parse 以靜態 issue 中止,不再回 500;這個 code 不是一般 REST permission payload 的契約。
{
  "detail": "line 3: [{\"type\": \"grant_access_level_type\", \"loc\": [\"grant\"], \"msg\": \"Grant access level must be a scalar or null\"}]"
}
403呼叫者未通過該 scope 的存取檢查。聊天室 route 允許聊天室的建立者、該聊天室所屬部門的部門管理者(角色 ≥ `CAN_MANAGE_DEPARTMENT`,預設 2),或公司管理者(角色 ≥ `CAN_MANAGE_COMPANY`,預設 3)。拒絕訊息為 `Insufficient permissions, not the creator. (Required department manager)`、`Insufficient permissions, not at the same department. (Required company manager)`;自後端 5.21.0 起,其他公司的聊天室與不存在的聊天室一樣回 `404 Chatroom Not found`。部門 route 允許該部門的管理者或公司管理者(`Insufficient permissions for department-level access.`);公司 route 允許公司管理者(`Insufficient permissions for company-level access.`)。
{
  "detail": "Insufficient permissions, not the creator. (Required department manager)"
}
403呼叫者不得使用文件所引用的某個資源:沒有所需權限的表格,或是不存在、屬於其他公司、無法讀取的表格 id(包含欄位 spec 中的 raw `target_table_id` 或 `source_table_id`)。`detail` 是只有一筆 `IacLineError` 的 list,其 `code` 為 `iac_permission_denied`,`line` 與 `kind` 指出被拒絕的那一行(被拒絕的是呼叫者本身時為 `line: 0`、`kind: null`;plan 為整份文件檢查的表格則為 `line: 1`、`kind: "header"`);回傳的是最先發現的拒絕(先依文件順序檢查各行引用的資源,再檢查整份文件依賴的表格,最後是 record 行的寫入權限),不一定是最早被拒絕的那一行。
{
  "detail": [
    {
      "line": 3,
      "kind": "column",
      "ref": "",
      "phase": "validate",
      "code": "iac_permission_denied",
      "reason": null,
      "column_id": null,
      "detail": "IaC resource authorization denied"
    }
  ]
}
404Route 無法解析指定的 scope,因此什麼都不會執行:不存在或已刪除的聊天室回 `Chatroom Not found`,不屬於你公司的部門回 `Department not found`。公司 route 沒有 scope 404。
{
  "detail": "Chatroom Not found"
}
422Request 超過了伺服器的 IaC 時間預算(預設 120 秒,由部署設定,client 無法調高),等待空閒的 IaC 執行 slot 的時間也計入。Plan、state 與 export 整個 request 都受限,apply 則只限唯讀階段(parse、plan、hash 檢查,以及同步或 ticket 的判斷):同步 apply 一旦開始執行各行,預算就不再適用。沒有寫入任何東西。請在系統較不忙時重試,或改送較小的文件。
{
  "detail": [
    {
      "line": 0,
      "kind": "header",
      "ref": "",
      "phase": "validate",
      "code": "ct.iac_time_budget_exceeded",
      "reason": null,
      "column_id": null,
      "detail": "IaC request exceeded its server time budget."
    }
  ]
}
500規劃時有未預期的例外拋出。回應只有 `Internal Server Error`;伺服器會回滾,日誌只記錄例外型別與資料庫錯誤代碼、絕不記錄例外文字,因為文件可能帶有唯寫的 trigger secret。
{
  "detail": "Internal Server Error"
}
POST
路由範本/private/module/custom_tables/{scope}/tables/iac/apply

套用 JSONL IaC 文件

用途

重新計算計畫、核對已審閱的指紋,再依文件順序執行可套用的各行。

適用時機

確認計畫仍是最新版本,且接受其中所有破壞性或漂移修正動作後才使用。

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

範圍

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

參數

欄位位置型別必填說明
plan_hashquerysha256否plan 回傳的 plan_hash:由伺服器金鑰計算的 64 位十六進位 HMAC-SHA-256,client 無法重算也無法預測。若不一致會回傳 409 plan_stale;請傳入此值來鎖定審閱過的計畫。
idempotency_keyquerystring否非同步票證流程可用的防重複鍵;同步套用時會忽略。它以呼叫者與 scope 為範圍,有效 24 小時,自後端 5.21.0 起還會綁定到第一次使用時的完整文件位元組(原始 request body,或 multipart 上傳的 `file` part)。同一份文件再送一次會回原本的 ticket,狀態碼 `202`、訊息 `Bulk iac-apply already submitted (idempotent replay)`,而且在 plan 之前就會找到它,所以重試一個已改動系統的 apply 不會因 `plan_stale` 失敗;不同的文件若會被 dispatch,則回 `409 ct.iac_idempotency_key_reused`。同一份文件的每次 replay 都會續期這個綁定,所以它可能比最初的 24 小時更久。
workerqueryenum:legacy|batch|sqs|pubsub否只有套用走非同步路徑時才會使用這個背景執行器:record line 太多、有重量級欄位變更,或(自後端 5.22.0 起)plan 建立、更新、刪除或搬移的資源超過 `CUSTOM_TABLE_IAC_SYNC_CHANGE_LIMIT`。預設值取自伺服器的 `DEFAULT_BACKGROUND_WORKER_TYPE` 設定,未設定或無效時為 `legacy`,所以各部署環境的預設值可能不同。除非 `legacy` 是部署的預設值,否則對重量級欄位變更或這種變更量大的 plan 明確指定 `legacy` 會被 `400 ct.iac_legacy_backfill_unavailable` 拒絕;變更量大時的拒絕有它自己的訊息。

範例

套用已審閱的資料表建立計畫

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111"
  },
  "query": {
    "plan_hash": "9a1b2c3d4e5f60718293a4b5c6d7e8f90123456789abcdef0123456789abcdef",
    "worker": "legacy"
  },
  "body": "{\"kind\":\"header\",\"version\":1,\"system\":\"catalog-demo\",\"description\":\"Catalog example\"}\n{\"kind\":\"table\",\"ref\":\"orders\",\"spec\":{\"name\":\"IaC orders\",\"description\":\"Orders managed from JSONL\",\"key\":\"order_no\"}}\n{\"kind\":\"column\",\"table\":\"orders\",\"ref\":\"order_no\",\"spec\":{\"name\":\"Order number\",\"type\":\"string\",\"required\":true}}"
}
回應200
{
  "applied": {
    "create": 2,
    "adopt": 0,
    "move": 0,
    "update": 0,
    "noop": 0,
    "delete": 0,
    "orphaned": 0,
    "insert": 0,
    "skip": 0
  },
  "results": [
    {
      "line": 2,
      "kind": "table",
      "ref": "orders",
      "action": "create",
      "adopted": false,
      "changes": [
        {
          "field": "name",
          "from": null,
          "to": "IaC orders",
          "secrets": null
        },
        {
          "field": "description",
          "from": null,
          "to": "Orders managed from JSONL",
          "secrets": null
        }
      ],
      "drifted_fields": [],
      "warnings": [],
      "errors": [],
      "applied": true
    },
    {
      "line": 3,
      "kind": "column",
      "ref": "orders.order_no",
      "action": "create",
      "adopted": false,
      "changes": [
        {
          "field": "name",
          "from": null,
          "to": "Order number",
          "secrets": null
        },
        {
          "field": "type",
          "from": null,
          "to": "string",
          "secrets": null
        },
        {
          "field": "required",
          "from": null,
          "to": true,
          "secrets": null
        }
      ],
      "drifted_fields": [],
      "warnings": [],
      "errors": [],
      "applied": true
    }
  ],
  "errors": []
}

錯誤

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

狀態發生條件錯誤本文
400JSONL 文件空白、格式錯誤或超過 parse-time cap;在比對 plan、dispatch 或 mutation 之前就會失敗。
{
  "detail": "line 2: invalid JSON: Expecting value"
}
400在預設 worker 不是 `legacy` 的部署上,對重量級欄位變更(對 live 記錄超過 10,000 筆的既有表格新增欄位、刪除欄位,或會改寫資料的 update;刪除欄位時已進垃圾桶的記錄也計入)指定了 `worker=legacy`。沒有暫存或 dispatch 任何東西;請不要帶 `worker`,或使用部署的預設值。若該 plan 同時也是變更量大的 plan,會得到下一則訊息。
{
  "detail": {
    "code": "ct.iac_legacy_backfill_unavailable",
    "message": "LEGACY backfill is available only when LEGACY is the default worker."
  }
}
400自後端 5.22.0 起:在預設 worker 不是 `legacy` 的部署上,對建立、更新、刪除或搬移的資源超過 `CUSTOM_TABLE_IAC_SYNC_CHANGE_LIMIT`(預設 300;`noop`、`adopt`、`orphaned` 與 record action 都不計入)的 plan 指定了 `worker=legacy`。文件同時有超過 200 條 record line 時,同樣適用。沒有暫存或 dispatch 任何東西;請不要帶 `worker`,或使用部署的預設值。
{
  "detail": {
    "code": "ct.iac_legacy_backfill_unavailable",
    "message": "LEGACY apply of a plan with more changes than the synchronous limit is available only when LEGACY is the default worker."
  }
}
400整數字面值超過 4300 位數(不計負號),或超過 Python 啟用的更嚴格限制。Plan、apply 都在寫入前中止 parse,以不含值的 line error 回報;引號內的小數字串不是整數字面值。
{
  "detail": "line 3: [{\"type\": \"json_integer_too_long\", \"loc\": [], \"msg\": \"JSON integer exceeds the safe digit limit\"}]"
}
400IaC grant 的 can_read 或 can_edit 使用 list/object。Parse 以靜態 issue 中止,不再回 500;這個 code 不是一般 REST permission payload 的契約。
{
  "detail": "line 3: [{\"type\": \"grant_access_level_type\", \"loc\": [\"grant\"], \"msg\": \"Grant access level must be a scalar or null\"}]"
}
403呼叫者未通過該 scope 的存取檢查。聊天室 route 允許聊天室的建立者、該聊天室所屬部門的部門管理者(角色 ≥ `CAN_MANAGE_DEPARTMENT`,預設 2),或公司管理者(角色 ≥ `CAN_MANAGE_COMPANY`,預設 3)。拒絕訊息為 `Insufficient permissions, not the creator. (Required department manager)`、`Insufficient permissions, not at the same department. (Required company manager)`;自後端 5.21.0 起,其他公司的聊天室與不存在的聊天室一樣回 `404 Chatroom Not found`。部門 route 允許該部門的管理者或公司管理者(`Insufficient permissions for department-level access.`);公司 route 允許公司管理者(`Insufficient permissions for company-level access.`)。
{
  "detail": "Insufficient permissions, not the creator. (Required department manager)"
}
403呼叫者不得使用文件所引用的某個資源:沒有所需權限的表格,或是不存在、屬於其他公司、無法讀取的表格 id(包含欄位 spec 中的 raw `target_table_id` 或 `source_table_id`)。`detail` 是只有一筆 `IacLineError` 的 list,其 `code` 為 `iac_permission_denied`,`line` 與 `kind` 指出被拒絕的那一行(被拒絕的是呼叫者本身時為 `line: 0`、`kind: null`;plan 為整份文件檢查的表格則為 `line: 1`、`kind: "header"`);回傳的是最先發現的拒絕(先依文件順序檢查各行引用的資源,再檢查整份文件依賴的表格,最後是 record 行的寫入權限),不一定是最早被拒絕的那一行。
{
  "detail": [
    {
      "line": 3,
      "kind": "column",
      "ref": "",
      "phase": "validate",
      "code": "iac_permission_denied",
      "reason": null,
      "column_id": null,
      "detail": "IaC resource authorization denied"
    }
  ]
}
404Route 無法解析指定的 scope,因此什麼都不會執行:不存在或已刪除的聊天室回 `Chatroom Not found`,不屬於你公司的部門回 `Department not found`。公司 route 沒有 scope 404。
{
  "detail": "Chatroom Not found"
}
404apply 執行期間聊天室被刪除:聊天室文件在每次變更前都會重新鎖定其聊天室,並回 `Chatroom not found`。`command` 行會鎖定自己的 scope,該 scope 已不存在時回 `Department not found` 或 `Company not found`。失敗前已套用的行維持已套用。
{
  "detail": "Chatroom not found"
}
409審閱後文件或現行資源已有變更,導致重新計算的計畫雜湊不同。
{
  "detail": {
    "code": "plan_stale",
    "message": "The live system changed since this plan was computed; re-plan and retry.",
    "plan_hash": "9a1b2c3d4e5f60718293a4b5c6d7e8f90123456789abcdef0123456789abcdef"
  }
}
409`idempotency_key` 已綁定到另一份 IaC 文件(以第一次使用時的完整文件位元組比對:原始 request body,或 multipart 上傳的 `file` part),而這次 apply 會被 dispatch 成 ticket。沒有 dispatch 任何東西;新的文件請使用新的 key。
{
  "detail": {
    "code": "ct.iac_idempotency_key_reused",
    "message": "This idempotency_key was already used with a different IaC document."
  }
}
409先前一個帶相同 idempotency_key 的請求仍在派送中,且在約兩秒的短暫輪詢內沒有綁定到 ticket。回應附 Retry-After: 1;請用同一個 key 重試。
{
  "detail": "A bulk iac-apply with this idempotency_key is already in progress"
}
409滾動部署期間,舊版伺服器保留了這個 idempotency_key。請在 replay 期間過後重試,或改用新 key 提交。
{
  "detail": "A bulk iac-apply with this idempotency_key was submitted during a deployment transition; retry after the replay window"
}
422重新計算的計畫至少含一個 validate 階段錯誤,因此不會執行任何動作。`detail` 列出 plan 層級的所有錯誤(包含 diff 階段的項目),每一項都帶 `line`、`kind`、`ref`、`phase`、`code` 與 `detail`。
{
  "detail": [
    {
      "line": 3,
      "kind": "column",
      "ref": "orders.order_no",
      "phase": "validate",
      "code": null,
      "detail": "duplicate ref 'orders.order_no' (already declared in this document)"
    }
  ]
}
422trigger 行想保留一個無法綁定的唯寫 secret——這裡是在建立 trigger 的行上使用遮罩的 `"__SECRET__"` 佔位符,所以沒有可保留的儲存值。完全沒有執行;請換成真實憑證後重新 plan。
{
  "detail": [
    {
      "line": 4,
      "kind": "trigger",
      "ref": "orders.sync_crm",
      "phase": "validate",
      "code": "trigger_secret_keep_refused",
      "detail": "2 trigger secret value(s) are the masked placeholder '__SECRET__', but this line creates the trigger here, so there is no stored value to keep — replace every placeholder with the real value"
    }
  ]
}
422Request 超過了伺服器的 IaC 時間預算(預設 120 秒,由部署設定,client 無法調高),等待空閒的 IaC 執行 slot 的時間也計入。Plan、state 與 export 整個 request 都受限,apply 則只限唯讀階段(parse、plan、hash 檢查,以及同步或 ticket 的判斷):同步 apply 一旦開始執行各行,預算就不再適用。沒有寫入任何東西。請在系統較不忙時重試,或改送較小的文件。
{
  "detail": [
    {
      "line": 0,
      "kind": "header",
      "ref": "",
      "phase": "validate",
      "code": "ct.iac_time_budget_exceeded",
      "reason": null,
      "column_id": null,
      "detail": "IaC request exceeded its server time budget."
    }
  ]
}
500有未預期的例外從整個 apply 拋出。該 request 已回滾,錯誤以不含值的方式記錄(只有型別與資料庫錯誤代碼),因為文件可能帶有唯寫的 trigger secret。失敗前已提交的行仍維持提交;重試前請重新 plan。
{
  "detail": "Internal Server Error"
}
500只發生在票證流程:送交 batch、sqs 或 pubsub worker 時拋出錯誤。`detail` 是有型別的 `{code: "ct.iac_dispatch_failed", message}`;provider 的錯誤文字只會寫進伺服器日誌。輪詢到的 ticket `body` 帶 `status: "failed"`,同一個物件放在 `error`,訊息放在 `error_message`;`idempotency_key` 仍綁定在這個 ticket 上,所以重試需要新的 key。
{
  "detail": {
    "code": "ct.iac_dispatch_failed",
    "message": "The background apply could not be submitted. Retry later."
  }
}
503冪等狀態儲存在已看到或已嘗試保留之後失敗。回應附 Retry-After: 1;請用同一個 key 重試。
{
  "detail": "Bulk iac-apply idempotency state is temporarily unavailable; retry with the same key"
}
503只發生在票證流程:`idempotency_key` 已綁定到某張 ticket,而伺服器無法檢查這個綁定(冪等狀態儲存失敗)。沒有 dispatch 任何東西;請稍後用同一個 key 重試。
{
  "detail": "IaC idempotency lookup unavailable; retry later."
}
GET
路由範本/private/module/custom_tables/{scope}/tables/iac/state
用途

回傳單一命名空間內受管理的資料表、欄位、規則、觸發器、檢視、授權、用戶端存取、command、insight_selection 與 public_read 清冊,並鎖定目前範圍。

適用時機

適合用來稽核資源歸屬、診斷孤立 ref,或確認先前 apply 納管了哪些資源。

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

範圍

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

參數

欄位位置型別必填說明
systemquerystring否來自 header.system 的狀態命名空間。預設為空字串,也就是沒有 header 或 system 為空的文件所用的命名空間。

回應結構

IacStateResponse
欄位型別必填說明
rowsIacStateRowResponse[]否Managed inventory for the queried system.
totalinteger是Number of rows.

範例

列出單一 system 的受管理資源

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111"
  },
  "query": {
    "system": "catalog-demo"
  }
}
回應200
{
  "rows": [
    {
      "system": "catalog-demo",
      "resource_type": "table",
      "ref": "orders",
      "resource_id": "22222222-2222-4222-8222-222222222222",
      "table_id": null,
      "updated_at": "2026-07-19T02:20:00Z"
    },
    {
      "system": "catalog-demo",
      "resource_type": "column",
      "ref": "orders.order_no",
      "resource_id": "22222222-2222-4222-8222-222222222222:col_33333333_3333_4333_8333_333333333333",
      "table_id": "22222222-2222-4222-8222-222222222222",
      "updated_at": "2026-07-19T02:20:00Z"
    }
  ],
  "total": 2
}

錯誤

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

狀態發生條件錯誤本文
422Request 超過了伺服器的 IaC 時間預算(預設 120 秒,由部署設定,client 無法調高),等待空閒的 IaC 執行 slot 的時間也計入。Plan、state 與 export 整個 request 都受限,apply 則只限唯讀階段(parse、plan、hash 檢查,以及同步或 ticket 的判斷):同步 apply 一旦開始執行各行,預算就不再適用。沒有寫入任何東西。請在系統較不忙時重試,或改送較小的文件。
{
  "detail": [
    {
      "line": 0,
      "kind": "header",
      "ref": "",
      "phase": "validate",
      "code": "ct.iac_time_budget_exceeded",
      "reason": null,
      "column_id": null,
      "detail": "IaC request exceeded its server time budget."
    }
  ]
}
GET
路由範本/private/module/custom_tables/{scope}/tables/iac/export
用途

從受管理的 system、明確指定的資料表集合或整個範圍,產生內容固定且已遮蔽秘密資訊的 IaC 文件。

適用時機

適合用於備份、審閱、移轉,或作為可再次匯入的宣告式文件起點。

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

範圍

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

參數

欄位位置型別必填說明
systemquerystring否要匯出的受管理 system 或標籤名稱;系統會合併狀態清冊與同名標籤中的資料表。
table_idsquerylist[uuid]否明確指定要匯出的資料表 UUID;多張資料表請重複使用 table_ids query key。
include_recordsqueryboolean否設為 true 時,替每張資料表加入最多 CUSTOM_TABLE_IAC_MAX_RECORDS 筆種子 record 行。

範例

匯出單一 system,但不包含資料列

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111"
  },
  "query": {
    "system": "catalog-demo",
    "include_records": "false"
  }
}
回應200
"{\"kind\":\"header\",\"version\":1,\"system\":\"catalog-demo\",\"description\":\"\"}\n{\"kind\":\"table\",\"ref\":\"orders\",\"spec\":{\"name\":\"IaC orders\",\"description\":\"Orders managed from JSONL\",\"key\":\"order_no\"}}\n{\"kind\":\"column\",\"table\":\"orders\",\"ref\":\"order_no\",\"spec\":{\"name\":\"Order number\",\"type\":\"string\",\"required\":true}}\n"

錯誤

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

狀態發生條件錯誤本文
400指定的資料表無效、`system=` 指名的 system 其 state 或 tag 仍指向已不存在的資料表(`managed table '<id>' not found in this scope`)、參照資料表無法解析,或匯出內容會超過設定上限。IaC 無條件可用,不存在 feature-disabled 分支。
{
  "detail": "table '99999999-9999-4999-8999-999999999999' not found in this scope"
}
403呼叫者未通過該 scope 的存取檢查。聊天室 route 允許聊天室的建立者、該聊天室所屬部門的部門管理者(角色 ≥ `CAN_MANAGE_DEPARTMENT`,預設 2),或公司管理者(角色 ≥ `CAN_MANAGE_COMPANY`,預設 3)。拒絕訊息為 `Insufficient permissions, not the creator. (Required department manager)`、`Insufficient permissions, not at the same department. (Required company manager)`;自後端 5.21.0 起,其他公司的聊天室與不存在的聊天室一樣回 `404 Chatroom Not found`。部門 route 允許該部門的管理者或公司管理者(`Insufficient permissions for department-level access.`);公司 route 允許公司管理者(`Insufficient permissions for company-level access.`)。
{
  "detail": "Insufficient permissions, not the creator. (Required department manager)"
}
404Route 無法解析指定的 scope,因此什麼都不會執行:不存在或已刪除的聊天室回 `Chatroom Not found`,不屬於你公司的部門回 `Department not found`。公司 route 沒有 scope 404。
{
  "detail": "Chatroom Not found"
}
422Request 超過了伺服器的 IaC 時間預算(預設 120 秒,由部署設定,client 無法調高),等待空閒的 IaC 執行 slot 的時間也計入。Plan、state 與 export 整個 request 都受限,apply 則只限唯讀階段(parse、plan、hash 檢查,以及同步或 ticket 的判斷):同步 apply 一旦開始執行各行,預算就不再適用。沒有寫入任何東西。請在系統較不忙時重試,或改送較小的文件。
{
  "detail": [
    {
      "line": 0,
      "kind": "header",
      "ref": "",
      "phase": "validate",
      "code": "ct.iac_time_budget_exceeded",
      "reason": null,
      "column_id": null,
      "detail": "IaC request exceeded its server time budget."
    }
  ]
}
Last updated on