Station Flow 總覽
Station Flow 是工作站流程管理系統。一件要做的事開成一張任務(task),任務依照流程(process)在一個個工作站(station)之間流轉,每一站由綁定的角色負責處理,處理完再選一個出口送往下一站,直到結束。每次換站都會留下一筆流轉紀錄。
工作站像一份合約:規定這一站要做什麼、做完能往哪走。執行的可以是人,也可以是 agent(就是你)。
名詞#
| 名詞 | 一句話解釋 |
|---|---|
| process(流程) | 一條業務流程的藍圖,由多個工作站與它們之間的連線組成。 |
| station(工作站) | 流程裡的一個步驟。每站有說明(execution_instructions)告訴執行者要做什麼。特殊站:開始站(start)、結束站(end)、存查站、異常站(exception)。 |
| transition(轉移、出口) | 從某站往下一站的連線。一站可以有多個出口(例如「核准」「退件」),推進任務時要指定走哪一個。 |
| routine(例行事務) | 把流程套用到實際業務的單位,在這裡決定每一站由哪個角色(role)、哪些人負責;事務負責人(owner)是需求方的窗口。任務一定屬於某個 routine。 |
| task(任務、票) | 實際在流程上跑的一件事,任何時刻都停在某一站(current_station_id)。 |
認證#
- 向你所屬組織的管理者(admin)申請一把 API key。key 以
sfk_開頭,只會顯示一次,請立刻存好,不要寫進程式碼或公開的地方。 - 每個請求都帶這兩個 header:
Authorization: Bearer <你的 API key>
Accept: application/json
注意:是 Authorization: Bearer,不是 X-API-Key。
- 先確認 key 可用:
curl -s -X GET "https://station-flow.staging.quanhox.com.tw/api/v1/auth/me" \
-H "Authorization: Bearer $SF_KEY" -H "Accept: application/json"
成功回 200,內容是你的身份與 key 所屬的組織:
{"data": {"id": 12, "name": "報價助理", "account": "quote-bot", "email": "...", "role": "staff",
"organization": {"id": 3, "role": "staff"}}}
- 一把 key 綁定一個組織,所有操作都只看得到該組織的資料。要操作另一個組織,需要那個組織的 admin 另外發 key。
organization.role是你在這個組織的身份:admin或一般成員(staff)。很多權限看這個值。另有requester(需求方):只能用/r前台留言提需求,API 不開放。
一定要帶 Accept: application/json#
沒帶時,伺服器會把你當成瀏覽器:
- 認證失敗不會回 401 JSON,而是回 302 轉址到網頁登入頁,body 是 HTML。
- 欄位驗證失敗也可能被轉址,而不是回 422 JSON。
看到 302 或 HTML 回應,第一步先檢查這個 header。送 JSON body 時再加 Content-Type: application/json。
回傳格式#
| 情況 | 格式 |
|---|---|
| 讀取、更新成功 | HTTP 200,{"data": ...} |
| 建立成功 | HTTP 201,{"data": ...} |
| 刪除成功 | HTTP 200 {"message": "..."},或 HTTP 204 沒有 body(依端點) |
| 流轉類動作(推進、退回、異常、跳回) | HTTP 200,扁平物件,沒有 data 包裹:{"task_id", "from_station", "to_station", "transition_type", "created_at"} |
| 錯誤 | {"message": "中文說明"};欄位驗證錯誤另帶 {"errors": {"欄位": ["說明"]}} |
時間欄位是 ISO 8601 字串,一律是 UTC:結尾可能是 Z 或 +00:00,秒以下的位數也不固定(例如 2026-10-30T02:00:00.000000Z、2026-10-30T02:00:00+00:00)。請用 ISO 8601 解析器讀,不要用字串比對;要給人看時再自行換算成當地時區。
授權原則#
權限由伺服器依你的身份判斷,不看你在 query 帶了什麼。
- 一般成員(非 admin)查任務清單時,帶
for_user_id=別人會被忽略,伺服器一律只回你自己的。只有 admin 可以查別人。 - 一般成員列 routine 時只看得到自己有角色的 routine。
- 推進、退回、送異常、跳回任務:你必須屬於任務目前所在站綁定的角色,否則 403。這條連 admin 也不例外。
- 建立、修改、刪除流程、刪除任務、管理別人的 key 等管理動作只有 admin 能做,其他人回 403
權限不足。 - 別的組織的資料一律當成不存在,回 404。
所以寫程式時,不要假設「帶了參數就會生效」。收到 403,代表你的身份沒有這個權限,換參數也沒用,請找組織管理者調整角色。
錯誤碼#
| HTTP | 意思 | 常見原因與處理 |
|---|---|---|
| 302 | 被轉址到登入頁 | 沒帶 Accept: application/json。 |
| 401 | 未認證 | key 錯誤、已撤銷,或 header 不是 Authorization: Bearer。message 為 Unauthenticated.。 |
| 403 | 已認證但沒權限 | 你不屬於任務目前站的角色(權限不足:你不屬於『某某』站綁定的角色)、非 admin 做管理動作、key 綁定的組織已停用。 |
| 404 | 不存在 | id 打錯,或資料屬於別的組織。message 如 任務不存在、屬性不存在。 |
| 405 | 方法不允許 | 路徑存在但 method 不對,例如想用 POST 寫流轉紀錄(留言請用留言端點)。 |
| 409 | 狀態衝突 | 任務已被別人認領(claim);或標已讀時帶的版本已過期。重新讀取後再決定。 |
| 410 | 功能已移除 | 打到已下線的舊端點,例如任務層附件的列表/上傳/刪除。照 message 指示改用新做法。 |
| 422 | 驗證失敗或違反業務規則 | 缺必填欄位、transition_id 不屬於目前站、開始站不能退回、出口要求的資料沒補齊等。看 message 與 errors。 |
| 429 | 請求太頻繁 | 有限流的端點超過次數(例如每分鐘 60 次)。等一分鐘再試,並降低輪詢頻率。 |
| 500 | 伺服器錯誤 | 不是你的問題。稍後重試;持續發生請回報組織管理者,附上請求內容與時間。 |
失敗的流轉不會留下紀錄,也不會留下上傳的檔案,修正後直接重送即可。
完整範例:從開票到流轉#
先設定環境變數:
export SF_KEY="<你的 API key>"
H=(-H "Authorization: Bearer $SF_KEY" -H "Accept: application/json")
0. 找到你能開票的 routine
GET /routines 只列出你有角色的 routine,但有角色不代表能開票——開票要屬於開始站綁定的角色。對每個候選 routine 查各站負責角色,找 station_type 是 start 的那一列,確認 role 是你所屬的角色(users 裡有你):
curl -s -X GET "https://station-flow.staging.quanhox.com.tw/api/v1/routines" "${H[@]}"
curl -s -X GET "https://station-flow.staging.quanhox.com.tw/api/v1/routines/1/station-assignees" "${H[@]}"
{"data": [{"station_id": 10, "station_name": "開始", "station_type": "start",
"role": {"id": 24, "name": "業務", "is_auto": false},
"users": [{"id": 12, "name": "報價助理"}]}]}
不要在正式業務的 routine 開測試票。 票一開出來,負責下一站的人或 agent 就會被通知並開始處理。要試 API,請組織管理者給你一個測試用的 routine。
1. 建立任務。 任務一律落在流程的開始站;你必須屬於開始站綁定的角色,否則 403。
curl -s -X POST "https://station-flow.staging.quanhox.com.tw/api/v1/tasks" "${H[@]}" -H "Content-Type: application/json" \
-d '{"routine_id": 1, "name": "A 客戶報價單", "priority": "high"}'
回 201:
{"data": {"id": 57, "name": "A 客戶報價單", "routine_id": 1, "current_station_id": 10,
"current_station_role_id": 24, "process_version": 3,
"priority": "high", "task_deadline_at": null, "station_deadline_at": null, "project": null}}
2. 讀任務與這一站的說明。 current_station.execution_instructions(站說明)和 current_station.process_common_instructions(流程每站共通說明)兩段都要讀,站說明比較具體時以站說明為準。
curl -s -X GET "https://station-flow.staging.quanhox.com.tw/api/v1/tasks/57" "${H[@]}"
3. 查目前站可以走哪些出口
curl -s -X GET "https://station-flow.staging.quanhox.com.tw/api/v1/tasks/57/transitions" "${H[@]}"
{"data": [{"id": 21, "name": "送審", "transition_type": "normal", "to_station_id": 11,
"to_station_name": "主管審核", "tone": "positive", "comment_required": false, "required_data": []}]}
comment_required 為 true 時一定要寫 comment;required_data 不是空的,代表送出前任務上必須先有那些屬性或附件。
4. 推進任務
curl -s -X POST "https://station-flow.staging.quanhox.com.tw/api/v1/tasks/57/transition" "${H[@]}" -H "Content-Type: application/json" \
-d '{"transition_id": 21, "comment": "報價已試算完成,請主管審核"}'
{"task_id": 57, "from_station": "開始", "to_station": "主管審核", "transition_type": "normal",
"created_at": "2026-10-30T02:00:00.000000Z"}
推進後任務到了新站,通常已經不歸你的角色管,之後對它的推進操作會回 403,這是正常的。
5. 查流轉紀錄
curl -s -X GET "https://station-flow.staging.quanhox.com.tw/api/v1/tasks/57/logs" "${H[@]}"
每筆紀錄有 from_station_name、to_station_name、transition_type(normal/rollback/exception/jumpback/comment)、transition_name、transition_tone、is_return、comment、actor、attachments 與 created_at。各欄位說明見任務操作。