Skip to Content
API 參考建立、診斷與遷移

建立、診斷與遷移

初始化資料表與結構、產生測試資料、執行診斷,並追蹤背景遷移工作。

破壞性生命週期操作也遵守保留期限與法律保全;這些控制不是資料列不可變封存。

POST
路由範本/private/module/custom_tables/{scope}/tables/bootstrap
用途

一次建立一張資料表,並依序走一般新增流程寫入最多 200 筆種子資料。

適用時機

新功能初始化時,結構與少量初始資料需要一起建立時使用。

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

範圍

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

請求結構

TableBootstrapRequest
欄位型別必填說明
created_by_aiboolean否Mark seeded records AI-authored
rowsobject[]否Seed record data dicts (display-name OR internal keys), inserted synchronously in order; max 200 (use bulk-insert for more)
tableCustomTableCreate是Table definition (same as POST .../tables)

回應結構

TableBootstrapResponse
欄位型別必填說明
recordsCustomTableRecordResponse[]否The seeded records in insertion order
tableCustomTableResponse是The created table (same as POST .../tables)

範例

建立庫存資料表與第一筆庫存

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111"
  },
  "body": {
    "table": {
      "name": "庫存",
      "description": "目前庫存量",
      "schema_definition": {
        "columns": [
          {
            "name": "品項",
            "type": "string",
            "required": true
          },
          {
            "name": "數量",
            "type": "integer"
          }
        ]
      }
    },
    "rows": [
      {
        "品項": "筆記本",
        "數量": 20
      }
    ],
    "created_by_ai": false
  }
}
回應201
{
  "table": {
    "id": "22222222-2222-4222-8222-222222222222",
    "name": "庫存",
    "description": "目前庫存量",
    "schema_definition": {
      "columns": [
        {
          "target_table_id": null,
          "cardinality": null,
          "link_field": null,
          "aggregation": null,
          "target_column": null,
          "direction": null,
          "source_table_id": null,
          "match": null,
          "filter": null,
          "expression": null,
          "pick": null,
          "fallback": null,
          "options": null,
          "max_count": null,
          "max_file_bytes": null,
          "allowed_mime_types": null,
          "restricted": null,
          "name": "id",
          "type": "string",
          "required": true,
          "default_value": null,
          "max_length": null,
          "description": "Auto-generated unique identifier"
        },
        {
          "target_table_id": null,
          "cardinality": null,
          "link_field": null,
          "aggregation": null,
          "target_column": null,
          "direction": null,
          "source_table_id": null,
          "match": null,
          "filter": null,
          "expression": null,
          "pick": null,
          "fallback": null,
          "options": null,
          "max_count": null,
          "max_file_bytes": null,
          "allowed_mime_types": null,
          "restricted": null,
          "name": "品項",
          "type": "string",
          "required": true,
          "default_value": null,
          "max_length": null,
          "description": null
        },
        {
          "target_table_id": null,
          "cardinality": null,
          "link_field": null,
          "aggregation": null,
          "target_column": null,
          "direction": null,
          "source_table_id": null,
          "match": null,
          "filter": null,
          "expression": null,
          "pick": null,
          "fallback": null,
          "options": null,
          "max_count": null,
          "max_file_bytes": null,
          "allowed_mime_types": null,
          "restricted": null,
          "name": "數量",
          "type": "integer",
          "required": false,
          "default_value": null,
          "max_length": null,
          "description": null
        }
      ]
    },
    "settings": {
      "default_permissions": {
        "can_read": "all",
        "can_insert": false,
        "can_edit": "none"
      },
      "column_mapping": {
        "品項": "col_a1111111_1111_4111_8111_111111111111",
        "數量": "col_b2222222_2222_4222_8222_222222222222"
      }
    },
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "department_id": null,
    "company_id": null,
    "record_count": 0,
    "created_at": "2026-07-19T02:20:00",
    "updated_at": "2026-07-19T02:25:00"
  },
  "records": [
    {
      "id": "33333333-3333-4333-8333-333333333333",
      "table_id": "22222222-2222-4222-8222-222222222222",
      "data": {
        "id": "77777777-7777-4777-8777-777777777777",
        "品項": "筆記本",
        "數量": 20
      },
      "created_by_ai": false,
      "created_by": {
        "id": "99999999-9999-4999-8999-999999999999",
        "created_at": "2026-01-01 08:00:00",
        "expired_at": "2027-01-01 08:00:00",
        "photo_url": "https://example.com/avatar.png",
        "enabled": true,
        "is_verified": true,
        "username": "api-user",
        "email": "api-user@example.com",
        "nickname": "API User",
        "department_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
        "department_name": "營運部"
      },
      "created_by_client": null,
      "is_deleted": false,
      "sort_order": 1,
      "version": 1,
      "expanded": null,
      "incoming_links": null,
      "can_edit": true,
      "pending_approval": null,
      "created_at": "2026-07-19T02:20:00",
      "updated_at": "2026-07-19T02:25:00"
    }
  ]
}

