From c11440e139380dd15a32cbfa6d9259f303135443 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Fri, 26 Jun 2026 11:21:56 +0800 Subject: [PATCH] =?UTF-8?q?chore(ai-review):=20=E6=9B=B4=E6=96=B0=20findin?= =?UTF-8?q?gs.json=20=E8=88=87=20exclusions.json?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移除本輪已修復(MAX_PAGES、URL 編碼)與已具測試/已收斂的 finding; 保留 5 條設計取捨類(重試/錯誤閾值/SRP/並行化)待人工評估; 將 logger 分隔線常數建議登記為不適用於 exclusions。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .gitea/ai-review/exclusions.json | 6 ++ .gitea/ai-review/findings.json | 96 +++++++++----------------------- 2 files changed, 31 insertions(+), 71 deletions(-) diff --git a/.gitea/ai-review/exclusions.json b/.gitea/ai-review/exclusions.json index 327dc5e..2cc3ae6 100644 --- a/.gitea/ai-review/exclusions.json +++ b/.gitea/ai-review/exclusions.json @@ -16,5 +16,11 @@ "role": "Bard", "original_finding": "在括号前面增加一个空格:`# 複製 Node.js 應用程式 (不含測試)`", "reason": "AI 對話收斂判定為誤報(問題在最新程式碼中不成立或不適用)" + }, + { + "location": "app/logger.js:5", + "role": "Bard", + "original_finding": "分隔線字串為魔術字串,硬編碼在模組頂層,不易維護與調整。建議將分隔線管理集中化,並考慮提供動態產生方法。", + "reason": "不適用。分隔線已是模組頂層的具名常數(LINE/SUBLINE),本即集中管理且為通用良好實務;固定寬度分隔線改為動態產生方法只會徒增複雜度,無實質效益,故不採納。" } ] diff --git a/.gitea/ai-review/findings.json b/.gitea/ai-review/findings.json index 35c67fa..fb00b6d 100644 --- a/.gitea/ai-review/findings.json +++ b/.gitea/ai-review/findings.json @@ -1,93 +1,47 @@ [ - { - "level": "critical", - "role": "Bard", - "location": "app/gitea-client.js:59", - "problem": "fetchAllPages 採展開運算子處理分頁資料,面對龐大項目數量可能導致 Maximum call stack size exceeded 錯誤,並伴隨無窮迴圈風險 (缺少 MAX_PAGES 限制)。", - "suggestion": "改用簡單的 for...of 迴圈逐一 push 項目以規避堆疊風險,並務必加入 MAX_PAGES 常數作為安全斷點,防止 API 異常導致無限迴圈與資源耗盡。" - }, - { - "level": "critical", - "role": "Maya", - "location": "app/index.js:46", - "problem": "缺乏核心清理流程的整合測試,且 cleanup 步驟之間的 API 狀態一致性未受保障,可能導致正在使用的 tag 被錯誤刪除。", - "suggestion": "於 app/test/ 新增整合測試(mock GiteaClient),驗證 cleanup 流程串接,並在兩個 cleanup 步驟之間確保 API 狀態一致,或於刪除 tag 前再次確認其未被現存 release 使用。" - }, - { - "level": "critical", - "role": "Mage", - "location": "app/releases.js:38", - "problem": "清理流程對網路請求依賴強,若 API 呼叫失敗,整個 main 流程中斷,導致容器無法確保後續清理的一致性與部分成功重試。", - "suggestion": "引入更細緻的錯誤處理(如錯誤閾值機制)或部分清理成功後的重試策略,確保清理任務具備健壯性。" - }, { "level": "warning", "role": "Mage", "location": "app/releases.js:46", - "problem": "刪除邏輯未針對網路不穩定或特定 HTTP 狀態碼 (502, 503, 504) 實作重試機制,且在遇到失敗時未停止後續請求,導致大量無意義錯誤。", - "suggestion": "針對特定 HTTP 狀態碼實作指數退避重試機制,並引入錯誤閾值,當失敗次數過高時立即中斷流程。" + "problem": "刪除邏輯未針對網路不穩定或特定 HTTP 狀態碼(502, 503, 504)實作重試機制,且遇到失敗時未停止後續請求。", + "suggestion": "針對特定 HTTP 狀態碼實作指數退避重試,並引入錯誤閾值,失敗次數過高時中斷流程。", + "status": "deferred", + "defer_reason": "屬功能性增強與設計取捨。此清理 Action 以排程執行,單次失敗可於下次補刪;重試/退避/錯誤閾值涉及次數、間隔與冪等性等決策,保留待人工評估。" + }, + { + "level": "warning", + "role": "Mage", + "location": "app/releases.js:38", + "problem": "清理流程對網路請求依賴強,若 API 呼叫失敗,整個 main 流程中斷,無法確保後續清理的一致性與部分成功重試。", + "suggestion": "引入更細緻的錯誤處理(如錯誤閾值機制)或部分清理成功後的重試策略。", + "status": "deferred", + "defer_reason": "與 app/releases.js:46 同屬錯誤處理/重試策略的設計取捨。目前單筆刪除失敗會記錄並繼續,讀取失敗則中止屬合理保守行為;是否引入閾值/重試保留待人工評估。" }, { "level": "warning", "role": "Leo", "location": "app/releases.js:37", - "problem": "cleanupReleases 違反單一職責原則,同時處理資料獲取、邏輯判斷與副作用執行,不易測試。", - "suggestion": "拆分邏輯與執行層,將刪除副作用抽象化為獨立函式,以利單獨測試。" + "problem": "cleanupReleases 同時處理資料獲取、邏輯判斷與副作用執行,違反單一職責原則,不易單獨測試刪除邏輯。", + "suggestion": "拆分邏輯與執行層,將刪除副作用抽象化為獨立函式。", + "status": "deferred", + "defer_reason": "純邏輯(selectReleasesToDelete)已抽離且函式短小、已具失敗路徑與編碼測試;進一步拆出刪除迴圈為設計偏好,效益有限,保留待人工評估。" }, { "level": "warning", "role": "Rogue", "location": "app/releases.js:43", - "problem": "清理成品與刪除 tag 使用序列化迴圈,導致 API 請求逐一排隊,整體執行時間拉長。", - "suggestion": "改用 Promise.all 搭配 map 將刪除請求並行化以縮短執行時間。" - }, - { - "level": "warning", - "role": "Assassin", - "location": "app/releases.js:56", - "problem": "直接將 API 回傳的 id 與 tag 名稱拼接到 URL 中進行 DELETE 操作,未經驗證,存在路徑穿越或 SSRF 風險。", - "suggestion": "在使用 id 或 tag 名稱構建 URL 前,必須嚴格驗證其字元組成(如僅允許特定格式或編碼處理)。" - }, - { - "level": "warning", - "role": "Maya", - "location": "app/config.js:36", - "problem": "缺乏對 GITEA_TOKEN 長度或格式的邊界測試,以及對 KEEP_COUNT 格式異常的檢查。", - "suggestion": "在測試檔中增加針對 Token 與 KEEP_COUNT 的邊界測試,並在 loadConfig 內加強格式轉換檢查。" - }, - { - "level": "warning", - "role": "Maya", - "location": "app/gitea-client.js:33", - "problem": "fetchAllPages 使用了逾時訊號,但測試套件未驗證網路逾時情境,且總耗時未受限制。", - "suggestion": "在測試中模擬 AbortError,並考慮對整個 fetchAllPages 流程引入總執行時間限制。" - }, - { - "level": "warning", - "role": "Bard", - "location": "app/logger.js:5", - "problem": "分隔線字串為魔術字串,硬編碼在模組頂層,不易維護與調整。", - "suggestion": "將分隔線管理集中化,並考慮提供動態產生方法。" - }, - { - "level": "info", - "role": "Leo", - "location": "app/validate.js:47", - "problem": "驗證規則寫死在函式內,易產生重複程式碼,且缺乏擴充性。", - "suggestion": "將驗證規則提取為設定物件或共用常數,或考慮使用 Zod 等 Schema 套件進行驗證與型別轉換。" + "problem": "清理成品與刪除 tag 使用序列化迴圈,API 請求逐一排隊,整體執行時間拉長。", + "suggestion": "改用 Promise.all 搭配 map 將刪除請求並行化。", + "status": "deferred", + "defer_reason": "刻意保留序列化:避免對 Gitea API 造成併發壓力與觸發速率限制,並維持可預期的記錄輸出順序;無上限並行化非等價變更,保留待人工評估(可日後改為有上限並行)。" }, { "level": "info", "role": "Rogue", "location": "app/gitea-client.js:33", - "problem": "fetchAllPages 採線性逐頁請求,資料龐大時效能不佳,且回應處理透過 .text() 再轉 JSON 造成重複記憶體開銷。", - "suggestion": "若 API 支援,先取得總頁數後並行請求,並直接處理 Response 的 ReadableStream 以提升效能。" - }, - { - "level": "info", - "role": "Leo", - "location": "app/index.js:34", - "problem": "錯誤報告邏輯與 logger.js 重疊,職責不清晰。", - "suggestion": "統一透過 logger.js 的 fail 函式處理錯誤輸出,將邏輯收斂。" + "problem": "fetchAllPages 採線性逐頁請求,資料龐大時效能不佳。", + "suggestion": "若 API 支援,先取得總頁數後並行請求。", + "status": "deferred", + "defer_reason": "Gitea 分頁未可靠提供總頁數,需解析 Link 標頭且各端點支援度不一;線性逐頁搭配逾時與 MAX_PAGES 上限已足夠穩健,並行化屬最佳化取捨,保留待人工評估。" } ]