AI GO 系統串接指南

本文檔完整說明第三方應用(Integrations)如何透過「引用」與「API」串接 AI GO 系統,涵蓋所有可被引用的 API Endpoint、資料表(Table)、Custom Table(動態資料表)、Schema 與欄位定義。


1. 系統總覽與架構

1.1 系統定位

AI GO 是一套企業級 PaaS ERP 平台,提供會計、銷售、採購、庫存、CRM、HR、MRP、專案管理等完整模組。透過 Integration(整合) 機制,第三方開發者可建立自建應用(Self-Built App),安全地存取 AI GO 的企業資料。

1.2 三種應用存取模式

特性Internal(內部)External(外部)Self-Built(自建)
使用場景組織內部工具對外客戶/供應商應用第三方獨立系統串接
認證方式Supabase Auth JWTCustom App AuthAPI Key
程式碼託管AI GO BuilderAI GO Builder第三方自行部署
資料存取Internal ProxyExternal ProxyOpen Proxy
引用需發布否(即時生效)否(即時生效)是(需發布快照)
access_modeinternalexternalself_built

本文檔聚焦於 Self-Built(自建)模式,這是第三方整合的核心使用場景。

1.3 整體架構流程

sequenceDiagram
    participant Dev as 開發者(管理端)
    participant AIGO as AI GO API
    participant App as 第三方應用

    Note over Dev,App: === 第一階段:建立整合 ===
    Dev->>AIGO: POST /integrations(建立自建應用)
    AIGO-->>Dev: 回傳 app_id, slug

    Dev->>AIGO: POST /integrations/{app_id}/api-keys(產生 API Key)
    AIGO-->>Dev: 回傳 sk_live_xxx...(僅此一次)

    Note over Dev,App: === 第二階段A:設定系統表引用 ===
    Dev->>AIGO: GET /refs/available-tables(查看可引用的表)
    Dev->>AIGO: GET /refs/tables/{name}/columns(查看欄位)
    Dev->>AIGO: POST /refs/apps/{app_id}(建立引用 + 設定權限)

    Note over Dev,App: === 第二階段B:建立 Custom Table ===
    Dev->>AIGO: 在 AI GO 管理介面建立 Custom Table 及欄位定義

    Note over Dev,App: === 第三階段:發布 ===
    Dev->>AIGO: POST /integrations/{app_id}/publish(發布引用設定)
    AIGO-->>Dev: 快照 columns + permissions 為 published 版本

    Note over Dev,App: === 第四階段:存取資料 ===
    App->>AIGO: GET /open/proxy/{table}(系統資料表)
    AIGO-->>App: 回傳已授權欄位的資料(tenant 隔離)
    App->>AIGO: GET /open/data/objects/{slug}/records(Custom Table)
    AIGO-->>App: 回傳 Custom Table 記錄(tenant 隔離)

2. 認證機制

2.1 API Key Server-to-Server 認證(主要方式)

適用於 Self-Built 應用的後端對後端通訊。

API Key 格式sk_live_ + 64 字元十六進位隨機字串

使用方式:在每個 HTTP 請求的 Header 中攜帶:

X-API-Key: sk_live_a1b2c3d4e5f6...

驗證流程

系統會自動驗證 API Key 的有效性與所屬應用,並自動取得 app_idtenant_id(不需額外傳遞)。無效或已撤銷的 Key 會回傳 401 Unauthorized

安全建議

  • API Key 僅在建立時回傳一次完整明文,請妥善保存
  • 建議將 Key 存放於環境變數或密鑰管理服務,不要寫入程式碼
  • 定期輪換 Key(撤銷舊 Key → 建立新 Key)
  • 同一整合可建立多把 Key(如 Production / Staging 分離)

2.2 Custom App User 認證

