在共用 endpoint 加無條件檢查會打爛其他呼叫者

主張:在一個多方共用的 endpoint 上加新的前置檢查,只要那個檢查依賴的欄位不是所有呼叫路徑都會填,就會把沒填的那些全部擋死——而且通常測試抓不到。

這次的形狀

新功能在 status endpoint 最前面加了 ownership 檢查:讀 workflow 的 memo.userId 跟呼叫者的 header 比對,fail-closed(缺值或不符就 403)。

問題是:只有這個新功能的三個地方會在啟動 workflow 時寫 memo: { userId, projectId };其他所有 workflow 走另一個 adapter,memo 裡只有 projectIdenterpriseId,從來沒有 userId。而那個 status endpoint 是全站共用的(bulk-delete、bulk-edit、pipeline… 都在打)。結果是這些既有功能一上線就全部拿到 403。

為什麼測試沒抓到

因為測試把 legacy 的案例也手動 stub 成有 userId 的 memo——stub 的形狀跟實際產出的不一致,於是測到的是「假設所有 workflow 都有 userId」的世界。

這是 mock 最典型的失效模式:mock 反映的是撰寫者的假設,不是系統的現實。

檢查清單

  • 這個 endpoint 有幾個呼叫方?新檢查依賴的欄位,每一條產生路徑都會填嗎?(用 grep 找全部寫入點,不要靠印象)
  • 檢查是 fail-open 還是 fail-closed?fail-closed 的爆炸半徑是全部既有呼叫者
  • 能不能只對新的那一族生效(用前綴、feature flag、或把檢查移到分支之後)?
  • 測試裡的 fixture 是不是照著實際產生路徑建的?

相關:契約 breaking 又沒有分流時,前後端不能分開部署