Skip to Content
API 參考歷程與版本

歷程與版本

稽核資料表變更、檢視資料列快照與差異,並安全還原歷史標量資料。

GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/records/{record_id}/as-of

讀取時間點的資料列

用途

回傳已儲存歷史版本、生命週期旗標與依目前權限篩選的已擷取 link。

適用時機

檢視歷史快照,不還原、不重建計算值。

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

範圍

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

參數

欄位位置型別必填說明
table_idpathuuid是目前可讀資料表的 UUID。
record_idpathuuid是位於呼叫者目前可讀範圍的現有資料列 UUID。
as_ofqueryRFC3339 timestamp with timezone是必填,帶明確時區的 RFC3339 時間戳記;包含截止值,先取最新歷史時間,再取最高 version。

回應結構

RecordAsOfResponse
欄位型別必填說明
as_ofstring (date-time)是未指定
change_type"create" | "update" | "delete" | "restore" | "revert" | "schema_add_column" | "schema_remove_column" | "schema_type_change"是未指定
dataobject是未指定
is_deletedboolean是未指定
linksRecord<string, string[]>是未指定
record_idstring是Custom-table or tag canonical UUID
recorded_atstring (date-time)是未指定
table_idstring是Custom-table or tag canonical UUID
versioninteger是未指定

範例

讀取包含截止時間的儲存 scalar 值

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "record_id": "33333333-3333-4333-8333-333333333333"
  },
  "query": {
    "as_of": "2026-07-19T04:06:00Z"
  }
}
回應200
{
  "record_id": "33333333-3333-4333-8333-333333333333",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "version": 2,
  "as_of": "2026-07-19T04:06:00Z",
  "recorded_at": "2026-07-19T04:05:00Z",
  "change_type": "update",
  "is_deleted": false,
  "data": {
    "col_77777777_7777_4777_8777_777777777777": "ORD-1001",
    "col_88888888_8888_4888_8888_888888888888": "已確認"
  },
  "links": {}
}

錯誤

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

