主題 6/9:流程設計 API 與設計原則
  1. 總覽:概念、認證與基本用法
  2. 任務操作
  3. 附件:隨流轉上傳、複製與下載
  4. 專案:跨票共享的檔案目錄
  5. 需求方窗口:接需求、開票、回覆
  6. 流程設計 API 與設計原則
  7. 報表:進度、流向、日誌與工作量
  8. 存成 skill 與定期更新
  9. 版本紀錄

流程設計 API 與設計原則

說明怎麼用 API 建流程,以及怎麼設計。任務流轉請看任務相關主題。

名詞#

名詞 是什麼
process(流程) 藍圖:有哪些工作站、站與站怎麼連
station(工作站) 一個階段:進來什麼、要做到什麼、做完往哪走
transition(出口) 從某站往下一站的一條線
routine(例行事務) 把一個流程拿來實際跑的一份套用;誰處理哪一站綁在這層
task(任務) 一張票,在 routine 的各站之間流動

不同團隊跑同一條流程時開新的 routine,不要複製 process。

權限與共通寫法#

  • 讀取(GET):組織內已認證的成員都可以。
  • 新增、修改、刪除:只有組織 admin,其他人回 403 權限不足。
  • 找不到資源回 404,驗證失敗回 422(errors 物件標出哪個欄位)。
export SF_KEY='<你的 API key>'
H=(-H "Authorization: Bearer $SF_KEY" -H "Accept: application/json" -H "Content-Type: application/json")

流程(process)#

端點 用途
GET https://station-flow.staging.quanhox.com.tw/api/v1/processes 列出流程
POST https://station-flow.staging.quanhox.com.tw/api/v1/processes 建立流程(admin)
GET https://station-flow.staging.quanhox.com.tw/api/v1/processes/{id} 流程詳情,含各站與全部出口
PUT https://station-flow.staging.quanhox.com.tw/api/v1/processes/{id} 修改(admin)
DELETE https://station-flow.staging.quanhox.com.tw/api/v1/processes/{id} 刪除(admin)
GET https://station-flow.staging.quanhox.com.tw/api/v1/processes/{id}/diagram 取得 Mermaid 流程圖

欄位:name(必填,組織內不可重複,≤128 字)、standard_days(標準天數)、sort_order、common_instructions(共通說明,見下)。

建立流程時,系統會自動產生四個系統站與兩條預設出口:

  • 系統站:開始(start)、結束(end)、存查(archive)、異常(exception)。系統站不能刪除。
  • 預設出口:開始 → 結束、結束 → 存查。
curl -s -X POST "https://station-flow.staging.quanhox.com.tw/api/v1/processes" "${H[@]}" \
  -d '{"name":"請假申請","standard_days":3}'

流程詳情的 data.transitions 攤平列出全部出口,查串線看這份。

共通說明(common_instructions)#

每一站都適用的規則,改了直接生效。站的詳情會並列回傳站自己的 execution_instructions 與流程的 process_common_instructions。

curl -s -X PUT "https://station-flow.staging.quanhox.com.tw/api/v1/processes/12" "${H[@]}" \
  -d '{"common_instructions":"動手前先讀票上最新留言。"}'

工作站(station)#

端點 用途
GET https://station-flow.staging.quanhox.com.tw/api/v1/processes/{processId}/stations 列出某流程的站
POST https://station-flow.staging.quanhox.com.tw/api/v1/processes/{processId}/stations 新增站(admin)
GET https://station-flow.staging.quanhox.com.tw/api/v1/stations/{id} 站的詳情,含出口與共通說明
PUT https://station-flow.staging.quanhox.com.tw/api/v1/stations/{id} 修改站、串線(admin)
DELETE https://station-flow.staging.quanhox.com.tw/api/v1/stations/{id} 刪除站(admin;系統站回 422)

主要欄位:

欄位 說明
name 站名,建立時必填
type 新增時只能是 normal(可省略)
description 這站是什麼、為什麼存在(≤2000 字)
execution_instructions 執行者照著做的步驟
standard_days、sort_order、entry_criteria、entry_data、exit_data、checklist、notes 標準天數、排序與其他文字欄位
next_action_template 選填 JSON 物件,給自動化執行者的出口提示
next_station_ids 下一站 id 陣列,用來建立或刪除出口
next_station_names 出口命名,key = 目標站 id,value = 出口名稱
previous_station_ids 上一站 id 陣列,從反方向接線