錯誤

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

狀態發生條件錯誤本文
400某筆種子資料無法通過一般新增驗證。
{
  "detail": "Seed row 0: Validation errors: Field '品項' is required"
}
400在 chatroom 或 company scope 的 bootstrap 上送了 `settings.default_permissions.audience: "company"`。detail 就是這一整句,而且整個呼叫在資料表列寫入之前就失敗——沒有表,也沒有種子資料列。這種分享只有在部門 scope 的表上才有意義,在那裡它取代了逐部門建立授權列。
{
  "detail": "settings.default_permissions.audience \"company\" is only valid on department-scoped tables"
}
400`audience` 帶了 `"scope"` 與 `"company"` 以外的值——該值會以 `repr` 形式回拋,所以 `"everyone"` 會呈現成 `'everyone'`。與 default-permissions 的 PATCH 不同,這條通道收的是 raw settings dict 而非 Pydantic `Literal`,因此錯誤的值會一路走到文法閘門,回 `400` 而不是一般的 `422` 驗證 body。
{
  "detail": "settings.default_permissions.audience must be \"scope\" or \"company\", got 'everyone'"
}
404某筆種子資料的 link 值指向不存在、已被 soft delete,或被目標表的 row ACL 對你隱藏的記錄。這就是一般新增記錄時統一的 `linked record not found`,前面再加上從 0 起算的資料列索引;資料表與先前的種子資料列仍會保留。
{
  "detail": "Seed row 0: linked record not found"
}
422資料表規格不合法,或 `rows` 超過 200 筆。驗證錯誤 body 會在 `input` 回顯送出的清單,並在 `ctx` 標出實際筆數。`table.settings` 不可帶有伺服器擁有的座標索引狀態 `_coordinate_cells_v1`:自後端 5.22.0 起會以 `Value error, Coordinate index state is server-owned` 拒絕。
{
  "detail": [
    {
      "type": "too_long",
      "loc": [
        "body",
        "rows"
      ],
      "msg": "List should have at most 200 items after validation, not 201",
      "input": [
        "…the 201 submitted rows…"
      ],
      "ctx": {
        "field_type": "List",
        "max_length": 200,
        "actual_length": 201
      }
    }
  ]
}
POST
路由範本/private/module/custom_tables/{scope}/tables/bootstrap-schema
用途

以請求內 alias 表示跨表參照,依相依順序建立最多 20 張資料表。

適用時機

要一次初始化一組有 link、rollup 或 lookup 相依關係的資料表時使用。

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

範圍

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

請求結構

SchemaBootstrapRequest
欄位型別必填說明
tablesSchemaBootstrapTable[]是Table specs (max 20); aliases must be unique within the request

回應結構

SchemaBootstrapResponse
欄位型別必填說明
tablesSchemaBootstrapResultEntry[]否未指定

