附件
Station Flow 的附件一律掛在某一筆流轉紀錄(task log)上,沒有獨立的「上傳附件到任務」動作。 要交檔,就在推進、退回、進異常、跳回或留言的那一次請求裡一起送檔案。
所有請求都要帶:
Authorization: Bearer <你的 API key>
Accept: application/json
哪些端點可以帶附件#
| 端點 | 用途 | comment |
|---|---|---|
POST https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/transition |
走一個出口推進 | 出口設了 comment_required 時必填 |
POST https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/rollback |
退回上一站 | 必填 |
POST https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/exception |
送進異常站 | 必填 |
POST https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/jumpback |
從異常站跳回 | 必填 |
POST https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/comments |
只留言、不推進 | 只帶 files[] 時必填;只帶複製參數時可省略 |
授權照各端點原本的規則:流轉要屬於目前站綁定的角色;留言比較寬,目前站角色或曾經處理過這張票的人都可以(GET https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id} 回的 can_comment 就是這個判斷結果)。
上傳檔案:multipart files[]#
不帶檔案時,上面這些端點收一般 JSON body。要附檔就改送 multipart/form-data,原本的欄位(transition_id、comment、target_station_id…)照樣用 form 欄位送,檔案放 files[]:
- 一次 0–10 個檔,單檔 ≤ 20 MB。
- 超過會回 422,例如「附件最多 10 個」「第 N 個附件超過 20 MB」。
- 檔案和那筆流轉紀錄寫在同一個交易裡:流轉失敗(403、422)就不會留下任何檔案,也不會寫紀錄。
curl -s -X POST "https://station-flow.staging.quanhox.com.tw/api/v1/tasks/55/transition" \
-H "Authorization: Bearer $SF_KEY" -H "Accept: application/json" \
-F transition_id=12 \
-F "comment=附上初稿與截圖" \
-F "files[]=@draft.pdf" \
-F "files[]=@screen.png"
- 檔案要附在 multipart 裡就一定要用 POST(這五個端點本來就是 POST)。
- 某些代理伺服器對
Expect: 100-continue處理不好,大檔上傳卡住時可加-H "Expect:"。
任務層附件端點已下線(410)#
以下三個舊端點保留路徑,但一律回 410 Gone(就算沒帶認證也是 410):
GET https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/attachmentsPOST https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/attachmentsDELETE https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/attachments/{attachmentId}
回應的 message 是「任務層附件已移除,請在流轉時附檔(files[])…」,並指引你到流轉紀錄的 attachments 找附件。
附件屬於流轉歷史,不能刪除、不能修改。要交新版就在下一次流轉或留言時再附一次。
查看一張票有哪些附件#
GET https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/logs 與 GET https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id} 的每一筆 log 都有 attachments 陣列(沒有就是空陣列):
{
"id": 1498,
"name": "draft.md",
"size": 10240,
"mime_type": "text/plain",
"previewable": true,
"copied_from_task_id": null,
"copied_from_attachment_id": null,
"copied_from_project_file": null,
"sha256": "9f2c..."
}
mime_type由伺服器依檔案內容判斷,不是看副檔名。例如.md、.yaml、短的.csv常被判成text/plain。sha256:新上傳的檔都有;很舊的資料可能是null。copied_from_*:這個附件是複製來的才有值,見下一節。
跨票複製附件#
把別張票(或專案)的檔做成本筆 log 的附件。五個可帶附件的端點都收以下參數,JSON 或 multipart 都可以,也能和 files[] 一起用:
| 參數 | 說明 |
|---|---|
copy_attachment_ids[] |
直接指定同組織任一張票的 attachment id |
copy_from_task_id + copy_from_station_name |
取來源票最後一次離開該站那筆流轉(不含留言)上的全部附件。站名可用流轉當時的名字或該站現在的名字 |
copy_from_task_id + copy_from_station_id |
同上,改用站 id 指定(不受改名影響;站必須屬於來源票的流程) |
copy_project_files |
專案檔,[{"file_id":12,"version":3}],version 省略就是最新版。詳見「專案」主題 |
規則:
copy_from_station_name與copy_from_station_id只能擇一;指定來源站時一定要有copy_from_task_id,反之亦然。- 幾組參數可以並用,同一個來源附件只算一次。合併後一次最多 100 個。
- 複製的檔不受單檔 20 MB 限制,也不重複佔空間。
- 這是快照:來源票之後交了新版,已複製的附件不會跟著變;來源票刪掉,複本仍可下載。
- 來源只要求同組織看得到;本票照原本的流轉/留言授權。
- 留言只帶複製參數時,
comment可省略,系統會寫「複製自 #來源票」。 - 來源 log 找到了但上面沒有附件時,複製 0 個,不會報錯。
- 如果目前出口設了「必附附件」,複製進來的檔和這次上傳的檔一樣算數。
以下情況回 422,整筆不寫 log、不留檔:
errors 欄位 |
訊息 |
|---|---|
copy_attachment_ids |
附件 #N 不存在或不屬於本組織 |
copy_from_task_id |
來源任務 #N 不存在或不屬於本組織 |
copy_from_station_name |
來源任務 #N 沒有離開『站名』的流轉紀錄 |
copy_from_station_id |
來源任務 #N 的流程沒有站 id S / 沒有離開該站的流轉紀錄 |
copy_project_files |
專案檔 #N 不存在或你沒有讀取權限 / 沒有第 V 版 |
範例:在票 #57 留言,帶入票 #42 最後一次離開「交付」站時附的所有檔:
curl -s -X POST "https://station-flow.staging.quanhox.com.tw/api/v1/tasks/57/comments" \
-H "Authorization: Bearer $SF_KEY" -H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"copy_from_task_id":42,"copy_from_station_name":"交付"}'
複製後的附件帶 copied_from_task_id、copied_from_attachment_id(直接來源,來源刪除後數字仍保留);從專案複製的則帶 copied_from_project_file: {project_code, file_id, version}。
下載與預覽#
GET https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/attachments/{attachmentId}
- 只要同組織看得到這張票就能下載。
- 一定要用附件所在那張票的 id。用 A 票的路徑抓 B 票的 attachment id 會回 404;複製來的附件請用本票路徑抓本票上的 attachment id。
- 預設回
Content-Disposition: attachment(下載),支援中文檔名。 - 加
?inline=1:只有previewable: true的檔會回inline;其他型別(svg、html、zip…)一律仍是 attachment。 - 文字類檔案帶
?inline=1時Content-Type一律是text/plain; charset=utf-8;不帶 inline 時維持原 mime。 - 支援 HTTP Range:帶
Range: bytes=0-1023回 206 與Content-Range;範圍完全超出回 416。 - 所有下載都帶
X-Content-Type-Options: nosniff。
previewable 的判斷:
- 直接預覽:
image/png、image/jpeg、image/gif、image/webp、application/pdf、audio/mpeg、video/mp4。 - 以純文字預覽:
text/plain、text/csv、text/markdown、application/json、yaml 類 mime;另外副檔名是 txt/json/yaml/yml/md/markdown/csv/log、且內容被判成任何text/*的也算。 - 二進位檔不會因為副檔名改成
.json就變成可預覽。
curl -s -o draft.md "https://station-flow.staging.quanhox.com.tw/api/v1/tasks/57/attachments/1498" \
-H "Authorization: Bearer $SF_KEY" -H "Accept: application/json"
常見錯誤#
| HTTP | 情況 | 怎麼處理 |
|---|---|---|
| 403 | 不屬於目前站角色(流轉)或沒有留言權 | 確認票目前在哪一站、你是否被指派 |
| 404 | 任務不存在、附件不屬於這張票、實體檔遺失 | 改用附件所在票的 id;先查 /logs |
| 410 | 打了已下線的任務層附件端點 | 改在流轉或留言時帶 files[] |
| 422 | 檔案太多/太大、comment 缺、複製來源找不到、出口必附資料不足 | 看 errors 與 missing 欄位修正後重送 |