狀態發生條件錯誤本文
404目前列不存在/隱藏,或截止時間沒有歷史;均回 Record not found。資料表/範圍權限錯誤另計。
{
  "detail": "Record not found"
}
409目前有可見 link 欄位,但此歷史項目沒有已擷取 link 狀態;不能改用現在的 link。
{
  "detail": {
    "error": "history_links_unavailable",
    "message": "This version has no captured link state"
  }
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/period-events

讀取期間事件

用途

以 {table_id, events, total} 列出期間狀態與邊界變更,以及已稽核的 Command 例外覆寫。

適用時機

檢視 period_fence 使用的期間歷史;三種資料表範圍皆支援。

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

範圍

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

參數

欄位位置型別必填說明
table_idpathuuid是要讀取 append-only 事件的期間資料表 UUID。
record_idquerystring否可選的期間紀錄 ID 篩選;仍套用一般的可讀資料範圍。
limitqueryint (1–1000)否每頁筆數,預設 100,範圍 1 到 1000。
offsetqueryint (≥0)否不可為負數的位移,預設 0。

回應結構

CtPeriodEventsResponse
欄位型別必填說明
eventsCtPeriodEvent[]是未指定
table_idstring是未指定
totalinteger是未指定

範例

讀取已授權、尚無事件的一頁

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "query": {
    "limit": "100",
    "offset": "0"
  }
}
回應200
{
  "table_id": "22222222-2222-4222-8222-222222222222",
  "events": [],
  "total": 0
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/history

列出資料表歷程

用途

由新至舊回傳涵蓋資料列與結構變更的資料表稽核記錄(依 `created_at`、`version`、再依歷程 id 排序)。觸發器設定的變更只顯示給資料表版主。

適用時機

適合製作稽核時間軸,或在深入某筆資料列版本前先篩選變更。

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

範圍

範圍是否提供驗證與權限
聊天室可使用CustomTableReadRequired (+ CustomTableTriggerConfigVisible)
部門可使用CustomTableReadRequired (+ CustomTableTriggerConfigVisible)
公司可使用CustomTableReadRequired (+ CustomTableTriggerConfigVisible)

參數

欄位位置型別必填說明
table_idpathuuid是要列出稽核記錄的資料表 UUID。
change_typequerystring否選填,精確比對的變更類型:`create`、`update`、`delete`、`restore`、`revert`、`schema_add_column`、`schema_remove_column`、`schema_type_change`、`schema_update_column`、`schema_rules_update` 或 `schema_triggers_update`(只列給資料表版主)。其他值不會命中任何項目。
record_idqueryuuid否選填的資料列 UUID;會排除其他資料列與整張表的結構記錄。
limitqueryint 1..1000否最多回傳幾筆歷程,可填 1 到 1,000,預設為 100。
offsetqueryint >= 0否略過前幾筆符合條件的歷程,預設為 0。`total` 是符合篩選且你看得到的全部項目數,即使 offset 已超過最後一頁、回傳空頁也一樣;回應沒有 `has_more`——只要 offset 加上本頁筆數小於 total,就還有更多項目。

回應結構

TableHistoryListResponse
欄位型別必填說明
historyRecordHistoryEntry[]是History entries, newest first
table_idstring是Table UUID
totalinteger是Total number of history entries

範例

列出某筆資料列的更新記錄

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "query": {
    "change_type": "update",
    "record_id": "33333333-3333-4333-8333-333333333333",
    "limit": "50",
    "offset": "0"
  }
}
回應200
{
  "history": [
    {
      "id": "44444444-4444-4444-8444-444444444444",
      "record_id": "33333333-3333-4333-8333-333333333333",
      "table_id": "22222222-2222-4222-8222-222222222222",
      "version": 2,
      "data": {
        "id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
        "col_77777777_7777_4777_8777_777777777777": "ORD-1001",
        "col_88888888_8888_4888_8888_888888888888": "已確認"
      },
      "diff": {
        "col_88888888_8888_4888_8888_888888888888": {
          "old": "草稿",
          "new": "已確認"
        }
      },
      "change_type": "update",
      "changed_by": {
        "id": "55555555-5555-4555-8555-555555555555",
        "created_at": "2026-01-15T01:00:00",
        "expired_at": "2027-01-15T01:00:00",
        "photo_url": null,
        "enabled": true,
        "is_verified": true,
        "username": "catalog.operator",
        "email": "operator@example.invalid",
        "nickname": "陳小安",
        "department_id": "66666666-6666-4666-8666-666666666666",
        "department_name": "營運部"
      },
      "changed_by_client": null,
      "changed_by_ai": false,
      "reverted_to": null,
      "created_at": "2026-07-19T04:05:00",
      "trigger_secrets": null
    }
  ],
  "total": 1,
  "table_id": "22222222-2222-4222-8222-222222222222"
}

錯誤

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

