--- description: AI review một PR/commit Gitea theo thứ tự Security → Logic → Performance → Consistency → Simplicity argument-hint: allowed-tools: Bash, Read, Grep, Glob --- # /ai-review Đầu vào (`$ARGUMENTS`) là **một link Gitea**, hai dạng: - Pull request: `https://///pulls/` (chấp nhận cả `/pull/`). - Commit: `https://///commit/` (chấp nhận cả `/commits/`). Nếu thiếu link, **dừng** và yêu cầu cung cấp. Gọi API bằng `curl -s -u "andrew.ng@apactech.io:andrew.ng@123" -H "Accept: application/json" --fail-with-body ""`. **Không** in lệnh kèm password ra response. Nếu 401/403, báo lỗi auth, không in credentials. ## Các bước phải làm ### 1. Parse link Từ URL suy ra: - `GITEA_HOST` = scheme + host. - `OWNER`, `REPO`. - `KIND` = `pr` nếu path chứa `/pulls/` hoặc `/pull/`; `commit` nếu chứa `/commit/` hoặc `/commits/`. - `REF` = số PR (cho `pr`) hoặc SHA (cho `commit`). Nếu không khớp pattern trên, hỏi lại thay vì đoán. ### 2. Lấy dữ liệu để review Base API: `${GITEA_HOST}/api/v1/repos/${OWNER}/${REPO}` #### KIND = pr - `GET /pulls/${REF}` → metadata (title, body, base.ref, head.ref, head.sha, state, merged). - `GET /pulls/${REF}/commits` → list commit + message. - `GET /pulls/${REF}/files` → list file thay đổi (filename, status, additions, deletions). - Lấy **diff đầy đủ** để đọc nội dung: `GET ${GITEA_HOST}/${OWNER}/${REPO}/pulls/${REF}.diff` (raw web endpoint, vẫn cùng Basic Auth). Lưu vào `/tmp/ai-review-${REF}.diff`. #### KIND = commit - `GET /git/commits/${REF}` → message, author, files (nếu có). - Lấy diff đầy đủ: `GET ${GITEA_HOST}/${OWNER}/${REPO}/commit/${REF}.diff` lưu vào `/tmp/ai-review-${REF}.diff`. **Fallback ưu tiên dùng git local** nếu `GITEA_HOST` trỏ về repo hiện tại (so sánh `git remote -v`): khi đó dùng `git show ` / `git diff ..` để có diff đầy đủ + nhanh hơn, không phải hit Gitea. Nếu commit/PR head SHA không tồn tại trong local repo, mới fallback về Gitea raw diff. ### 3. Đọc context xung quanh Trước khi nhận xét, với mỗi file đụng đến trong diff: - Mở file bằng `Read` (ưu tiên đọc nguyên file nếu < 800 dòng; nếu lớn hơn, đọc các vùng quanh dòng thay đổi). - Đọc `CLAUDE.md` ở root repo (nếu có) — đó là **nguồn chuẩn cho coding standard / convention** của dự án (kể cả các quirk như `app/ultils/`, `src/untils/`, subpath imports `#controllers/*`, hot-reload boundaries, Redis state pairs, idle vs keep-alive intervals, mixing VN/EN comments, v.v.). - Nếu repo có `.editorconfig`, `eslint.config.*`, `tsconfig.json`, `.prettierrc*` → đọc để biết coding standard cụ thể. ### 4. Thực hiện review theo **đúng thứ tự** dưới đây Với MỖI mục, output: - Status: ✅ Pass / ⚠️ Cần cải thiện / ❌ Có vấn đề. - Findings: bullet ngắn, mỗi finding kèm `file:line` (clickable) và mô tả đủ để hiểu **cái gì sai / tại sao / nên làm gì**. - Nếu không có gì để nói: ghi rõ "Không phát hiện vấn đề" — không bịa. - Ghi ngắn gọn nội dung Thứ tự **cố định**: #### 4.1. Security Soi các nguy cơ: - Injection (SQL, command, prompt, log), template/string interpolation từ input người dùng. - Hardcoded secret / token / credential trong code mới. - AuthZ/AuthN: endpoint mới có thuộc middleware `auth` không? (theo `start/kernel.ts` + `start/routes.ts`). Có lộ thông tin user khác không? - Unsafe deserialization / `eval` / `Function`. - File path không sanitize (path traversal) khi đọc/ghi file. - Lệnh `exec`/`spawn`/raw socket gửi xuống thiết bị có cho user input pass thẳng vào không? - CORS / cookie / token handling thay đổi (đặc biệt trong `socket_io_provider.ts`). - Logging có in PII / password / token không. #### 4.2. Logic & Edge Cases - Happy path đúng chưa? Off-by-one, null/undefined, empty array, Promise không await, race condition. - Error path: try/catch có nuốt lỗi không, có rollback / restore state không. - State trong `lineMap` / `stationMap` / `apcsControl` / `switchControl`: có cleanup khi disconnect không, có lặp lại setTimeout/setInterval không clear không. - Redis state (`socket_state`, `station:{id}:line:{id}:history`): khi thêm field mới, `saveState` / `restoreState` có cover không. - Idle-timeout (`setTimeoutConnect`, 8h) **và** keep-alive (`keepConnectAPC` 40s / `keepConnectStation` 120s) có được wire đầy đủ cho connection mới không (theo CLAUDE.md). - Socket event mới: cả hai phía FE/BE có khớp tên + payload shape không. - Ghi ngắn gọn nội dung #### 4.3. Performance - Vòng lặp lồng nhau / N+1 query Lucid (eager loading?). - `await` trong `for` thay vì `Promise.all` khi có thể song song. - Re-render React thừa (`App.tsx` đang dùng `lineBuffersRef` + flush 50ms — diff mới có phá vỡ pattern này không). - Bộ nhớ giữ output dài (truncate ở `saveState` 5000 chars — diff mới có giữ thêm field nặng không). - Setinterval/setTimeout có dồn (leak) không. - Ghi ngắn gọn nội dung #### 4.5. Simplicity - Có code trùng lặp với chỗ đã có (helper trong `BACKEND/app/ultils/helper.ts`, hook/component sẵn ở FE) mà nên reuse không. - Có over-engineering, abstraction sớm. - Có thể gộp branch / sớm return để giảm nesting. - Đề xuất cụ thể cách rút gọn (mỗi đề xuất kèm trước/sau ngắn nếu hữu ích). - Ghi ngắn gọn nội dung ### 5. Trả về kết quả Format output (Vietnamese): ``` # AI Review — # ## 1. Security — - ... ## 2. Logic & Edge Cases — - ... ## 3. Performance — - ... ## 4. Simplicity — - — <đề xuất rút gọn> ... ## Tổng kết - Đánh giá chung: <1–2 câu> ``` ### 6. Không tự ý - **Không** sửa code (đây là review only). Nếu muốn fix, người dùng sẽ chạy `/simplify` hoặc `/code-review --fix` riêng. - **Không** comment lên Gitea / Jira. - **Không** approve / merge / close PR. - **Không** in password.