專案(projects)
一個專案是一棵有版本的檔案樹,放「完成品與跨票共用的資訊」,例如定稿的人設圖、風格包、每集成品、要避開的題目清單。 草稿和中間產物仍然當票的流轉附件(見「附件」主題),只有定稿才寫進專案。
所有請求都要帶:
Authorization: Bearer <你的 API key>
Accept: application/json
路徑裡的 {code} 可以填專案代號(例如 lin-manman),也可以填數字 id。
權限#
權限只看專案成員名單,跟票目前在哪一站無關。等級由低到高:
| 等級 | 是誰 |
|---|---|
read(可讀) |
成員 |
write(可寫) |
成員 |
owner(負責人) |
專案負責人,只有一位,不在成員名單裡 |
admin(組織管理員) |
組織 admin,所有專案全權 |
每個動作至少要哪一級:
動作(can 的 key) |
最低等級 | 包含 |
|---|---|---|
view |
read | 讀專案資訊、列目錄、搜尋、讀檔與舊版 |
write_files |
write | 新增檔、寫新版、改檔案說明標籤、搬移、刪除/還原、建刪目錄 |
manage_members |
owner | 改成員名單、看完整成員名單 |
edit_settings |
owner | 改專案說明、一句話說明、標籤、保留規則 |
view_audit |
owner | 看稽核紀錄 |
rename |
owner | 改專案名稱 |
archive |
owner | 封存/解除封存 |
export |
owner | 匯出 zip |
transfer_owner |
admin | 轉交負責人 |
delete |
admin | 刪除專案 |
import |
admin | 匯入專案 |
create |
admin | 建立專案(組織層級;can.create 在每個專案都會回,值只看你是不是 admin) |
- 不要自己比等級:
GET https://station-flow.staging.quanhox.com.tw/api/v1/projects與專案詳情都會回my_access(你是哪一級)和can({動作: true/false}),要不要做某件事看can。等級表之後可能調整,can會跟著變。 - 不是成員、專案不存在、屬於別的組織:一律 404(刻意不區分,不洩漏專案是否存在)。
- 等級不夠:403,
message寫明需要哪一級(例如「此操作需要「負責人」以上權限」)。 - 專案已封存:寫檔與改專案設定(
write_files、edit_settings、rename、transfer_owner)一律 423,讀取照常;這時can裡這幾項也是 false。
讀#
| 端點 | 說明 |
|---|---|
GET https://station-flow.staging.quanhox.com.tw/api/v1/projects |
我看得到的專案。?status=active(預設)/archived/all |
GET https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code} |
專案說明(description)、tags、保留規則、member_count、my_access |
GET https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files |
列目錄。?prefix=資料夾路徑 只列那一層;?recursive=1 遞迴;?deleted=1 列已軟刪的檔 |
GET https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/search |
依檔名、說明、標籤找候選檔與目錄。?q=關鍵字、?tag=標籤(至少給一個)、?limit=(預設 10,最多 50),依 score 排序 |
GET https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files/by-path |
?path=a/b.md 依路徑找。檔案被搬走時仍回 200,多帶 redirected_from(舊路徑) |
GET https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files/{id} |
檔案 metadata 與 versions 版本清單 |
GET https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files/{id}/content |
讀內容,預設最新版;?version=N 讀舊版;?inline=1 預覽 |
列目錄的回應:data 是檔案陣列(id、path、description、tags、current_version、size、mime_type、updated_at、updated_by),folders 是子目錄路徑字串陣列,folder_details 帶每個目錄的 readme_file_id 與 readme_summary。
讀內容的回應 header X-File-Version 是這次讀到的版本號,寫回時要帶這個值。inline、Range、nosniff 的規則和流轉附件下載相同。舊版可能已依專案的保留規則刪除,此時回 404「版本不存在」。
建議的找檔順序#
- 先讀根目錄或目標目錄的
README.md(擺放規則)。 - 用
search依用途標籤或關鍵字找候選。 - 讀 metadata 判斷要用哪一個。
- 讀 content。
記檔案 id,不要寫死路徑:路徑會因為搬移、改名而變,檔案 id 不會變。找不到檔時不要讓票卡住,照站說明處理(例如在票上留言列出搜尋過的關鍵字)。
md 裡的內嵌圖片#
在網頁上預覽專案裡的 .md 檔時, 會顯示成專案裡的圖片:
- 相對路徑以這個 md 檔所在的目錄為基準解析,可用
./、../。例如docs/spec.md裡寫,對應專案內的docs/img/flow.png。 - 圖片要一起上傳到同一個專案,路徑對得上才會顯示。
- 只顯示圖片(PNG、JPEG、GIF、WebP)。找不到檔、不是圖片、或路徑跑出專案根目錄時,顯示灰框「圖片不存在:路徑」。
http(s)://開頭或/開頭的網址不會改寫,照原樣顯示。- 這只影響網頁預覽;用 API 讀內容拿到的仍是 md 原文。
寫(需要 write)#
| 端點 | 說明 |
|---|---|
POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files |
新增檔,回 201。路徑已存在回 409 |
POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files/{id}/content |
寫新版,base_version 必填 |
PATCH https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files/{id} |
只改 description/tags,不產生新版 |
POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files/{id}/move |
{"path":"新路徑","base_version":N}。id 不變,舊路徑留轉址 |
DELETE https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files/{id} |
軟刪除 |
POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files/{id}/restore |
還原軟刪除的檔;原路徑已被佔用回 409 |
POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/folders |
{"path":"…","readme":"…"} 建目錄(上層自動補建);帶 readme 會同時建 README.md。已存在回 409 |
DELETE https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/folders |
?path=…,只能刪空目錄,否則 409 |
POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/folders/move |
{"from":"…","to":"…"} 整個目錄搬移或改名;有任何衝突回 409,整批不搬 |
新增檔與寫新版的欄位#
| 欄位 | 說明 |
|---|---|
path |
只有新增時要給。1–512 字,用 / 分層;不可用 / 開頭或結尾,不可有空段、.、..、反斜線、控制字元;每段最長 128 字;大小寫有別 |
base_version |
只有寫新版時要給,填你讀到的 X-File-Version |
| 內容(三選一) | multipart file(≤ 20 MB);upload_id(大檔分段上傳);from_attachment_id(同組織某張票的附件,做快照,不重複佔空間) |
description |
選填,≤ 200 字 |
tags[] |
選填,必須是專案 tags 裡已定義的標籤,否則 422 |
task_id |
選填。帶了會記在這個版本上(哪張票寫的);這張票必須綁在同一個專案,否則 422 |
note |
選填,≤ 500 字,版本備註 |
- 用 multipart 傳檔一定要用 POST;寫新版的路由也接受 PUT,但只適用於 JSON body(
upload_id、from_attachment_id)。 - 寫入的檔案若是文字類且 ≤ 5 MB,會先掃描是否含密鑰(API key、
sk-、AKIA…、私鑰等),命中回 422「內容疑似包含密鑰」。密鑰不要放進專案。
版本號樂觀鎖#
寫新版與搬移都要帶 base_version。如果它不是目前最新版,回 409:
{"message":"檔案已被更新,請重讀最新版","current_version":5,"updated_by":12,"updated_at":"2026-10-30T02:15:00+00:00"}
收到 409:重讀最新版 → 把你的改動合併進去 → 用新的版本號再寫一次。不要直接拿 current_version 重送,那會蓋掉別人的改動。
# 讀最新版並記下版本號
curl -s -D headers.txt -o draft.md "https://station-flow.staging.quanhox.com.tw/api/v1/projects/lin-manman/files/12/content" \
-H "Authorization: Bearer $SF_KEY" -H "Accept: application/json"
V=$(grep -i '^x-file-version' headers.txt | tr -dc 0-9)
# 改完寫回
curl -s -X POST "https://station-flow.staging.quanhox.com.tw/api/v1/projects/lin-manman/files/12/content" \
-H "Authorization: Bearer $SF_KEY" -H "Accept: application/json" \
-F base_version=$V -F task_id=230 -F "note=第 3 集定稿" -F "file=@draft.md"
成功回 {"data":{"file":{…},"version":{"version":6,"size":…,"sha256":…,"task_id":230,"note":…}}}。
大檔:分段上傳(> 20 MB,最大 2 GB)#
POST https://station-flow.staging.quanhox.com.tw/api/v1/uploads,body{"total_size":<bytes>,"sha256":"<選填>"}→ 回id、part_size、part_count、expires_at。- 每一段
PUT https://station-flow.staging.quanhox.com.tw/api/v1/uploads/{id}/parts/{n},body 是該段原始位元組,n從 1 開始;除最後一段外每段大小必須剛好是part_size。 POST https://station-flow.staging.quanhox.com.tw/api/v1/uploads/{id}/complete→ 回upload_id。- 用
upload_id呼叫新增檔或寫新版。
- 只有建立這個 upload 的本人能用,別人一律 404。逾期(24 小時)回 410;放棄可
DELETE https://station-flow.staging.quanhox.com.tw/api/v1/uploads/{id}。 - 主機磁碟可用空間不足時,建立 upload 回 507,請稍後再試或通知組織管理員。
票與專案#
GET https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}、GET https://station-flow.staging.quanhox.com.tw/api/v1/me/tasks、GET https://station-flow.staging.quanhox.com.tw/api/v1/routines/{routineId}/tasks每張票都有project: {id, code, name, status}或null。null表示這張票沒有綁專案,照原本做法跑即可。- 開票時綁:
POST https://station-flow.staging.quanhox.com.tw/api/v1/tasks帶project(代號或 id)。要開「衍生票」改帶from_task_id,會沿用來源票的專案(來源票沒綁就不綁)。兩個都帶回 422。專案必須是 active,而且你至少有 read 權,否則 422「專案不存在、已封存或你沒有權限」。 - 事後改:
PUT https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/project,body{"project":"lin-manman"}。只有票在開始站、而且你屬於該站綁定的角色時可以改;不在角色回 403,不在開始站回 422。 - 出口必填專案:流程設計者可在出口的
required_data加{"type":"project","label":"專案"}。票沒有專案或專案已封存時,走這個出口回 422,missing[].type為project。 - 專案檔附到票上:流轉四端點與留言端點都收
copy_project_files: [{"file_id":12,"version":3}](version省略=最新版),做成快照附件,附件帶copied_from_project_file。你要有該專案的 read 權。 - 票附件存回專案:
POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/files帶from_attachment_id+task_id(+path)。
讀寫原則#
一般站只讀。只有產出最終成品或跨票資訊的站(例如歸檔、交付)才寫回專案;寫入時順便更新所在目錄的 README.md 與檔案的 description,讓下一個讀的人找得到。
管理端點#
各端點要的等級見上面的動作表:
POST https://station-flow.staging.quanhox.com.tw/api/v1/projects建立:只限組織 admin(其他人 403「只有組織管理員可以建立專案」)。owner_user_id指定負責人,沒帶就是 admin 自己。members不能包含負責人本人(422)。PATCH https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}改設定:name要rename;owner_user_id要transfer_owner;description/summary/tags/retention 要edit_settings;代號不可改。- 轉交負責人(
PATCH帶owner_user_id):新負責人必須是組織成員,而且不能是現任負責人(422「新負責人不能是目前的負責人」,不會記owner_transfer)。轉交只限 admin;轉交後原負責人自動以write留在成員名單,新負責人如果原本是成員就移出名單;稽核記一筆owner_transfer。 PUT https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/members整包覆寫成員名單,access只能填read/write(其他值含manage一律 422);名單不能包含負責人本人(422)。POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/archive/POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/unarchiveGET https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/export匯出 zip;POST https://station-flow.staging.quanhox.com.tw/api/v1/projects/import匯入(只限 admin)DELETE https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}:只限 admin;必須先封存,且最後一次寫入後已匯出過,否則 422GET https://station-flow.staging.quanhox.com.tw/api/v1/projects/{code}/audit稽核紀錄
錯誤碼#
| HTTP | 意思 | 怎麼處理 |
|---|---|---|
| 403 | 等級不夠(message 寫明需要哪一級)、改票專案時不在目前站角色 |
先看 can;需要更高權限請專案負責人或組織管理員調整成員;不要借用別人的 key |
| 404 | 專案或檔案不存在、你不是成員、屬於別組織(刻意不區分)、指定版本已刪除 | 先 GET https://station-flow.staging.quanhox.com.tw/api/v1/projects 確認看得到這個專案 |
| 409 | base_version 過期、路徑已存在、目錄不是空的、搬移或還原衝突 |
重讀最新版再寫;路徑衝突就換名字或改用寫新版 |
| 410 | 分段上傳已逾期 | 重新開一個 upload |
| 422 | 欄位驗證失敗、轉交給現任負責人、成員名單含負責人、成員等級不是 read/write、標籤不在專案清單、內容疑似含密鑰、task_id 不是本專案的票、刪除前未封存或未匯出 |
依 message/errors 修正 |
| 423 | 專案已封存,檔案唯讀 | 讀照常;需要寫入請負責人或組織管理員解除封存 |
| 507 | 主機磁碟空間不足,拒收大檔上傳 | 稍後再試並通知組織管理員 |