範例

以 alias 建立客戶與訂單資料表

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111"
  },
  "body": {
    "tables": [
      {
        "alias": "orders",
        "name": "訂單",
        "columns": [
          {
            "name": "編號",
            "type": "string",
            "required": true
          },
          {
            "name": "客戶",
            "type": "link",
            "target_table_alias": "customers",
            "cardinality": "one"
          }
        ]
      },
      {
        "alias": "customers",
        "name": "客戶",
        "columns": [
          {
            "name": "名稱",
            "type": "string",
            "required": true
          }
        ]
      }
    ]
  }
}
回應201
{
  "tables": [
    {
      "alias": "orders",
      "table": {
        "id": "55555555-5555-4555-8555-555555555555",
        "name": "訂單",
        "description": null,
        "schema_definition": {
          "columns": [
            {
              "target_table_id": null,
              "cardinality": null,
              "link_field": null,
              "aggregation": null,
              "target_column": null,
              "direction": null,
              "source_table_id": null,
              "match": null,
              "filter": null,
              "expression": null,
              "pick": null,
              "fallback": null,
              "options": null,
              "max_count": null,
              "max_file_bytes": null,
              "allowed_mime_types": null,
              "restricted": null,
              "name": "id",
              "type": "string",
              "required": true,
              "default_value": null,
              "max_length": null,
              "description": "Auto-generated unique identifier"
            },
            {
              "target_table_id": null,
              "cardinality": null,
              "link_field": null,
              "aggregation": null,
              "target_column": null,
              "direction": null,
              "source_table_id": null,
              "match": null,
              "filter": null,
              "expression": null,
              "pick": null,
              "fallback": null,
              "options": null,
              "max_count": null,
              "max_file_bytes": null,
              "allowed_mime_types": null,
              "restricted": null,
              "name": "編號",
              "type": "string",
              "required": true,
              "default_value": null,
              "max_length": null,
              "description": null
            },
            {
              "target_table_id": "44444444-4444-4444-8444-444444444444",
              "cardinality": "one",
              "link_field": null,
              "aggregation": null,
              "target_column": null,
              "direction": null,
              "source_table_id": null,
              "match": null,
              "filter": null,
              "expression": null,
              "pick": null,
              "fallback": null,
              "options": null,
              "max_count": null,
              "max_file_bytes": null,
              "allowed_mime_types": null,
              "restricted": null,
              "name": "客戶",
              "type": "link",
              "required": false,
              "default_value": null,
              "max_length": null,
              "description": null
            }
          ]
        },
        "settings": {
          "default_permissions": {
            "can_read": "all",
            "can_insert": false,
            "can_edit": "none"
          },
          "column_mapping": {
            "編號": "col_d4444444_4444_4444_8444_444444444444",
            "客戶": "col_e5555555_5555_4555_8555_555555555555"
          }
        },
        "chatroom_id": "11111111-1111-4111-8111-111111111111",
        "department_id": null,
        "company_id": null,
        "record_count": 0,
        "created_at": "2026-07-19T02:20:00",
        "updated_at": "2026-07-19T02:25:00"
      }
    },
    {
      "alias": "customers",
      "table": {
        "id": "44444444-4444-4444-8444-444444444444",
        "name": "客戶",
        "description": null,
        "schema_definition": {
          "columns": [
            {
              "target_table_id": null,
              "cardinality": null,
              "link_field": null,
              "aggregation": null,
              "target_column": null,
              "direction": null,
              "source_table_id": null,
              "match": null,
              "filter": null,
              "expression": null,
              "pick": null,
              "fallback": null,
              "options": null,
              "max_count": null,
              "max_file_bytes": null,
              "allowed_mime_types": null,
              "restricted": null,
              "name": "id",
              "type": "string",
              "required": true,
              "default_value": null,
              "max_length": null,
              "description": "Auto-generated unique identifier"
            },
            {
              "target_table_id": null,
              "cardinality": null,
              "link_field": null,
              "aggregation": null,
              "target_column": null,
              "direction": null,
              "source_table_id": null,
              "match": null,
              "filter": null,
              "expression": null,
              "pick": null,
              "fallback": null,
              "options": null,
              "max_count": null,
              "max_file_bytes": null,
              "allowed_mime_types": null,
              "restricted": null,
              "name": "名稱",
              "type": "string",
              "required": true,
              "default_value": null,
              "max_length": null,
              "description": null
            }
          ]
        },
        "settings": {
          "default_permissions": {
            "can_read": "all",
            "can_insert": false,
            "can_edit": "none"
          },
          "column_mapping": {
            "名稱": "col_c3333333_3333_4333_8333_333333333333"
          }
        },
        "chatroom_id": "11111111-1111-4111-8111-111111111111",
        "department_id": null,
        "company_id": null,
        "record_count": 0,
        "created_at": "2026-07-19T02:20:00",
        "updated_at": "2026-07-19T02:25:00"
      }
    }
  ]
}

