檢視
一次載入整合資料,並建立、管理或套用可重複使用的儲存檢視。
/private/module/custom_tables/{scope}/tables/{table_id}/view在一次回應中提供資料表資訊、一頁資料列、has_more,以及呼叫者的實際權限。預設的 offset 模式還會回傳精確的 total;帶 page_mode=cursor 則改回 next_cursor,total 為 null。
適合只用一次往返就完成資料表初始畫面。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/view - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/view - 公司
/private/module/custom_tables/company/tables/{table_id}/view
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableReadRequired |
| 部門 | 可使用 | CustomTableReadRequired |
| 公司 | 可使用 | CustomTableReadRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 要載入整合檢視的資料表 UUID。 |
skip | query | int >= 0 | 否 | 略過前幾筆可見資料列,預設為 0。 |
limit | query | int 1..1000 | 否 | 最多回傳幾筆資料列,可填 1 到 1,000,預設為 100。 |
page_mode | query | enum:offset|cursor | 否 | 分頁方式。offset(預設)用 skip/offset 跳頁,並一併回傳精確的 total;cursor 用 next_cursor 接著往下讀,不做筆數統計,total 回 null。只要帶了 cursor,就會自動採用 cursor 模式。 |
cursor | query | string ≤ 8192 | 否 | 上一頁回應的 next_cursor,原封不動送回來,並維持相同的資料表、條件、q、檢視與排序。它是不透明且有簽章的字串,不要自己組合、修改或長期保存;被改過或對不上這次查詢的值會回 400 ct.invalid_cursor,超過 8,192 個字元的值會被請求驗證以 422 拒絕。每一頁的 limit 可以不同;skip 與 offset 會被忽略。 |
sort_by | query | string | 否 | 內部欄位 ID,或 id、created_at、updated_at。 |
sort_order | query | enum:asc|desc | 否 | 排序方向:asc 或 desc。 |
expand_links | query | boolean | 否 | 設為 true 時,替可讀取的連結欄位內嵌有上限的關聯資料預覽。 |
回應結構
CustomTableViewResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
has_more | boolean | 否 | Whether another records page exists. |
my_permissions | MyPermissionsResponse | 是 | Caller's effective permissions (identical to `GET .../permissions/me`) |
next_cursor | string | null | 否 | Opaque continuation for cursor mode; null on the last page or in offset mode. |
records | CustomTableRecordResponse[] | 是 | Records page (identical to `GET .../records`) |
table | CustomTableResponse | 是 | Table metadata (same object as the list endpoint's `table`) |
total | integer | null | 是 | Exact matching records in offset mode; null in cursor mode. Deprecated: total and offset will be removed after migration; use records/count. |
範例
載入資料表初始畫面
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222"
},
"query": {
"skip": "0",
"limit": "20",
"sort_order": "asc",
"expand_links": "false"
}
}{
"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": 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,
"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": 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:20:00",
"updated_at": "2026-07-19T01:25:00"
},
"records": [],
"total": 0,
"has_more": false,
"next_cursor": null,
"my_permissions": {
"can_read": "all",
"can_insert": true,
"can_edit": "all",
"is_manager": true,
"visible_columns": null
}
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 400 | 排序欄位不存在或對你隱藏(兩者回應相同,detail 會列出你有權讀取之欄位的 Valid columns),或它無法排序:attachment、json 或 principal(user、social_client、principal)欄位,或排序編譯器拒絕的計算欄,此時 detail 就是它的訊息(link 欄位、未帶 pick 的 cardinality-many lookup、帶有 fallback 的 lookup 或讀取它的 formula、使用 IF、AND、OR、CONCAT、日期函式或 [Link -> Column] 引用的 formula,以及 live 紀錄超過 50,000 筆的表上的任何計算欄)。decimal formula(包括呼叫 DECIMAL、QUANTIZE 或 DIVIDE 的)只有在能編譯成精確的 SQL 時才會精確排序;無法編譯時(例如含有 / 除法,或乘上對 integer 或 float 欄位的 rollup 或 lookup),detail 會說明原因,例如 computed decimal expression is not exactly SQL-representable: <reason>;若有資料列無法精確求值,detail 為 ct.numeric_overflow: computed decimal cannot be evaluated exactly,或代碼換成 ct.numeric_invalid 的同一段文字。在有 link、rollup、lookup 或 formula 欄位的表上,若該頁超過 100 筆紀錄,expand_links 同樣以 400 拒絕。 | |
| 400 | cursor 無效:內容被改過,或不屬於這次的查詢(資料表、條件、q、檢視、排序、欄位結構或呼叫者不同),也可能是發出這一頁之後你的權限變了。請不帶 cursor,從第一頁重新開始。超過 8,192 個字元的 cursor 不會走到這一步:請求驗證會先以 422 拒絕。 | |
| 400 | 這次讀取超過時間上限(預設 15 秒,limit_ms 會回報實際的設定值)。請縮小篩選範圍,或改用 cursor 分頁,不要翻很深的 offset;對符合筆數非常多的條件做 count,也可能碰到這個上限。 | |
| 503 | 目前無法使用 cursor 分頁,因為伺服器無法為 cursor 簽章(沒有設定簽章用的密鑰)。offset 模式仍可使用,請通知維運人員。 | |
| 403 | 讀取門檻拒絕了你:你的有效讀取層級為 none 時回 Read access denied for this table.。資料表門檻會先回應:聊天室資料表而你不在該聊天室時回 Not a member of this chatroom.,除非有個人或部門授權開放它,或你管理聊天室所屬部門或公司;部門資料表而你不在該部門時回 Insufficient permissions for department-scoped table.,除非你是公司管理者,或有授權、moderator 列或全公司受眾開放它。另一家公司的資料表不會走到這些 403:自後端 5.21.0 起,它與 id 不存在一樣回 404 CustomTable Not found。 | |
| 404 | 資料表 ID 不存在或已進垃圾桶(所有範圍都回 CustomTable Not found;資料表所屬聊天室已刪除時則回 Chatroom Not found),或現行資料表不在路徑範圍內:聊天室範圍回 CustomTable Not found,部門範圍回 Table not found in this department,公司範圍回 Table not found in this company。 | |
| 422 | sort_order 不是 asc 或 desc、skip 為負數,或 limit 超出 1–1,000。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/views保存篩選、排序與顯示欄位設定,供之後重複使用。
讀取者要保存私人檢視,或管理者要發布共享檢視時使用。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/views - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/views - 公司
/private/module/custom_tables/company/tables/{table_id}/views
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableReadRequired |
| 部門 | 可使用 | CustomTableReadRequired |
| 公司 | 可使用 | CustomTableReadRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 此儲存檢視所屬的資料表 UUID。 |
請求結構
CustomTableSavedViewPayload| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
config | CustomTableViewConfig | 否 | Stored filter/sort/column-set config (re-validated against the caller's ACL on apply). |
is_shared | boolean | 否 | Share with all table readers (moderator only) vs private to the creator. |
name | string | 是 | View name (unique per creator within the table). |
回應結構
CustomTableSavedViewResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
config | CustomTableViewConfig | 是 | Stored filter/sort/column-set config |
created_at | string (date-time) | 是 | View creation timestamp |
created_by | string | null | 否 | Creator user UUID. Soft deletion of the account preserves this UUID; only hard deletion of its users row makes it null through the foreign key. |
id | string | 是 | View UUID |
is_owner | boolean | 是 | Whether the requesting caller created this view |
is_shared | boolean | 是 | Whether the view is shared with all table readers |
name | string | 是 | View name |
table_id | string | 是 | Parent table UUID |
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": "待處理訂單",
"config": {
"filters": {},
"stored_filters": null,
"computed_filters": null,
"q": null,
"sort_by": null,
"sort_order": "asc",
"columns": [
"品項",
"數量"
]
},
"is_shared": false
}
}{
"id": "44444444-4444-4444-8444-444444444444",
"table_id": "22222222-2222-4222-8222-222222222222",
"name": "待處理訂單",
"config": {
"filters": {},
"stored_filters": null,
"computed_filters": null,
"q": null,
"sort_by": null,
"sort_order": "asc",
"columns": [
"品項",
"數量"
],
"any_of": null,
"sort": null,
"kind": "list",
"matrix": null,
"timeline": null
},
"is_shared": false,
"is_owner": true,
"created_by": "66666666-6666-4666-8666-666666666666",
"created_at": "2026-07-19T01:20:00",
"updated_at": "2026-07-19T01:25:00"
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 400 | config 指到不存在或對你隱藏的欄位(Column '<name>' does not exist in table schema)、儲存了 name_eq 或 name_contains predicate(Op '<op>' cannot be saved in a view — display-name filters are request-scoped; resolve the person to a raw id and store eq/in instead),或設定了欄位無法承載的版面:matrix 的 bucket_column 不是 date、datetime 或 select(Matrix bucket_column '<column>' must be a date, datetime or select column)、select 的 bucket_column 上的 column_bucket 不是 day(column_bucket must be 'day' (the default) when bucket_column '<column>' is a select column)、timeline 的 start_column 或 end_column 不是 date 或 datetime(Timeline column '<column>' must be a date or datetime column),或 start_column 與 end_column 型別不同(Timeline start_column '<start>' and end_column '<end>' must share the same type (both date or both datetime))。 | |
| 403 | 非管理者嘗試建立共享檢視。 | |
| 403 | 讀取門檻拒絕了你:你的有效讀取層級為 none 時回 Read access denied for this table.。資料表門檻會先回應:聊天室資料表而你不在該聊天室時回 Not a member of this chatroom.,除非有個人或部門授權開放它,或你管理聊天室所屬部門或公司;部門資料表而你不在該部門時回 Insufficient permissions for department-scoped table.,除非你是公司管理者,或有授權、moderator 列或全公司受眾開放它。另一家公司的資料表不會走到這些 403:自後端 5.21.0 起,它與 id 不存在一樣回 404 CustomTable Not found。 | |
| 404 | 資料表 ID 不存在或已進垃圾桶(所有範圍都回 CustomTable Not found;資料表所屬聊天室已刪除時則回 Chatroom Not found),或現行資料表不在路徑範圍內:聊天室範圍回 CustomTable Not found,部門範圍回 Table not found in this department,公司範圍回 Table not found in this company。 | |
| 409 | 同一建立者在此資料表已有同名檢視。 | |
| 422 | body 沒通過 model 驗證:name 為空或超過 64 個字元;body 或 config 帶了 model 沒宣告的 key(包含 editable、pending_approval、limit 與 offset);config 超過上限(20 個 stored_filters、3 個 computed_filters、10 個各含 1–10 個 predicate 的 any_of 群組、3 個 sort key、200 個 columns、200 個字元的 q)或送出空的 any_of;stored_filters、any_of 或 computed_filters 的某個 predicate 沒通過自身的形狀檢查(未知的 op、值運算子沒有 value 或 null/presence 運算子帶了 value、需要純量之處給了 list 或 object、in 的清單為空、超過 100 項或不全是純量、between 不是兩個純量、within_last、within_next 或 older_than 的時間窗格式錯誤、overlaps 或 contains_point 的界線不是正規的 YYYY-MM-DD HH:MM datetime,或 overlaps 的起點不早於終點);sort_order、sort key 的 order 或 kind 不是允許的值;sort 與 sort_by 同時送出;或 kind 缺少它的 matrix 或 timeline 子設定、帶了另一種 kind 的子設定,或子設定格式錯誤(缺少或未知的欄位、超出 5–1440 的 slot_minutes、不是 day、week 或 month 的 column_bucket)。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/views回傳呼叫者看得到的檢視:本人建立與共享檢視;管理者則可看到全部。
用來填入檢視選單:包含呼叫者自己的 private views 與可見 shared views,不會暴露他人的私人檢視。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/views - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/views - 公司
/private/module/custom_tables/company/tables/{table_id}/views
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableReadRequired |
| 部門 | 可使用 | CustomTableReadRequired |
| 公司 | 可使用 | CustomTableReadRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 要列出檢視的資料表 UUID。 |
回應結構
CustomTableSavedViewListResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
total | integer | 是 | Number of visible saved views |
views | CustomTableSavedViewResponse[] | 是 | Visible saved views |
範例
列出目前可見的儲存檢視
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222"
}
}{
"views": [
{
"id": "44444444-4444-4444-8444-444444444444",
"table_id": "22222222-2222-4222-8222-222222222222",
"name": "待處理訂單",
"config": {
"filters": {},
"stored_filters": null,
"computed_filters": null,
"q": null,
"sort_by": null,
"sort_order": "asc",
"columns": [
"品項",
"數量"
],
"any_of": null,
"sort": null,
"kind": "list",
"matrix": null,
"timeline": null
},
"is_shared": false,
"is_owner": true,
"created_by": "66666666-6666-4666-8666-666666666666",
"created_at": "2026-07-19T01:20:00",
"updated_at": "2026-07-19T01:25:00"
}
],
"total": 1
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 403 | 讀取門檻拒絕了你:你的有效讀取層級為 none 時回 Read access denied for this table.。資料表門檻會先回應:聊天室資料表而你不在該聊天室時回 Not a member of this chatroom.,除非有個人或部門授權開放它,或你管理聊天室所屬部門或公司;部門資料表而你不在該部門時回 Insufficient permissions for department-scoped table.,除非你是公司管理者,或有授權、moderator 列或全公司受眾開放它。另一家公司的資料表不會走到這些 403:自後端 5.21.0 起,它與 id 不存在一樣回 404 CustomTable Not found。 | |
| 404 | 資料表 ID 不存在或已進垃圾桶(所有範圍都回 CustomTable Not found;資料表所屬聊天室已刪除時則回 Chatroom Not found),或現行資料表不在路徑範圍內:聊天室範圍回 CustomTable Not found,部門範圍回 Table not found in this department,公司範圍回 Table not found in this company。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/views/{view_id}回傳一筆可見的儲存檢視設定與擁有者資訊。
使用者選定檢視 UUID 後,需要查看或編輯內容時使用。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/views/{view_id} - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/views/{view_id} - 公司
/private/module/custom_tables/company/tables/{table_id}/views/{view_id}
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableReadRequired |
| 部門 | 可使用 | CustomTableReadRequired |
| 公司 | 可使用 | CustomTableReadRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 檢視所屬資料表 UUID。 |
view_id | path | uuid | 是 | 儲存檢視 UUID。 |
回應結構
CustomTableSavedViewResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
config | CustomTableViewConfig | 是 | Stored filter/sort/column-set config |
created_at | string (date-time) | 是 | View creation timestamp |
created_by | string | null | 否 | Creator user UUID. Soft deletion of the account preserves this UUID; only hard deletion of its users row makes it null through the foreign key. |
id | string | 是 | View UUID |
is_owner | boolean | 是 | Whether the requesting caller created this view |
is_shared | boolean | 是 | Whether the view is shared with all table readers |
name | string | 是 | View name |
table_id | string | 是 | Parent table UUID |
updated_at | string (date-time) | 是 | Last modification timestamp |
範例
取得儲存檢視
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222",
"view_id": "44444444-4444-4444-8444-444444444444"
}
}{
"id": "44444444-4444-4444-8444-444444444444",
"table_id": "22222222-2222-4222-8222-222222222222",
"name": "待處理訂單",
"config": {
"filters": {},
"stored_filters": null,
"computed_filters": null,
"q": null,
"sort_by": null,
"sort_order": "asc",
"columns": [
"品項",
"數量"
],
"any_of": null,
"sort": null,
"kind": "list",
"matrix": null,
"timeline": null
},
"is_shared": false,
"is_owner": true,
"created_by": "66666666-6666-4666-8666-666666666666",
"created_at": "2026-07-19T01:20:00",
"updated_at": "2026-07-19T01:25:00"
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 403 | 讀取門檻拒絕了你:你的有效讀取層級為 none 時回 Read access denied for this table.。資料表門檻會先回應:聊天室資料表而你不在該聊天室時回 Not a member of this chatroom.,除非有個人或部門授權開放它,或你管理聊天室所屬部門或公司;部門資料表而你不在該部門時回 Insufficient permissions for department-scoped table.,除非你是公司管理者,或有授權、moderator 列或全公司受眾開放它。另一家公司的資料表不會走到這些 403:自後端 5.21.0 起,它與 id 不存在一樣回 404 CustomTable Not found。 | |
| 404 | 資料表 ID 不存在或已進垃圾桶(所有範圍都回 CustomTable Not found;資料表所屬聊天室已刪除時則回 Chatroom Not found),或現行資料表不在路徑範圍內:聊天室範圍回 CustomTable Not found,部門範圍回 Table not found in this department,公司範圍回 Table not found in this company。 | |
| 404 | 檢視不存在、不屬於此資料表,或是其他使用者的私人檢視。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/views/{view_id}重新命名檢視、整份替換保存設定,或調整共享狀態。
檢視建立者或資料表管理者要修改保存查詢時使用。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/views/{view_id} - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/views/{view_id} - 公司
/private/module/custom_tables/company/tables/{table_id}/views/{view_id}
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableReadRequired |
| 部門 | 可使用 | CustomTableReadRequired |
| 公司 | 可使用 | CustomTableReadRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 檢視所屬資料表 UUID。 |
view_id | path | uuid | 是 | 要更新的儲存檢視 UUID。 |
請求結構
CustomTableSavedViewUpdatePayload| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
config | CustomTableViewConfig | null | 否 | Replacement config (fully replaces the stored config). |
is_shared | boolean | null | 否 | Toggle sharing (moderator only to publish). |
name | string | null | 否 | New view name (unique per creator within the table). |
回應結構
CustomTableSavedViewResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
config | CustomTableViewConfig | 是 | Stored filter/sort/column-set config |
created_at | string (date-time) | 是 | View creation timestamp |
created_by | string | null | 否 | Creator user UUID. Soft deletion of the account preserves this UUID; only hard deletion of its users row makes it null through the foreign key. |
id | string | 是 | View UUID |
is_owner | boolean | 是 | Whether the requesting caller created this view |
is_shared | boolean | 是 | Whether the view is shared with all table readers |
name | string | 是 | View name |
table_id | string | 是 | Parent table UUID |
updated_at | string (date-time) | 是 | Last modification timestamp |
範例
重新命名儲存檢視
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222",
"view_id": "44444444-4444-4444-8444-444444444444"
},
"body": {
"name": "優先處理訂單"
}
}{
"id": "44444444-4444-4444-8444-444444444444",
"table_id": "22222222-2222-4222-8222-222222222222",
"name": "優先處理訂單",
"config": {
"filters": {},
"stored_filters": null,
"computed_filters": null,
"q": null,
"sort_by": null,
"sort_order": "asc",
"columns": [
"品項",
"數量"
],
"any_of": null,
"sort": null,
"kind": "list",
"matrix": null,
"timeline": null
},
"is_shared": false,
"is_owner": true,
"created_by": "66666666-6666-4666-8666-666666666666",
"created_at": "2026-07-19T01:20:00",
"updated_at": "2026-07-19T01:25:00"
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 400 | 未提供任何更新欄位(Provide at least one of 'name', 'config' or 'is_shared' to update;明確傳 null 視同省略),或替換用設定沒通過 views.create 的某項檢查,並回相同的 400 訊息:欄位不存在或對你隱藏、儲存了 name_eq 或 name_contains predicate、matrix 或 timeline 的欄位型別不對,或 select 的 bucket_column 上的 column_bucket 不是 day。body 的形狀錯誤則改為 422。 | |
| 403 | 呼叫者既不是建立者,也不是資料表管理者。 | |
| 403 | 只有資料表管理者可以把私人檢視改成共享檢視。 | |
| 403 | 讀取門檻拒絕了你:你的有效讀取層級為 none 時回 Read access denied for this table.。資料表門檻會先回應:聊天室資料表而你不在該聊天室時回 Not a member of this chatroom.,除非有個人或部門授權開放它,或你管理聊天室所屬部門或公司;部門資料表而你不在該部門時回 Insufficient permissions for department-scoped table.,除非你是公司管理者,或有授權、moderator 列或全公司受眾開放它。另一家公司的資料表不會走到這些 403:自後端 5.21.0 起,它與 id 不存在一樣回 404 CustomTable Not found。 | |
| 404 | 資料表 ID 不存在或已進垃圾桶(所有範圍都回 CustomTable Not found;資料表所屬聊天室已刪除時則回 Chatroom Not found),或現行資料表不在路徑範圍內:聊天室範圍回 CustomTable Not found,部門範圍回 Table not found in this department,公司範圍回 Table not found in this company。 | |
| 404 | 檢視不存在、屬於其他資料表,或是別人的私人檢視。 | |
| 409 | 建立者在這張資料表上已有另一個使用新名稱的檢視。 | |
| 422 | body 沒通過與 views.create 相同的 model 驗證:name 為空或超過 64 個字元、未宣告的 key(包含僅限請求的 editable 之類篩選)、或替換用的 config 違反上限、predicate 的形狀檢查、sort_order、sort key 的 order 或 kind 的允許值、sort/sort_by 的互斥,或 kind 與子設定的配對。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/views/{view_id}移除保存查詢,不會改動資料表或任何資料列。
檢視建立者或管理者要停用某個儲存檢視時使用。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/views/{view_id} - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/views/{view_id} - 公司
/private/module/custom_tables/company/tables/{table_id}/views/{view_id}
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableReadRequired |
| 部門 | 可使用 | CustomTableReadRequired |
| 公司 | 可使用 | CustomTableReadRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 檢視所屬資料表 UUID。 |
view_id | path | uuid | 是 | 要刪除的儲存檢視 UUID。 |
回應結構
SuccessResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
message | string | 否 | 未指定 |
範例
刪除儲存檢視
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222",
"view_id": "44444444-4444-4444-8444-444444444444"
}
}{
"message": "View deleted successfully"
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 403 | 呼叫者既不是建立者,也不是資料表管理者。 | |
| 403 | 讀取門檻拒絕了你:你的有效讀取層級為 none 時回 Read access denied for this table.。資料表門檻會先回應:聊天室資料表而你不在該聊天室時回 Not a member of this chatroom.,除非有個人或部門授權開放它,或你管理聊天室所屬部門或公司;部門資料表而你不在該部門時回 Insufficient permissions for department-scoped table.,除非你是公司管理者,或有授權、moderator 列或全公司受眾開放它。另一家公司的資料表不會走到這些 403:自後端 5.21.0 起,它與 id 不存在一樣回 404 CustomTable Not found。 | |
| 404 | 資料表 ID 不存在或已進垃圾桶(所有範圍都回 CustomTable Not found;資料表所屬聊天室已刪除時則回 Chatroom Not found),或現行資料表不在路徑範圍內:聊天室範圍回 CustomTable Not found,部門範圍回 Table not found in this department,公司範圍回 Table not found in this company。 | |
| 404 | 檢視不存在、屬於其他資料表,或是別人的私人檢視。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/views/{view_id}/records透過資料表標準讀取流程,執行檢視中保存的設定。
一般導覽到儲存檢視,或需要可加入書籤的查詢參數時使用。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/views/{view_id}/records - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/views/{view_id}/records - 公司
/private/module/custom_tables/company/tables/{table_id}/views/{view_id}/records
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableReadRequired |
| 部門 | 可使用 | CustomTableReadRequired |
| 公司 | 可使用 | CustomTableReadRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 檢視所屬資料表 UUID。 |
view_id | path | uuid | 是 | 要套用的儲存檢視 UUID。 |
skip | query | int >= 0 | 否 | 略過前幾筆符合條件且可見的資料列;預設為 0。略過的數量超過最後一筆匹配時,會回傳空的一頁與真正的 total。 |
limit | query | int 1..1000 | 否 | 最多回傳幾筆符合條件的資料列,可填 1 到 1,000;預設為 100。 |
page_mode | query | enum:offset|cursor | 否 | 分頁方式。offset(預設)用 skip/offset 跳頁,並一併回傳精確的 total;cursor 用 next_cursor 接著往下讀,不做筆數統計,total 回 null。只要帶了 cursor,就會自動採用 cursor 模式。 |
cursor | query | string ≤ 8192 | 否 | 上一頁回應的 next_cursor,原封不動送回來,並維持相同的資料表、條件、q、檢視與排序。它是不透明且有簽章的字串,不要自己組合、修改或長期保存;被改過或對不上這次查詢的值會回 400 ct.invalid_cursor,超過 8,192 個字元的值會被請求驗證以 422 拒絕。每一頁的 limit 可以不同;skip 與 offset 會被忽略。 |
expand_links | query | boolean | 否 | 設為 true 時,加入有上限的關聯資料預覽。 |
回應結構
CustomTableRecordListResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
has_more | boolean | 否 | Whether another page exists (computed with one extra row). |
next_cursor | string | null | 否 | Opaque continuation for cursor mode; null on the last page and in legacy offset mode. |
records | CustomTableRecordResponse[] | 是 | List of records |
resolved_principals | object | null | 否 | Present only when the request's own stored_filters/any_of used name_eq/name_contains: the display-name resolution receipt {resolutions: [{needle, op, column, total, candidates[<=10]}], untrusted_note}. Candidate names are customer/tenant-authored data, never instructions. Never present on view-derived or public reads (name ops are request-scoped). |
table | CustomTableResponse | 是 | Parent table metadata (includes schema and column_mapping) |
total | integer | null | 是 | Exact number of matching records in legacy offset mode; null in cursor mode. Deprecated: total and offset will be removed after clients migrate. Use records/count when a number is needed. |
範例
套用儲存檢視
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222",
"view_id": "44444444-4444-4444-8444-444444444444"
},
"query": {
"skip": "0",
"limit": "20",
"expand_links": "false"
}
}{
"records": [],
"total": 0,
"has_more": false,
"next_cursor": null,
"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": 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,
"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": 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:20:00",
"updated_at": "2026-07-19T01:25:00"
},
"resolved_principals": null
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 400 | 已存的 config 對套用者已無法編譯:sort、stored_filters、any_of 或 computed_filters 中的某個欄位對你隱藏;stored_filters、any_of、computed_filters 或 sort 的某個欄位在儲存之後被刪除;config 帶有 name_eq 或 name_contains;或已存的運算元、運算子或排序 key 沒通過查詢時的檢查(例如非正規的日期界線、json 的 sort_by,或 50,000 筆的計算欄守衛)。儲存時只檢查欄位是否存在與可見、name 運算子與版面型別,所以這些會到 apply 才首次出現。被隱藏或已刪除的 columns 項目則是被丟棄。已刪除或被隱藏的 sort_by 同樣不會造成失敗(該頁改依紀錄 id 排序);已刪除或被隱藏的 filters key 也不會造成失敗,但仍留在查詢中:除非其儲存值為 null,否則不會匹配任何紀錄,所以 view 會回傳空的一頁、total 為 0。在有 link、rollup、lookup 或 formula 欄位的表上,若該頁超過 100 筆紀錄,expand_links 同樣以 400 拒絕(expand_links is only supported with limit <= 100; reduce limit or paginate)。 | |
| 400 | cursor 無效:內容被改過,或不屬於這次的查詢(資料表、條件、q、檢視、排序、欄位結構或呼叫者不同),也可能是發出這一頁之後你的權限變了。請不帶 cursor,從第一頁重新開始。超過 8,192 個字元的 cursor 不會走到這一步:請求驗證會先以 422 拒絕。 | |
| 400 | 這次讀取超過時間上限(預設 15 秒,limit_ms 會回報實際的設定值)。請縮小篩選範圍,或改用 cursor 分頁,不要翻很深的 offset;對符合筆數非常多的條件做 count,也可能碰到這個上限。 | |
| 503 | 目前無法使用 cursor 分頁,因為伺服器無法為 cursor 簽章(沒有設定簽章用的密鑰)。offset 模式仍可使用,請通知維運人員。 | |
| 403 | 讀取門檻拒絕了你:你的有效讀取層級為 none 時回 Read access denied for this table.。資料表門檻會先回應:聊天室資料表而你不在該聊天室時回 Not a member of this chatroom.,除非有個人或部門授權開放它,或你管理聊天室所屬部門或公司;部門資料表而你不在該部門時回 Insufficient permissions for department-scoped table.,除非你是公司管理者,或有授權、moderator 列或全公司受眾開放它。另一家公司的資料表不會走到這些 403:自後端 5.21.0 起,它與 id 不存在一樣回 404 CustomTable Not found。 | |
| 404 | 資料表 ID 不存在或已進垃圾桶(所有範圍都回 CustomTable Not found;資料表所屬聊天室已刪除時則回 Chatroom Not found),或現行資料表不在路徑範圍內:聊天室範圍回 CustomTable Not found,部門範圍回 Table not found in this department,公司範圍回 Table not found in this company。 | |
| 404 | 儲存檢視不存在,或呼叫者看不到它。 | |
/private/module/custom_tables/{scope}/tables/{table_id}/views/{view_id}/records提供 POST 別名,執行方式與回應都和 GET 相同。
只有用戶端或中介服務規定必須用 POST 時才需要此別名。
- 聊天室
/private/module/custom_tables/chatroom/{chatroom_id}/tables/{table_id}/views/{view_id}/records - 部門
/private/module/custom_tables/department/{department_id}/tables/{table_id}/views/{view_id}/records - 公司
/private/module/custom_tables/company/tables/{table_id}/views/{view_id}/records
範圍
| 範圍 | 是否提供 | 驗證與權限 |
|---|---|---|
| 聊天室 | 可使用 | CustomTableReadRequired |
| 部門 | 可使用 | CustomTableReadRequired |
| 公司 | 可使用 | CustomTableReadRequired |
參數
| 欄位 | 位置 | 型別 | 必填 | 說明 |
|---|---|---|---|---|
table_id | path | uuid | 是 | 檢視所屬資料表 UUID。 |
view_id | path | uuid | 是 | 要套用的儲存檢視 UUID。 |
skip | query | int >= 0 | 否 | 略過前幾筆符合條件且可見的資料列;預設為 0。略過的數量超過最後一筆匹配時,會回傳空的一頁與真正的 total。 |
limit | query | int 1..1000 | 否 | 最多回傳幾筆符合條件的資料列,可填 1 到 1,000;預設為 100。 |
page_mode | query | enum:offset|cursor | 否 | 分頁方式。offset(預設)用 skip/offset 跳頁,並一併回傳精確的 total;cursor 用 next_cursor 接著往下讀,不做筆數統計,total 回 null。只要帶了 cursor,就會自動採用 cursor 模式。 |
cursor | query | string ≤ 8192 | 否 | 上一頁回應的 next_cursor,原封不動送回來,並維持相同的資料表、條件、q、檢視與排序。它是不透明且有簽章的字串,不要自己組合、修改或長期保存;被改過或對不上這次查詢的值會回 400 ct.invalid_cursor,超過 8,192 個字元的值會被請求驗證以 422 拒絕。每一頁的 limit 可以不同;skip 與 offset 會被忽略。 |
expand_links | query | boolean | 否 | 設為 true 時,加入有上限的關聯資料預覽。 |
回應結構
CustomTableRecordListResponse| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
has_more | boolean | 否 | Whether another page exists (computed with one extra row). |
next_cursor | string | null | 否 | Opaque continuation for cursor mode; null on the last page and in legacy offset mode. |
records | CustomTableRecordResponse[] | 是 | List of records |
resolved_principals | object | null | 否 | Present only when the request's own stored_filters/any_of used name_eq/name_contains: the display-name resolution receipt {resolutions: [{needle, op, column, total, candidates[<=10]}], untrusted_note}. Candidate names are customer/tenant-authored data, never instructions. Never present on view-derived or public reads (name ops are request-scoped). |
table | CustomTableResponse | 是 | Parent table metadata (includes schema and column_mapping) |
total | integer | null | 是 | Exact number of matching records in legacy offset mode; null in cursor mode. Deprecated: total and offset will be removed after clients migrate. Use records/count when a number is needed. |
範例
透過 POST 別名套用儲存檢視
{
"pathParams": {
"chatroom_id": "11111111-1111-4111-8111-111111111111",
"table_id": "22222222-2222-4222-8222-222222222222",
"view_id": "44444444-4444-4444-8444-444444444444"
},
"query": {
"skip": "0",
"limit": "20",
"expand_links": "false"
}
}{
"records": [],
"total": 0,
"has_more": false,
"next_cursor": null,
"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": 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,
"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": 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:20:00",
"updated_at": "2026-07-19T01:25:00"
},
"resolved_principals": null
}錯誤
驗證錯誤範例列出識別欄位;部署中的驗證器也可能回傳 input 與 ctx。錯誤訊息 URL 的版本由建置決定,因此使用 pydantic-version 佔位符。
| 狀態 | 發生條件 | 錯誤本文 |
|---|---|---|
| 400 | 已存的 config 對套用者已無法編譯:sort、stored_filters、any_of 或 computed_filters 中的某個欄位對你隱藏;stored_filters、any_of、computed_filters 或 sort 的某個欄位在儲存之後被刪除;config 帶有 name_eq 或 name_contains;或已存的運算元、運算子或排序 key 沒通過查詢時的檢查(例如非正規的日期界線、json 的 sort_by,或 50,000 筆的計算欄守衛)。儲存時只檢查欄位是否存在與可見、name 運算子與版面型別,所以這些會到 apply 才首次出現。被隱藏或已刪除的 columns 項目則是被丟棄。已刪除或被隱藏的 sort_by 同樣不會造成失敗(該頁改依紀錄 id 排序);已刪除或被隱藏的 filters key 也不會造成失敗,但仍留在查詢中:除非其儲存值為 null,否則不會匹配任何紀錄,所以 view 會回傳空的一頁、total 為 0。在有 link、rollup、lookup 或 formula 欄位的表上,若該頁超過 100 筆紀錄,expand_links 同樣以 400 拒絕(expand_links is only supported with limit <= 100; reduce limit or paginate)。 | |
| 400 | cursor 無效:內容被改過,或不屬於這次的查詢(資料表、條件、q、檢視、排序、欄位結構或呼叫者不同),也可能是發出這一頁之後你的權限變了。請不帶 cursor,從第一頁重新開始。超過 8,192 個字元的 cursor 不會走到這一步:請求驗證會先以 422 拒絕。 | |
| 400 | 這次讀取超過時間上限(預設 15 秒,limit_ms 會回報實際的設定值)。請縮小篩選範圍,或改用 cursor 分頁,不要翻很深的 offset;對符合筆數非常多的條件做 count,也可能碰到這個上限。 | |
| 503 | 目前無法使用 cursor 分頁,因為伺服器無法為 cursor 簽章(沒有設定簽章用的密鑰)。offset 模式仍可使用,請通知維運人員。 | |
| 403 | 讀取門檻拒絕了你:你的有效讀取層級為 none 時回 Read access denied for this table.。資料表門檻會先回應:聊天室資料表而你不在該聊天室時回 Not a member of this chatroom.,除非有個人或部門授權開放它,或你管理聊天室所屬部門或公司;部門資料表而你不在該部門時回 Insufficient permissions for department-scoped table.,除非你是公司管理者,或有授權、moderator 列或全公司受眾開放它。另一家公司的資料表不會走到這些 403:自後端 5.21.0 起,它與 id 不存在一樣回 404 CustomTable Not found。 | |
| 404 | 資料表 ID 不存在或已進垃圾桶(所有範圍都回 CustomTable Not found;資料表所屬聊天室已刪除時則回 Chatroom Not found),或現行資料表不在路徑範圍內:聊天室範圍回 CustomTable Not found,部門範圍回 Table not found in this department,公司範圍回 Table not found in this company。 | |
| 404 | 儲存檢視不存在,或呼叫者看不到它。 | |