請你對目前這個 repository 進行「全面程式碼審查」。
重要限制:
1. 先不要直接修改任何程式碼。
2. 不要只做表面掃描,請先理解專案架構、執行流程、驗證機制、資料存取、部署方式後再提出問題。
3. 所有發現都必須指出:
- 嚴重程度:Critical / High / Medium / Low
- 問題類型:安全性 / 架構 / 錯誤處理 / 效能 / 可維護性 / 測試不足 / 部署風險
- 影響範圍
- 相關檔案與程式碼位置
- 為什麼這是問題
- 建議修正方式
- 是否需要補測試
4. 不要提出沒有依據的猜測;如果無法確認,請標註「需人工確認」。
5. 優先找出會造成資安風險、生產環境錯誤、資料不一致、權限繞過、Token / Cookie / CORS / CSRF 問題、例外未處理、日誌外洩、弱掃風險的問題。
6. 請依照實際程式碼內容審查,不要只給一般建議。
請依照以下順序執行:
第一階段:專案盤點
- 說明此 repository 的專案組成、主要技術棧、入口點、重要設定請使用 lighthouse MCP 對以下登入頁執行行動裝置 Performance 稽核:
<Url>
請執行下列工作:
1. 記錄 Performance 分數、FCP、LCP、TBT、CLS 和 Speed Index。
2. 找出造成 LCP 超過 2.5 秒的主要原因。
3. 檢查 ASP.NET Core 10、Razor View、Razor Layout、CSS、JavaScript、圖片、Web Font、靜態資源、中介軟體及第三方資源。
4. 檢查靜態檔案壓縮、快取標頭、Response Compression、資源載入順序,以及是否存在 Render-blocking resources。
5. 依改善效益、修改風險與實作成本排序改善項目。
6. 修改程式碼時不得改變登入流程、驗證邏輯、頁面功能及既有 UI 行為。
7. 修改後再次使用 lighthouse MCP 執行相同條件的測試。
8. 比較修改前後的 Lighthouse 結果。
9. LCP 目標為 2.5 秒以下。
10. 最後列出:
* 修改的檔案
var/log/system.log
var/log/exception.log
var/log/debug.log9:30 am
Halindale
central street
792
?
1,80
19:30
7.15
Commuter
?early morning
A 13
B 14
C 11 12
-
first-year
balance
foreign students
Relaxation
Motivation
research
The secret garden
-
walk
motivation
abstract ideas
-
darkness to lightness
-
-
human companionship
Negative
pleasure
fate
Active
success
B
B/C
A
A
B請只審查 `sha_old..sha_new` 範圍內的變更,不要修改任何檔案。
請以以下 Git 範圍為審查依據:
```bash
git log --oneline sha_old..sha_new
git diff --stat sha_old..sha_new
git diff sha_old..sha_new
```
審查範圍只限於 `sha_old` 之後到 `sha_new` 為止的變更。
可以閱讀其他未變更檔案作為上下文,但不要把原本就存在的舊問題列為本次問題,除非該問題是由 `sha_old..sha_new` 範圍內的變更引入、擴大或暴露。
本專案是 Flutter 專案,請特別審查:
* Widget lifecycle,例如 `initState`、`dispose`、Controller / Listener / Worker 是否釋放
* GetX 狀態管理是否有狀態殘留、重複刷新、Controller 過肥問題
* async / await 是否有 race condition、重複請求、頁面離開後仍更新狀/**
* @param {number} n
* @param {number[]} nums
* @param {number} maxDiff
* @param {number[][]} queries
* @return {boolean[]}
*/
var pathExistenceQueries = function(n, nums, maxDiff, queries) {
const comp = new Array(n).fill(0);
// Build connected components
for (let i = 1; i < n; i++) {
if (nums[i] - nums[i - 1] <= maxDiff) {
comp[i] = comp[i - 1];
} else {
comp[i] = comp[i - 1] + 1;
}
}
// Answer queries
const ans/**
* @param {string} s
* @param {number[][]} queries
* @return {number[]}
*/
var sumAndMultiply = function(s, queries) {
const MOD = 1000000007;
const MODB = BigInt(MOD);
// Safe modular multiplication using BigInt
const mulmod = (a, b) => Number((BigInt(a) * BigInt(b)) % MODB);
// ------------------------------------------------------------
// STEP 1: Extract all NON-ZERO digits and their original positions
// --------------------------------------------------/**
* @param {number} n
* @return {number}
*/
var sumAndMultiply = function(n) {
// Step 1: build x by concatenating non-zero digits
let s = String(n);
let filtered = "";
for (let ch of s) {
if (ch !== '0') filtered += ch;
}
let x = filtered.length === 0 ? 0 : Number(filtered);
// Step 2: compute digit sum of x
let sum = 0;
while (x > 0) {
sum += x % 10;
x = Math.floor(x / 10);
}
// Step 3: multiply original x by sum
r/**
* @param {number[][]} intervals
* @return {number}
*/
var removeCoveredIntervals = function(intervals) {
// Step 1: Sort intervals by:
// - start ascending
// - if starts are equal, end descending
//
// This ensures that any interval that *could* cover another
// appears before the interval it might cover.
intervals.sort((a, b) => {
if (a[0] === b[0]) {
// For same start, put the longer interval first
return b[1] - a[1];
/**
* @param {string[]} board
* @return {number[]}
*/
var pathsWithMaxScore = function(board) {
const n = board.length;
const MOD = 1e9 + 7;
// dpScore[i][j] = max score to reach (i,j)
// dpCount[i][j] = number of ways to achieve that score
const dpScore = Array.from({ length: n }, () => Array(n).fill(-Infinity));
const dpCount = Array.from({ length: n }, () => Array(n).fill(0));
// Start at S (bottom-right)
dpScore[n-1][n-1] = 0;
dpCount[n-1][n-1] = 1;
/**
* @param {number} n
* @param {number[][]} roads
* @return {number}
*/
var minScore = function(n, roads) {
const graph = Array.from({ length: n + 1 }, () => []);
for (const [a, b, w] of roads) {
graph[a].push([b, w]);
graph[b].push([a, w]);
}
const seen = new Array(n + 1).fill(false);
const stack = [1];
seen[1] = true;
// Find all nodes reachable from 1
while (stack.length) {
const node = stack.pop();
for (const [nei] of grnvapi-_Zi-Adap2_aIvT_mlR1eQzRRNbXx6uE3_-5_giTAz34rMWIaBJhpb9G_oa0CKl2B/**
* @param {number[][]} edges
* @param {boolean[]} online
* @param {number} k
* @return {number}
*/
var findMaxPathScore = function(edges, online, k) {
const n = online.length;
// Build adjacency list only for edges whose endpoints are online
const adj = Array.from({ length: n }, () => []);
let maxEdgeCost = 0;
for (const [u, v, cost] of edges) {
if (online[u] && online[v]) {
adj[u].push([v, cost]);
if (cost > maxEdgeCost) maxEdgeCost dig +short A sub.domain.end/**
* @param {number[][]} grid
* @param {number} health
* @return {boolean}
*/
var findSafeWalk = function (grid, health) {
const m = grid.length;
const n = grid[0].length;
// dist[i][j] = minimum health lost to reach cell (i, j)
const dist = Array.from({ length: m }, () => Array(n).fill(Infinity));
// Starting cell: if it's unsafe (1), you lose 1 health immediately
dist[0][0] = grid[0][0];
// Directions for moving up, down, left, right
const dirs = [
[1, 0],
[-1,