錯誤

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

狀態發生條件錯誤本文
400兩個資料表規格使用相同的 alias(detail 為 `Duplicate alias in bootstrap-schema request`),或欄位的 `target_table_alias`/`source_table_alias` 指向請求中不存在的 alias(即此處顯示的 body)。這兩項檢查都在建立任何資料表之前執行。
{
  "detail": "Table 'orders' references unknown alias 'customers'"
}
400alias 之間形成循環相依,無法先建立任何一張目標表。
{
  "detail": "Circular link references among aliases ['orders', 'customers']; create these tables individually then add the link column"
}
422某個資料表規格在 alias 改寫後,未通過一般建立資料表的驗證——此例是缺少 `type` 的欄位。與一般的 422 不同,`detail` 是單一字串:`Table '<alias>': ` 後面接著以 Python 文字印出的 Pydantic 錯誤清單(其中的 `url` 帶有實際部署的 Pydantic 版本),所以只比對前綴即可。資料表的 `settings` 若帶有伺服器擁有的座標索引狀態 `_coordinate_cells_v1`,自後端 5.22.0 起也以同樣方式失敗。依相依順序先建立的資料表仍會保留。
{
  "detail": "Table 'orders': [{'type': 'missing', 'loc': ('schema_definition', 'columns', 0, 'type'), 'msg': 'Field required', 'input': {'name': '編號'}, 'url': 'https://errors.pydantic.dev/<pydantic-version>/v/missing'}]"
}
POST
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/test-data

產生測試資料

用途

依欄位型別產生隨機資料列,用於開發、效能與遷移測試。

適用時機

只在可丟棄或明確隔離的測試資料表需要快速造資料時使用。

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

範圍

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

參數

欄位位置型別必填說明
table_idpathuuid是要插入隨機測試資料的自訂資料表 UUID。

請求結構

TestDataInsertRequest
欄位型別必填說明
record_countinteger是Number of test records to insert

回應結構

TestDataInsertResponse
欄位型別必填說明
background_processingboolean是Whether the insertion is running in background
inserted_countinteger | null否Number of records inserted (for synchronous operations)
messagestring是Status message
migration_idstring | null否Migration ID for tracking background operations
requested_recordsinteger | null否Number of records requested for background processing
total_requestedinteger | null否Total number of records requested

範例

同步產生一筆測試資料

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  },
  "body": {
    "record_count": 1
  }
}
回應200
{
  "background_processing": false,
  "inserted_count": 1,
  "total_requested": 1,
  "requested_records": null,
  "migration_id": null,
  "message": "Successfully inserted 1 test records"
}

錯誤

驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 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": "create",
    "surface": "test_data"
  }
}
400資料表不在路徑指定的聊天室、部門或公司中(detail 為 `Table not found`)、產生的資料列驗證失敗——例如必填的 user、social_client 或 principal 欄位,測試資料永遠不會填入——或插入流程發生非預期錯誤(detail 以 `Test data insertion failed:` 開頭)。
{
  "detail": "Table not found"
}
403呼叫者不是資料表版主:既不是明確指定的版主、聊天室建立者,也不是該表所屬部門或公司的管理者。403 的確切文字依資料表的 scope 而異;這裡是 company 資料表的版本。自後端 5.21.0 起,其他公司的資料表改為回 `404 CustomTable Not found`。
{
  "detail": "Insufficient permissions. Required: table moderator or company management rights."
}
404資料表 id 不存在或已在垃圾桶(版主權限相依)。現行但不在路徑 scope 內的資料表會通過門檻,改回 400 `Table not found`;在 company 路由上,自己公司的部門資料表也算在 scope 內。
{
  "detail": "CustomTable Not found"
}
422`record_count` 缺漏、不是整數,或超出 1–100,000。欄位限制會以標準驗證 body 回應——小於 1 為 `greater_than_equal`,大於 100,000 為 `less_than_equal`(即此處顯示的 body)——並在模型自己的範圍檢查之前生效,所以那段檢查的訊息永遠不會送到客戶端。
{
  "detail": [
    {
      "type": "less_than_equal",
      "loc": [
        "body",
        "record_count"
      ],
      "msg": "Input should be less than or equal to 100000",
      "input": 100001,
      "ctx": {
        "le": 100000
      }
    }
  ]
}
423資料表已被鎖定(detail 為 `Table is locked for operation: <op>`)。只有背景執行(超過 2,000 筆)會在背景工作中自行取得 `test_data_insertion` 鎖;同步執行不取得任何鎖。
{
  "detail": "Table is locked for operation: test_data_insertion"
}
POST
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/diagnosis
用途

驗證所有資料列、找出結構與完整性問題,並提供效能建議。

適用時機

大量匯入、結構遷移後,或懷疑既有資料不符合目前結構時使用。

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

範圍

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

參數

欄位位置型別必填說明
table_idpathuuid是要執行診斷的自訂資料表 UUID。

回應結構

TableDiagnosisResponse
欄位型別必填說明
background_processingboolean是Whether the diagnosis is running in background
diagnosis_resultsobject | null否Complete diagnosis results (for synchronous operations)
estimated_recordsinteger | null否Estimated number of records to process
messagestring是Status message
migration_idstring | null否Migration ID for tracking background operations

範例

同步診斷小型資料表

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  }
}
回應200
{
  "background_processing": false,
  "migration_id": "88888888-8888-4888-8888-888888888888",
  "estimated_records": null,
  "diagnosis_results": {
    "total_records": 1,
    "valid_records": 1,
    "invalid_records": 0,
    "validation_errors": [],
    "schema_issues": [],
    "data_integrity_issues": [],
    "performance_recommendations": []
  },
  "message": "Diagnosis completed"
}

錯誤

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

狀態發生條件錯誤本文
400資料表不在路徑指定的聊天室、部門或公司中(detail 為 `Table not found`),或診斷發生非預期錯誤(detail 以 `Diagnosis failed:` 開頭)。不合法的資料列不會造成 400——它們會列在 200 的報告中。
{
  "detail": "Table not found"
}
403呼叫者不是資料表版主:既不是明確指定的版主、聊天室建立者,也不是該表所屬部門或公司的管理者。403 的確切文字依資料表的 scope 而異;這裡是 company 資料表的版本。自後端 5.21.0 起,其他公司的資料表改為回 `404 CustomTable Not found`。
{
  "detail": "Insufficient permissions. Required: table moderator or company management rights."
}
404資料表 id 不存在或已在垃圾桶(版主權限相依)。現行但不在路徑 scope 內的資料表會通過門檻,改回 400 `Table not found`;在 company 路由上,自己公司的部門資料表也算在 scope 內。
{
  "detail": "CustomTable Not found"
}
423資料表已被鎖定(detail 為 `Table is locked for operation: <op>`)。只有背景診斷(超過 5,000 筆現行資料列)會在背景工作中自行取得 `diagnosis` 鎖。
{
  "detail": "Table is locked for operation: diagnosis"
}
GET
路由範本/private/module/custom_tables/{scope}/tables/{table_id}/migration/status
用途

