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

附件

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}/attachments
  • POST https://station-flow.staging.quanhox.com.tw/api/v1/tasks/{id}/attachments
  • DELETE 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 欄位修正後重送