PUT https://station-flow.staging.quanhox.com.tw/api/v1/stations/{id} 是部分更新:沒帶的欄位保留原值,串線時不必把整站資料帶回去。

# 新增一站,同時接在「開始」(id 40) 後面、往「結束」(id 42) 走
curl -s -X POST "https://station-flow.staging.quanhox.com.tw/api/v1/processes/12/stations" "${H[@]}" \
  -d '{"name":"主管審核","sort_order":10,"previous_station_ids":[40],
       "next_station_ids":[42],
       "execution_instructions":"確認假別與天數,核可選「核可」,不核可選「退回補件」。"}'

出口(transition)#

出口類別#

類別 怎麼設 用途
正常 normal 出口,tone: positive(預設) 往前推進;一站可有多條
退回 normal 出口,tone: negative,回傳 is_return: true 依原因退到指定站(任意站)
系統動作 不用設定 每站都有:rollback(退回流轉歷史的前一站)、exception(送異常站)、jumpback(從異常站跳回指定站)。執行時呼叫任務端點,不會出現在出口清單

設定的出口都是 transition_type: normal;找退回類出口看 is_return。「放棄/不做」不算退回,設成正常。

建立、刪除、命名:透過工作站#

出口沒有獨立的新增端點,用 PUT https://station-flow.staging.quanhox.com.tw/api/v1/stations/{id} 處理:

帶的欄位 效果
next_station_ids(可加 next_station_names) ids 是這站完整的出口清單:多的新增、少的刪除,再依 names 命名
只帶 next_station_names 只改既有出口的名稱,不動連線。指向沒有出口的站回 422
只帶 next_station_ids 增刪連線,既有的自訂名稱保留

未命名的出口叫「完成」。

curl -s -X PUT "https://station-flow.staging.quanhox.com.tw/api/v1/stations/43" "${H[@]}" \
  -d '{"next_station_ids":[42,44],
       "next_station_names":{"42":"核可","44":"退回補件"}}'

限制:

  • 不能指向自己、別的流程的站、「存查」或「異常」(422)。「結束 → 存查」是系統線,不能改名,刪掉就補不回來。
  • 存查、異常不能當來源;開始、存查、異常不能用 previous_station_ids 指派上一站。

讀取、設定細節、刪除單條#

端點 用途
GET https://station-flow.staging.quanhox.com.tw/api/v1/stations/{stationId}/transitions 某站的全部出口
GET https://station-flow.staging.quanhox.com.tw/api/v1/transitions/{id} 單條出口
PUT https://station-flow.staging.quanhox.com.tw/api/v1/transitions/{id}(PATCH 也可以) 設定名稱、類別、必填意見、必附資料、排序(admin)
DELETE https://station-flow.staging.quanhox.com.tw/api/v1/transitions/{id} 刪除單條 normal 出口(admin)

PUT/PATCH 欄位,name、tone、comment_required、required_data 至少帶一個:

  • name(≤128 字)、sort_order;tone:positive/negative;comment_required:true 時走這個出口必須留言。
  • required_data:走這個出口前票上必須有的資料,最多 10 項,帶 null 清空。只在正常流轉時檢查,rollback、exception、jumpback 不檢查。缺資料時流轉回 422,錯誤在 errors.required_data。

required_data 每項的格式:

type 欄位
attribute label(≤64 字)、key(票屬性 key,^[a-z0-9_.-]{1,64}$)、optional、選填 format(date)、pattern(正規表示式)
attachment label、patterns(1–5 個檔名樣式,可用 {屬性key} 代入票屬性)、min(1–10,預設 1)、scope、optional
project label;票必須綁專案,不能設成選填

附件的 scope:task(預設,票上任何時候附過都算)、transition(只算這次流轉附的)、station_visit(只算這次進站後附的)。退件後要交新版的出口用 station_visit。

curl -s -X PATCH "https://station-flow.staging.quanhox.com.tw/api/v1/transitions/88" "${H[@]}" \
  -d '{"tone":"negative","comment_required":true,
       "required_data":[{"type":"attribute","label":"假別","key":"leave_type"}]}'

刪除單條:只能刪 normal,開始站最後一個出口不能刪(422)。

Mermaid 流程圖#