狀態發生條件錯誤本文
404資料表 id 不存在或已在垃圾桶(讀取門檻,任何 scope),或——chatroom 路由——資料表不在路徑指定的聊天室中(路由自己的查詢,回應相同)。
{
  "detail": "CustomTable Not found"
}
404Department 或 company 路由:路徑 scope 之外的現行資料表。
{
  "detail": "Table not found"
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/records/{record_id}/history

列出資料列歷程

用途

由新至舊回傳某筆資料列所有保留的版本快照——資料列在垃圾桶中時也一樣(歷程仍可讀取;但要還原它的某個版本,必須先把資料列從垃圾桶救回)。

適用時機

適合製作資料列時間軸,或挑選要檢視、比對或還原的版本。

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

範圍

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

參數

欄位位置型別必填說明
table_idpathuuid是上層資料表 UUID。
record_idpathuuid是要列出版本的資料列 UUID。
change_typequerystring否選填,精確比對此資料列版本的變更類型:`create`、`update`、`delete`、`restore`、`revert`,或改寫過這列資料的結構操作(`schema_add_column`、`schema_remove_column`、`schema_type_change`)。
limitqueryint 1..1000否最多回傳幾筆歷程,可填 1 到 1,000,預設為 100。
offsetqueryint >= 0否略過前幾個符合條件的版本,預設為 0。`total` 是符合 `change_type` 的全部版本數,即使 offset 已超過最後一頁、回傳空頁也一樣;回應沒有 `has_more`——只要 offset 加上本頁筆數小於 total,就還有更多版本。

回應結構

RecordHistoryListResponse
欄位型別必填說明
historyRecordHistoryEntry[]是History entries, newest first
record_idstring是Record UUID
totalinteger是Total number of history entries

範例

列出某筆資料列的版本

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "record_id": "33333333-3333-4333-8333-333333333333"
  },
  "query": {
    "limit": "50",
    "offset": "0"
  }
}
回應200
{
  "history": [
    {
      "id": "44444444-4444-4444-8444-444444444444",
      "record_id": "33333333-3333-4333-8333-333333333333",
      "table_id": "22222222-2222-4222-8222-222222222222",
      "version": 2,
      "data": {
        "id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
        "col_77777777_7777_4777_8777_777777777777": "ORD-1001",
        "col_88888888_8888_4888_8888_888888888888": "已確認"
      },
      "diff": {
        "col_88888888_8888_4888_8888_888888888888": {
          "old": "草稿",
          "new": "已確認"
        }
      },
      "change_type": "update",
      "changed_by": {
        "id": "55555555-5555-4555-8555-555555555555",
        "created_at": "2026-01-15T01:00:00",
        "expired_at": "2027-01-15T01:00:00",
        "photo_url": null,
        "enabled": true,
        "is_verified": true,
        "username": "catalog.operator",
        "email": "operator@example.invalid",
        "nickname": "陳小安",
        "department_id": "66666666-6666-4666-8666-666666666666",
        "department_name": "營運部"
      },
      "changed_by_client": null,
      "changed_by_ai": false,
      "reverted_to": null,
      "created_at": "2026-07-19T04:05:00",
      "trigger_secrets": null
    },
    {
      "id": "ffffffff-ffff-4fff-8fff-ffffffffffff",
      "record_id": "33333333-3333-4333-8333-333333333333",
      "table_id": "22222222-2222-4222-8222-222222222222",
      "version": 1,
      "data": {
        "id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
        "col_77777777_7777_4777_8777_777777777777": "ORD-1001",
        "col_88888888_8888_4888_8888_888888888888": "草稿"
      },
      "diff": null,
      "change_type": "create",
      "changed_by": {
        "id": "55555555-5555-4555-8555-555555555555",
        "created_at": "2026-01-15T01:00:00",
        "expired_at": "2027-01-15T01:00:00",
        "photo_url": null,
        "enabled": true,
        "is_verified": true,
        "username": "catalog.operator",
        "email": "operator@example.invalid",
        "nickname": "陳小安",
        "department_id": "66666666-6666-4666-8666-666666666666",
        "department_name": "營運部"
      },
      "changed_by_client": null,
      "changed_by_ai": false,
      "reverted_to": null,
      "created_at": "2026-07-19T04:00:00",
      "trigger_secrets": null
    }
  ],
  "total": 2,
  "record_id": "33333333-3333-4333-8333-333333333333"
}

錯誤

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

