chore(ai-review 狀態): 解決並排除 usage.js findings
This commit is contained in:
@@ -440,5 +440,29 @@
|
||||
"role": "Leo",
|
||||
"original_finding": "`usage.js` 模組目前承擔了 Token 計算、Rate Limit 記錄、以及各平台帳號額度查詢等多重職責(SRP),未來若支援更多平台會變得龐大難維護;建議將各平台 QuotaStrategy 拆分至獨立檔案。",
|
||||
"reason": "過早最佳化。目前 usage.js 仍圍繞單一「使用量」領域且體積適中(約 250 行),token 計算與額度查詢彼此關聯(同屬使用量呈現);在尚未有多平台 strategy 膨脹的實際痛點前拆檔,徒增檔案與匯入複雜度。待 strategy 數量明顯成長再拆分較合適。"
|
||||
},
|
||||
{
|
||||
"location": "app/usage.js:132",
|
||||
"role": "Assassin",
|
||||
"original_finding": "在 QUOTA_STRATEGIES 中,若 config.apiKeys 是陣列,代碼只取 [0] 作為 API Key,可能在未經嚴格驗證下將敏感資訊送至 baseURL 指定端點。",
|
||||
"reason": "已緩解。額度查詢只有 OpenRouter 一條會送出 API key,且僅在 isOpenRouterBaseURL 以 hostname 精確比對為 openrouter.ai 時才送出;baseURL 為 operator 控制之 action input,非外部不可信輸入;API key 本身的正確性與權限屬 operator 設定責任,非程式可驗證範圍。"
|
||||
},
|
||||
{
|
||||
"location": "app/usage.js:17",
|
||||
"role": "Mage",
|
||||
"original_finding": "在 extractUsage 中,對 data.usage 直接用 num(...) 存取;若 data.usage 為 null 但被 typeof 判斷通過(typeof null === 'object'),會導致錯誤。",
|
||||
"reason": "誤判。該區塊條件為 `if (u && typeof u === 'object')`,`u &&` 已先短路 null/undefined,不會進入存取;即使傳入陣列也只會讓 num(undefined) 回 0,不會丟錯。"
|
||||
},
|
||||
{
|
||||
"location": "app/usage.js:176",
|
||||
"role": "Mage",
|
||||
"original_finding": "在 fetchAccountQuota 中,呼叫 strategy 時傳入的 config 物件若被 strategy 修改,會影響全域 config 狀態;建議淺拷貝。",
|
||||
"reason": "已緩解。strategy 收到的是每次呼叫新建的物件字面值 `{ apiKey, baseURL: config.baseURL }`,並非呼叫端傳入的 config 本身,strategy 內的任何修改都不會回寫到呼叫端或全域狀態。"
|
||||
},
|
||||
{
|
||||
"location": "app/usage.js:115",
|
||||
"role": "Mage",
|
||||
"original_finding": "在 recordRateLimit 中,將所有 header key 轉小寫存入物件 h,若原始 header 有同名不同大小寫者可能造成覆蓋。",
|
||||
"reason": "誤判/不適用。HTTP header 名稱本即不分大小寫(RFC 7230),axios 回傳前已正規化為小寫;同名 header 由 HTTP 層合併(以逗號串接),不存在「不同大小寫同名 header」並存而被覆蓋的情況,轉小寫僅為防禦性處理。"
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user