回傳指定資料表目前是否被遷移鎖定、鎖定資訊,以及呼叫者自己的資料列數(與資料表詳細資料顯示給他的數字相同)。

適用時機

在可能衝突的結構或資料寫入前,顯示資料表是否暫時忙碌時使用。

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

範圍

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

參數

欄位位置型別必填說明
table_idpathuuid是要檢查鎖定狀態的自訂資料表 UUID。

回應結構

TableMigrationStatusResponse
欄位型別必填說明
is_lockedboolean是Whether the table is currently locked
lock_infoobject是Lock information if table is locked
record_countinteger是Current number of records in the table
table_idstring是Table ID

範例

確認資料表目前未被鎖定

請求
{
  "pathParams": {
    "chatroom_id": "11111111-1111-4111-8111-111111111111",
    "table_id": "22222222-2222-4222-8222-222222222222"
  }
}
回應200
{
  "table_id": "22222222-2222-4222-8222-222222222222",
  "is_locked": false,
  "lock_info": {},
  "record_count": 1
}

錯誤

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

狀態發生條件錯誤本文
404資料表 id 不存在或已在垃圾桶、屬於其他 scope 或(自後端 5.21.0 起)其他公司,或呼叫者對它沒有任何權利(包括同公司但被門檻拒絕的情況)——全部回 404 `CustomTable Not found`。在 chatroom scope,聊天室門檻會先執行,並保留自己的 403/404。
{
  "detail": "CustomTable Not found"
}
GET
路由範本/private/module/custom_tables/{scopeName}/migrations/{migration_id}/status
用途

回傳背景工作的狀態、進度與時間戳記:已結束的工作,或自被接受起的欄位新增。該表的管理者與版主另外會看到 `error_message` 與儲存的筆數;其他呼叫者只有在自己對該表的資料列數不受限時才看得到筆數(否則為 `null`)。

適用時機

端點回傳 `migration_id` 後查詢。工作執行期間沒有任何紀錄——完成前此路由回 404 `Migration not found`——結束後會以 `completed`(progress 100)或 `failed`(progress 0)保留一小時。背景欄位新增是例外:它的紀錄從一開始就存在(`queued`、`processing`,然後 `completed` 或 `failed`)。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/migrations/{migration_id}/status
  • 部門/private/module/custom_tables/department/migrations/{migration_id}/status
  • 公司/private/module/custom_tables/company/migrations/{migration_id}/status

範圍

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

參數

欄位位置型別必填說明
migration_idpathuuid是全域唯一的背景遷移 UUID。

回應結構

MigrationStatusResponse
欄位型別必填說明
created_atstring是Migration creation timestamp
error_messagestring | null否Error message if the migration failed — only for the table's managers and moderators; null for every other caller
migrated_recordsinteger | null是Number of records processed: null exactly when total_records is
migration_idstring是Migration ID
operationstring是Migration operation type
progressinteger是Progress percentage (0-100)
statusstring是Current migration status
table_idstring是Table ID
total_recordsinteger | null是Total records to process (a whole-table figure): null for a caller whose own record count of the table is restricted (row policy, own rows only, insert-only)
updated_atstring是Last update timestamp

範例

取得已完成診斷工作的進度

請求
{
  "pathParams": {
    "migration_id": "88888888-8888-4888-8888-888888888888"
  }
}
回應200
{
  "migration_id": "88888888-8888-4888-8888-888888888888",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "operation": "diagnosis",
  "status": "completed",
  "progress": 100,
  "total_records": 5001,
  "migrated_records": 5001,
  "error_message": null,
  "created_at": "2026-07-19T02:20:00.183412+00:00",
  "updated_at": "2026-07-19T02:25:07.529130+00:00"
}

