# CLAUDE.md — Template cho dự án PHP (Laravel)
# Cách dùng: copy vào gốc repo, chạy /init, merge, điền [ĐIỀN], xoá dòng không đúng.
# Nếu dự án PHP thuần/framework khác: giữ khung, thay lệnh tương ứng.

## Lệnh thường dùng
- Cài deps: `composer install`
- Test: `php artisan test` (hoặc `./vendor/bin/phpunit`) — chạy TRƯỚC mọi commit
- Format: `./vendor/bin/pint` — bắt buộc pass trước PR
- Static analysis: `./vendor/bin/phpstan analyse` [ĐIỀN: level hiện tại]
- Migrate DB local: `php artisan migrate`; refresh + seed: `php artisan migrate:fresh --seed`
- Queue local: `php artisan queue:work`

## Kiến trúc
- Laravel [ĐIỀN: version] + PHP [ĐIỀN: version] + [ĐIỀN: MySQL/PostgreSQL] + [ĐIỀN: Redis]
- Luồng: Route → FormRequest (validate) → Controller (mỏng) → Service (`app/Services`) → Model/Repository
- Business logic ở Service, KHÔNG ở Controller và KHÔNG ở Model
- API trả về qua API Resource (`app/Http/Resources`); job nền ở `app/Jobs`

## Quy ước code (bắt buộc)
- PSR-12; type hint đầy đủ tham số & return; `declare(strict_types=1)` cho file mới
- Validate bằng FormRequest, KHÔNG validate trong controller
- Truy vấn: Eloquent; tránh N+1 (dùng `with()`); truy vấn phức tạp đặt trong scope/repository
- Không dùng `env()` ngoài file config — dùng `config()`
- Exception nghiệp vụ tự định nghĩa ở `app/Exceptions`, không throw `\Exception` trần

## Test
- PHPUnit/Pest [ĐIỀN: chọn 1]; Feature test cho endpoint, Unit test cho service
- Dùng `RefreshDatabase` + factory; KHÔNG test dựa vào dữ liệu thật
- Bugfix bắt buộc kèm test tái hiện bug

## Git & PR
- Nhánh `feature/<ticket>`, `fix/<ticket>`; Conventional Commits
- Trước PR: pint pass + phpstan pass + test pass; migration mới phải có `down()` hoạt động
- KHÔNG sửa migration đã chạy trên môi trường chung — tạo migration mới

## Definition of Done (feature chỉ được coi là xong khi)
1. Hành vi đúng theo spec ở mọi kịch bản mô tả, kể cả edge case đã nêu
2. `php artisan test` pass 100%; bugfix có test tái hiện kèm theo
3. `./vendor/bin/pint` và phpstan pass; không còn dd()/dump()
4. Migration mới có `down()` chạy được; API mới có Feature test
5. Không lộ secret trong diff

## Cấm
- Không chạy `migrate:fresh`/`db:wipe` trên bất kỳ môi trường nào ngoài local
- Không thêm package composer khi chưa được duyệt
- Không hardcode credential; secrets qua `.env`