狀態發生條件錯誤本文
404資料表 id 不存在或已在垃圾桶(讀取門檻),或——chatroom 路由——資料表不在路徑指定的聊天室中(路由自己的查詢,回應相同)。
{
  "detail": "CustomTable Not found"
}
404Department 或 company 路由:路徑 scope 之外的現行資料表。
{
  "detail": "Table not found"
}
404這張資料表中沒有此 id 的資料列(或它屬於其他資料表)。
{
  "detail": "Record not found"
}
404資料列存在,但被資料列層級存取權對你隱藏。
{
  "detail": "Record not found"
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/records/{record_id}/history/{version}

取得單一資料列版本

用途

回傳某個資料列版本的不可變快照與變更資訊。

適用時機

適合在比對或還原前,先檢視確切的歷史狀態。

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

範圍

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

參數

欄位位置型別必填說明
table_idpathuuid是上層資料表 UUID。
record_idpathuuid是擁有該版本的資料列 UUID。
versionpathint是要取得的正整數資料列版本號。

回應結構

RecordHistoryEntry
欄位型別必填說明
change_typestring是Open-ended change discriminator, not a closed enum. Includes row create/update/delete/revert and schema changes such as schema_add_column, schema_remove_column, schema_type_change, schema_rules_update and schema_triggers_update. Table-history responses omit trigger-configuration rows for non-moderators.
changed_byBaseUserInfo | null否User who made the change (null for external client changes)
changed_by_aiboolean是Whether the change was made by an AI agent
changed_by_clientSocialMediaClientBasicInfo | null否Social media client who made the change (null for internal user changes)
created_atstring (date-time)是Timestamp of the change
dataobject是Full record data snapshot at this version
diffobject | null否Field-level diff: {column_id: {old: ..., new: ...}}
idstring是History entry UUID
record_idstring | null否Record UUID (null for table-wide schema changes)
reverted_tointeger | null否Target version (only present for revert operations)
table_idstring是Parent table UUID
trigger_secretsTriggerHistorySecretSlots | null否Trigger-configuration rows (change_type "schema_triggers_update") only: the typed slot list of every "__SECRET__" in `data.triggers`, `diff.old` and `diff.new` (never a value, hash or prefix). Null on every other row.
versioninteger是Record version at the time of this change

範例

取得資料列的第 2 版

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "record_id": "33333333-3333-4333-8333-333333333333",
    "version": "2"
  }
}
回應200
{
  "id": "44444444-4444-4444-8444-444444444444",
  "record_id": "33333333-3333-4333-8333-333333333333",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "version": 2,
  "data": {
    "id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
    "col_77777777_7777_4777_8777_777777777777": "ORD-1001",
    "col_88888888_8888_4888_8888_888888888888": "已確認"
  },
  "diff": {
    "col_88888888_8888_4888_8888_888888888888": {
      "old": "草稿",
      "new": "已確認"
    }
  },
  "change_type": "update",
  "changed_by": {
    "id": "55555555-5555-4555-8555-555555555555",
    "created_at": "2026-01-15T01:00:00",
    "expired_at": "2027-01-15T01:00:00",
    "photo_url": null,
    "enabled": true,
    "is_verified": true,
    "username": "catalog.operator",
    "email": "operator@example.invalid",
    "nickname": "陳小安",
    "department_id": "66666666-6666-4666-8666-666666666666",
    "department_name": "營運部"
  },
  "changed_by_client": null,
  "changed_by_ai": false,
  "reverted_to": null,
  "created_at": "2026-07-19T04:05:00",
  "trigger_secrets": null
}

錯誤

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

狀態發生條件錯誤本文
404資料表 id 不存在或已在垃圾桶(讀取門檻),或——chatroom 路由——資料表不在路徑指定的聊天室中(路由自己的查詢,回應相同)。
{
  "detail": "CustomTable Not found"
}
404Department 或 company 路由:路徑 scope 之外的現行資料表。
{
  "detail": "Table not found"
}
404這張資料表中沒有此 id 的資料列(或它屬於其他資料表)。
{
  "detail": "Record not found"
}
404資料列存在,但被資料列層級存取權對你隱藏。
{
  "detail": "Record not found"
}
404這筆資料列不存在指定版本。
{
  "detail": "Version 2 not found"
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/records/{record_id}/history/{version}/diff

比對資料列版本

用途

回傳路徑版本與指定比較版本之間的欄位級差異,由兩份儲存的快照計算:快照相同時 `diff` 為 `{}`;連結變更永遠不會出現——連結不在 `data` 中,改動連結的那筆歷程會在自己的 `diff` 裡記錄新舊目標 id 清單。

適用時機

適合在使用者決定要還原的版本前,說明究竟改了什麼。

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

範圍

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

參數

欄位位置型別必填說明
table_idpathuuid是上層資料表 UUID。
record_idpathuuid是要比對版本的資料列 UUID。
versionpathint是URL 中的來源版本號。
compare_toqueryint是要比較的目標版本號;聊天室路由必填。

回應結構

RecordDiffResponse
欄位型別必填說明
diffobject是Field-level changes: {column_id: {old: ..., new: ...}}
from_versioninteger是Source version number
to_versioninteger是Target version number

範例

將第 2 版與第 1 版比較

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "record_id": "33333333-3333-4333-8333-333333333333",
    "version": "2"
  },
  "query": {
    "compare_to": "1"
  }
}
回應200
{
  "from_version": 2,
  "to_version": 1,
  "diff": {
    "col_88888888_8888_4888_8888_888888888888": {
      "old": "已確認",
      "new": "草稿"
    }
  }
}

