資料表
建立、檢視、更新、移入垃圾桶、還原——以及走兩步驟 preview → ticket 流程永久 purge——聊天室、部門及公司層級的自訂資料表。
/private/module/custom_tables/{scope}/tables回傳指定範圍內仍在使用的資料表,並依呼叫者權限提供資料表資訊與分頁總數。
適合用來製作資料表選單、瀏覽某個範圍,或在呼叫其他端點前先取得資料表。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables - 部門
/private/module/custom_tables/department/{department_id}/tables - 公司
/private/module/custom_tables/company/tables
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | ChatRoomJoinedRequired |
| 部門 | 可使用 | DepartmentAccessRequired |
| 公司 | 可使用 | CompanyAccessRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
skip | query | int >= 0 | 否 | 略過前幾筆符合條件的資料表,預設為 0。 |
limit | query | int 1..1000 | 否 | 最多回傳幾筆資料表,可填 1 到 1,000,預設為 100。 |
tag_id | query | uuid | 否 | 選填的標籤 UUID;填入後,清單與總數都只計入已套用該標籤的資料表。 |
回應結構
CustomTableListResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
tables | CustomTableResponse[] | 是 | List of custom tables |
total | integer | 是 | Total number of tables matching the query |
範例
取得第一頁資料表
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111"
},
"query": {
"skip": "0",
"limit": "20"
}
}{
"tables": [
{
"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,
"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,
"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": 120,
"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,
"options": null,
"max_count": null,
"max_file_bytes": null,
"allowed_mime_types": null,
"restricted": null,
"name": "數量",
"type": "integer",
"required": false,
"default_value": 1,
"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-19T01:00:00",
"updated_at": "2026-07-19T01:05:00"
}
],
"total": 1
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 403 | 呼叫者無權存取指定範圍。 | |
| 404 | 篩選用的標籤不在這個範圍內。 | |
/private/module/custom_tables/{scope}/tables建立資料表、替各欄位產生穩定的內部鍵值,並套用該範圍的預設權限設定。
確認顯示用結構與資料表所屬範圍後,再呼叫此端點。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables - 部門
/private/module/custom_tables/department/{department_id}/tables - 公司
/private/module/custom_tables/company/tables
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | ChatRoomAccessRequired |
| 部門 | 可使用 | DepartmentAccessRequired |
| 公司 | 可使用 | CompanyAccessRequired |
請求結構
CustomTableCreate| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
description | string | null | 否 | Human-readable table description |
name | string | 是 | Table name (unique within scope, max 64 chars (ORM column width), non-ASCII allowed) |
schema_definition | TableSchema | 是 | Column definitions for the table |
settings | object | null | 否 | Optional table settings. Known keys: **default_permissions** — `{"can_read": "all"|"own"|"none", "can_insert": bool, "can_edit": "all"|"own"|"none", "audience": "scope"|"company"}` (fallback permissions for users without an explicit grant; auto-populated with system defaults if omitted; `audience: "company"` — department tables only — shares the table to ALL departments in the company with these defaults). |
回應結構
CustomTableResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
chatroom_id | string | null | 否 | Chatroom scope (mutually exclusive with department_id/company_id) |
company_id | string | null | 否 | Company scope |
created_at | string (date-time) | 是 | Table creation timestamp |
department_id | string | null | 否 | Department scope |
description | string | null | 否 | Table description |
id | string | 是 | Table UUID |
name | string | 是 | Table display name |
record_count | integer | null | 否 | Total number of non-deleted records |
schema_definition | TableSchemaResponse | 是 | Schema for responses - allows 'id' column since it's auto-generated |
settings | object | null | 否 | Table configuration. Known keys: **default_permissions** — `{"can_read": "all"|"own"|"none", "can_insert": bool, "can_edit": "all"|"own"|"none", "audience": "scope"|"company"}` (fallback permissions for users without an explicit grant; `audience: "company"` — department tables only — shares the table to ALL departments in the company); **column_mapping** — `{original_name: internal_uuid_name}` (maps user-friendly column names to internal IDs). |
updated_at | string (date-time) | 是 | Last modification timestamp |
範例
建立含兩個欄位的訂單資料表
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111"
},
"body": {
"name": "訂單",
"description": "客戶訂單",
"schema_definition": {
"columns": [
{
"name": "品項",
"type": "string",
"required": true,
"max_length": 120
},
{
"name": "數量",
"type": "integer",
"default_value": 1
}
]
}
}
}{
"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,
"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,
"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": 120,
"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,
"options": null,
"max_count": null,
"max_file_bytes": null,
"allowed_mime_types": null,
"restricted": null,
"name": "數量",
"type": "integer",
"required": false,
"default_value": 1,
"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-19T01:00:00",
"updated_at": "2026-07-19T01:05:00"
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 400 | 同一範圍已有同名資料表,或計算欄位的參照設定不正確。 | |
| 409 | 兩筆寫入爭用同一批資料列,InnoDB 中止了這一筆。交易已回滾,不會留下建到一半的資料表——直接重送請求即可。 | |
| 422 | 請求格式不符規格,例如缺少名稱,或自行加入保留的 id 欄位。 | |
/private/module/custom_tables/{scope}/tables/trash依最近刪除時間列出軟刪除的資料表;這些資料表不會出現在一般清單中。
適合製作垃圾桶頁面,或在還原前先找到目標資料表。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/trash - 部門
/private/module/custom_tables/department/{department_id}/tables/trash - 公司
/private/module/custom_tables/company/tables/trash
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | ChatRoomAccessRequired |
| 部門 | 可使用 | DepartmentAccessRequired |
| 公司 | 可使用 | CompanyAccessRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
skip | query | int >= 0 | 否 | 略過前幾筆垃圾桶資料表,預設為 0。 |
limit | query | int 1..200 | 否 | 最多回傳幾筆,可填 1 到 200,預設為 100。 |
回應結構
TrashedTablesResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
tables | TrashedTableInfo[] | 是 | Trashed tables, most-recently-deleted first |
total | integer | 是 | Total trashed tables in this scope |
範例
列出最近移入垃圾桶的資料表
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111"
},
"query": {
"skip": "0",
"limit": "20"
}
}{
"tables": [
{
"id": "22222222-2222-4222-8222-222222222222",
"name": "訂單",
"description": "客戶訂單",
"deleted_at": "2026-07-19T01:05:00",
"created_at": "2026-07-19T01:00:00"
}
],
"total": 1
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 403 | 呼叫者沒有檢視此範圍垃圾桶所需的權限。 | |
/private/module/custom_tables/{scope}/tables/schema-graph把可讀取的資料表整理成節點,並以邊表示 link、rollup 與 lookup 的相依關係。
適合繪製類 ER 圖,或在調整結構前先盤點跨資料表相依關係。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/schema-graph - 部門
/private/module/custom_tables/department/{department_id}/tables/schema-graph - 公司
/private/module/custom_tables/company/tables/schema-graph
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | ChatRoomJoinedRequired |
| 部門 | 可使用 | DepartmentAccessRequired |
| 公司 | 可使用 | CompanyAccessRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
format | query | string | 否 | 省略時回傳 JSON;填入 drawio 時回傳可匯入 draw.io 的 mxfile XML。 |
回應結構
SchemaGraphResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
edges | SchemaGraphEdge[] | 是 | Dependency edges between readable tables |
tables | SchemaGraphTable[] | 是 | Readable tables of the scope |
範例
取得 JSON 格式的結構圖
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111"
}
}{
"tables": [
{
"id": "22222222-2222-4222-8222-222222222222",
"name": "訂單",
"record_count": 0,
"columns": [
{
"name": "品項",
"type": "string"
},
{
"name": "數量",
"type": "integer"
}
]
}
],
"edges": []
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 403 | 呼叫者無權讀取指定範圍。 | |
/private/module/custom_tables/{scope}/tables/shared列出授權給此聊天室的部門層級資料表,以及呼叫者實際解析後的權限。
聊天室介面需要同時呈現本身資料表與部門分享資料時,可使用此端點。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/shared
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | ChatRoomJoinedRequired |
| 部門 | 未提供 | 不適用 |
| 公司 | 未提供 | 不適用 |
回應結構
SharedTablesResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
tables | SharedTableItem[] | 是 | Shared tables |
範例
列出分享進來的部門資料表
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111"
}
}{
"tables": []
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 403 | 呼叫者不是此聊天室成員。 | |
/private/module/custom_tables/shared-with-me唯一能回答「哪些 table id 我讀得到、但我的任何 scope 清單都不會列出來」的端點。回傳所有可透過 per-user grant、我所屬部門的 grant、我所屬活房間的 internal chatroom grant,或已分享給全部部門的部門表(`settings.default_permissions.audience: "company"`)讀到的活表;每筆都附上放行的 `sources` 與 resolver 解析出的 `my_permissions`。
當使用者被授權了別的部門或別的房間的表、手上卻沒有 id 時呼叫。取得 `table_id` 後改走該表擁有 scope 的 by-id 路由——這裡的項目不含 `schema_definition`、`settings` 與 tags,也沒有 `tag_id` 篩選。
- 完整路由
/private/module/custom_tables/shared-with-me
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 完整路由 | 可使用 | get_current_user |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
skip | query | int >= 0 | 否 | 略過的筆數,`>= 0`,預設 0。分頁在權限過濾之後才套用,因此 `total` 與該頁內容永遠一致。 |
limit | query | int 1..200 | 否 | 每頁筆數,`1..200`,預設 100。上限是 200,不是各 scope 表清單的 1000。 |
回應結構
SharedWithMeResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
tables | SharedWithMeEntry[] | 是 | 未指定 |
total | integer | 是 | Total matching tables before skip/limit paging |
範例
列出所有跨出我自身 scope、分享給我的表
{
"pathParams": {},
"query": {
"skip": "0",
"limit": "100"
}
}{
"tables": [
{
"table_id": "22222222-2222-4222-8222-222222222222",
"name": "出貨單",
"description": "跨部門出貨追蹤",
"scope": "department",
"department_id": "33333333-3333-4333-8333-333333333333",
"department_name": "物流部",
"chatroom_id": null,
"sources": [
"company_share",
"department_grant"
],
"my_permissions": {
"can_read": "all",
"can_insert": false,
"can_edit": "none",
"is_manager": false
}
},
{
"table_id": "77777777-7777-4777-8777-777777777777",
"name": "客服工單",
"description": null,
"scope": "chatroom",
"department_id": null,
"department_name": null,
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"sources": [
"user_grant"
],
"my_permissions": {
"can_read": "own",
"can_insert": true,
"can_edit": "own",
"is_manager": false
}
}
],
"total": 2
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 422 | `skip < 0`、`limit < 1` 或 `limit > 200`。這條路由沒有 403 也沒有 404:讀不到的表只是不出現在 `tables`,也不計入 `total`。 | |
/private/module/custom_tables/tables/resolve把穩定的表名轉成這個環境的 table id,逐表由權限 resolver 把關,而不是用角色把關。`get_current_user` 就是全部的閘門;沒有 scope 路徑段、沒有 `acting_chatroom_id`,這條路由也沒有 403。
用在客戶端原本要逐環境硬寫 id 的地方,以及沒有任何清單服務得到的呼叫者:對 company scope 表沒有管理角色的人,或跨部門分享的讀者——其 id 不會出現在他碰得到的任何清單上。
- 完整路由
/private/module/custom_tables/tables/resolve
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 完整路由 | 可使用 | get_current_user |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
name | query | string 1..64 | 是 | 精確表名,1..64 字元,必填。比對是逐位元組的——欄位是 `String(64, collation="utf8mb4_bin")`——不做大小寫折疊,也不做前綴比對。 |
回應結構
TableResolveResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
department_id | string | null | 否 | Owning department (scope == department); the path segment for the department scope's by-id routes |
department_name | string | null | 否 | Owning department display name (scope == department) |
description | string | null | 否 | Table description |
my_permissions | MyPermissionsResponse | 是 | The caller's resolved effective permissions on this table (resolver-authoritative; can_read == "none" resolves as 404). |
name | string | 是 | Table display name (byte-exact match of the query) |
scope | "company" | "department" | 是 | Owning scope of the resolved table: "company" or "department" (chatroom shares resolve via /shared-with-me instead) |
table_id | string | 是 | Table UUID (use with the owning scope's by-id routes) |
範例
解析一張分享給全公司的部門表
{
"pathParams": {},
"query": {
"name": "出貨單"
}
}{
"table_id": "22222222-2222-4222-8222-222222222222",
"name": "出貨單",
"description": "跨部門出貨追蹤",
"scope": "department",
"department_id": "33333333-3333-4333-8333-333333333333",
"department_name": "物流部",
"my_permissions": {
"can_read": "all",
"can_insert": false,
"can_edit": "none",
"is_manager": false
}
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 404 | 單一且一致的 miss。名稱不存在、resolver 判定不可讀(`can_read: "none"`)、已在垃圾桶、屬於別家公司、以及任何 chatroom scope 的表,全都回完全相同的 `{"detail": "Table not found"}`,因此不會開出存在性 oracle。 | |
| 422 | `name` 未給、為空或超過 64 字元——標準的 FastAPI 驗證錯誤 body。 | |
/private/module/custom_tables/{scope}/tables/{table_id}回傳資料表結構、設定、顯示名稱對照,以及呼叫者看得到的資料列總數。
適合在顯示資料表編輯器或組合資料列請求前使用。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id} - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id} - 公司
/private/module/custom_tables/company/tables/{table_id}
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | ChatRoomJoinedRequired |
| 部門 | 可使用 | CustomTableAccessRequired |
| 公司 | 可使用 | CustomTableAccessRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 指定範圍內的自訂資料表 UUID。 |
回應結構
CustomTableResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
chatroom_id | string | null | 否 | Chatroom scope (mutually exclusive with department_id/company_id) |
company_id | string | null | 否 | Company scope |
created_at | string (date-time) | 是 | Table creation timestamp |
department_id | string | null | 否 | Department scope |
description | string | null | 否 | Table description |
id | string | 是 | Table UUID |
name | string | 是 | Table display name |
record_count | integer | null | 否 | Total number of non-deleted records |
schema_definition | TableSchemaResponse | 是 | Schema for responses - allows 'id' column since it's auto-generated |
settings | object | null | 否 | Table configuration. Known keys: **default_permissions** — `{"can_read": "all"|"own"|"none", "can_insert": bool, "can_edit": "all"|"own"|"none", "audience": "scope"|"company"}` (fallback permissions for users without an explicit grant; `audience: "company"` — department tables only — shares the table to ALL departments in the company); **column_mapping** — `{original_name: internal_uuid_name}` (maps user-friendly column names to internal IDs). |
updated_at | string (date-time) | 是 | Last modification timestamp |
範例
取得資料表詳細資訊
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222"
}
}{
"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,
"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,
"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": 120,
"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,
"options": null,
"max_count": null,
"max_file_bytes": null,
"allowed_mime_types": null,
"restricted": null,
"name": "數量",
"type": "integer",
"required": false,
"default_value": 1,
"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-19T01:00:00",
"updated_at": "2026-07-19T01:05:00"
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 404 | 資料表不存在、已刪除,或不屬於指定範圍。 | |
/private/module/custom_tables/{scope}/tables/{table_id}修改顯示名稱或說明,不會重寫欄位內部鍵值,也不會搬移資料列。
重新命名資料表或修改說明時使用,並先留意同一範圍內的名稱衝突。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id} - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id} - 公司
/private/module/custom_tables/company/tables/{table_id}
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableModeratorRequired |
| 部門 | 可使用 | CustomTableModeratorRequired |
| 公司 | 可使用 | CustomTableModeratorRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 要更新的資料表 UUID。 |
請求結構
CustomTableUpdatePayload| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
description | string | null | 否 | New table description |
name | string | null | 否 | New table name (unique within scope) |
回應結構
CustomTableResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
chatroom_id | string | null | 否 | Chatroom scope (mutually exclusive with department_id/company_id) |
company_id | string | null | 否 | Company scope |
created_at | string (date-time) | 是 | Table creation timestamp |
department_id | string | null | 否 | Department scope |
description | string | null | 否 | Table description |
id | string | 是 | Table UUID |
name | string | 是 | Table display name |
record_count | integer | null | 否 | Total number of non-deleted records |
schema_definition | TableSchemaResponse | 是 | Schema for responses - allows 'id' column since it's auto-generated |
settings | object | null | 否 | Table configuration. Known keys: **default_permissions** — `{"can_read": "all"|"own"|"none", "can_insert": bool, "can_edit": "all"|"own"|"none", "audience": "scope"|"company"}` (fallback permissions for users without an explicit grant; `audience: "company"` — department tables only — shares the table to ALL departments in the company); **column_mapping** — `{original_name: internal_uuid_name}` (maps user-friendly column names to internal IDs). |
updated_at | string (date-time) | 是 | Last modification timestamp |
範例
重新命名訂單資料表
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222"
},
"body": {
"name": "訂單追蹤",
"description": "追蹤客戶訂單狀態"
}
}{
"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,
"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,
"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": 120,
"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,
"options": null,
"max_count": null,
"max_file_bytes": null,
"allowed_mime_types": null,
"restricted": null,
"name": "數量",
"type": "integer",
"required": false,
"default_value": 1,
"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-19T01:00:00",
"updated_at": "2026-07-19T01:05:00"
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 400 | name 與 description 都未提供。 | |
| 409 | 同一範圍內已有其他資料表使用指定名稱。 | |
/private/module/custom_tables/{scope}/tables/{table_id}以軟刪除方式移除資料表,保留資料列、歷程與相依設定,之後仍可還原。
需要可復原地移除資料表時使用;永久刪除是另一條兩步驟 purge 流程(先 tables.purgePreview 取得一次性 ticket,再 tables.purge 執行)——版主權限即可,不需要 root 管理端。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id} - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id} - 公司
/private/module/custom_tables/company/tables/{table_id}
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableModeratorRequired |
| 部門 | 可使用 | CustomTableModeratorRequired |
| 公司 | 可使用 | CustomTableModeratorRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 要移入垃圾桶的現行資料表 UUID。 |
回應結構
SuccessResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
message | string | 否 | 未指定 |
範例
刪除測試用資料表
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222"
}
}{
"message": "Table moved to trash successfully"
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 404 | 資料表不存在、已在垃圾桶中,或不屬於指定範圍。 | |
| 423 | 資料表目前正被資料遷移鎖定。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/restore清除資料表的刪除狀態,並回傳還原後的結構與基本資訊。
先從垃圾桶清單找到資料表,再呼叫此端點。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/restore - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/restore - 公司
/private/module/custom_tables/company/tables/{table_id}/restore
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableModeratorTrashedRequired |
| 部門 | 可使用 | CustomTableModeratorTrashedRequired |
| 公司 | 可使用 | CustomTableModeratorTrashedRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 指定範圍內已軟刪除的資料表 UUID。 |
回應結構
CustomTableResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
chatroom_id | string | null | 否 | Chatroom scope (mutually exclusive with department_id/company_id) |
company_id | string | null | 否 | Company scope |
created_at | string (date-time) | 是 | Table creation timestamp |
department_id | string | null | 否 | Department scope |
description | string | null | 否 | Table description |
id | string | 是 | Table UUID |
name | string | 是 | Table display name |
record_count | integer | null | 否 | Total number of non-deleted records |
schema_definition | TableSchemaResponse | 是 | Schema for responses - allows 'id' column since it's auto-generated |
settings | object | null | 否 | Table configuration. Known keys: **default_permissions** — `{"can_read": "all"|"own"|"none", "can_insert": bool, "can_edit": "all"|"own"|"none", "audience": "scope"|"company"}` (fallback permissions for users without an explicit grant; `audience: "company"` — department tables only — shares the table to ALL departments in the company); **column_mapping** — `{original_name: internal_uuid_name}` (maps user-friendly column names to internal IDs). |
updated_at | string (date-time) | 是 | Last modification timestamp |
範例
從垃圾桶還原資料表
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222"
}
}{
"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,
"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,
"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": 120,
"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,
"options": null,
"max_count": null,
"max_file_bytes": null,
"allowed_mime_types": null,
"restricted": null,
"name": "數量",
"type": "integer",
"required": false,
"default_value": 1,
"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-19T01:00:00",
"updated_at": "2026-07-19T01:05:00"
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 404 | 此 UUID 並不是指定範圍內的垃圾桶資料表。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/purge/preview計算永久銷毀一張表的完整爆炸半徑——現存資料列數、外部活表會被剝除的連結欄位(以顯示名稱列出)與被剝除的 rules 數量、saved views、IaC state rows,以及會被刪除或變成殭屍的 commands——在沒有 blocker 時,同時發出一張 15 分鐘內有效、只能用一次的 ticket。
租戶端永久刪除的第一步,永遠先做。把這份回應原樣渲染成同意畫面:使用者核准的就是實際會執行的那一份,因為之後任何結構漂移都會讓 ticket 失效。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/purge/preview - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/purge/preview - 公司
/private/module/custom_tables/company/tables/{table_id}/purge/preview
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableModeratorTrashedRequired |
| 部門 | 可使用 | CustomTableModeratorTrashedRequired |
| 公司 | 可使用 | CustomTableModeratorTrashedRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 要 purge 的表。活表與垃圾桶中的表都解析得到——purge 不要求先軟刪。 |
回應結構
PurgePreviewResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
blockers | PurgeBlocker[] | 是 | Conditions preventing a ticket (empty = ticket issued) |
commands_affected | PurgeCommandInfo[] | 是 | OTHER live commands whose dependency set references a purged table — they become zombies (still deletable individually), NOT deleted by this purge |
commands_to_delete | PurgeCommandInfo[] | 是 | Commands the purge deletes (tag lane: every command bound to the tag; names release immediately) |
cross_table_impact | PurgeCrossTableImpact[] | 是 | Live tables outside the purge set whose schemas/rules the cascade mutates |
expires_at | string (date-time) | null | 否 | Ticket expiry (UTC) |
iac_state_rows | integer | 是 | IaC state rows removed with the purged tables |
tables | PurgeImpactTable[] | 是 | Tables that will be permanently destroyed (records + history + row) |
ticket | string | null | 否 | One-shot purge ticket (null when blockers exist); bound to the previewing user |
views | integer | 是 | Saved views destroyed with the purged tables |
範例
預覽一張活表的 purge(含一張受牽連的外部表)
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222"
}
}{
"tables": [
{
"id": "22222222-2222-4222-8222-222222222222",
"name": "訂單",
"record_count": 128,
"is_deleted": false
}
],
"cross_table_impact": [
{
"table_id": "66666666-6666-4666-8666-666666666666",
"table_name": "出貨單",
"stripped_columns": [
"訂單編號"
],
"stripped_rules": 1
}
],
"commands_to_delete": [],
"commands_affected": [
{
"id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
"name": "ship-order"
}
],
"views": 2,
"iac_state_rows": 3,
"blockers": [],
"ticket": "f0f0f0f0-f0f0-4f0f-8f0f-f0f0f0f0f0f0",
"expires_at": "2026-07-28T03:15:00Z"
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 404 | 此 scope 內沒有這個 id 的活表或已刪表。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/purge永久銷毀該表——資料列、歷史、相依設定與 IaC state rows——執行前會重新驗證結構仍與 preview 所示一致,並燒掉一次性 ticket。
第二步:preview 後 15 分鐘內、由同一位使用者呼叫。把它當成不可回頭的那一步:purge 之後沒有任何還原。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/purge - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/purge - 公司
/private/module/custom_tables/company/tables/{table_id}/purge
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableModeratorTrashedRequired |
| 部門 | 可使用 | CustomTableModeratorTrashedRequired |
| 公司 | 可使用 | CustomTableModeratorTrashedRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 要 purge 的表——必須是 ticket 簽發時的同一張表。 |
ticket | query | uuid | 是 | preview 回應中的一次性 ticket。無論執行成功或被拒,用過即燒。 |
回應結構
PurgeTableResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
message | string | 是 | Human-readable outcome |
purged | boolean | 是 | True when the table was permanently destroyed |
table_id | string | 是 | The purged table's id |
範例
執行已預覽的 purge
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222"
},
"query": {
"ticket": "f0f0f0f0-f0f0-4f0f-8f0f-f0f0f0f0f0f0"
}
}{
"table_id": "22222222-2222-4222-8222-222222222222",
"purged": true,
"message": "Table permanently purged (records, history, and dependent config removed)"
}錯誤
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 404 | ticket 不存在或已過期(效期 15 分鐘)。請重新 preview。 | |
| 403 | ticket 屬於另一位使用者。誰 preview,誰執行。 | |
| 409 | preview 之後結構漂移了——表被還原、改名,或 command/tag 集合變動。ticket 已燒掉;重新 preview 並重新核准你看到的內容。 | |
| 409 | ticket 是為另一個標的(或另一條 lane)簽發的。ticket 已燒掉。 | |
| 423 | 表上有 migration 鎖。等 migration 結束後重新 preview——這次嘗試花掉的 ticket 不會回來。 | |