Files
release-cleanup/.gitea/ai-review/findings.json
T
JefferyandClaude Opus 4.8 8dae4aceaf
CI / AI Code Review (pull_request) Failing after 1m10s
chore(ai-review): 更新 findings.json
移除本輪已修復(JSON/陣列處理、sanitize、failError 收斂、常數抽出)與
已存在測試覆蓋的 finding;保留 7 條設計取捨類(重試/TOCTOU/並行化/SRP)待人工評估。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:04:29 +08:00

66 lines
4.2 KiB
JSON

[
{
"level": "warning",
"role": "Mage",
"location": "app/releases.js:46",
"problem": "在 `cleanupReleases` 迴圈中執行 DELETE 請求時,未針對網路不穩定或暫時性服務錯誤(如 502, 503, 504)實作重試機制。若刪除過程中發生瞬間網路中斷,該 release 將不會被刪除。",
"suggestion": "對於特定的 HTTP 狀態碼(502, 503, 504),建議引入簡單的指數退避重試機制(Exponential Backoff)。",
"status": "deferred",
"defer_reason": "屬功能性增強與設計取捨。此清理 Action 通常以排程執行,單次失敗可於下次執行補刪;是否引入重試/退避涉及重試次數、間隔與冪等性等設計決策,保留待人工評估。"
},
{
"level": "warning",
"role": "Mage",
"location": "app/tags.js:56",
"problem": "`cleanupReleases` 與 `cleanupOrphanTags` 非同步先後執行,若兩者之間 Gitea 上有新的 release 被建立,releaseTagNames 快照會過時,可能導致正在使用的 tag 被錯誤刪除。",
"suggestion": "在兩個 cleanup 步驟之間確保 API 狀態一致性,或在刪除 tag 前再次檢查該 tag 是否仍未被任何現存 release 使用。",
"status": "deferred",
"defer_reason": "現行程式已在 cleanupOrphanTags 開頭重新抓取最新 release 清單作為主要緩解;殘餘競態窗極小且屬排程任務可接受範圍。是否再加每筆刪除前複查屬一致性/成本的設計取捨,保留待人工評估。"
},
{
"level": "warning",
"role": "Rogue",
"location": "app/releases.js:43",
"problem": "刪除舊成品時使用序列化的 `for...of` + `await`,刪除請求逐一排隊等待 API 回應。",
"suggestion": "改用 `Promise.all` 搭配 `map` 將刪除請求並行化以縮短總執行時間。",
"status": "deferred",
"defer_reason": "刻意保留序列化:可避免對 Gitea API 造成併發壓力與觸發速率限制,並維持可預期的記錄輸出順序,且與原 bash 版本行為一致。無上限並行化非等價變更,保留待人工評估(可日後改為有上限的並行)。"
},
{
"level": "warning",
"role": "Rogue",
"location": "app/tags.js:46",
"problem": "刪除孤立 tag 時同樣使用序列化迴圈,造成總執行時間拉長。",
"suggestion": "改用 `Promise.all` 將刪除請求並行化。",
"status": "deferred",
"defer_reason": "與 app/releases.js:43 同理,刻意保留序列化以避免併發壓力與速率限制並維持記錄順序,屬設計取捨,保留待人工評估。"
},
{
"level": "warning",
"role": "Leo",
"location": "app/releases.js:37",
"problem": "`cleanupReleases` 同時負責取得資料、判斷邏輯與執行刪除副作用,違反單一職責原則,未來不易單獨測試刪除邏輯。",
"suggestion": "將取得/過濾的純邏輯與執行刪除的副作用層拆開(目前 `selectReleasesToDelete` 已做了一部分)。",
"status": "deferred",
"defer_reason": "純邏輯(selectReleasesToDelete)已抽離且函式短小、已具失敗路徑測試覆蓋;進一步拆出刪除迴圈為設計偏好,效益有限且增加表面積,保留待人工評估。"
},
{
"level": "warning",
"role": "Leo",
"location": "app/tags.js:46",
"problem": "`cleanupOrphanTags` 直接在主流程遍歷並刪除,未來若需更複雜的失敗處理(重試、批次)會難以維護。",
"suggestion": "參考 cleanupReleases 結構,將分類過濾與執行刪除進一步解耦。",
"status": "deferred",
"defer_reason": "分類邏輯(categorizeTags)已抽為純函式並具測試;是否進一步拆出刪除執行層為設計偏好,與 app/releases.js:37 一併保留待人工評估。"
},
{
"level": "info",
"role": "Rogue",
"location": "app/gitea-client.js:33",
"problem": "`fetchAllPages` 採線性逐頁請求,資料量龐大時總請求時間較長。",
"suggestion": "若 API 支援,先取得總頁數再並行發出請求。",
"status": "deferred",
"defer_reason": "Gitea 分頁未可靠提供總頁數,需額外解析 Link 標頭且各端點支援度不一;線性逐頁搭配逾時已足夠穩健且簡單,並行化屬最佳化取捨,保留待人工評估。"
}
]