錯誤

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

狀態發生條件錯誤本文
404資料表 id 不存在或已在垃圾桶(讀取門檻),或——chatroom 路由——資料表不在路徑指定的聊天室中(路由自己的查詢,回應相同)。
{
  "detail": "CustomTable Not found"
}
404Department 或 company 路由:路徑 scope 之外的現行資料表。
{
  "detail": "Table not found"
}
404這張資料表中沒有此 id 的資料列(或它屬於其他資料表)。
{
  "detail": "Record not found"
}
404資料列存在,但被資料列層級存取權對你隱藏。
{
  "detail": "Record not found"
}
404指定的一個或兩個版本不存在。
{
  "detail": "One or both versions not found"
}
422僅聊天室路由:缺少 `compare_to`(如上所示);部門與公司路由預設為 1。`compare_to` 或 `version` 不是整數時,任何路由都回 422 `int_parsing`。
{
  "detail": [
    {
      "type": "missing",
      "loc": [
        "query",
        "compare_to"
      ],
      "msg": "Field required",
      "input": null
    }
  ]
}
POST
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/records/{record_id}/history/{version}/restore

還原資料列版本

用途

將歷史的標量快照複製到現行資料列,並把結果記錄為新的 revert 版本。

適用時機

檢視目標快照與差異,並確認目前連結與結構相容後使用。

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

範圍

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

參數

欄位位置型別必填說明
table_idpathuuid是上層資料表 UUID。
record_idpathuuid是要還原的資料列 UUID。
versionpathint是要還原標量資料的歷史版本號。

回應結構

RestoreResponse
欄位型別必填說明
links_not_restoredboolean否True when the table has link columns: version restore reverts only scalar cells — the record's CURRENT link relations were NOT reverted to the target version. Surface this so the user knows relations differ.
messagestring是Status message
new_versioninteger是The new version number after restore
recordCustomTableRecordResponse是The restored record (now at a new version)
restored_from_versioninteger是The version that was restored from

範例