GET https://station-flow.staging.quanhox.com.tw/api/v1/processes/{id}/diagram 回 {"mermaid":"graph TD ..."}。節點 id 是 S<站 id>;正常出口畫實線,退回出口畫虛線並標名稱。執行時的 rollback、exception、jumpback 不畫。

curl -s "https://station-flow.staging.quanhox.com.tw/api/v1/processes/12/diagram" "${H[@]}"

例行事務(routine)#

端點 用途
GET https://station-flow.staging.quanhox.com.tw/api/v1/routines 列表;admin 可加 ?for_user=me 或 ?for_user=<user id> 只看某人有角色的;非 admin 一律只看到自己有角色的
POST https://station-flow.staging.quanhox.com.tw/api/v1/routines 建立(admin):name(必填,組織內不可重複)、process_id(必填)、description、sort_order、owner_user_id(事務負責人,省略=建立者)
GET https://station-flow.staging.quanhox.com.tw/api/v1/routines/{id} 詳情,含角色清單
PUT https://station-flow.staging.quanhox.com.tw/api/v1/routines/{id} 修改 name、description、sort_order、owner_user_id(admin)
DELETE https://station-flow.staging.quanhox.com.tw/api/v1/routines/{id} 刪除(admin)

事務負責人(owner_user_id)是需求方的窗口(一位、須為組織成員),自動是開始、結束、異常站的處理者,並負責存查;換人時四站換掉舊的、其他人不動。詳情回 owner({id, name} 或 null),任務詳情回 routine_owner。

curl -s -X POST "https://station-flow.staging.quanhox.com.tw/api/v1/routines" "${H[@]}" \
  -d '{"name":"2026 請假","process_id":12}'

每站指派處理者#

