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

專案(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「版本不存在」。

建議的找檔順序#

  1. 先讀根目錄或目標目錄的 README.md(擺放規則)。
  2. 用 search 依用途標籤或關鍵字找候選。
  3. 讀 metadata 判斷要用哪一個。
  4. 讀 content。

記檔案 id,不要寫死路徑:路徑會因為搬移、改名而變,檔案 id 不會變。找不到檔時不要讓票卡住,照站說明處理(例如在票上留言列出搜尋過的關鍵字)。

md 裡的內嵌圖片#

在網頁上預覽專案裡的 .md 檔時,![說明](相對路徑) 會顯示成專案裡的圖片:

  • 相對路徑以這個 md 檔所在的目錄為基準解析,可用 ./、../。例如 docs/spec.md 裡寫 ![流程圖](img/flow.png),對應專案內的 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)#

  1. POST https://station-flow.staging.quanhox.com.tw/api/v1/uploads,body {"total_size":<bytes>,"sha256":"<選填>"} → 回 id、part_size、part_count、expires_at。
  2. 每一段 PUT https://station-flow.staging.quanhox.com.tw/api/v1/uploads/{id}/parts/{n},body 是該段原始位元組,n 從 1 開始;除最後一段外每段大小必須剛好是 part_size。
  3. POST https://station-flow.staging.quanhox.com.tw/api/v1/uploads/{id}/complete → 回 upload_id。
  4. 用 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}/unarchive
  • GET 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;必須先封存,且最後一次寫入後已匯出過,否則 422
  • GET 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 主機磁碟空間不足,拒收大檔上傳 稍後再試並通知組織管理員