還原第 1 版的標量資料

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "record_id": "33333333-3333-4333-8333-333333333333",
    "version": "1"
  }
}
回應200
{
  "record": {
    "id": "33333333-3333-4333-8333-333333333333",
    "data": {
      "id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
      "訂單編號": "ORD-1001",
      "狀態": "草稿"
    },
    "version": 3,
    "is_deleted": false,
    "created_by_ai": false,
    "created_by": {
      "id": "55555555-5555-4555-8555-555555555555",
      "created_at": "2026-01-15T01:00:00",
      "expired_at": "2027-01-15T01:00:00",
      "photo_url": null,
      "enabled": true,
      "is_verified": true,
      "username": "catalog.operator",
      "email": "operator@example.invalid",
      "nickname": "陳小安",
      "department_id": "66666666-6666-4666-8666-666666666666",
      "department_name": "營運部"
    },
    "created_by_client": null,
    "sort_order": 1,
    "table_id": "22222222-2222-4222-8222-222222222222",
    "created_at": "2026-07-19T04:00:00",
    "updated_at": "2026-07-19T04:10:00",
    "expanded": null,
    "incoming_links": null,
    "can_edit": true,
    "pending_approval": null
  },
  "restored_from_version": 1,
  "new_version": 3,
  "message": "Record restored to version 1",
  "links_not_restored": 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。讀取不受影響。
{
  "detail": {
    "error": "governed_context_required",
    "message": "This table accepts record writes only through Commands (write_policy: commands_only). Run a Command that is allowed to write it instead.",
    "table_id": "22222222-2222-4222-8222-222222222222",
    "operation": "revert"
  }
}
409`date_interval_exclusion` 規則拒絕此次寫入:`date_interval_exclusion_invalid_period`(建立時省略 end key、結束日為空字串或不晚於起始日,或 scope link 沒有恰好一個目標)、`date_interval_exclusion_overlap`(另一筆 live 資料列涵蓋了這段期間的一部分),或 `date_interval_exclusion_retry`(寫入等待期間資料表的規則被改變;沒有寫入任何東西,請重送)。body 是固定訊息,絕不會指出資料列、日期或 scope 值。
{
  "detail": {
    "error": "date_interval_exclusion_overlap",
    "message": "Date period overlaps another period in this partition."
  }
}
409排除送審者(`exclude_requester`)之後,某個必要的審批 gate 沒有任何可核准者。送出會在任何 review process 出現之前就被拒絕;`gate_order` 指出該 gate。對於不管理每一張被引用資料表的 `authority: definition` command 呼叫者,只會回傳安全的 key,所以沒有 `gate_order`。
{
  "detail": {
    "error": "no_eligible_approver",
    "message": "Excluding the requester leaves a required review gate with no eligible approver",
    "gate_order": 1
  }
}
409這筆寫入需要排除送審者,但呼叫的主體沒有已驗證的人類身分(例如 service account),無法歸屬。不會暫存任何東西。
{
  "detail": {
    "error": "requester_unattributable",
    "message": "This review requires the requester to be excluded, but the submitting principal has no verified human identity"
  }
}
404這張資料表中沒有此資料列,或它在垃圾桶中(請先從垃圾桶還原)——或編輯層級為 `filtered` 時,資料列存在但被你的讀取篩選隱藏;這個 body 適用於管理此表或編輯層級為 `all`、`filtered` 的呼叫者。資料表不存在或已在垃圾桶時,編輯門檻會回 `404 CustomTable Not found`(chatroom 路由上,資料表不在路徑指定的聊天室中時也是)。
{
  "detail": "Record not found"
}
404own/filtered 編輯者無法找到資料列,或資料列被可讀範圍隱藏。body 與一般資料列可見性檢查相同,使用 Record not found。
{
  "detail": "Record not found"
}
404Department 或 company 路由:路徑 scope 之外的現行資料表。
{
  "detail": "Table not found"
}
403你的編輯層級為 own,資料列由他人建立且可讀取;不可讀的資料列改回 404 Record not found。
{
  "detail": "You can only restore records you created."
}
403你的編輯層級是 `filtered`,而資料列目前的內容或你要還原的版本落在你的編輯篩選之外——還原不能把資料列移出你可編輯的範圍。被你的讀取篩選隱藏的資料列則改回 `404 Record not found`。
{
  "detail": "This record is outside your editable scope."
}
400這筆資料列沒有此版本號的歷程。與讀取路由不同,還原時找不到目標版本回的是 400,而不是 404。
{
  "detail": "Version 7 not found for this record"
}
400有寫入規則否決還原後的資料列——`compare`、`check`、`require`、`no_overlap`、`exists`/`not_exists`、`count_limit` 或 `immutable_when` 會回 `400 Rule '<名稱或 id>' violated: …`——或某個被改動的 `user`、`social_client` 或 `principal` 欄位指向已刪除或不在公司內的對象(`400 Unknown or inaccessible user ids: [...]`,或 `… social_client ids`/`… chatroom ids`)。`transition` 與 `unique` 規則則回 409。
{
  "detail": "Rule 'draft-cap' violated: limit of 20 matching rows reached"
}
409目標版本已不符合資料表目前的欄位結構,沒有還原任何資料。每筆衝突的 `field` 是內部欄位鍵:`removed_column`(該版本含有之後被刪除的欄位——這種版本無法還原)、`missing_required_field`(之後新增了沒有預設值的必填欄位),或 `type_mismatch`(儲存的值已不被改型後的欄位型別接受——string→text 或 integer→float 可以正常還原——或 decimal 值已不符合欄位的精度或正負號,或必填的 decimal 欄位存著明確的 null;符合的 decimal 會依目前的 scale 重新序列化)。值規則造成的衝突另外回報(`invalid_value`)。
{
  "detail": {
    "detail": "Cannot restore to version 1: schema has changed incompatibly",
    "conflicts": [
      {
        "type": "removed_column",
        "field": "col_88888888_8888_4888_8888_888888888888",
        "message": "Column 'col_88888888_8888_4888_8888_888888888888' no longer exists in schema"
      }
    ]
  }
}
409目標版本通過欄位檢查,但有值違反目前結構的欄位規則——例如之後停用的 select 選項、現在必填的(非 decimal)欄位存著明確的 null,或文字超過調低後的 `max_length`。每筆衝突為 `type: "invalid_value"`、`field: null`,並由 `message` 以顯示名稱指出欄位。只有在沒有欄位衝突時才會做這項檢查,所以兩類衝突不會出現在同一個回應中;核准後重播還原時也會再檢查一次。
{
  "detail": {
    "detail": "Cannot restore to version 1: schema has changed incompatibly",
    "conflicts": [
      {
        "type": "invalid_value",
        "field": null,
        "message": "Field '狀態' value '草稿' is not an allowed option (valid: 已確認, 已出貨)"
      }
    ]
  }
}
409資料表的 require_approval 規則命中這次還原——版本還原算作 `update` 事件,只要目前資料列或還原後的資料任一符合 `when` 就算命中——因此還原被暫存為 staged change、等待覆核;核准前現行資料列不會改變。
{
  "detail": {
    "error": "approval_required",
    "process_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
    "rule_id": "cccccccc-cccc-4ccc-8ccc-cccccccccccc",
    "rule_label": "require_approval",
    "staged_change_id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd"
  }
}
409這筆資料列已被另一個等待覆核的暫存變更鎖住;在該覆核結束前,不論這次還原是否會命中審批規則,資料列都不接受其他寫入。
{
  "detail": {
    "error": "approval_pending",
    "process_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
    "staged_change_id": "dddddddd-dddd-4ddd-8ddd-dddddddddddd"
  }
}
409`transition` 規則不允許這次還原造成的值變更(把狀態倒回去也算一次轉移)。`unique` 衝突同樣回 409,`detail` 為結構化物件。
{
  "detail": "Rule 'order-flow' violated: transition of '狀態' from '已出貨' to '草稿' is not allowed"
}
423資料表目前被結構遷移鎖定。
{
  "detail": "Table is currently locked for operation: add_column"
}
429此表或此操作者的待覆核暫存變更已達上限(staged_cap_exceeded)。
{
  "detail": {
    "error": "staged_cap_exceeded",
    "scope": "actor",
    "limit": 500
  }
}
413還原會寫入的資料列同時「超過上限」且「比目前更大」。把超大資料列還原成較小的版本仍然允許。
{
  "detail": {
    "error": "record_too_large",
    "message": "Record data is 1310720 bytes; the limit is 1048576 bytes",
    "limit": 1048576,
    "size": 1310720,
    "previous_size": 1049600
  }
}

目前的欄位 ACL 與 schema ceiling會過濾 record/table history、stored version 與 diff。受限 principal 看不到已移除欄位;未受欄位限制的讀者仍可能取得已移除的 stored field。這不會還原舊權限,也不會繞過目前 row authorization。

歷史 as-of 讀取 依目前權限取回時間點的儲存版本;不是 ACL 或計算值的時間旅行。

Last updated on