任務只有該站綁定角色的成員能推進,admin 也一樣。開始站的角色決定誰能開票(POST https://station-flow.staging.quanhox.com.tw/api/v1/tasks 不在開始站角色裡回 403)。有兩種做法,可以混用。

做法一:每站直接指派(建議)#

端點 用途
GET https://station-flow.staging.quanhox.com.tw/api/v1/routines/{routineId}/station-assignees 流程現行版本的每一站一列:station_id、station_name、station_type、role(id、name、is_auto,沒綁是 null)、users
PUT https://station-flow.staging.quanhox.com.tw/api/v1/routines/{routineId}/stations/{stationId}/assignees 指派(admin);body {"user_ids":[...]},空陣列 = 取消指派

系統自動建角色(「<站名> 處理者」),成員相同就共用,沒綁站就自動刪。user_ids 必須是組織成員,否則 422。

curl -s -X PUT "https://station-flow.staging.quanhox.com.tw/api/v1/routines/7/stations/43/assignees" "${H[@]}" \
  -d '{"user_ids":[5,9]}'

做法二:手動角色(同一組人管多站時)#

端點 用途
GET https://station-flow.staging.quanhox.com.tw/api/v1/routines/{routineId}/roles / POST https://station-flow.staging.quanhox.com.tw/api/v1/routines/{routineId}/roles 列出/建立角色(name、sort_order)
PUT https://station-flow.staging.quanhox.com.tw/api/v1/roles/{id} / DELETE https://station-flow.staging.quanhox.com.tw/api/v1/roles/{id} 改名/刪除角色
GET https://station-flow.staging.quanhox.com.tw/api/v1/roles/{id}/users 角色成員
POST https://station-flow.staging.quanhox.com.tw/api/v1/roles/{id}/users 加成員:{"user_id":5}(已在角色或不屬於組織回 422)
DELETE https://station-flow.staging.quanhox.com.tw/api/v1/roles/{id}/users/{userId} 移除成員
GET https://station-flow.staging.quanhox.com.tw/api/v1/routines/{routineId}/station-roles / POST https://station-flow.staging.quanhox.com.tw/api/v1/routines/{routineId}/station-roles 列出/建立站與角色的綁定:{"station_id":43,"role_id":3};一站只綁一個角色,重複回 422
PUT https://station-flow.staging.quanhox.com.tw/api/v1/station-roles/{id} / DELETE https://station-flow.staging.quanhox.com.tw/api/v1/station-roles/{id} 換綁的角色(role_id)/解除綁定

寫入都要 admin。讓系統站少了事務負責人的寫入(含成員、角色、綁定)一律 422 且不生效。手動角色和舊資料的「流程負責人」角色不會被自動刪除;換人只改角色成員,綁這個角色的站一起生效。

設計原則#

切站:換手才開站#

一個站至少要符合下面一條才值得存在,都不符合就併進前一站:

  1. 責任換手:下一段的執行者可能跟這段不同(看「可能」,不是看現在誰在做)。
  2. 要有人拍板才能繼續。
  3. 要等外部回覆或排程,票停在這裡是合理的。
  4. 這一段的耗時需要單獨看得出來。

站名寫「在做什麼」(審核),不寫「誰」,因為人會換。

人站與 agent 站#

  • 判斷偏好、承擔後果的給人(定方向、驗收、對外承諾、花錢、不可逆動作);照既定標準執行的給 agent(拆規格、實作、測試、彙整、歸檔)。
  • 先假設 agent 做得到,答不出「agent 憑什麼替他決定」才改成人站。人站要少而集中,例如前面拍板一次、後面驗收一次。
  • 會自動撿票的 agent 不要跟人共用角色,否則 agent 會撿到該角色所有站的票。

出口#

  • 有兩個以上出口的站一定要命名。名稱寫「選這條會發生什麼」,不寫「去哪一站」。
  • 打回上一站重做用系統的 rollback,不要另拉一條反向線。要依原因退到不同站時才建退回出口(tone: negative),並開 comment_required。
  • 送異常是給事務負責人決定票回哪一站;要跳好幾站回去或要特別處理時才用。
  • 「選 X 之前一定要有 Y」用 required_data 擋。只設「選這條時一定有值」的資料,可能合法空白的設下去,票會永遠送不出去。設之前先查停在這站的票缺不缺。
  • 給 agent 撿的站,出口名只用文字、數字、-、_,不放標點和空白,比對才不會出錯。

說明怎麼寫#

  • execution_instructions 只寫「選『核可』」「選退回」,不寫「推進到 X 站」。線會改,寫死的站名漏改不會報錯,執行者只會照錯的做。
  • 執行者通常只看當前站的說明。每站都要遵守的規則寫進 common_instructions,或在每站重寫一次。
  • 決策站寫明「撿到票就要選一個出口;拿不準就退回並寫明要改什麼」。要交檔案的站寫「流轉時附上 X」。

需求不清楚時先訪談#

除非開票時規格就完整,開始站後第一站做成「需求訪談」:問清楚目標、現有資料、限制,整理成文件附在票上,審核站要有退回訪談站的出口。先畫草圖讓需求方回「對/不對/哪裡改」,不要丟大問卷。

建置順序#

  1. POST https://station-flow.staging.quanhox.com.tw/api/v1/processes:自動產生四個系統站與預設出口。
  2. POST https://station-flow.staging.quanhox.com.tw/api/v1/processes/{processId}/stations:逐站建立。sort_order 留間隔(10、20、30),之後插站不用重編。
  3. PUT https://station-flow.staging.quanhox.com.tw/api/v1/stations/{id}:用 next_station_ids 串線,多出口時一起帶 next_station_names。
  4. PUT https://station-flow.staging.quanhox.com.tw/api/v1/transitions/{id}:設定退回類別、必填意見、必附資料。
  5. POST https://station-flow.staging.quanhox.com.tw/api/v1/routines:建例行事務,owner_user_id 帶真正的需求方窗口(四個系統站會自動有他)。
  6. 指派每一個會停票的站;四個系統站需要別人一起處理時再加協作者。
  7. GET https://station-flow.staging.quanhox.com.tw/api/v1/processes/{id}/diagram 看整條線,GET https://station-flow.staging.quanhox.com.tw/api/v1/routines/{routineId}/station-assignees 確認沒有 role: null 的站。

常見地雷#

  • owner 為 null 的舊 routine 系統站可能沒人:漏綁「結束」無法歸檔,漏綁「存查」撤不回來。
  • 負責人預設是建立者,通常不是真正的窗口;建立時就帶 owner_user_id。
  • 票一律從開始站建立。開始站綁會開票的委託方(或代表委託方的窗口),不是處理方。
  • 上線前用一張真實的票走完全程,並實際走一次 rollback 或 exception → jumpback。「票開得出來」不等於能上線。
  • 交給 agent 的站,先確認那個 agent 真的會定期查自己的待辦,否則票會停著沒人撿。