同一個工作,由資料列數受限的呼叫者讀取

請求
{
  "pathParams": {
    "migration_id": "88888888-8888-4888-8888-888888888888"
  }
}
回應200
{
  "migration_id": "88888888-8888-4888-8888-888888888888",
  "table_id": "22222222-2222-4222-8222-222222222222",
  "operation": "diagnosis",
  "status": "completed",
  "progress": 100,
  "total_records": null,
  "migrated_records": null,
  "error_message": null,
  "created_at": "2026-07-19T02:20:00.183412+00:00",
  "updated_at": "2026-07-19T02:25:07.529130+00:00"
}

錯誤

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

狀態發生條件錯誤本文
404id 不存在、工作(欄位新增除外)仍在執行中,或結果已過期(一小時;欄位新增保留 24 小時);或是對該遷移所屬資料表的任何拒絕——沒有權利、門檻拒絕、其他公司、資料表在垃圾桶,或(company 路由)該表不是 company scope 資料表。以上全部回應相同的 404。
{
  "detail": "Migration not found"
}
GET
路由範本/private/module/custom_tables/{scopeName}/migrations/{migration_id}/diagnosis-results

取得背景診斷結果

用途

依診斷工作的 migration_id 回傳完整驗證、結構、完整性與效能結果。

適用時機

背景 diagnosis 已完成,且需要取得詳細問題清單時使用。

實際掛載路徑
  • 聊天室/private/module/custom_tables/chatroom/migrations/{migration_id}/diagnosis-results
  • 部門/private/module/custom_tables/department/migrations/{migration_id}/diagnosis-results
  • 公司/private/module/custom_tables/company/migrations/{migration_id}/diagnosis-results

範圍

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

參數

欄位位置型別必填說明
migration_idpathuuid是背景診斷工作的全域唯一 UUID。

回應結構

TableDiagnosisResponse
欄位型別必填說明
background_processingboolean是Whether the diagnosis is running in background
diagnosis_resultsobject | null否Complete diagnosis results (for synchronous operations)
estimated_recordsinteger | null否Estimated number of records to process
messagestring是Status message
migration_idstring | null否Migration ID for tracking background operations

範例

取得已完成的背景診斷結果

請求
{
  "pathParams": {
    "migration_id": "88888888-8888-4888-8888-888888888888"
  }
}
回應200
{
  "background_processing": false,
  "migration_id": null,
  "estimated_records": null,
  "diagnosis_results": {
    "total_records": 5001,
    "valid_records": 5001,
    "invalid_records": 0,
    "validation_errors": [],
    "schema_issues": [],
    "data_integrity_issues": [],
    "performance_recommendations": []
  },
  "message": "Background diagnosis completed"
}

錯誤

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

狀態發生條件錯誤本文
404診斷尚未結束(執行期間不存在紀錄)、結果已在一小時後過期,或 migration_id 不存在。
{
  "detail": "Diagnosis results not found"
}
403呼叫者對遷移所屬資料表沒有版主權限(自 #1748 起所有 scope 皆然;department 路由原本就要求)。body 是版主門檻的 403,文字依資料表的 scope 而異;其他公司的 migration id 在到達這道門檻之前就回 `404 Diagnosis results not found`(自後端 5.21.0 起)。
{
  "detail": "Insufficient permissions. Required: table moderator or company management rights."
}
404無法解析儲存的資料表,或——僅 company 路由——它不是呼叫者公司的現行 company scope 資料表(包括已在垃圾桶或已被 purge 的表)。
{
  "detail": "Migration not found"
}
404Chatroom 與 department 路由:遷移所屬的資料表之後已移入垃圾桶或已被 purge,因此版主門檻會像資料表不存在一樣回應。
{
  "detail": "CustomTable Not found"
}
Last updated on