AI GO 平台為自建整合提供完整的獨立用戶認證系統,包含:

  • Email + 密碼:註冊 / 登入
  • OAuth 第三方登入:LINE、Google、Facebook 等(參見 §2.4
  • JWT Access Token + Refresh Token Rotation
  • Builder 端用戶管理:啟用 / 停用 / 刪除

重要:Independent 模式不需要第三方開發者自行建立認證系統。AI GO 已提供現成的認證 API,開發者只需要呼叫這些端點即可為自己的應用實現完整的用戶註冊與登入功能。

2.3.1 認證流程總覽

sequenceDiagram
    participant User as 終端用戶
    participant App as 第三方前端
    participant AIGO as AI GO API

    alt Email + 密碼
        User->>App: 填寫註冊 / 登入表單
        App->>AIGO: POST /custom-app-auth/{slug}/register 或 login
        AIGO-->>App: { access_token, refresh_token, user }
    else OAuth 登入(如 LINE)
        User->>App: 點擊 LINE 登入
        App->>AIGO: GET /custom-app-oauth/{slug}/line/authorize
        AIGO-->>User: 302 重導 LINE 授權頁
        User->>AIGO: 授權回呼
        AIGO-->>App: 302 redirect?oauth_token=<base64 encoded tokens>
    end

    Note over App: 儲存 access_token + refresh_token

    App->>AIGO: GET /custom-app-auth/{slug}/me(Bearer Token)
    AIGO-->>App: { user info }

    Note over App: Token 即將過期時
    App->>AIGO: POST /custom-app-auth/{slug}/refresh
    AIGO-->>App: { new access_token, new refresh_token }

路徑說明:所有 Custom App User 認證端點以 app_slug(非 app_id)作為路徑參數。slug 可在整合詳情頁面的標題旁查看(12 位元十六進位字串)。系統也支援以 subdomain 替代 slug


2.3.2 註冊(Register)

POST /api/v1/custom-app-auth/{app_slug}/register

認證:無需認證(公開端點)

Request Body

{
  "email": "user@example.com",
  "password": "my_secure_password",
  "display_name": "王小明"
}
欄位型別必填驗證規則
emailstring合法 email 格式,1~255 字元,自動轉小寫
passwordstring6~128 字元
display_namestring1~100 字元

Response 201 Created

{
  "access_token": "eyJhbGciOiJIUzI1NiI...",
  "refresh_token": "a1b2c3d4e5f6...",
  "expires_in": 900,
  "token_type": "Bearer",
  "user": {
    "id": "uuid",
    "custom_app_id": "uuid",
    "tenant_id": "uuid",
    "email": "user@example.com",
    "display_name": "王小明",
    "avatar_url": null,
    "extra_data": {},
    "is_active": true,
    "last_login_at": null,
    "created_at": "2026-04-01T00:00:00Z",
    "updated_at": null
  }
}

錯誤碼

HTTP Codedetail原因
409此 Email 已被註冊同一 App 下 email 不可重複
403此來源不在白名單中Origin 不在 allowed_origins 白名單中
404App 不存在slug 無效
403此 App 不支援用戶認證access_modeexternal / self_built

2.3.3 登入(Login)

POST /api/v1/custom-app-auth/{app_slug}/login

認證:無需認證(公開端點)

Request Body

{
  "email": "user@example.com",
  "password": "my_secure_password"
}

Response 200 OK:格式同 §2.3.2 註冊 的 Response

錯誤碼

HTTP Codedetail原因
401帳號或密碼錯誤email 不存在或密碼不符
403帳號已被停用使用者已被 Builder 停用

2.3.4 取得當前用戶(Me)

GET /api/v1/custom-app-auth/{app_slug}/me

認證:Bearer Token(Access Token)

Authorization: Bearer eyJhbGciOiJIUzI1NiI...

Response 200 OK

{
  "id": "uuid",
  "custom_app_id": "uuid",
  "tenant_id": "uuid",
  "email": "user@example.com",
  "display_name": "王小明",
  "avatar_url": "https://...",
  "extra_data": {},
  "is_active": true,
  "last_login_at": "2026-04-01T12:00:00Z",
  "created_at": "2026-04-01T00:00:00Z",
  "updated_at": null
}

錯誤碼

HTTP Codedetail原因
401未提供認證 Token缺少 Authorization header
401無效或已過期的 TokenAccess Token 過期或格式不正確
403帳號已被停用使用者已被停用

2.3.5 刷新 Token(Refresh)

POST /api/v1/custom-app-auth/{app_slug}/refresh

認證:無需 Bearer Token(公開端點,需 refresh_token 作為 Body 參數)

Request Body

{
  "refresh_token": "a1b2c3d4e5f6..."
}

Response 200 OK:格式同 §2.3.2 註冊 的 Response(包含全新的 access_tokenrefresh_token

⚠️ Token Rotation:每次 refresh 成功後,舊的 Refresh Token 立即失效(撤銷)。請務必儲存並使用回傳的新 refresh_token

錯誤碼

HTTP Codedetail原因
401無效的 Refresh TokenToken 不存在或已被撤銷
401Refresh Token 已過期超過 7 天有效期
401使用者不存在或已停用用戶帳號已刪除或停用

2.3.6 登出(Logout)

POST /api/v1/custom-app-auth/{app_slug}/logout

認證:Bearer Token(Access Token)

Request Body

{
  "refresh_token": "a1b2c3d4e5f6..."
}

Response 200 OK

{
  "message": "已登出"
}

2.3.7 ext/ 端點群:Custom App User 專用 API

以下端點需以 Custom App User Token(Bearer)認證,適用於 Independent 模式的前端直接存取資料:

端點前綴說明備註
/api/v1/ext/proxy/存取系統資料表與 Open Proxy 相同引擎,認證方式不同
/api/v1/ext/data/存取 Custom Table/open/data/ 對應
/api/v1/ext/compile/取得/執行 VFS 前端渲染程式碼適用於 AI GO 託管的前端
/api/v1/ext/actions/執行 Server-Side Actions執行後端自動化動作
/api/v1/ext/storage/存取 Supabase Storage 檔案上傳/下載應用相關檔案

使用方式:

# 使用 Custom App User Token 存取系統資料表
curl -H "Authorization: Bearer <access_token>" \
     https://api.ai-go.app/api/v1/ext/proxy/customers

# 使用 Custom App User Token 存取 Custom Table
curl -H "Authorization: Bearer <access_token>" \
     https://api.ai-go.app/api/v1/ext/data/objects/group_tour/records

與 Open Proxy 的區別

  • /ext/* 端點使用 Bearer Token(Custom App User Token),tenant_idcustom_app_id 從 Token payload 自動解析
  • /open/* 端點使用 API KeyX-API-Key),適用於後端 Server-to-Server 呼叫
  • 兩者共用相同的引用白名單和資料過濾引擎

2.3.8 網域白名單(Origin 檢查)

設定 allowed_origins 後,Custom App Auth 端點(register / login 等)會檢查 HTTP Origin header:

情境行為
白名單為空放行所有來源(尚未設定)
無 Origin header(後端呼叫 / curl)放行
Origin 在白名單中放行
Origin 不在白名單中回傳 403 此來源不在白名單中

⚠️ Port 注意事項:Port 是 Origin 的一部分(RFC 6454),例如 http://localhost:3000http://localhost:8000。設定白名單時需包含完整的 scheme://host:port


2.3.9 Builder 端用戶管理 API

以下端點供整合管理者(Builder)在 AI GO 管理介面中管理 Custom App 的用戶,需主站 JWT 認證(builder.access 權限):

端點說明
GET /api/v1/custom-app-auth/manage/{app_id}/users列出 App 所有用戶
PATCH /api/v1/custom-app-auth/manage/{app_id}/users/{user_id}啟用/停用用戶(Body: { "is_active": false }
DELETE /api/v1/custom-app-auth/manage/{app_id}/users/{user_id}刪除用戶(連帶刪除所有 Session)

停用或刪除用戶後,該用戶的認證快取會立即清除,已發出的 Access Token 在快取 TTL(60 秒)後將無法使用。


2.3 OAuth 第三方登入(LINE 等)

自建整合可額外設定 OAuth Provider(如 LINE Login),讓終端用戶透過第三方帳號直接登入。

2.4.1 前置設定

Builder 需在 AI GO 管理介面為 App 設定 OAuth Provider:

  1. 進入整合管理 → 選擇 App → 設定 Tab
  2. 填入 Provider 的 Client IDClient Secret(系統會以 AES-256 加密儲存)
  3. 在第三方平台(如 LINE Developers Console)設定 Callback URL 為:
https://<YOUR_API_HOST>/api/v1/custom-app-oauth/{app_slug}/{provider}/callback

2.4.2 OAuth 端點清單

端點認證說明
GET /api/v1/custom-app-oauth/{slug}/auth-providers列出已啟用的 provider
GET /api/v1/custom-app-oauth/{slug}/{provider}/authorize302 重導至第三方授權頁
GET /api/v1/custom-app-oauth/{slug}/{provider}/callback第三方回呼處理(系統內部)
POST /api/v1/custom-app-oauth/{slug}/oauth/complete-email補填 email(Body: { "pending_token": "...", "email": "..." }

目前支援的 provider 值:line(LINE Login)。Google、Facebook、GitHub 等架構已就緒。

2.4.3 OAuth 登入流程

sequenceDiagram
    participant User as 終端用戶
    participant App as 第三方前端
    participant AIGO as AI GO API
    participant LINE as LINE Login

    App->>AIGO: GET /{slug}/auth-providers
    AIGO-->>App: [{ "provider": "line" }]

    User->>App: 點擊 LINE 登入按鈕
    App->>AIGO: GET /{slug}/line/authorize
    AIGO-->>User: 302 → LINE 授權頁
    User->>LINE: 同意授權
    LINE-->>AIGO: callback?code=xxx&state=yyy

    alt 有 email
        AIGO-->>App: 302 → {app_url}?oauth_token=<base64>
        Note over App: base64 解碼得到<br/>{ access_token, refresh_token, user }
    else 無 email
        AIGO-->>App: 302 → {app_url}?oauth_pending=<token>
        App->>User: 顯示補填 email 表單
        User->>App: 輸入 email
        App->>AIGO: POST /{slug}/oauth/complete-email
        AIGO-->>App: { access_token, refresh_token, user }
    end

2.4.4 OAuth Token 傳遞方式

OAuth 登入成功後,系統透過 query parameter 將 token 回傳至 App 的 live_url

Query Parameter說明
oauth_tokenBase64 URL-safe 編碼的 JSON 字串,包含完整 token 和用戶資訊
oauth_pending無 email 時的暫時 token(有效 30 分鐘),前端需顯示補填 email 表單
oauth_errorOAuth 過程中發生錯誤時的錯誤描述文字

前端解碼範例

// OAuth 登入成功後解碼 token
const params = new URLSearchParams(window.location.search);
const encoded = params.get('oauth_token');
if (encoded) {
  const decoded = JSON.parse(atob(encoded));
  // decoded = { access_token, refresh_token, expires_in, user }
  localStorage.setItem('access_token', decoded.access_token);
  localStorage.setItem('refresh_token', decoded.refresh_token);
}

2.4.5 OAuth 帳號綁定行為

情境系統行為
OAuth identity 已存在(已綁定)直接登入,更新 profile
有 email 且同 email 帳號已存在自動綁定 OAuth identity 到現有帳號
有 email 但無現有帳號自動註冊新帳號 + 建立 identity
無 email回傳 oauth_pending token,等待補填

⚠️ OAuth 用戶的 password_hashnull,無法使用 Email + 密碼登入。若需要啟用密碼登入,用戶需另行設定密碼。


2.4 Token 技術規格

Custom App User 認證使用的 Token 機制:

項目規格
簽發函式create_custom_app_user_token()
JWT 演算法HS256
Payload scopeapp_runtime
Payload auth_typecustom_app_user
Payload subCustom App User UUID
Access Token TTL15 分鐘(900 秒)
Refresh 機制Refresh Token Rotation(舊 token 立即撤銷)
Refresh Token TTL7 天
Refresh Token 格式64 字元 hex 隨機字串
Refresh Token 儲存SHA-256 hash 後寫入 DB
密碼雜湊bcrypt(自動 salt)

Access Token JWT Payload 範例

{
  "sub": "550e8400-e29b-41d4-a716-446655440000",
  "custom_app_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "tenant_id": "11111111-2222-3333-4444-555555555555",
  "auth_type": "custom_app_user",
  "scope": "app_runtime",
  "iat": 1711929600,
  "exp": 1711930500
}

關鍵區分auth_type 欄位固定為 "custom_app_user"/ext/* 端點會據此驗證身份。


2.4.1 Quick Start:30 分鐘完成整合

以下是端對端整合的最小步驟:

Step 1 — 建立整合並取得 API Key:

# 在 AI GO 管理介面建立新整合
# 取得 app_slug(如 e9abbb866184)和 API Key(如 sk_live_xxx)

Step 2 — 設定網域白名單:

在設定 Tab 中將前端 Origin(如 https://myapp.example.com)加入白名單。

Step 3 — 前端串接範例(JavaScript):

const API_BASE = 'https://api.ai-go.app/api/v1';
const APP_SLUG = 'e9abbb866184';

// ── 1. 使用者註冊 ──
async function register(email, password, displayName) {
  const res = await fetch(`${API_BASE}/custom-app-auth/${APP_SLUG}/register`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password, display_name: displayName }),
  });
  const data = await res.json();
  if (!res.ok) throw new Error(data.detail);
  
  // 儲存 token
  localStorage.setItem('access_token', data.access_token);
  localStorage.setItem('refresh_token', data.refresh_token);
  return data.user;
}

// ── 2. 使用者登入 ──
async function login(email, password) {
  const res = await fetch(`${API_BASE}/custom-app-auth/${APP_SLUG}/login`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password }),
  });
  const data = await res.json();
  if (!res.ok) throw new Error(data.detail);
  
  localStorage.setItem('access_token', data.access_token);
  localStorage.setItem('refresh_token', data.refresh_token);
  return data.user;
}

// ── 3. 使用 Token 存取資料 ──
async function fetchCustomers() {
  const token = localStorage.getItem('access_token');
  const res = await fetch(`${API_BASE}/ext/proxy/customers`, {
    headers: { 'Authorization': `Bearer ${token}` },
  });
  return res.json();
}

// ── 4. Token 刷新 ──
async function refreshTokens() {
  const refreshToken = localStorage.getItem('refresh_token');
  const res = await fetch(`${API_BASE}/custom-app-auth/${APP_SLUG}/refresh`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ refresh_token: refreshToken }),
  });
  const data = await res.json();
  if (!res.ok) throw new Error(data.detail);
  
  // ⚠️ 務必更新兩個 token(Token Rotation)
  localStorage.setItem('access_token', data.access_token);
  localStorage.setItem('refresh_token', data.refresh_token);
  return data;
}

Step 4 — 後端 Server-to-Server 存取資料(Python):

import requests

API_KEY = 'sk_live_a1b2c3d4...'
API_BASE = 'https://api.ai-go.app/api/v1'

# 直接用 API Key 存取資料(不涉及用戶認證)
resp = requests.get(
    f'{API_BASE}/open/proxy/customers',
    headers={'X-API-Key': API_KEY},
)
print(resp.json())

3. 整合管理 API

前綴/api/v1/integrations 認證:主站 JWT(需 builder.access 權限)

3.1 列出所有整合

GET /api/v1/integrations

Response 200 OK

[
  {
    "id": "uuid",
    "tenant_id": "uuid",
    "name": "我的 ERP 整合",
    "slug": "e9abbb866184",
    "subdomain": "my-erp",
    "live_url": "https://my-erp.example.com",
    "allowed_origins": ["https://my-erp.example.com"],
    "api_key_count": 2,
    "created_at": "2026-03-01T00:00:00Z",
    "updated_at": "2026-03-20T00:00:00Z"
  }
]

3.2 建立新整合

POST /api/v1/integrations
欄位型別必填說明
namestring整合名稱(1-100 字)
subdomainstring自訂子域名(2-63 字、全域唯一)

Response 201 CreatedIntegrationDetail 物件

3.3 取得整合詳情

GET /api/v1/integrations/{app_id}

Response 200 OK

{
  "id": "uuid",
  "tenant_id": "uuid",
  "name": "...",
  "slug": "...",
  "subdomain": null,
  "live_url": null,
  "allowed_origins": [],
  "access_mode": "self_built",
  "created_at": "...",
  "updated_at": "..."
}

3.4 重新命名

PATCH /api/v1/integrations/{app_id}/name
欄位型別必填說明
namestring新名稱(1-100 字)

3.5 更新設定

PATCH /api/v1/integrations/{app_id}/settings
欄位型別必填說明
live_urlstring上線 URL(最長 500 字)
allowed_originsstring[]網域白名單(CORS 限制)

3.6 刪除整合

DELETE /api/v1/integrations/{app_id}

Response 204 No Content(連帶刪除所有 API Keys)

3.7 API Key 管理

列出 API Keys

GET /api/v1/integrations/{app_id}/api-keys

Response 200 OK

[
  {
    "id": "uuid",
    "app_id": "uuid",
    "key_prefix": "sk_live_a1b2",
    "name": "Production Key",
    "is_active": true,
    "last_used_at": "2026-03-20T12:00:00Z",
    "expires_at": null,
    "created_at": "2026-03-01T00:00:00Z"
  }
]

建立 API Key

POST /api/v1/integrations/{app_id}/api-keys
欄位型別必填說明
namestringKey 名稱(1-100 字),如 "Production Key"

Response 201 Created

{
  "id": "uuid",
  "app_id": "uuid",
  "key_prefix": "sk_live_a1b2",
  "name": "Production Key",
  "api_key": "sk_live_a1b2c3d4e5f6g7h8...",
  "created_at": "..."
}

⚠️ api_key 欄位僅在建立時回傳一次,請立即妥善保存。

撤銷 API Key

DELETE /api/v1/integrations/{app_id}/api-keys/{key_id}

Response 204 No Content

3.8 發布審核流程

引用設定修改後,需通過「發布」才能在 Open Proxy 中生效。

發布整合

POST /api/v1/integrations/{app_id}/publish
Query型別說明
notestring發布備註

行為

  • builder.publish 權限 → 直接發布(自動 approved)
  • builder.publish 權限 → 建立 pending 申請等候審核

列出發布申請

GET /api/v1/integrations/{app_id}/publish-requests

核准 / 拒絕 / 取消發布申請

POST /api/v1/integrations/{app_id}/publish-requests/{req_id}/approve
POST /api/v1/integrations/{app_id}/publish-requests/{req_id}/reject
POST /api/v1/integrations/{app_id}/publish-requests/{req_id}/cancel
  • approve:需 builder.publish 權限
  • reject:需 builder.publish 權限,Body: { "reject_reason": "..." }
  • cancel:僅申請者本人可取消

取得發布狀態

GET /api/v1/integrations/{app_id}/publish-status

Response

{
  "can_publish": true,
  "is_locked": false,
  "pending_request": null,
  "published_at": "2026-03-20T00:00:00Z"
}

4. 引用系統 API

前綴/api/v1/refs 認證:主站 JWT(需 builder.access 權限)

引用(Reference)是 AI GO 的資料授權核心機制。每個整合必須先建立引用,指定要存取哪些表的哪些欄位,以及具備什麼操作權限。

4.1 列出可引用的表

GET /api/v1/refs/available-tables

Response 200 OK

[
  { "name": "customers", "comment": "客戶" },
  { "name": "sale_orders", "comment": "銷售訂單" },
  { "name": "product_products", "comment": "" }
]

4.2 取得表的欄位資訊

GET /api/v1/refs/tables/{table_name}/columns

Response 200 OK

[
  {
    "name": "name",
    "type": "VARCHAR",
    "nullable": false,
    "is_system": false
  },
  {
    "name": "email",
    "type": "VARCHAR",
    "nullable": true,
    "is_system": false
  },
  {
    "name": "customer_id",
    "type": "UUID",
    "nullable": true,
    "is_system": false,
    "is_fk": true,
    "fk_target": "customers.id"
  }
]

4.3 引用 CRUD

列出 App 的所有引用

GET /api/v1/refs/apps/{app_id}

建立引用

POST /api/v1/refs/apps/{app_id}
欄位型別必填說明
table_namestring要引用的表名,如 "customers"
columnsstring[]授權的欄位清單,如 ["name", "email", "phone"]
permissionsstring[]權限清單,如 ["read", "create"]

更新引用

PATCH /api/v1/refs/{ref_id}
欄位型別說明
columnsstring[]新的授權欄位清單
permissionsstring[]新的權限清單

刪除引用

DELETE /api/v1/refs/{ref_id}

4.4 權限值說明

權限對應 Proxy 操作說明
readGET / POST query查詢資料
createPOST insert新增記錄
updatePATCH更新記錄
deleteDELETE刪除記錄

4.5 不可引用的表

系統核心表(如身份驗證、租戶管理、權限設定、稽核紀錄等)因安全原因永遠不可被引用。嘗試引用這些表時,API 會回傳 403 此表不可引用

可引用的表清單請透過 GET /api/v1/refs/available-tables API 查詢。

4.6 系統欄位

以下欄位由系統自動管理,寫入時會被自動排除:

欄位型別說明
idUUID主鍵,自動生成
created_attimestamptz建立時間,自動設定
updated_attimestamptz更新時間,自動更新
tenant_idUUID租戶 ID,自動注入(row-level 隔離)

4.7 共用業務欄位:custom_data(JSONB)

所有功能性資料表皆包含 custom_data 欄位,專為第三方應用儲存業態專屬的自訂資料設計。

特性說明
型別JSONB(PostgreSQL 原生 JSON 二進位格式)
預設值'{}'::jsonb(空 JSON 物件)
Nullable是(可設為 null
存取方式僅透過 Proxy API(Internal / External / Open)
資料隔離遵循現有 tenant_id row-level 隔離機制

使用方式:在建立引用時將 custom_data 加入 columns 清單:

{
  "table_name": "customers",
  "columns": ["id", "name", "email", "custom_data"],
  "permissions": ["read", "create", "update"]
}

⚠️ 若引用的 columns 中未包含 custom_data,則該 App 在讀取時不會看到此欄位,寫入時也會被自動忽略。


5. 資料代理 Proxy API(Open Proxy)

前綴/api/v1/open/proxy 認證:API Key(X-API-Key Header) 資料隔離:自動以 Key 所屬的 tenant_id 做 row-level 過濾 引用版本:使用已發布(published)的引用快照

5.0 三套 Proxy 對照表

系統提供三套 Proxy 端點,共用同一個核心查詢引擎,差異僅在認證方式與引用版本:

特性Internal ProxyExternal ProxyOpen Proxy(自建應用)
URL 前綴/api/v1/proxy/{app_id}//api/v1/ext/proxy//api/v1/open/proxy/
認證方式Supabase Auth JWTCustom App TokenAPI Key(X-API-Key
路徑需 app_id❌(Token 自帶)❌(Key 自帶)
引用版本columns + permissions(即時)published_columns + published_permissions(需發布)published_columns + published_permissions(需發布)
簡單查詢 limit 上限50010001000
支援進階查詢✅(完整支援 filter / search / order_by)

重要:自建應用透過 Open Proxy 同樣支援完整的進階查詢功能(filters、search、order_by、select、count_only 等),並非只有 limit / offset。使用 POST /{table_name}/query 即可。

External Proxy 認證說明:External Proxy(/ext/proxy/)需使用 Custom App User Token(Bearer)認證,適用於 Independent 模式的前端直接存取資料。Token 的取得方式請參閱 §2.3 Custom App User 認證

5.1 簡單查詢

GET /api/v1/open/proxy/{table_name}?limit=100&offset=0
Query型別預設說明
limitint100每頁筆數(最大 1000)
offsetint0偏移量

Response 200 OK

[
  {
    "id": "uuid",
    "name": "客戶 A",
    "email": "a@example.com",
    "phone": "0912345678"
  }
]

5.2 進階查詢

POST /api/v1/open/proxy/{table_name}/query

Request Body

{
  "filters": [
    { "column": "status", "op": "eq", "value": "active" },
    { "column": "amount_total", "op": "gte", "value": 1000 }
  ],
  "order_by": [
    { "column": "created_at", "direction": "desc" }
  ],
  "search": "關鍵字",
  "search_columns": ["name", "email"],
  "select_columns": ["id", "name", "email"],
  "limit": 50,
  "offset": 0,
  "count_only": false
}

Filter 運算子

運算子SQL 對應說明value 型別
eq=等於any
ne!=不等於any
gt>大於number/string
gte>=大於等於number/string
lt<小於number/string
lte<=小於等於number/string
likeLIKE模糊匹配(區分大小寫)string
ilikeILIKE模糊匹配(不區分大小寫)string
is_nullIS NULL為空不需要
is_not_nullIS NOT NULL不為空不需要
inIN (...)包含於列表array

Filter 組合邏輯

  • 多個 filter 之間以 AND 連接
  • 不支援 OR 組合(例外:search 功能在多個搜尋欄之間使用 OR)
  • 不支援巢狀分組條件(如 (A AND B) OR (C AND D)
  • 若需要 BETWEEN 效果,可組合 gte + lte 兩個 filter

範例 — 查詢金額 ≥ 1000 且狀態為 active 的銷售訂單

{
  "filters": [
    { "column": "amount_total", "op": "gte", "value": 1000 },
    { "column": "state", "op": "eq", "value": "sale" }
  ]
}

Search 全文搜尋行為

  • search 會對 search_columns(或所有授權非 id 欄位)執行 ILIKE '%keyword%'
  • 多個搜尋欄之間以 OR 連接(任一欄位命中即回傳)
  • search 與 filters 之間為 AND(兩者同時滿足)
  • 搜尋時欄位值會被 cast 為 text 型別,因此也可搜尋數值或 UUID 欄位

count_only 模式

設定 "count_only": true 時,僅回傳符合條件的總筆數(filters 與 search 均生效):

{ "total": 42 }

5.3 新增記錄

[!WARNING] Proxy API 操作不觸發業務單據自動生成 (Workflow Triggers) 透過 Proxy API 新增或更新業務資料(如將訂單 state 改為 sale),系統 不會 自動建立後續單據(如自動產生出貨單、發票)。Proxy API 為「資料層代理」,第三方應用需自行 INSERT 所有相關單據,但特定欄位(如已開票量、付款狀態等)系統會自動維護。各表的「自動觸發流程(Triggers)」請參閱第 8 章。

POST /api/v1/open/proxy/{table_name}

Request Body

{
  "name": "新客戶",
  "email": "new@example.com",
  "phone": "0912345678",
  "custom_data": {
    "passport_no": "A123456789",
    "travel_pref": ["eco", "window_seat"]
  }
}

custom_data 接受任意 JSON 結構(物件、陣列、巢狀皆可)。

Response 201 Created

{
  "id": "uuid",
  "created_at": "2026-03-24T00:00:00Z",
  "data": {
    "name": "新客戶",
    "email": "new@example.com",
    "custom_data": "{\"passport_no\": \"A123456789\"}"
  }
}

tenant_id 由系統自動注入,不需手動提供。

5.4 更新記錄

PATCH /api/v1/open/proxy/{table_name}/{row_id}

Request Body

{
  "name": "更新後名稱",
  "phone": "0987654321"
}

Response 200 OK

{ "id": "uuid", "updated": true }

5.5 刪除記錄

DELETE /api/v1/open/proxy/{table_name}/{row_id}

Response 204 No Content

5.6 自動型別轉換

Proxy 會自動將字串轉為對應的 PostgreSQL 型別:

輸入格式轉換結果範例
YYYY-MM-DD(正好 10 字元)date"2026-03-24"
T 的 ISO 字串datetime"2026-03-24T12:00:00Z"
dict / list(JSON 物件/陣列)jsonbCAST AS jsonb{"key": "value"}
UUID 格式字串(在 _id 結尾的欄位)uuid"a24bc8fe-5942-4937-ad2f-28812caa5425"
空字串 ""(在 _id 結尾的欄位)NULL"" → 寫入 NULL

⚠️ UUID 欄位注意事項

  • 所有以 _id 結尾的欄位(如 product_idorder_id)在寫入時會自動嘗試轉為 UUID 型別
  • 若值為空字串 "",系統會自動轉為 NULL(避免 PostgreSQL 型別錯誤)
  • 若值不是合法的 UUID 格式(如 LINE ID U1234567890),則保留原始字串

5.7 AI GO 簽核系統整合 (Approval Workflow)

💡 適用於:POST, PATCH, DELETE 等任何會修改資料的 Proxy 操作。

AI GO 提供了彈性的簽核工作流引擎。當系統管理員在後台為特定資料表(例如 sale_orders)設定了簽核關卡時,您的 Proxy API 呼叫將會自動受到簽核系統的審查攔截。

攔截與 API 旁路機制 (Bypass)

  1. 一般情況 (攔截):當簽核流程被觸發,API 操作不會直接生效。相反的,系統會:
    • 針對 POST (Insert-then-flag):先行新增未生效的記錄,確保取得 ID 後供參照。
    • 針對 PATCH / DELETE (Pre-guard):完全暫停對資料庫的實際改動,將異動內容封裝進入「簽核申請單」中等待判斷。
    • 您的 API 呼叫會收到帶有 approval_status: "pending" 的回傳值。
  2. API 旁路 (Bypass):若管理員在後台開啟了對應工作流的「允許 API 旁路」選項,第三方 API 將可以無視簽核規則強制寫入資料。系統僅會在背景紀錄一筆 Bypass Audit Log 供後續稽核追蹤。

被攔截時的回傳格式

當未開啟旁路,且操作觸發了簽核條件時,API 不會回傳標準的成功格式,而是如下:

Update 操作被攔截的範例:

{
  "id": "e305d21a-e75b-42e1-886d-a1112345abcd",
  "updated": false,
  "approval_status": "pending",
  "approval_request_id": "123e4567-e89b-12d3-a456-426614174000",
  "approval_message": "此更新需要簽核審批(2 層),已建立申請"
}

開發者注意事項:在串接有潛在簽核規則的 Table(如採購單、銷貨單、請假單等)時,請務必在處理 API Response 中捕捉 approval_status === "pending" 這個屬性,避免將 Pending 視為實際的修改成功。


6. Custom Table API(動態資料表)

前綴/api/v1/open/data 認證:API Key(X-API-Key Header) 資料隔離:自動以 Key 所屬的 tenant_id 做 row-level 過濾 引用白名單:不適用(Custom Table 隸屬於 App 本身,不走引用機制)

6.0 Custom Table 與系統資料表的差異

AI GO 提供兩種資料儲存方式,分別使用不同的 API 端點:

特性系統資料表(Open Proxy)Custom Table(Open Custom Data)
端點前綴/api/v1/open/proxy/{table}/api/v1/open/data/
資料來源系統內建模組(customers, sale_orders 等)App 自建的動態資料表
Schema 定義固定 PostgreSQL 表結構動態 JSONB(自訂欄位定義)
引用白名單✅ 需要建立引用 + 發布❌ 不需要(App 自有資料)
資料識別方式table_name(如 customersobject_idapi_slug
管理方式系統內建,不可增刪表在 AI GO 管理介面自行建立

⚠️ 常見錯誤:請勿使用 /open/proxy/ 端點存取 Custom Table。Custom Table 不是實體 PostgreSQL 表,不存在於引用系統中,使用 Proxy 端點會收到 403 App 未被授權存取表 錯誤。

6.1 Custom Table 概念說明

Custom Table 是 AI GO 的動態資料庫系統,允許每個 App 自行定義資料表結構:

  • CustomObject(資料表定義):邏輯上等同一張「表」,包含名稱和 api_slug(API 識別碼)
  • CustomField(欄位定義):每個 Object 可定義多個欄位(名稱、型別、是否必填等)
  • CustomRecord(資料記錄):實際資料以 JSONB 格式儲存在 data 欄位中
erDiagram
    CustomObject ||--o{ CustomField : "has fields"
    CustomObject ||--o{ CustomRecord : "has records"
    CustomObject {
        UUID id PK
        UUID app_id FK
        string name
        string api_slug
    }
    CustomField {
        UUID id PK
        UUID object_id FK
        string name
        string field_key
        string field_type
        boolean is_required
        int sequence
    }
    CustomRecord {
        UUID id PK
        UUID object_id FK
        JSONB data
    }

6.2 列出 App 的 Custom Table

GET /api/v1/open/data/objects

Response 200 OK

[
  {
    "id": "uuid",
    "tenant_id": "uuid",
    "app_id": "uuid",
    "name": "團體行程",
    "api_slug": "group_tour",
    "created_at": "2026-03-20T00:00:00Z",
    "updated_at": "2026-03-20T00:00:00Z",
    "fields": [
      {
        "id": "uuid",
        "object_id": "uuid",
        "name": "行程名稱",
        "field_key": "tour_name",
        "field_type": "text",
        "is_required": true,
        "sequence": 10
      },
      {
        "id": "uuid",
        "object_id": "uuid",
        "name": "金額",
        "field_key": "amount",
        "field_type": "number",
        "is_required": false,
        "sequence": 20
      }
    ]
  }
]

回傳的 fields 陣列包含完整的欄位定義,可用於動態生成表單或表格。

6.3 列出 Custom Table 的記錄

GET /api/v1/open/data/objects/{obj_id}/records

路徑參數

參數說明
obj_idCustom Table 的 UUID api_slug(如 group_tour

Response 200 OK

[
  {
    "id": "uuid",
    "tenant_id": "uuid",
    "object_id": "uuid",
    "data": {
      "tour_name": "日本東京五日遊",
      "amount": 35000,
      "departure_date": "2026-05-01"
    },
    "created_at": "2026-03-20T00:00:00Z",
    "updated_at": "2026-03-20T00:00:00Z"
  },
  {
    "id": "uuid",
    "tenant_id": "uuid",
    "object_id": "uuid",
    "data": {
      "tour_name": "韓國首爾三日遊",
      "amount": 18000,
      "departure_date": "2026-06-15"
    },
    "created_at": "2026-03-21T00:00:00Z",
    "updated_at": "2026-03-21T00:00:00Z"
  }
]

data 欄位為 JSONB,其結構由 Custom Table 的 fields 定義決定。

6.4 新增記錄

POST /api/v1/open/data/objects/{obj_id}/records

路徑參數obj_id 支援 UUID 或 api_slug

Request Body

{
  "data": {
    "tour_name": "泰國曼谷四日遊",
    "amount": 22000,
    "departure_date": "2026-07-20",
    "max_people": 30,
    "itinerary": ["大皇宮", "水上市場", "芭達雅"]
  }
}

data 接受任意 JSON 結構,包含物件、陣列、巢狀結構等。field_key 對應 Custom Table 的欄位定義。

Response 201 Created

{
  "id": "uuid",
  "tenant_id": "uuid",
  "object_id": "uuid",
  "data": {
    "tour_name": "泰國曼谷四日遊",
    "amount": 22000,
    "departure_date": "2026-07-20",
    "max_people": 30,
    "itinerary": ["大皇宮", "水上市場", "芭達雅"]
  },
  "created_at": "2026-03-29T00:00:00Z",
  "updated_at": null
}

tenant_id 由系統根據 API Key 自動注入,不需手動提供。

6.5 更新記錄

PATCH /api/v1/open/data/records/{record_id}

路徑參數

參數說明
record_id記錄的 UUID

Request Body

{
  "data": {
    "amount": 25000,
    "status": "confirmed"
  }
}

更新為合併模式(Merge):僅覆寫傳入的欄位,未傳入的欄位保持不變。例如上例只會更新 amount 和新增 status,其餘欄位(如 tour_name)不受影響。

Response 200 OK

{
  "id": "uuid",
  "tenant_id": "uuid",
  "object_id": "uuid",
  "data": {
    "tour_name": "泰國曼谷四日遊",
    "amount": 25000,
    "departure_date": "2026-07-20",
    "max_people": 30,
    "itinerary": ["大皇宮", "水上市場", "芭達雅"],
    "status": "confirmed"
  },
  "created_at": "2026-03-29T00:00:00Z",
  "updated_at": "2026-03-29T01:00:00Z"
}

6.6 刪除記錄

DELETE /api/v1/open/data/records/{record_id}

Response 200 OK

{
  "message": "已刪除",
  "id": "uuid"
}

6.7 欄位型別說明

型別說明data 中的值範例
text文字"日本東京五日遊"
number數值3500099.5
date日期(ISO 格式字串)"2026-05-01"
relation關聯其他記錄的 UUID"550e8400-e29b-41d4-a716-446655440000"

由於 data 是 JSONB 欄位,實際上可以儲存任意 JSON 結構(陣列、巢狀物件等),field_type 主要用於 UI 表單顯示和前端驗證。

6.8 Custom Table 完整使用範例

以下展示第三方旅行社 ERP 系統串接 Custom Table 的完整流程:

# ── 第一步:取得 API Key 後,查看 App 有哪些 Custom Table ──
curl -H "X-API-Key: sk_live_a1b2c3d4e5f6..." \
     https://api.ai-go.app/api/v1/open/data/objects

# 回應範例:
# [
#   {
#     "id": "...", "name": "團體行程", "api_slug": "group_tour",
#     "fields": [{"field_key": "tour_name", "field_type": "text"}, ...]
#   },
#   {
#     "id": "...", "name": "訂單紀錄", "api_slug": "booking",
#     "fields": [{"field_key": "customer_name", ...}, ...]
#   }
# ]


# ── 第二步:用 api_slug 列出「團體行程」的所有記錄 ──
curl -H "X-API-Key: sk_live_a1b2c3d4e5f6..." \
     https://api.ai-go.app/api/v1/open/data/objects/group_tour/records


# ── 第三步:新增一筆行程記錄 ──
curl -X POST \
     -H "X-API-Key: sk_live_a1b2c3d4e5f6..." \
     -H "Content-Type: application/json" \
     -d '{
       "data": {
         "tour_name": "沖繩四日遊",
         "amount": 28000,
         "departure_date": "2026-08-10",
         "max_people": 25
       }
     }' \
     https://api.ai-go.app/api/v1/open/data/objects/group_tour/records


# ── 第四步:更新記錄(Merge 模式,僅更新指定欄位)──
curl -X PATCH \
     -H "X-API-Key: sk_live_a1b2c3d4e5f6..." \
     -H "Content-Type: application/json" \
     -d '{"data": {"amount": 32000, "status": "full"}}' \
     https://api.ai-go.app/api/v1/open/data/records/{record_id}


# ── 第五步:刪除記錄 ──
curl -X DELETE \
     -H "X-API-Key: sk_live_a1b2c3d4e5f6..." \
     https://api.ai-go.app/api/v1/open/data/records/{record_id}

6.9 與 Open Proxy 的端點對照

如果您同時需要存取系統資料表(如 customers)和 Custom Table,請注意使用不同的 API 端點:

# ── 存取系統資料表(如客戶)→ 使用 Open Proxy ──
curl -H "X-API-Key: sk_live_xxx" \
     https://api.ai-go.app/api/v1/open/proxy/customers

# ── 存取 Custom Table(如團體行程)→ 使用 Open Custom Data ──
curl -H "X-API-Key: sk_live_xxx" \
     https://api.ai-go.app/api/v1/open/data/objects/group_tour/records
我要存取的資料正確的端點錯誤的端點(會收到 403)
系統內建表(customers, sale_orders 等)/open/proxy/{table}/open/data/objects/{table}/records
Custom Table(App 自建的動態表)/open/data/objects/{slug}/records/open/proxy/{slug}(❌ 403)


7. 可引用的資料表與 Schema 完整清單

以下列出所有可被引用的資料表(僅適用於 Open Proxy,Custom Table 請參閱 §6)。 每張表皆包含 id(UUID)、created_at(timestamptz)、updated_at(timestamptz)、tenant_id(UUID) 四個系統欄位,以及 custom_data(JSONB) 自訂資料欄位(參見 §4.7),以下不重複列出。


7.1 客戶模組

customers — 客戶

欄位型別NullableFK說明
nameVARCHAR客戶名稱
customer_typeVARCHARcompany / individual
birthdayVARCHAR生日
id_numberVARCHAR身分證號/統編
registered_addressVARCHAR登記地址
contact_addressVARCHAR聯絡地址
phoneVARCHAR電話
emailVARCHAR電子郵件
line_idVARCHARLINE ID
faxVARCHAR傳真
noteTEXT備註
id_file_urlVARCHAR身分證檔案 URL
contact_personVARCHAR聯繫窗口
vatVARCHAR稅籍編號
currency_idUUIDcurrencies.id幣別
payment_termVARCHAR付款條件
credit_limitFLOAT信用額度
is_companyBOOLEAN法人/自然人
country_idUUIDcountries.id國家
state_idUUIDcountry_states.id州省
cityVARCHAR城市
zip_codeVARCHAR郵遞區號
langVARCHAR語言偏好
refVARCHAR客戶代碼
website_urlVARCHAR網站
activeBOOLEAN啟用狀態
short_nameVARCHAR簡稱
statusVARCHARactive / suspended
level_idUUIDcustomer_levels.id客戶等級
salesperson_idUUIDusers.id負責業務員

customer_levels — 客戶等級

欄位型別Nullable說明
nameVARCHAR等級名稱
discount_rateNUMERIC(5,4)折扣比率(1.0=原價)
descriptionTEXT說明

customer_tags — 客戶標籤

欄位型別Nullable說明
nameVARCHAR標籤名稱
colorVARCHAR顯示顏色

customer_tag_rel — 客戶-標籤關聯

欄位型別FK說明
customer_idUUIDcustomers.id客戶
tag_idUUIDcustomer_tags.id標籤

customer_tag_prices — 標籤專屬價

欄位型別FK說明
tag_idUUIDcustomer_tags.id標籤
product_idUUIDproduct_products.id商品
special_priceNUMERIC(16,2)專屬價格

7.2 供應商模組

suppliers — 供應商

欄位型別NullableFK說明
nameVARCHAR名稱
supplier_typeVARCHARcompany / individual
refVARCHAR供應商代碼
vatVARCHAR統編
contact_personVARCHAR聯繫窗口
phoneVARCHAR電話
emailVARCHAR電子郵件
faxVARCHAR傳真
registered_addressVARCHAR登記地址
contact_addressVARCHAR聯絡地址
cityVARCHAR城市
zip_codeVARCHAR郵遞區號
country_idUUIDcountries.id國家
state_idUUIDcountry_states.id州省
payment_termVARCHAR付款條件
credit_limitFLOAT信用額度
currency_idUUIDcurrencies.id幣別
website_urlVARCHAR網站
noteTEXT備註
activeBOOLEAN啟用
statusVARCHARactive / suspended

7.3 產品模組

product_categories — 產品分類

欄位型別NullableFK說明
nameVARCHAR名稱
complete_nameVARCHAR完整路徑名
parent_idUUIDproduct_categories.id父分類
codeVARCHAR類別編號
property_valuationVARCHARperiodic / real_time
property_cost_methodVARCHARstandard / fifo / average
property_account_income_idUUIDaccount_accounts.id收入科目
property_account_expense_idUUIDaccount_accounts.id費用科目
default_warehouse_idUUIDstock_warehouses.id預設倉庫

product_templates — 產品範本

欄位型別NullableFK說明
nameVARCHAR名稱
typeVARCHARconsu / service / combo
categ_idUUIDproduct_categories.id分類
list_priceNUMERIC(16,2)銷售價
standard_priceNUMERIC(16,2)成本價
descriptionTEXT描述
default_codeVARCHARSKU
barcodeVARCHAR條碼
activeBOOLEAN啟用
sale_okBOOLEAN可銷售
purchase_okBOOLEAN可採購
uom_idUUIDuom_uom.id銷售單位
uom_po_idUUIDuom_uom.id採購單位
invoice_policyVARCHARorder / delivery

product_products — 產品變體

欄位型別FK說明
product_tmpl_idUUIDproduct_templates.id範本
default_codeVARCHARSKU
barcodeVARCHAR條碼
activeBOOLEAN啟用
lst_price_extraNUMERIC(16,2)額外售價
standard_priceNUMERIC(16,2)成本價

product_price_tiers — 階梯定價

欄位型別FK說明
product_tmpl_idUUIDproduct_templates.id產品範本
price_typeVARCHARfixed / market
min_qtyNUMERIC(16,4)數量下限
max_qtyNUMERIC(16,4)數量上限
priceNUMERIC(16,2)單價
guide_priceNUMERIC(16,2)指導價格

product_supplierinfo — 供應商價格

欄位型別FK說明
supplier_idUUIDsuppliers.id供應商
product_tmpl_idUUIDproduct_templates.id產品範本
product_idUUIDproduct_products.id產品變體
product_nameVARCHAR供應商品名
product_codeVARCHAR供應商品號
min_qtyNUMERIC(16,4)最低訂購量
priceNUMERIC(16,2)價格
currency_idUUIDcurrencies.id幣別
date_startDATE生效日
date_endDATE失效日
delayINTEGER前置時間(天)

7.4 銷售模組

sale_orders — 銷售訂單

📌 自動觸發流程 (Triggers)

  • 新增或更新此表(以及 sale_order_lines)時,系統會自動比對出貨量與開票量,並重新計算更新本訂單的 invoice_statusno, to_invoice, invoiced)。
欄位型別NullableFK說明
nameVARCHAR單號
stateVARCHARdraft/sent/sale/done/cancel
date_orderDATE下單日
validity_dateDATE有效期
noteTEXT備註
amount_untaxedNUMERIC(16,2)未稅金額
amount_taxNUMERIC(16,2)稅額
amount_totalNUMERIC(16,2)總金額
marginNUMERIC(16,2)毛利
invoice_statusVARCHARno/to_invoice/invoiced
customer_idUUIDcustomers.id客戶
currency_idUUIDcurrencies.id幣別
user_idUUIDusers.id業務員
department_idUUIDhr_departments.id部門

sale_order_lines — 銷售訂單明細

欄位型別FK說明
order_idUUIDsale_orders.id訂單
nameTEXT描述
product_idUUIDproduct_products.id產品
product_uom_qtyNUMERIC(16,4)數量
qty_deliveredNUMERIC(16,4)已交貨量
qty_invoicedNUMERIC(16,4)已開票量
price_unitNUMERIC(16,2)單價
discountNUMERIC(5,2)折扣 %
price_subtotalNUMERIC(16,2)小計
price_totalNUMERIC(16,2)含稅總計
tax_idUUIDaccount_taxes.id稅率
delivery_dateDATE預交貨日

7.5 採購模組

purchase_orders — 採購訂單

📌 自動觸發流程 (Triggers)

  • 新增或更新此表(以及 purchase_order_lines)時,系統會自動重新計算更新本訂單的開票狀態。
欄位型別FK說明
nameVARCHAR單號
stateVARCHARdraft/sent/purchase/done/cancel
date_orderDATE下單日
date_plannedDATE預計交貨日
amount_untaxedNUMERIC(16,2)未稅金額
amount_taxNUMERIC(16,2)稅額
amount_totalNUMERIC(16,2)總金額
supplier_idUUIDsuppliers.id供應商
currency_idUUIDcurrencies.id幣別
user_idUUIDusers.id負責人
notesTEXT備註
originVARCHAR來源文件

purchase_order_lines — 採購訂單明細

欄位型別FK說明
order_idUUIDpurchase_orders.id訂單
product_idUUIDproduct_products.id產品
product_qtyNUMERIC(16,4)數量
qty_receivedNUMERIC(16,4)已收貨量
price_unitNUMERIC(16,2)單價
price_subtotalNUMERIC(16,2)小計
price_totalNUMERIC(16,2)總計
tax_idUUIDaccount_taxes.id稅率

7.6 會計模組

⚠️ 核心會計邏輯與專屬 API 提醒 請注意:若您直接使用 Open Proxy APIaccount_movesaccount_move_lines 進行 INSERT,系統不會觸發會計防呆與自動化處理(例如:自動取號、防呆自動平衡分錄等),這可能導致借貸不平的髒資料產生。

若您正在開發獨立的會計/發票整合系統,強烈建議您全面改用 AI GO 專屬的會計業務 API

  1. POST /api/v1/accounting/vouchers (建立傳票:自動設定 entry 與 mapping)
  2. POST /api/v1/accounting/vouchers/{id}/post (過帳傳票:自動依據結算差額插入「自動平衡分錄」並生成 Voucher Number)

在專屬 API 中,只要偵測到 Debit ≠ Credit,系統會自動幫您墊入一筆「自動平衡分錄」將總金額強制打平,確保會計約束不崩潰!詳細 Endpoint 規格請見系統的 /docs Swagger 頁面。

account_moves — 會計傳票/發票

📌 自動觸發流程 (Triggers)

  • 更新此發票或其明細,以及關聯付款對帳時(account_payments),系統會自動重新計算這張發票的付款狀態 payment_state(如 paid, partial, not_paid)。
欄位型別FK說明
nameVARCHAR單號
move_typeVARCHARentry/out_invoice/in_invoice/out_refund/in_refund/out_receipt/in_receipt
stateVARCHARdraft/posted/cancel
dateDATE記帳日期
invoice_dateDATE發票日期
invoice_date_dueDATE到期日
customer_idUUIDcustomers.id客戶
supplier_idUUIDsuppliers.id供應商
currency_idUUIDcurrencies.id幣別
journal_idUUIDaccount_journals.id日記帳
amount_untaxedNUMERIC(16,2)未稅金額
amount_taxNUMERIC(16,2)稅額
amount_totalNUMERIC(16,2)總金額
amount_residualNUMERIC(16,2)未付餘額
payment_stateVARCHARnot_paid/partial/paid/reversed/invoicing_legacy/in_payment
voucher_numberVARCHAR傳票號碼

account_move_lines — 傳票明細行

欄位型別FK說明
move_idUUIDaccount_moves.id傳票
nameVARCHAR摘要
quantityNUMERIC(16,4)數量
price_unitNUMERIC(16,2)單價
debitNUMERIC(16,2)借方
creditNUMERIC(16,2)貸方
balanceNUMERIC(16,2)餘額
account_idUUIDaccount_accounts.id會計科目
tax_rateNUMERIC(5,2)稅率 %
tax_amountNUMERIC(16,2)稅額

會計模組還包含 account_accountsaccount_journalsaccount_taxesaccount_payment_termsaccount_fiscal_positionsaccount_paymentsaccount_bank_statementsaccount_move_templates 等表,結構請透過 GET /refs/tables/{table_name}/columns API 即時查詢。


7.7 庫存模組

stock_warehouses — 倉庫

欄位型別說明
nameVARCHAR倉庫名稱
codeVARCHAR(5)簡碼
activeBOOLEAN啟用
reception_stepsVARCHARone_step/two_steps/three_steps
delivery_stepsVARCHARship_only/pick_ship/pick_pack_ship

stock_locations — 庫位

欄位型別FK說明
nameVARCHAR名稱
usageVARCHARsupplier/view/internal/customer/inventory/transit/production
activeBOOLEAN啟用
barcodeVARCHAR條碼
location_idUUIDstock_locations.id父庫位

stock_pickings — 揀貨單/調撥單

欄位型別FK說明
nameVARCHAR單號
stateVARCHARdraft/waiting/confirmed/assigned/done/cancel
originVARCHAR來源文件
picking_type_idUUIDstock_picking_types.id揀貨類型
location_idUUIDstock_locations.id來源庫位
location_dest_idUUIDstock_locations.id目的庫位
customer_idUUIDcustomers.id客戶
supplier_idUUIDsuppliers.id供應商
sale_idUUIDsale_orders.id銷售訂單
purchase_idUUIDpurchase_orders.id採購訂單

stock_moves — 庫存移動

📌 自動觸發流程 (Triggers)

  • 更新此表的狀態時,系統會自動重新計算關聯揀貨單 (stock_pickings) 的部分出入庫完成狀態。
欄位型別FK說明
nameTEXT描述
stateVARCHARdraft/waiting/confirmed/partially_available/assigned/done/cancel
product_idUUIDproduct_products.id產品
product_uom_qtyNUMERIC(16,4)需求量
quantityNUMERIC(16,4)完成量
location_idUUIDstock_locations.id來源
location_dest_idUUIDstock_locations.id目的
picking_idUUIDstock_pickings.id揀貨單

stock_quants — 庫存量

欄位型別FK說明
product_idUUIDproduct_products.id產品
location_idUUIDstock_locations.id庫位
lot_idUUIDstock_lots.id批號
quantityNUMERIC(16,4)在手量
reserved_quantityNUMERIC(16,4)保留量

📌 關於庫存量維護 (Triggers):新增或更新 stock_move_lines (庫存移動明細) 時,系統會自動計算並更新對應庫位商品的保留數量 (stock_quants.reserved_quantity)。

庫存模組還包含 stock_lotsstock_picking_typesstock_move_linesstock_routesstock_rulesstock_packagesstock_scrapsstock_warehouse_orderpointsstock_landed_costsstock_picking_batchesdelivery_carriersinventory_check_batchesinventory_check_itemsinventory_convertsfreight_groupsfreight_group_tiers 等表。


7.8 CRM 模組

crm_leads — 商機

欄位型別FK說明
nameVARCHAR名稱
typeVARCHARlead / opportunity
activeBOOLEAN啟用
priorityVARCHAR0/1/2/3(星級)
stage_idUUIDcrm_stages.id階段
probabilityFLOAT機率 %
expected_revenueNUMERIC(16,2)預期營收
customer_idUUIDcustomers.id客戶
contact_nameVARCHAR聯絡人
email_fromVARCHAREmail
phoneVARCHAR電話
user_idUUIDusers.id負責人
team_idUUIDcrm_teams.id銷售團隊
date_deadlineDATE預計結案日
descriptionTEXT描述

還包含 crm_stagescrm_teamscrm_team_memberscrm_lost_reasonscrm_tagscrm_recurring_planscrm_activities 等表。


7.9 HR 人力資源模組

hr_employees — 員工

📌 自動觸發流程 (Triggers)

  • 出勤 (hr_attendances):新增或更新出勤紀錄時,會自動更新對應員工目前的出勤狀態。
  • 請假 (hr_leaves):請假單狀態更新為 validate(核准)時,會自動扣除該員工可用休假額度(hr_leave_allocations)。
  • 工時 (hr_timesheets):填寫工時表會自動累加 project_tasks.effective_hours(任務實際工時),並更新專案任務進度百分比。
欄位型別FK說明
nameVARCHAR姓名
activeBOOLEAN啟用
employee_typeVARCHARemployee/student/trainee/contractor/freelance
job_titleVARCHAR職稱
work_phoneVARCHAR公司電話
work_emailVARCHAR公司信箱
mobile_phoneVARCHAR手機
genderVARCHARmale/female/other
birthdayDATE生日
department_idUUIDhr_departments.id部門
job_idUUIDhr_jobs.id職位
parent_idUUIDhr_employees.id直屬主管
user_idUUIDusers.id關聯使用者
member_idUUIDmembers.id系統帳號

還包含 hr_departmentshr_jobshr_work_locationshr_attendanceshr_leave_typeshr_leaveshr_leave_allocationshr_expense_sheetshr_expenseshr_skill_typeshr_skillshr_timesheetshr_work_entry_typeshr_work_entries 等表。


7.10 MRP 製造模組

mrp_productions — 生產訂單

📌 自動觸發流程 (Triggers)

  • 更新關聯工單 (mrp_workorders) 的狀態時,系統會自動結算並刷新本生產訂單的完成進度。
欄位型別FK說明
nameVARCHAR單號
product_idUUIDproduct_products.id產品
product_qtyFLOAT計畫數量
qty_producedFLOAT已完成數量
stateVARCHARdraft/confirmed/progress/to_close/done/cancel
bom_idUUIDmrp_boms.id物料清單
date_startTIMESTAMPTZ開始日期
date_finishedTIMESTAMPTZ完成日期
user_idUUIDusers.id負責人
is_subcontractBOOLEAN委外

還包含 mrp_workcentersmrp_bomsmrp_bom_linesmrp_bom_byproductsmrp_routing_workcentersmrp_workordersmrp_unbuilds 等表。


7.11 專案管理模組

project_projects — 專案

📌 自動觸發流程 (Triggers)

  • 建立或刪除關聯任務 (project_tasks) 時,系統會自動維護並更新此專案主檔的總任務數 (task_count)。
欄位型別FK說明
nameVARCHAR專案名稱
activeBOOLEAN啟用
descriptionTEXT描述
date_startDATE開始日
dateDATE截止日
stage_idUUIDproject_project_stages.id階段
customer_idUUIDcustomers.id客戶
user_idUUIDusers.idPM
task_countINTEGER任務數

project_tasks — 任務

欄位型別FK說明
nameVARCHAR名稱
stateVARCHAR01_in_progress/1_done/1_canceled/04_waiting_normal/03_approved/02_changes_requested
priorityVARCHAR0(一般)/1(緊急)
descriptionTEXT描述
date_deadlineDATE截止日
project_idUUIDproject_projects.id專案
stage_idUUIDproject_task_types.id看板階段
parent_idUUIDproject_tasks.id父任務
planned_hoursFLOAT計畫工時
effective_hoursFLOAT實際工時
progressFLOAT進度 %

還包含 project_project_stagesproject_task_typesproject_milestonesproject_tagsproject_rolesproject_collaboratorsproject_task_recurrencesproject_updates 等表。


7.12 核心參考表

countries — 國家

欄位型別說明
nameVARCHAR名稱
codeVARCHAR(2)ISO 3166-1 alpha-2
phone_codeINTEGER國際電話區碼
currency_idUUID預設幣別

currencies — 幣別

欄位型別說明
nameVARCHAR(3)ISO 4217(TWD、USD)
full_nameVARCHAR完整名稱
symbolVARCHAR(10)符號(NT$、$)
decimal_placesINTEGER小數位數

uom_uom — 計量單位

欄位型別FK說明
nameVARCHAR名稱
category_idUUIDuom_categories.id類別
uom_typeVARCHARreference/bigger/smaller
factorFLOAT轉換因子

還包含 country_statescurrency_rateslanguagesuom_categoriesir_sequences 等表。


7.13 其他模組

表名說明
analytic_accounts分析帳戶
analytic_lines分析行
utm_sourcesUTM 來源
utm_mediumsUTM 媒介
utm_campaignsUTM 活動
announcements公告
file_nodes檔案節點
purchase_stock_links採購-庫存連結
sale_stock_links銷售-庫存連結
sale_purchase_links銷售-採購連結

所有表的完整欄位可透過 GET /api/v1/refs/tables/{table_name}/columns 即時查詢。


8. 錯誤碼與限制

8.1 HTTP 狀態碼

狀態碼說明
200成功
201建立成功
204刪除成功(無回傳內容)
400請求格式錯誤(如無效的權限值、不合法的篩選欄位)
401未認證(API Key 無效或缺失)
403無權限(表不可引用、未授權的操作、未發布的引用)
404資源不存在
409衝突(如子域名已被使用、已有 pending 發布申請)
422請求驗證失敗
429超過速率限制
500伺服器內部錯誤

8.2 常見錯誤訊息

訊息原因可能的解決方案
"App 未被授權存取表 '{table}'"尚未建立該表的引用若為系統表,請建立引用;若為 Custom Table,請改用 /open/data/ 端點
"表 '{table}' 的引用尚未發布"引用已建立但未發布(Open Proxy 需發布版本)在整合管理中發布引用設定
"App 未被授權對表 '{table}' 執行 '{op}' 操作"引用的 permissions 不含該操作更新引用加入所需權限
"未授權的篩選欄位: {col}"查詢使用了未在 columns 中授權的欄位在引用中加入該欄位
"此表不可引用"該表在黑名單中系統核心表無法存取
"API Key 無效或已撤銷"Key 不存在或已被停用重新建立 API Key
"資料表不存在"Custom Table 的 object_id 或 api_slug 不正確先呼叫 GET /open/data/objects 確認可用的 Custom Table
"記錄不存在"Custom Table 的 record_id 不正確或已被刪除確認 record_id 正確且屬於該 App

8.3 速率限制

系統對所有 API 請求實施 Per-App 速率限制。超過限制時回傳 429 Too Many Requests

8.4 安全注意事項

  • 所有資料查詢自動以 tenant_id 做 row-level 隔離,無法跨租戶存取
  • tenant_id 由 API Key 自動決定,無法偽造
  • 寫入操作時,系統欄位(idcreated_atupdated_attenant_id)會被自動排除
  • 欄位名稱經正則驗證(^[a-zA-Z_][a-zA-Z0-9_]*$),防止 SQL 注入
  • 僅允許白名單運算子,不接受任意 SQL

9. Proxy 查詢完整安全機制與功能限制

9.1 安全驗證流程

每次 Proxy 呼叫都會依序執行以下驗證:

① AppDataReference 白名單驗證
   → 檢查 App 是否有對目標表的引用(Open Proxy 需已發布快照)
② CRUD 權限檢查
   → 引用的 permissions 必須包含所需操作(read / create / update / delete)
③ 黑名單表檢查
   → 14 張系統核心表永遠不可存取
④ 欄位白名單驗證
   → filter / select / insert / update 的欄位必須在授權的 columns 清單中
⑤ 欄位名稱正則驗證
   → 只允許 ^[a-zA-Z_][a-zA-Z0-9_]*$,防止 SQL 注入
⑥ 運算子白名單驗證
   → 只接受 11 種已定義運算子(eq, ne, gt, gte, lt, lte, like, ilike, in, is_null, is_not_null)
⑦ Tenant 隔離注入
   → 所有查詢自動加上 WHERE tenant_id = :tid(不可跨租戶)
⑧ 系統欄位保護
   → INSERT / UPDATE 時自動排除 id, created_at, updated_at, tenant_id

9.2 Open Proxy 存取方式對照

呼叫方式簡單查詢進階查詢(含 filter)說明
GET /open/proxy/{table}limit / offset
POST /open/proxy/{table}/query完整 filter / search / order_by / select / count_only

9.3 已知查詢功能限制

限制項目說明替代方案
不支援 OR 條件filters 之間只能 AND使用 search 做多欄位 OR 搜尋,或拆分為多次查詢
不支援巢狀條件無法表達 (A AND B) OR C拆分為多次查詢後在應用層合併
不支援 JOIN只能查單一表分別查詢兩張表後在應用層關聯
不支援聚合函式無 SUM / AVG / GROUP BY查出原始資料後在應用層計算
不支援 BETWEENbetween 運算子組合 gte + lte 兩個 filter
不支援 NOT IN只有 in,無 not_in查出全部後在應用層篩選
不支援 NOT LIKE只有 like / ilike查出全部後在應用層篩選
單次查詢上限limit 最大 500(GET)或 1000(Open Proxy GET)使用 offset 分頁迭代
無 cursor 分頁只有 limit + offset大量資料建議配合 order_by + offset 遞增
無跨租戶查詢tenant_id 由系統強制注入此為安全設計,無替代方案

9.4 Filter 欄位驗證規則彙整

驗證項目檢查內容失敗回傳
欄位名稱格式必須符合 ^[a-zA-Z_][a-zA-Z0-9_]*$400 不合法的欄位名稱
欄位授權必須在 allowed_columns 清單中(id 始終允許)400 未授權的篩選欄位
運算子合法性必須為 11 種白名單運算子之一400 不支援的運算子
in 運算子型別value 必須為 array400 'in' 運算子的 value 必須是陣列
select_columns 授權所選欄位必須在 allowed_columns400 未授權的欄位
Order By 欄位不在白名單中的欄位會被靜默忽略回退為預設排序 created_at DESC

提示:所有表的最新欄位結構可透過 GET /api/v1/refs/tables/{table_name}/columns 動態取得,包含型別、是否 Nullable、外鍵指向等資訊。建議在開發時搭配此 API 使用。


10. Enum 值速查附錄

所有 VARCHAR 型別但僅接受固定值的欄位完整清單。

  • [DB]:有 PostgreSQL CHECK CONSTRAINT,寫入非法值會直接報錯 400 / 500
  • [建議]:無資料庫約束,為系統建議值;前後端介面以此為準,API 不會拒絕其他值但可能導致顯示異常

10.1 客戶模組

欄位約束可接受值說明
customerscustomer_type[DB]company, individual法人 / 自然人
customersstatus[DB]active, suspended啟用 / 停權

10.2 供應商模組

欄位約束可接受值說明
supplierssupplier_type[DB]company, individual法人 / 自然人
suppliersstatus[DB]active, suspended啟用 / 停權

10.3 產品模組

欄位約束可接受值說明
product_categoriesproperty_valuation[建議]periodic, real_time定期盤點 / 即時(永續盤存)
product_categoriesproperty_cost_method[建議]standard, fifo, average標準成本 / 先進先出 / 加權平均
product_templatestype[DB]consu, service, combo消耗品 / 服務 / 組合商品
product_templatesinvoice_policy[DB]order, delivery依訂單開票 / 依出貨開票
product_templatesservice_type[DB]manual, timesheet手動 / 依工時
product_templatesexpense_policy[DB]no, cost, sales_price不可報銷 / 依成本 / 依售價
product_price_tiersprice_type[DB]fixed, market定價模式 / 時價模式

10.4 銷售模組

欄位約束可接受值說明
sale_ordersstate[DB]draft, sent, sale, done, cancel草稿 → 已報價 → 銷售訂單 → 完成 → 取消
sale_ordersinvoice_status[DB]no, to_invoice, invoiced無須開票 / 待開票 / 已開票
sale_orderstax_type[建議]tax_included, tax_excluded, tax_exempt, zero_rate含稅 / 未稅 / 免稅 / 零稅率
sale_ordersinvoice_format[建議]duplicate, triplicate, none二聯式 / 三聯式 / 不開
sale_orderscarrier_type[建議]barcode, citizen_digital, mobile, none條碼載具 / 自然人憑證 / 手機條碼 / 無
sale_ordersdelivery_method[建議]pickup, delivery, mail, freight自取 / 宅配 / 郵寄 / 貨運
sale_order_linesinvoice_status[DB]no, to_invoice, invoiced無須開票 / 待開票 / 已開票
sale_order_linesdisplay_type[DB]line_section, line_note區段標題 / 備註行
sale_order_template_linesdisplay_type[建議]line_section, line_note區段標題 / 備註行

10.5 採購模組

欄位約束可接受值說明
purchase_ordersstate[DB]draft, sent, purchase, done, cancel草稿 → 已報價 → 採購訂單 → 完成 → 取消
purchase_ordersinvoice_status[DB]no, to_invoice, invoiced無須開票 / 待開票 / 已開票
purchase_orderstax_type[建議]tax_included, tax_excluded, tax_exempt, zero_rate含稅 / 未稅 / 免稅 / 零稅率
purchase_requisitionsstate[DB]draft, ongoing, in_progress, open, done, cancel草稿 → 進行中 → 處理中 → 開放 → 完成 → 取消
purchase_requisitionsrequisition_type[DB]purchase, blanket_order採購協議 / 框架協議

10.6 會計模組

欄位約束可接受值說明
account_movesmove_type[DB]entry, out_invoice, out_refund, in_invoice, in_refund, out_receipt, in_receipt日記帳分錄 / 銷項發票 / 銷項折讓 / 進項發票 / 進項折讓 / 收據 / 付款收據
account_movesstate[DB]draft, posted, cancel草稿 / 已過帳 / 已取消
account_movespayment_state[DB]not_paid, partial, paid, reversed, invoicing_legacy, in_payment未付 / 部分付款 / 已付 / 已沖回 / 舊版格式 / 付款中
account_movesjournal_type[建議]sale, purchase, cash, bank, general銷售 / 採購 / 現金 / 銀行 / 一般
account_movesvoucher_type[建議]general, cash, transfer, bank一般傳票 / 現金傳票 / 轉帳傳票 / 銀行傳票
account_movessettlement_status[建議]receivable, payable, provisional_receipt, provisional_payment, settled應收 / 應付 / 暫收 / 暫付 / 已結清
account_fiscal_yearsstate[DB]open, closed開放 / 關閉
account_periodsstate[DB]open, closed開放 / 關閉
account_lock_dateslock_date_field[DB]fiscalyear_lock_date, tax_lock_date, sale_lock_date, purchase_lock_date全域鎖帳 / 稅務鎖帳 / 銷售鎖帳 / 採購鎖帳
account_lock_datesstate[DB]active, revoked, expired生效中 / 已撤銷 / 已過期
account_reportsreport_type[DB]general_ledger, balance_sheet, profit_loss, cash_flow, aged_receivable, aged_payable, tax_report, partner_ledger, trial_balance總帳 / 資產負債表 / 損益表 / 現金流量 / 應收帳齡 / 應付帳齡 / 稅務報表 / 夥伴帳 / 試算表
account_report_linesexpression_engine[DB]domain, account_codes, aggregation, tax_tags, customDomain 篩選 / 科目代碼 / 聚合 / 稅額標籤 / 自訂
account_paymentspayment_type[建議]inbound, outbound收款 / 付款
account_paymentspartner_type[建議]customer, supplier客戶 / 供應商

10.7 庫存模組

欄位約束可接受值說明
stock_warehousesreception_steps[DB]one_step, two_steps, three_steps一步收貨 / 兩步收貨 / 三步收貨
stock_warehousesdelivery_steps[DB]ship_only, pick_ship, pick_pack_ship直接出貨 / 揀貨+出貨 / 揀貨+包裝+出貨
stock_locationsusage[DB]supplier, view, internal, customer, inventory, production, transit供應商 / 檢視(虛擬群組) / 內部 / 客戶 / 盤點 / 生產 / 中轉
stock_picking_typescode[DB]incoming, outgoing, internal, mrp_operation進貨 / 出貨 / 內部調撥 / 製造作業
stock_pickingsstate[DB]draft, waiting, confirmed, assigned, done, cancel草稿 / 等待 / 已確認 / 已指派 / 完成 / 取消
stock_pickingspriority[DB]0, 1一般 / 緊急
stock_movesstate[DB]draft, waiting, confirmed, partially_available, assigned, done, cancel草稿 / 等待 / 已確認 / 部分可用 / 已指派 / 完成 / 取消
stock_movesprocure_method[DB]make_to_stock, make_to_order庫存供應 / 訂單觸發
stock_move_linesstate[建議]draft, assigned, done, cancel草稿 / 已指派 / 完成 / 取消
stock_rulesaction[DB]pull, push, pull_push, buy, manufacture拉式 / 推式 / 推拉混合 / 採購 / 製造
stock_rulesprocure_method[DB]make_to_stock, make_to_order庫存供應 / 訂單觸發
stock_scrapsstate[DB]draft, done草稿 / 完成
stock_scrapsscrap_reason[建議]damaged, expired, quality, other損壞 / 過期 / 品質不良 / 其他
stock_storage_categoriesallow_new_product[DB]empty, same, mixed僅空位 / 僅同品 / 混放
stock_landed_costsstate[DB]draft, done, cancel草稿 / 完成 / 取消
stock_landed_cost_linessplit_method[DB]equal, by_quantity, by_current_cost_price, by_weight, by_volume均分 / 依數量 / 依成本 / 依重量 / 依體積
stock_picking_batchesstate[DB]draft, in_progress, done, cancel草稿 / 進行中 / 完成 / 取消
delivery_carriersdelivery_type[DB]fixed, base_on_rule固定運費 / 依規則計算
inventory_check_batchesstate[DB]draft, done草稿 / 完成
inventory_convertsstate[DB]draft, done草稿 / 完成
freight_groupsmode[DB]fixed, tiered, free固定運費 / 級距運費 / 免運

10.8 CRM 模組

欄位約束可接受值說明
crm_leadstype[DB]lead, opportunity潛在客戶 / 商機
crm_leadspriority[DB]0, 1, 2, 3無星 / 一星 / 二星 / 三星
crm_activitiesactivity_type[DB]email, call, meeting, todo郵件 / 通話 / 會議 / 待辦
crm_activitiesstate[DB]planned, done, overdue, cancelled已排程 / 已完成 / 已逾期 / 已取消

10.9 HR 人力資源模組

欄位約束可接受值說明
hr_employeesemployee_type[建議]employee, student, trainee, contractor, freelance正職 / 學生 / 實習 / 約聘 / 自由工作者
hr_employeesgender[建議]male, female, other男 / 女 / 其他
hr_employeesmarital[建議]single, married, cohabitant, widower, divorced單身 / 已婚 / 同居 / 喪偶 / 離婚
hr_employeeshr_presence_state[建議]present, absent, to_define在線 / 離線 / 待定義
hr_work_locationslocation_type[DB]home, office, other居家 / 辦公室 / 其他
hr_leave_typesrequires_allocation[建議]yes, no需配額 / 不需配額
hr_leave_typesleave_validation_type[建議]no_validation, hr, manager, both無需審核 / HR 審核 / 主管審核 / 雙重審核
hr_leave_typestime_type[建議]leave, other請假 / 其他
hr_leave_typesrequest_unit[建議]day, half_day, hour天 / 半天 / 小時
hr_leavesstate[DB]draft, confirm, refuse, validate1, validate, cancel草稿 / 已提交 / 已拒絕 / 一級核准 / 最終核准 / 已取消
hr_leavesholiday_type[建議]employee, company, department, category個人 / 全公司 / 部門 / 分類
hr_leave_allocationsstate[建議]draft, confirm, validate1, validate, refuse草稿 / 已提交 / 一級核准 / 最終核准 / 已拒絕
hr_leave_allocationsallocation_type[建議]regular, accrual一般分配 / 累計分配
hr_expense_sheetsstate[DB]draft, submit, approve, post, done, cancel草稿 / 已提交 / 已核准 / 已入帳 / 完成 / 取消
hr_expense_sheetspayment_state[建議]not_paid, in_payment, paid未付 / 付款中 / 已付
hr_expensesstate[DB]draft, reported, approved, done, refused草稿 / 已報告 / 已核准 / 完成 / 已拒絕
hr_expensespayment_mode[建議]own_account, company_account個人墊付 / 公司帳戶
hr_work_entriesstate[DB]draft, validated, conflict, cancelled草稿 / 已驗證 / 衝突 / 已取消

10.10 MRP 製造模組

欄位約束可接受值說明
mrp_bomstype[DB]normal, phantom, subcontracting一般 / 套件(phantom) / 委外加工
mrp_bomsready_to_produce[DB]all_available, asap全部備料才生產 / 儘速生產
mrp_routing_workcenterstime_mode[DB]auto, manual自動計算 / 手動設定
mrp_productionsstate[DB]draft, confirmed, progress, to_close, done, cancel草稿 / 已確認 / 製造中 / 待結案 / 完成 / 取消
mrp_productionspriority[DB]0, 1一般 / 緊急
mrp_workordersstate[DB]pending, waiting, ready, progress, done, cancel待排程 / 等待物料 / 就緒 / 進行中 / 完成 / 取消
mrp_unbuildsstate[DB]draft, done草稿 / 完成

10.11 專案管理模組

欄位約束可接受值說明
project_projectsprivacy_visibility[DB]portal, employees, followers入口網站可見 / 僅員工 / 僅追蹤者
project_tasksstate[DB]01_in_progress, 1_done, 1_canceled, 04_waiting_normal, 03_approved, 02_changes_requested進行中 / 完成 / 取消 / 等待中 / 已核准 / 需修改
project_taskskanban_state[DB]normal, done, blocked一般 / 就緒 / 受阻
project_taskspriority[DB]0, 1一般 / 緊急
project_task_recurrencesrepeat_unit[DB]day, week, month, year每日 / 每週 / 每月 / 每年
project_task_recurrencesrepeat_type[DB]forever, until, after永久重複 / 至指定日 / 指定次數
project_updatesstatus[DB]on_track, at_risk, off_track, on_hold, done進度正常 / 有風險 / 偏離 / 暫停 / 完成

10.12 公告模組

欄位約束可接受值說明
announcementspriority[建議]normal, high, urgent一般 / 重要 / 緊急
announcementsannouncement_type[建議]bulletin, push公告 / 推播通知
announcementssend_mode[建議]immediate, scheduled立即發送 / 排程發送
announcementssend_status[建議]draft, pending, sent, failed草稿 / 待發送 / 已發送 / 發送失敗
announcementstarget_type[建議]all, tag, level全體 / 指定標籤 / 指定等級
announcementsvalidity_type[建議]permanent, limited永久有效 / 有效期限

10.13 固定資產模組

欄位約束可接受值說明
fixed_assetsstate[DB]draft, running, fully_depreciated, disposed, closed草稿 / 使用中 / 已完全折舊 / 已處分 / 已結案
fixed_assetsdepreciation_method[DB]straight_line, declining_balance, sum_of_years直線法 / 餘額遞減 / 年數合計法
fixed_asset_depreciationsstatus[DB]draft, posted草稿 / 已入帳

10.14 金融/銀行模組

欄位約束可接受值說明
partner_banksaccount_type[DB]bank, iban一般銀行 / IBAN 帳號
partner_bankspartner_type[DB]customer, supplier, member, tenant客戶 / 供應商 / 成員 / 租戶

10.15 核心參考表

欄位約束可接受值說明
uom_uomuom_type[DB]reference, bigger, smaller參考單位 / 較大單位 / 較小單位
countriesname_position[建議]before, after姓名在前 / 姓名在後
currenciesposition[建議]before, after符號在前 / 符號在後
languagesdirection[建議]ltr, rtl左至右 / 右至左
ir_sequencesimplementation[DB]standard, no_gap標準(允許跳號) / 無間隙

10.16 系統管理模組

欄位約束可接受值說明
custom_appsaccess_mode[建議]internal, external, self_built內部應用 / 外部應用 / 自建應用

使用提示

  • 查詢 filter 時,enum 欄位使用 eq 運算子精確比對,例如 {"column": "state", "op": "eq", "value": "draft"}
  • 查詢多個 enum 值可使用 in 運算子,例如 {"column": "state", "op": "in", "value": ["draft", "sent"]}
  • 新增/更新記錄時,[DB] 約束的 enum 欄位必須使用清單中的值,否則會收到 400 / 500 錯誤

11. 第三方應用實戰指南(Best Practices & Gotchas)

[!TIP] 彙整第三方開發者常見痛點,包含資料隔離機制、查詢防呆、遷移腳本與 CI/CD 注意事項。

11.1 多應用共享租戶 (Multi-App Tenant) 的最佳實踐

[!IMPORTANT] 為什麼這很重要? 在 AI GO 系統中,同一個租戶(Tenant)可能同時啟用多套 Custom App(例如:同時有「訂房平台」與「電商商城」),如果不進行資料隔離,使用者的商城頁面就會看見「高級海景房」被當成商品販售。

建議擴充內容

  • Data Domain Separation (App Domain) 策略:強制規範所有使用到共用表(如 product_templatessale_orders)的 Custom App,必須在創建資料時注入識別用的領域標籤(例如 custom_data: { "app_domain": "ec-platform" })。
  • Proxy 層面攔截實作:如果您是在前端實作 API Request 攔截器(Interceptor)或是撰寫了自有的 API Proxy 層,建議在 createlist 動作中,自動幫請求補上 app_domain 的篩選或預設欄位,實現全站「無感隔離」。

11.2 PostgreSQL JSONB 查詢的格式陷阱 (Gotchas)

[!WARNING] 陷阱警告! JSON 序列化後的空格特性,會導致直覺寫法的 ilike 查詢失敗。

建議擴充內容

  • 字串查詢特性:AI GO 將 custom_data 以 JSONB 格式儲存於資料庫中。當您使用開放代理 API (如 /query 端點) 進行 ilike 過濾時,若使用精準的 {"app_domain":"ec-platform"} 作為條件,通常會匹配不到資料。
  • 解決方案:因為 PostgreSQL 在將 JSONB 物件序列化成字串(Text)進行比較時,常在 JSON 冒號後面自動加上空格({"app_domain": "ec-platform"})。因此,建議寫法應為寬鬆字串匹配:
    • 錯誤寫法custom_data::text ilike '%"app_domain":"ec-platform"%'
    • 正確寫法custom_data::text ilike '%app_domain%ec-platform%'

11.3 API Proxy 的安全存取控制 (Access & Auth Models)

[!CAUTION] 某些系統核心表(如 sale_order_lines)擁有底層的硬性權限保護,不允許任意增刪。

建議擴充內容

  • 區分 Open Proxy 與 Ext Proxy:明列哪些場景(如公開型錄讀取)可使用 API Key,哪些場景(如消費者自主結帳)必須強制使用 Bearer Token(Custom App User Token)。
  • Capability Matrix 限制:針對特定的表,即使您有該表的 Delete 引用,如果遇到底層防呆機制(例如:無法刪除已結帳訂單的明細),API 會回應 403 Forbidden 錯誤,請直接導引客戶至「AI GO 管理員介面」進行圖文操作或授權退款。

11.4 資料遷移腳本範例 (Data Migration Boilerplate)

[!TIP] 當應用程式發展至第二階段(例如後期才加入資料隔離網),不可避免需要批量更新舊有歷史資料的 custom_data

Node.js Migration Script 範例: 為了確保向前相容,您可以在本地準備一支批次腳本來自動更新:

const axios = require('axios');
const API_URL = 'https://api.ai-go.app/api/v1/open/proxy/product_templates/query';
const API_KEY = 'sk_live_xxxxxx';

async function migrate() {
    let offset = 0;
    while (true) {
        // 先查出尚無標籤的紀錄 (僅示意,請依實際情況運用)
        const resp = await axios.post(API_URL, {
            limit: 100,
            offset: offset
        }, { headers: { 'X-API-Key': API_KEY } });

        const products = resp.data.data || [];
        if (products.length === 0) break;

        for (const p of products) {
            // 檢查且對每筆舊資料 PATCH 加入 app_domain
            if (!p.custom_data || !p.custom_data.app_domain) {
                await axios.patch(`https://api.ai-go.app/api/v1/open/proxy/product_templates/${p.id}`, {
                    custom_data: { ...(p.custom_data || {}), app_domain: 'ec-platform' }
                }, { headers: { 'X-API-Key': API_KEY } });
            }
        }
        offset += 100;
        console.log(`Migrated batch offset ${offset}`);
    }
}
migrate();

11.5 端到端部署與 CI/CD (E2E Deployment)

建議擴充內容

  • 環境變數同步規範:在將前端應用推播至 Vercel 或 GitHub Actions 進行建置前,請務必再三確認 .env.production 或 CI/CD Secrets 儀表板中的 VITE_API_BASEVITE_APP_SLUGAIGO_API_KEY 皆已正確配置為 Production 環境對應的值。
  • Repository Visibility 提醒:若您使用了 Vercel 的自動化拉取原始碼部署功能(Git Integration),必須賦予 Vercel 應用讀取該 Private GitHub Repository 的權限。若建置過程中發生模組丟失錯誤,請檢查儲存庫權限,或斟酌將原始碼庫設為 Public。