feat: add AI code review documentation, demonstration project, and update guidelines
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
# CLAUDE.md
|
||||
|
||||
## Business rules — Order
|
||||
- KHÔNG được cancel order đã ở trạng thái `shipped` hoặc `delivered`.
|
||||
Phải kiểm tra `order.status` trước; nếu đã shipped thì throw lỗi.
|
||||
- Refund (hoàn tiền) xử lý async qua queue, không inline trong hàm cancel.
|
||||
|
||||
## Conventions
|
||||
- Format tiền tệ: LUÔN dùng `formatCurrency()` ở `src/lib/format.js`.
|
||||
KHÔNG tự viết hàm format tiền mới.
|
||||
- Số tiền lưu dưới dạng VND nguyên (integer).
|
||||
@@ -0,0 +1,22 @@
|
||||
# PR: Thêm tính năng hủy đơn hàng (cancel order)
|
||||
|
||||
Diff thêm vào cuối `src/services/orderService.js`:
|
||||
|
||||
```diff
|
||||
@@ src/services/orderService.js @@
|
||||
+function toMoney(n) { // hàm format tiền tự viết
|
||||
+ return n.toLocaleString('vi-VN') + ' đ';
|
||||
+}
|
||||
+
|
||||
+export async function cancelOrder(id) {
|
||||
+ const order = await getOrder(id);
|
||||
+ order.status = 'cancelled'; // cập nhật trạng thái
|
||||
+ await db.orders.save(order);
|
||||
+ return `Đã hủy đơn. Hoàn ${toMoney(order.total)}`;
|
||||
+}
|
||||
```
|
||||
|
||||
## Hai lỗi được cài (đáp án cho người trình bày — KHÔNG chiếu)
|
||||
1. **Lỗi business:** `cancelOrder` không kiểm tra `order.status` → hủy được cả đơn đã `shipped`,
|
||||
vi phạm rule trong CLAUDE.md. Chỉ phát hiện được nếu AI đọc business rule.
|
||||
2. **Lỗi maintainability:** `toMoney()` trùng chức năng `formatCurrency()` đã có ở `src/lib/format.js`.
|
||||
@@ -0,0 +1,66 @@
|
||||
# Prompt Cheat-Sheet (copy-paste khi demo)
|
||||
|
||||
Dùng được cho mọi tool (Claude Code, Cursor, Codex, ChatGPT...). Mở sẵn file này, demo chỉ việc copy.
|
||||
|
||||
---
|
||||
|
||||
## ① BEFORE — cách làm sai (sẽ bỏ lọt lỗi business)
|
||||
|
||||
> Dán **cả file** `orderService.js` (bản đã thêm code mới), prompt mơ hồ, KHÔNG kèm CLAUDE.md, KHÔNG nói ý định:
|
||||
|
||||
```
|
||||
Review giúp tôi file orderService.js này xem có vấn đề gì không:
|
||||
|
||||
<dán toàn bộ nội dung orderService.js vào đây>
|
||||
```
|
||||
|
||||
Kết quả điển hình: vài góp ý chung chung (thêm try/catch, kiểm tra null, đặt tên...) và **bỏ lọt** lỗi cancel đơn đã shipped.
|
||||
|
||||
---
|
||||
|
||||
## ② AFTER — đúng phương pháp (bắt đúng lỗi business)
|
||||
|
||||
> Kèm **CLAUDE.md**, chỉ đưa **diff**, nói rõ **ý định**, ép **lọc false positive**:
|
||||
|
||||
```
|
||||
Bạn review CHỈ phần code MỚI THÊM (diff) dưới đây.
|
||||
Mục tiêu của PR: thêm tính năng hủy đơn hàng (cancel order).
|
||||
Đối chiếu với rule trong CLAUDE.md (đính kèm).
|
||||
Chỉ báo lỗi bạn CHẮC CHẮN, kèm dòng code + lý do (trích rule nếu vi phạm).
|
||||
Bỏ qua nitpick và lỗi linter tự bắt.
|
||||
|
||||
--- CLAUDE.md ---
|
||||
<dán nội dung CLAUDE.md>
|
||||
|
||||
--- DIFF ---
|
||||
<dán phần diff trong PR-diff.md>
|
||||
```
|
||||
|
||||
Kết quả mong đợi: bắt đúng **lỗi cancel đơn shipped** (trích rule) + chỉ ra **toMoney trùng formatCurrency**, bỏ hết nitpick.
|
||||
|
||||
---
|
||||
|
||||
## ③ PERSONA AGENTS — chia vai để đào sâu (tùy chọn, ấn tượng)
|
||||
|
||||
Chạy 2 lượt riêng, mỗi lượt một vai (hoặc tạo subagent trong `.claude/agents/`):
|
||||
|
||||
**Business-logic agent:**
|
||||
```
|
||||
Bạn là reviewer chuyên về BUSINESS LOGIC.
|
||||
Đối chiếu diff dưới đây với phần "Business rules" trong CLAUDE.md.
|
||||
Chỉ ra mọi chỗ code đi ngược rule, kèm trích dẫn rule.
|
||||
<đính kèm CLAUDE.md + diff>
|
||||
```
|
||||
|
||||
**Maintainability agent:**
|
||||
```
|
||||
Bạn là reviewer chuyên về MAINTAINABILITY.
|
||||
Kiểm tra code mới có viết trùng hàm/util đã tồn tại trong repo không
|
||||
(gợi ý: xem src/lib/format.js). Đề xuất tái sử dụng.
|
||||
<đính kèm diff + nội dung src/lib/format.js>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ④ (Tùy chọn) Claude Code /code-review trên PR thật
|
||||
Nếu muốn demo lệnh native: chạy `setup.sh` để tạo branch + diff, push lên GitHub tạo PR, rồi chạy `/code-review`.
|
||||
@@ -0,0 +1,24 @@
|
||||
# Runbook Demo — 5 phút
|
||||
|
||||
## Chuẩn bị trước (KHÔNG làm live)
|
||||
- Mở sẵn: `PROMPTS.md`, `CLAUDE.md`, `PR-diff.md`, `orderService.js`.
|
||||
- Chạy thử 1 lần trước buổi nói, **quay màn hình** làm backup (AI live đôi khi chậm/khác).
|
||||
- Diff đã đủ nhỏ (~10 dòng) để khán giả đọc hết trong 10 giây.
|
||||
|
||||
## Kịch bản
|
||||
| Thời gian | Làm gì | Thông điệp |
|
||||
|-----------|--------|-----------|
|
||||
| 0:00–0:30 | Chiếu PR-diff, đọc to "feature hủy đơn, ~10 dòng". Đừng nói có lỗi. | Bối cảnh |
|
||||
| 0:30–2:00 | Chạy prompt **① BEFORE** | Góp ý linh tinh, **bỏ lọt** lỗi nguy hiểm |
|
||||
| 2:00–3:30 | Chạy prompt **② AFTER** | Bắt đúng lỗi cancel-shipped + trích rule, bỏ nitpick |
|
||||
| 3:30–4:30 | Chạy **③ persona** (maintainability) | Tóm `toMoney` trùng `formatCurrency` |
|
||||
| 4:30–5:00 | Slide so sánh + chốt | "Cùng một model, khác ở cách đưa context" |
|
||||
|
||||
## Mẹo chống "chết" trên sân khấu
|
||||
- Tuyệt đối không gõ tay — copy từ PROMPTS.md.
|
||||
- Nếu "before" lỡ bắt được lỗi: nhấn mạnh nó vẫn báo kèm nhiều nitpick vô nghĩa, còn "after" thì gọn & trúng.
|
||||
- Có thể chia màn hình chạy song song before/after cho tương phản tức thì.
|
||||
|
||||
## Đáp án 2 lỗi cài sẵn (cho người trình bày)
|
||||
1. cancelOrder không check `status === 'shipped'` → vi phạm business rule.
|
||||
2. `toMoney()` trùng `formatCurrency()` đã có.
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
# Tùy chọn: tạo git repo + branch có diff để demo /code-review trên PR thật
|
||||
set -e
|
||||
git init -q && git add . && git commit -qm "base: order service"
|
||||
git checkout -qb feature/cancel-order
|
||||
cat >> src/services/orderService.js << 'JS'
|
||||
|
||||
function toMoney(n) {
|
||||
return n.toLocaleString('vi-VN') + ' đ';
|
||||
}
|
||||
|
||||
export async function cancelOrder(id) {
|
||||
const order = await getOrder(id);
|
||||
order.status = 'cancelled';
|
||||
await db.orders.save(order);
|
||||
return `Đã hủy đơn. Hoàn ${toMoney(order.total)}`;
|
||||
}
|
||||
JS
|
||||
git add . && git commit -qm "feat: thêm cancelOrder"
|
||||
echo "Xong. 'git diff main' để xem diff, hoặc push lên GitHub tạo PR rồi chạy /code-review."
|
||||
@@ -0,0 +1,4 @@
|
||||
// src/lib/format.js — tiện ích format đã có sẵn trong repo
|
||||
export function formatCurrency(amount, currency = 'VND') {
|
||||
return new Intl.NumberFormat('vi-VN', { style: 'currency', currency }).format(amount);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// src/services/orderService.js
|
||||
import { db } from '../db.js';
|
||||
import { formatCurrency } from '../lib/format.js';
|
||||
|
||||
export async function getOrder(id) {
|
||||
return db.orders.findById(id);
|
||||
}
|
||||
|
||||
export function orderSummary(order) {
|
||||
return `Đơn ${order.id}: ${formatCurrency(order.total)}`;
|
||||
}
|
||||
Reference in New Issue
Block a user