source: Add rules for AI Coding

This commit is contained in:
2026-03-09 16:51:44 +07:00
parent 4b7236493f
commit 3003a0ff0b
27 changed files with 2103 additions and 70 deletions

View File

@@ -0,0 +1,334 @@
# Huong Dan Dat Ten Git Branch Trong Du An
> **Tham khao:** [Git Branch Naming Conventions - Codiga](https://codiga.io/blog/git-branch-naming-conventions)
---
## Muc Luc
1. [Nguyen Tac Chung](#1-nguyen-tac-chung)
2. [Cau Truc Ten Branch](#2-cau-truc-ten-branch)
3. [Cac Loai Branch (Branch Types)](#3-cac-loai-branch-branch-types)
4. [Bang Mau Ten Branch Theo Chuc Nang](#4-bang-mau-ten-branch-theo-chuc-nang)
5. [Quy Tac Dat Ten (Good Practices)](#5-quy-tac-dat-ten-good-practices)
6. [Mo Hinh Git Flow](#6-mo-hinh-git-flow)
7. [Vi Du Thuc Te Trong Du An](#7-vi-du-thuc-te-trong-du-an)
8. [Checklist Truoc Khi Tao Branch](#8-checklist-truoc-khi-tao-branch)
---
## 1. Nguyen Tac Chung
Theo bai viet tu Codiga, mot quy uoc dat ten branch tot giup:
| # | Loi ich | Mo ta |
|---|---------|-------|
| 1 | **Truy vet tac gia** | Biet ai da tao branch (developer nao) |
| 2 | **Lien ket voi issue tracker** | De dang trace branch voi task/ticket tren JIRA, Trello, GitHub Issues... |
| 3 | **Hieu muc dich branch** | Nhanh chong biet branch la bugfix, feature, hay hotfix |
| 4 | **To chuc workflow** | Giu cho quy trinh lam viec co trat tu va hieu qua |
---
## 2. Cau Truc Ten Branch
### Format chung
```
<type>/<ticket-id>-<short-description>
```
Trong do:
| Thanh phan | Bat buoc | Mo ta | Vi du |
|-----------|----------|-------|-------|
| `type` | Co | Loai branch (feature, bugfix, hotfix...) | `feature` |
| `ticket-id` | Co (neu co) | Ma ticket/issue tu issue tracker | `PROJ-1234` |
| `short-description` | Co | Mo ta ngan 3-6 tu, phan cach bang dau `-` | `add-user-authentication` |
### Vi du day du
```
feature/PROJ-1234-add-user-authentication
bugfix/PROJ-5678-fix-login-redirect
hotfix/PROJ-9012-patch-security-vulnerability
```
### Format mo rong (co ten tac gia)
Neu team co nhieu nguoi lam chung mot ticket, them ten tac gia:
```
<author>/<type>/<ticket-id>-<short-description>
```
Vi du:
```
julien/feature/1234-new-dashboard
david/feature/1234-new-dashboard
```
Dieu nay giup phan biet ro rang code cua tung developer cho cung mot task.
---
## 3. Cac Loai Branch (Branch Types)
### Branch chinh (Long-lived branches)
| Branch | Muc dich | Duoc merge tu | Ghi chu |
|--------|---------|---------------|---------|
| `main` (hoac `master`) | Code production, luon o trang thai stable | `release`, `hotfix` | Khong bao gio commit truc tiep |
| `develop` | Code moi nhat cho phien ban tiep theo | `feature`, `bugfix` | Nhanh tich hop chinh |
| `staging` | Moi truong test truoc khi len production | `develop` | Tuy chon, tuy du an |
### Branch tam thoi (Short-lived branches)
| Prefix | Muc dich | Tao tu | Merge vao | Vi du |
|--------|---------|--------|----------|-------|
| `feature/` | Tinh nang moi | `develop` | `develop` | `feature/PROJ-101-add-login-page` |
| `bugfix/` | Sua loi trong qua trinh phat trien | `develop` | `develop` | `bugfix/PROJ-202-fix-null-reference` |
| `hotfix/` | Sua loi khan cap tren production | `main` | `main` va `develop` | `hotfix/PROJ-303-fix-payment-crash` |
| `release/` | Chuan bi phien ban moi | `develop` | `main` va `develop` | `release/v1.2.0` |
| `chore/` | Cong viec bao tri, refactor, CI/CD | `develop` | `develop` | `chore/update-dependencies` |
| `docs/` | Cap nhat tai lieu | `develop` | `develop` | `docs/update-api-documentation` |
| `test/` | Viet test hoac cai thien test | `develop` | `develop` | `test/add-unit-tests-user-service` |
| `refactor/` | Tai cau truc code, khong thay doi chuc nang | `develop` | `develop` | `refactor/clean-up-user-repository` |
---
## 4. Bang Mau Ten Branch Theo Chuc Nang
### Authentication & Authorization
```
feature/PROJ-101-add-jwt-authentication
feature/PROJ-102-implement-refresh-token
feature/PROJ-103-add-role-based-access
bugfix/PROJ-104-fix-token-expiration
hotfix/PROJ-105-patch-auth-bypass
```
### CRUD Entity
```
feature/PROJ-201-create-product-entity
feature/PROJ-202-add-product-api-endpoints
feature/PROJ-203-implement-product-search
bugfix/PROJ-204-fix-product-update-validation
```
### Infrastructure & DevOps
```
chore/PROJ-301-setup-docker-compose
chore/PROJ-302-configure-ci-cd-pipeline
chore/PROJ-303-add-redis-caching
chore/PROJ-304-setup-logging-serilog
```
### Database & Migration
```
feature/PROJ-401-add-migration-user-table
feature/PROJ-402-seed-initial-data
bugfix/PROJ-403-fix-migration-conflict
```
### Documentation
```
docs/PROJ-501-update-readme
docs/PROJ-502-add-api-swagger-docs
docs/PROJ-503-create-deployment-guide
```
---
## 5. Quy Tac Dat Ten (Good Practices)
### Nen lam
| Quy tac | Chi tiet | Vi du |
|---------|---------|-------|
| **Dung ten mo ta** | Ten branch phai phan anh ro noi dung thay doi | `feature/PROJ-101-add-user-authentication` |
| **Giu ngan gon** | Chi 3-6 tu khoa, phan cach bang dau `-` | `bugfix/PROJ-202-fix-null-ref` |
| **Viet thuong toan bo** | Khong viet hoa | `feature/add-login` |
| **Dung dau `-` phan cach tu** | Khong dung dau cach, underscore, hoac camelCase | `fix-login-redirect` |
| **Bat dau bang type prefix** | Luon co prefix xac dinh loai branch | `feature/`, `bugfix/`, `hotfix/` |
| **Lien ket ticket ID** | Giup trace nguon goc thay doi | `PROJ-1234-...` |
### Khong nen lam
| Quy tac | Vi du sai | Vi du dung |
|---------|----------|-----------|
| **Khong dung ky tu dac biet** | `feature/add@user#auth` | `feature/add-user-auth` |
| **Khong dung dau cach** | `feature/add user auth` | `feature/add-user-auth` |
| **Khong viet hoa** | `Feature/Add-User-Auth` | `feature/add-user-auth` |
| **Khong dat ten chung chung** | `feature/new-stuff` | `feature/PROJ-101-add-payment-gateway` |
| **Khong dat ten qua dai** | `feature/PROJ-101-add-new-user-authentication-with-jwt-and-refresh-token-support-for-all-roles` | `feature/PROJ-101-add-jwt-auth` |
| **Khong dung so thuong** | `feature/123` | `feature/PROJ-123-add-login` |
| **Khong commit truc tiep vao main/develop** | — | Luon tao branch rieng |
---
## 6. Mo Hinh Git Flow
### So do tong quat
```
main (production)
|
|--- hotfix/PROJ-xxx-fix-critical-bug
| |
| v
| (merge vao main VA develop)
|
|--- release/v1.2.0
| |
| v
| (merge vao main VA develop)
|
develop (integration)
|
|--- feature/PROJ-xxx-new-feature
| |
| v
| (merge vao develop qua Pull Request)
|
|--- bugfix/PROJ-xxx-fix-bug
| |
| v
| (merge vao develop qua Pull Request)
|
|--- chore/update-packages
|
v
(merge vao develop qua Pull Request)
```
### Quy trinh lam viec
1. **Tao branch** tu `develop` (hoac `main` cho hotfix)
2. **Commit** thuong xuyen voi message ro rang
3. **Push** branch len remote
4. **Tao Pull Request** (PR) de review code
5. **Review & Approve** boi it nhat 1 thanh vien khac
6. **Merge** vao branch dich (squash merge hoac merge commit)
7. **Xoa branch** sau khi merge thanh cong
### Lenh Git mau
```bash
# Tao branch feature moi tu develop
git checkout develop
git pull origin develop
git checkout -b feature/PROJ-101-add-login-page
# Lam viec va commit
git add .
git commit -m "feat(PROJ-101): add login page UI"
# Push len remote
git push origin feature/PROJ-101-add-login-page
# Sau khi merge PR, xoa branch local
git checkout develop
git pull origin develop
git branch -d feature/PROJ-101-add-login-page
```
---
## 7. Vi Du Thuc Te Trong Du An
### Ap dung cho du an Clean Architecture (MyNewProjectName)
#### Sprint 1: Khoi tao du an
```bash
# Cau hinh co ban
chore/PROJ-001-setup-clean-architecture
chore/PROJ-002-configure-dependency-injection
chore/PROJ-003-setup-ef-core-database
chore/PROJ-004-add-serilog-logging
chore/PROJ-005-setup-docker-compose
```
#### Sprint 2: Authentication
```bash
# Tinh nang xac thuc
feature/PROJ-010-add-user-entity
feature/PROJ-011-implement-jwt-authentication
feature/PROJ-012-add-refresh-token-flow
feature/PROJ-013-implement-role-authorization
bugfix/PROJ-014-fix-token-validation-error
```
#### Sprint 3: CRUD cho SampleEntity
```bash
# Tinh nang CRUD
feature/PROJ-020-add-sample-entity-crud
feature/PROJ-021-add-pagination-support
feature/PROJ-022-implement-search-filter
bugfix/PROJ-023-fix-sample-delete-cascade
```
#### Hotfix khan cap
```bash
# Sua loi tren production
hotfix/PROJ-099-fix-sql-injection-vulnerability
hotfix/PROJ-100-patch-cors-configuration
```
### Quy uoc Commit Message (di kem voi branch)
De dong bo voi quy uoc branch, nen dung [Conventional Commits](https://www.conventionalcommits.org/):
```
<type>(<scope>): <description>
```
| Type | Muc dich | Vi du |
|------|---------|-------|
| `feat` | Tinh nang moi | `feat(PROJ-101): add login page` |
| `fix` | Sua loi | `fix(PROJ-202): resolve null reference in UserService` |
| `chore` | Bao tri | `chore: update NuGet packages` |
| `docs` | Tai lieu | `docs: update API documentation` |
| `refactor` | Tai cau truc | `refactor: simplify UserRepository queries` |
| `test` | Them/sua test | `test: add unit tests for AuthService` |
| `style` | Format code | `style: apply editorconfig rules` |
| `ci` | CI/CD | `ci: add GitHub Actions workflow` |
---
## 8. Checklist Truoc Khi Tao Branch
- [ ] Ten branch co bat dau bang type prefix khong? (`feature/`, `bugfix/`, `hotfix/`...)
- [ ] Ten branch co chua ticket/issue ID khong? (`PROJ-1234`)
- [ ] Mo ta co ngan gon va ro rang khong? (3-6 tu)
- [ ] Chi dung chu thuong, so, dau `-` va dau `/`?
- [ ] Khong co ky tu dac biet, dau cach, hoac chu viet hoa?
- [ ] Branch duoc tao tu dung branch nguon? (`develop` hoac `main`)
- [ ] Da pull code moi nhat tu branch nguon truoc khi tao?
---
## Tom Tat Nhanh
```
Format: <type>/<ticket-id>-<short-description>
Vi du: feature/PROJ-101-add-user-authentication
Type: feature | bugfix | hotfix | release | chore | docs | test | refactor
Chu y: - Viet thuong toan bo
- Dung dau `-` phan cach tu
- Giu ngan gon (3-6 tu)
- Khong ky tu dac biet
- Lien ket ticket ID
- Xoa branch sau khi merge
```

View File

@@ -0,0 +1,468 @@
# Huong Dan Viet Git Commit Message Trong Du An
> **Tham khao:** [Conventional Commits](https://www.conventionalcommits.org/)
---
## Muc Luc
1. [Nguyen Tac Chung](#1-nguyen-tac-chung)
2. [Cau Truc Commit Message](#2-cau-truc-commit-message)
3. [Cac Loai Type](#3-cac-loai-type)
4. [Scope - Pham Vi Thay Doi](#4-scope---pham-vi-thay-doi)
5. [Quy Tac Viet Description](#5-quy-tac-viet-description)
6. [Commit Message Voi Body Va Footer](#6-commit-message-voi-body-va-footer)
7. [Bang Vi Du Day Du](#7-bang-vi-du-day-du)
8. [Vi Du Thuc Te Trong Du An](#8-vi-du-thuc-te-trong-du-an)
9. [Nhung Loi Thuong Gap](#9-nhung-loi-thuong-gap)
10. [Checklist Truoc Khi Commit](#10-checklist-truoc-khi-commit)
---
## 1. Nguyen Tac Chung
Viet commit message chuan giup:
| # | Loi ich | Mo ta |
|---|---------|-------|
| 1 | **Doc lich su de dang** | Nhin vao git log biet ngay thay doi gi |
| 2 | **Tu dong tao changelog** | Cac tool co the tu dong tao changelog tu commit message |
| 3 | **Lien ket voi issue tracker** | De dang trace commit voi task/ticket |
| 4 | **Review code hieu qua** | Nguoi review hieu nhanh muc dich cua commit |
| 5 | **Tu dong versioning** | Xac dinh phien ban tu dong (semantic versioning) dua tren type |
---
## 2. Cau Truc Commit Message
### Format chung
```
<type>(<scope>): <description>
```
Trong do:
| Thanh phan | Bat buoc | Mo ta | Vi du |
|-----------|----------|-------|-------|
| `type` | Co | Loai thay doi (feat, fix, chore...) | `feat` |
| `scope` | Khong | Pham vi/module bi anh huong | `auth`, `api`, `user` |
| `description` | Co | Mo ta ngan, duoi 50 ky tu, viet hoa dau cau, khong dau cham cuoi | `add Google login` |
### Format day du (voi body va footer)
```
<type>(<scope>): <description>
<body>
<footer>
```
### Vi du nhanh
```
feat(auth): add Google login
fix(api): resolve 404 error
docs(readme): update install guide
chore: update dependencies
```
---
## 3. Cac Loai Type
### Type chinh (thuong dung)
| Type | Muc dich | Anh huong version | Vi du |
|------|---------|-------------------|-------|
| `feat` | Them tinh nang moi | MINOR (1.x.0) | `feat(auth): add Google OAuth` |
| `fix` | Sua loi | PATCH (1.0.x) | `fix(api): resolve 404 error` |
| `docs` | Cap nhat tai lieu | Khong | `docs(readme): update install guide` |
| `style` | Doi format/UI khong anh huong logic | Khong | `style: apply prettier formatting` |
| `refactor` | Tai cau truc code, khong thay doi chuc nang | Khong | `refactor: simplify UserService logic` |
| `perf` | Toi uu hieu nang | PATCH (1.0.x) | `perf: optimize database queries` |
| `test` | Them hoac sua test | Khong | `test: add unit tests for AuthService` |
| `chore` | Thay doi nho, bao tri, CI/CD | Khong | `chore: update dependencies` |
### Type bo sung (it dung hon)
| Type | Muc dich | Vi du |
|------|---------|-------|
| `build` | Thay doi build system hoac dependencies | `build: upgrade to .NET 8` |
| `ci` | Thay doi CI/CD pipeline | `ci: add GitHub Actions workflow` |
| `revert` | Hoan tac commit truoc do | `revert: revert feat(auth): add Google login` |
---
## 4. Scope - Pham Vi Thay Doi
Scope la phan **tuy chon** nam trong dau ngoac `()`, xac dinh module/file/module cu the bi anh huong.
### Danh sach scope khuyen nghi cho du an Clean Architecture
| Scope | Layer/Module | Vi du |
|-------|-------------|-------|
| `domain` | MyNewProjectName.Domain | `feat(domain): add Order entity` |
| `app` | MyNewProjectName.Application | `feat(app): add CreateUserCommand` |
| `infra` | MyNewProjectName.Infrastructure | `feat(infra): configure EF Core DbContext` |
| `api` | MyNewProjectName.WebAPI | `fix(api): resolve CORS issue` |
| `admin` | MyNewProjectName.AdminAPI | `feat(admin): add dashboard endpoint` |
| `contract` | MyNewProjectName.Contracts | `feat(contract): add UserDto` |
| `test` | MyNewProjectName.UnitTest | `test(test): add UserService tests` |
| `auth` | Module xac thuc | `feat(auth): implement JWT refresh token` |
| `cache` | Module caching/Redis | `feat(cache): add Redis caching layer` |
| `db` | Database/Migration | `feat(db): add migration for User table` |
| `docker` | Docker/Container | `chore(docker): update docker-compose` |
| `deps` | Dependencies/NuGet | `chore(deps): update MediatR to v12` |
### Quy tac scope
- Viet thuong toan bo
- Ngan gon, 1-2 tu
- Phai nhat quan trong toan du an
- Co the bo qua neu thay doi anh huong nhieu module
---
## 5. Quy Tac Viet Description
### Nen lam
| Quy tac | Chi tiet | Vi du |
|---------|---------|-------|
| **Viet hoa chu dau** | Chu dau tien cua description viet hoa | `feat: Add login page` |
| **Duoi 50 ky tu** | Giu description ngan gon | `fix: Resolve null reference in UserService` |
| **Dung dong tu menh lenh** | Bat dau bang dong tu (add, fix, update, remove...) | `feat: Add user authentication` |
| **Khong dau cham cuoi** | Khong ket thuc bang dau `.` | `docs: Update README` |
| **Mo ta "lam gi"** | Tap trung vao ket qua, khong phai qua trinh | `fix: Resolve 404 on login redirect` |
### Khong nen lam
| Quy tac | Vi du sai | Vi du dung |
|---------|----------|-----------|
| **Khong viet chung chung** | `fix: Fix bug` | `fix(auth): Resolve token expiration error` |
| **Khong qua dai** | `feat: Add new user authentication with JWT and refresh token and role-based access control` | `feat(auth): Add JWT authentication` |
| **Khong dung qua khu** | `feat: Added login page` | `feat: Add login page` |
| **Khong ghi ten file** | `fix: Fix UserService.cs` | `fix(app): Resolve null ref in user creation` |
| **Khong dung tieng Viet trong type** | `feat: Them trang dang nhap` | `feat: Add login page` |
### Danh sach dong tu khuyen dung
| Dong tu | Khi nao dung | Vi du |
|---------|-------------|-------|
| `add` | Them moi | `feat: Add payment gateway` |
| `remove` | Xoa bo | `refactor: Remove unused imports` |
| `update` | Cap nhat | `docs: Update API documentation` |
| `fix` | Sua loi | `fix: Fix null reference exception` |
| `resolve` | Giai quyet | `fix: Resolve race condition in checkout` |
| `implement` | Hien thuc | `feat: Implement search filter` |
| `refactor` | Tai cau truc | `refactor: Refactor UserRepository` |
| `optimize` | Toi uu | `perf: Optimize query performance` |
| `configure` | Cau hinh | `chore: Configure Serilog logging` |
| `migrate` | Di chuyen/migration | `feat: Migrate user table schema` |
| `replace` | Thay the | `refactor: Replace raw SQL with EF Core` |
| `rename` | Doi ten | `refactor: Rename UserDto to UserResponse` |
| `move` | Di chuyen | `refactor: Move validators to shared folder` |
| `simplify` | Don gian hoa | `refactor: Simplify error handling logic` |
| `extract` | Tach ra | `refactor: Extract email service interface` |
---
## 6. Commit Message Voi Body Va Footer
Khi commit phuc tap, can giai thich them, su dung body va footer:
### Format
```
<type>(<scope>): <description>
<-- dong trong bat buoc
<body>
<-- dong trong bat buoc
<footer>
```
### Vi du 1: Commit co body
```
feat(auth): Add JWT authentication
Implement JWT-based authentication using IdentityServer.
Include access token and refresh token flow.
Configure token expiration to 15 minutes for access token
and 7 days for refresh token.
```
### Vi du 2: Commit co body va footer (lien ket ticket)
```
fix(api): Resolve 500 error on user creation
The API was returning 500 when creating a user with an existing email.
Added proper validation check before inserting into database.
Return 409 Conflict instead of 500 Internal Server Error.
Resolves: PROJ-1234
```
### Vi du 3: Breaking change
```
feat(api)!: Change response format for all endpoints
BREAKING CHANGE: All API responses now follow the new standard format:
{
"success": true,
"data": {},
"message": "",
"errors": []
}
Previous format with flat response body is no longer supported.
Clients must update to handle the new wrapper format.
Resolves: PROJ-5678
```
### Footer keywords
| Keyword | Muc dich | Vi du |
|---------|---------|-------|
| `Resolves:` | Dong issue/ticket | `Resolves: PROJ-1234` |
| `Closes:` | Dong issue tren GitHub | `Closes: #123` |
| `Related:` | Lien quan den issue khac | `Related: PROJ-5678` |
| `BREAKING CHANGE:` | Thay doi khong tuong thich nguoc | `BREAKING CHANGE: API response format changed` |
| `Co-authored-by:` | Dong tac gia | `Co-authored-by: Name <email>` |
| `Reviewed-by:` | Nguoi review | `Reviewed-by: Name <email>` |
---
## 7. Bang Vi Du Day Du
### feat - Them tinh nang moi
```bash
feat(auth): Add Google OAuth login
feat(api): Add pagination support for product list
feat(domain): Add Order entity with value objects
feat(app): Add CreateUserCommand with validation
feat(infra): Add Redis caching for product queries
feat(admin): Add dashboard statistics endpoint
feat(contract): Add OrderResponseDto
```
### fix - Sua loi
```bash
fix(api): Resolve 404 error on login redirect
fix(auth): Fix token expiration calculation
fix(infra): Resolve database connection timeout
fix(app): Fix null reference in GetUserQuery
fix(domain): Fix value object equality comparison
```
### docs - Tai lieu
```bash
docs(readme): Update installation guide
docs(api): Add Swagger annotations for OrderController
docs: Add contributing guidelines
docs: Update environment variables documentation
```
### style - Format code
```bash
style: Apply EditorConfig formatting rules
style(api): Fix indentation in controllers
style: Remove trailing whitespace
```
### refactor - Tai cau truc
```bash
refactor(app): Simplify UserService error handling
refactor(infra): Extract IEmailService interface
refactor: Move validation logic to domain layer
refactor(api): Replace manual mapping with AutoMapper
```
### perf - Toi uu hieu nang
```bash
perf(infra): Optimize database queries with projection
perf(api): Add response compression middleware
perf(cache): Reduce Redis round trips with pipeline
```
### test - Them/sua test
```bash
test(app): Add unit tests for CreateUserCommand
test(domain): Add tests for Order entity validation
test(infra): Add integration tests for UserRepository
test: Increase code coverage to 80%
```
### chore - Bao tri
```bash
chore: Update NuGet packages
chore(deps): Upgrade to .NET 8
chore(docker): Update docker-compose configuration
chore(ci): Add GitHub Actions build workflow
chore: Update .gitignore
```
### build - Build system
```bash
build: Upgrade to .NET 8 SDK
build: Add Directory.Build.props for shared config
build: Configure multi-stage Docker build
```
### ci - CI/CD
```bash
ci: Add GitHub Actions workflow for PR checks
ci: Configure automatic deployment to staging
ci: Add SonarQube code analysis step
```
---
## 8. Vi Du Thuc Te Trong Du An
### Luong lam viec mot feature hoan chinh
Gia su lam task PROJ-101: Them tinh nang dang nhap
```bash
# 1. Tao branch
git checkout -b feature/PROJ-101-add-login
# 2. Them entity va domain logic
git commit -m "feat(domain): Add User entity with email and password"
# 3. Them command/query
git commit -m "feat(app): Add LoginCommand with FluentValidation"
# 4. Them infrastructure
git commit -m "feat(infra): Implement UserRepository with EF Core"
git commit -m "feat(infra): Add password hashing service"
# 5. Them API endpoint
git commit -m "feat(api): Add AuthController with login endpoint"
# 6. Them test
git commit -m "test(app): Add unit tests for LoginCommand handler"
# 7. Cap nhat tai lieu
git commit -m "docs(api): Add Swagger docs for auth endpoints"
# 8. Push va tao PR
git push origin feature/PROJ-101-add-login
```
### Luong sua loi
```bash
# 1. Tao branch
git checkout -b bugfix/PROJ-202-fix-login-error
# 2. Sua loi
git commit -m "fix(auth): Resolve incorrect password validation logic"
# 3. Them test cho truong hop loi
git commit -m "test(auth): Add test for invalid password scenario"
# 4. Push va tao PR
git push origin bugfix/PROJ-202-fix-login-error
```
### Luong hotfix khan cap
```bash
# 1. Tao branch tu main
git checkout main
git checkout -b hotfix/PROJ-303-fix-sql-injection
# 2. Sua loi
git commit -m "fix(infra): Sanitize SQL parameters to prevent injection
The raw SQL query in SearchRepository was concatenating user input
directly into the query string. Replaced with parameterized query
using EF Core's FromSqlInterpolated method.
Resolves: PROJ-303"
# 3. Push va tao PR vao main
git push origin hotfix/PROJ-303-fix-sql-injection
```
---
## 9. Nhung Loi Thuong Gap
| # | Loi sai | Vi du sai | Vi du dung |
|---|--------|----------|-----------|
| 1 | **Message qua chung chung** | `fix: Fix bug` | `fix(auth): Resolve token expiration error` |
| 2 | **Khong co type** | `Add login page` | `feat: Add login page` |
| 3 | **Dung qua khu** | `feat: Added new feature` | `feat: Add new feature` |
| 4 | **Qua nhieu thay doi trong 1 commit** | `feat: Add login, register, forgot password` | Tach thanh 3 commit rieng |
| 5 | **Commit file khong lien quan** | Commit ca file config lan feature | Chi commit file lien quan |
| 6 | **Message tieng Viet** | `feat: Them trang dang nhap` | `feat: Add login page` |
| 7 | **Dau cham cuoi** | `feat: Add login page.` | `feat: Add login page` |
| 8 | **Khong co scope khi can thiet** | `fix: Fix null reference` | `fix(app): Resolve null ref in GetUserQuery` |
| 9 | **Type sai** | `feat: Fix bug` | `fix: Resolve login error` |
| 10 | **Description qua dai** | 100+ ky tu tren 1 dong | Giu duoi 50 ky tu, dung body cho chi tiet |
---
## 10. Checklist Truoc Khi Commit
- [ ] Commit message co dung format `<type>(<scope>): <description>` khong?
- [ ] Type co chinh xac khong? (feat, fix, docs, style, refactor, perf, test, chore)
- [ ] Scope co phan anh dung module bi anh huong khong?
- [ ] Description co duoi 50 ky tu khong?
- [ ] Description co bat dau bang dong tu menh lenh khong? (add, fix, update...)
- [ ] Description co viet hoa chu dau khong?
- [ ] Khong co dau cham cuoi trong description?
- [ ] Moi commit chi chua 1 thay doi logic duy nhat?
- [ ] Commit co lien ket ticket ID khong? (trong scope hoac footer)
- [ ] Neu la breaking change, da danh dau `!` va them `BREAKING CHANGE:` trong footer?
---
## Tom Tat Nhanh
```
Format: <type>(<scope>): <description>
Type: feat | fix | docs | style | refactor | perf | test | chore | build | ci | revert
Scope: domain | app | infra | api | admin | contract | test | auth | cache | db | docker | deps
Vi du:
feat(auth): Add Google OAuth login # scope = "auth" (module authentication)
fix(api): Resolve 404 error # scope = "api" (API endpoints)
docs(readme): Update install guide # scope = "readme" (file/module cu the)
feat: Them tinh nang moi (VD: feat(login): Add Google OAuth).
fix: Sua loi (VD: fix(api): Resolve 404 error).
docs: Cap nhat tai lieu.
style: Doi format/UI khong anh huong logic.
refactor: Tai cau truc code.
perf: Toi uu hieu nang.
chore: Thay doi nho (VD: chore: Update dependencies).
Quy tac:
- Type va scope viet thuong
- Description viet hoa chu dau, duoi 50 ky tu
- Dung dong tu menh lenh (add, fix, update, remove, implement...)
- Khong dau cham cuoi
- 1 commit = 1 thay doi logic
- Lien ket ticket ID khi co the
```

394
base/.agent/rules/Redis.md Normal file
View File

@@ -0,0 +1,394 @@
---
trigger: always_on
---
# Hướng Dẫn Đặt Tên Redis Key Trong Dự Án
> **Tham khảo:** [Redis Namespace and Other Keys to Developing with Redis](https://redis.io/blog/5-key-takeaways-for-developing-with-redis/)
---
## Mục Lục
1. [Nguyên Tắc Chung](#1-nguyên-tắc-chung)
2. [Quy Ước Đặt Tên Key (Naming Convention)](#2-quy-ước-đặt-tên-key-naming-convention)
3. [Cấu Trúc Key Theo Namespace](#3-cấu-trúc-key-theo-namespace)
4. [Bảng Mẫu Key Theo Chức Năng](#4-bảng-mẫu-key-theo-chức-năng)
5. [Quy Tắc Về Độ Dài Key](#5-quy-tắc-về-độ-dài-key)
6. [Chọn Đúng Data Structure](#6-chọn-đúng-data-structure)
7. [Quản Lý Key: SCAN thay vì KEYS](#7-quản-lý-key-scan-thay-vì-keys)
8. [Chiến Lược TTL & Expiration](#8-chiến-lược-ttl--expiration)
9. [Cache Invalidation](#9-cache-invalidation)
10. [Ví Dụ Thực Tế Trong Dự Án](#10-ví-dụ-thực-tế-trong-dự-án)
---
## 1. Nguyên Tắc Chung
Theo bài viết từ Redis, có **5 điểm quan trọng** khi phát triển với Redis:
| # | Nguyên tắc | Mô tả |
|---|-----------|-------|
| 1 | **Namespace cho key** | Sử dụng dấu `:` để phân tách các phần của tên key, giúp dễ quản lý và tìm kiếm |
| 2 | **Giữ key ngắn gọn** | Key name cũng chiếm bộ nhớ — key dài 12 ký tự tốn thêm ~15% RAM so với key 6 ký tự (trên 1 triệu key) |
| 3 | **Dùng đúng data structure** | Hash, List, Set, Sorted Set — mỗi loại phù hợp với một use case khác nhau |
| 4 | **Dùng SCAN, không dùng KEYS** | Lệnh `KEYS` có thể block server, `SCAN` an toàn hơn cho production |
| 5 | **Sử dụng Lua Scripts** | Xử lý logic phía server để giảm latency và tối ưu hiệu suất |
---
## 2. Quy Ước Đặt Tên Key (Naming Convention)
### Format chung
```
{project}:{service}:{entity}:{identifier}
```
- **Dấu phân cách:** Luôn dùng dấu hai chấm `:` (colon) — đây là **convention chuẩn** của Redis
- **Chữ thường:** Tất cả các phần của key đều viết **lowercase**
- **Không dấu cách, không ký tự đặc biệt:** Chỉ dùng chữ cái, số, dấu `:` và dấu `-` hoặc `_`
### Đúng
```
myapp:user:profile:12345
myapp:order:detail:ORD-001
myapp:cache:product:list:page:1
```
### Sai
```
MyApp_User_Profile_12345 # Dùng underscore thay vì colon, viết hoa
user profile 12345 # Có dấu cách
MYAPP:USER:PROFILE:12345 # Viết hoa toàn bộ (lãng phí bộ nhớ)
```
---
## 3. Cấu Trúc Key Theo Namespace
Áp dụng cho dự án **Clean Architecture**, cấu trúc key nên phản ánh rõ layer và module:
```
{app}:{layer}:{entity}:{action/scope}:{identifier}
```
### Các prefix theo layer
| Prefix | Ý nghĩa | Ví dụ |
|--------|---------|-------|
| `app:cache` | Cache dữ liệu | `app:cache:product:list` |
| `app:session` | Quản lý session | `app:session:user:abc123` |
| `app:rate` | Rate limiting | `app:rate:api:login:192.168.1.1` |
| `app:lock` | Distributed lock | `app:lock:order:process:ORD-001` |
| `app:queue` | Message queue | `app:queue:email:pending` |
| `app:temp` | Dữ liệu tạm thời | `app:temp:otp:user:12345` |
| `app:pub` | Pub/Sub channels | `app:pub:notifications:user:12345` |
| `app:counter` | Bộ đếm | `app:counter:visit:page:home` |
---
## 4. Bảng Mẫu Key Theo Chức Năng
### Authentication & Authorization
| Key Pattern | Data Type | TTL | Mô tả |
|------------|-----------|-----|--------|
| `app:session:{sessionId}` | Hash | 30 phút | Thông tin session người dùng |
| `app:token:refresh:{userId}` | String | 7 ngày | Refresh token |
| `app:token:blacklist:{jti}` | String | Thời gian còn lại của token | JWT bị thu hồi |
| `app:temp:otp:{userId}` | String | 5 phút | Mã OTP xác thực |
| `app:rate:login:{ip}` | String (counter) | 15 phút | Giới hạn số lần đăng nhập |
### Cache Dữ Liệu (CRUD)
| Key Pattern | Data Type | TTL | Mô tả |
|------------|-----------|-----|--------|
| `app:cache:{entity}:detail:{id}` | Hash/String | 10 phút | Cache chi tiết 1 entity |
| `app:cache:{entity}:list:{hash}` | String (JSON) | 5 phút | Cache danh sách có phân trang/filter |
| `app:cache:{entity}:count` | String | 5 phút | Cache tổng số record |
| `app:cache:{entity}:ids:all` | Set | 10 phút | Tập hợp tất cả ID của entity |
> **`{hash}`** là hash MD5/SHA256 của query parameters (page, filter, sort) để tạo key unique cho mỗi truy vấn khác nhau.
### 🔔 Real-time & Pub/Sub
| Key Pattern | Data Type | TTL | Mô tả |
|------------|-----------|-----|--------|
| `app:pub:notification:{userId}` | Channel | — | Kênh thông báo realtime |
| `app:queue:email:pending` | List | — | Hàng đợi gửi email |
| `app:counter:online:users` | String | — | Đếm user đang online |
### 🔒 Distributed Locking
| Key Pattern | Data Type | TTL | Mô tả |
|------------|-----------|-----|--------|
| `app:lock:{resource}:{id}` | String | 30 giây | Lock tài nguyên để tránh race condition |
---
## 5. Quy Tắc Về Độ Dài Key
Theo bài viết từ Redis:
> *"Storing 1,000,000 keys, each set with a 32-character value, will consume about **96MB** when using 6-character key names, and **111MB** with 12-character names. This overhead of more than **15%** becomes quite significant as your number of keys grows."*
### Hướng dẫn cân bằng
| Quy tắc | Chi tiết |
|---------|---------|
| **Tối đa 50 ký tự** | Giữ tổng chiều dài key không quá 50 ký tự |
| **Viết tắt hợp lý** | `usr` thay vì `user`, `prod` thay vì `product` — nhưng phải có **bảng chú giải** |
| **Không lạm dụng viết tắt** | Key phải đọc được, tránh như `a:b:c:d:1` |
| **Ưu tiên rõ ràng nếu < 10K keys** | Nếu dataset nhỏ, ưu tiên key dễ đọc hơn key ngắn |
### Bảng viết tắt chuẩn (nếu cần tối ưu)
| Viết tắt | Đầy đủ |
|----------|--------|
| `usr` | user |
| `prod` | product |
| `ord` | order |
| `sess` | session |
| `notif` | notification |
| `cfg` | config |
| `inv` | inventory |
| `txn` | transaction |
---
## 6. Chọn Đúng Data Structure
Theo bài viết, việc chọn đúng cấu trúc dữ liệu giúp **tối ưu bộ nhớ và hiệu suất**:
| Data Structure | Khi nào dùng | Ví dụ trong dự án |
|---------------|-------------|-------------------|
| **String** | Giá trị đơn giản, counter, cache JSON | `app:cache:product:detail:123` → JSON string |
| **Hash** | Object có nhiều field, profile user | `app:session:abc123``{userId, role, name, exp}` |
| **List** | Queue, danh sách có thứ tự, cho phép trùng | `app:queue:email:pending` → FIFO queue |
| **Set** | Tập hợp unique, kiểm tra membership | `app:cache:user:ids:all` → tập hợp user IDs |
| **Sorted Set** | Leaderboard, ranking, timeline | `app:rank:score:board:game1` → ranking theo điểm |
| **Bitmap** | Track true/false cho lượng lớn, analytics | `app:analytics:daily:login:2026-02-23` → bit per user |
### 💡 Tips quan trọng:
- **Hash thay vì nhiều String**: Nhóm dữ liệu liên quan vào 1 Hash thay vì tạo nhiều key String riêng lẻ → tiết kiệm bộ nhớ đáng kể
- **List thay vì Set**: Nếu không cần kiểm tra uniqueness, List nhanh hơn và tốn ít RAM hơn
- **Tránh Sorted Set nếu không cần ranking**: Sorted Set tốn nhiều bộ nhớ và phức tạp nhất
---
## 7. Quản Lý Key: SCAN thay vì KEYS
### ⚠️ KHÔNG BAO GIỜ dùng `KEYS` trong production!
Lệnh `KEYS *` sẽ:
- **Block toàn bộ Redis server** cho đến khi hoàn thành
- **Tiêu tốn RAM** nguy hiểm
- Gây **downtime** nếu dataset lớn
### Dùng `SCAN` để duyệt key an toàn
```bash
# Cú pháp
SCAN cursor [MATCH pattern] [COUNT count]
# Ví dụ: Tìm tất cả cache key của product
SCAN 0 MATCH "app:cache:product:*" COUNT 100
# Dùng HSCAN cho Hash
HSCAN app:session:abc123 0 MATCH "*"
# Dùng SSCAN cho Set
SSCAN app:cache:user:ids:all 0 COUNT 50
```
### Trong code C# (StackExchange.Redis):
```csharp
// Đúng: Dùng SCAN
var server = redis.GetServer(endpoint);
var keys = server.Keys(pattern: "app:cache:product:*", pageSize: 100);
// Sai: Dùng KEYS (block server)
// var keys = server.Keys(pattern: "app:cache:product:*", pageSize: int.MaxValue);
```
---
## 8. Chiến Lược TTL & Expiration
| Loại dữ liệu | TTL khuyến nghị | Lý do |
|--------------|----------------|-------|
| **Cache API response** | 5 15 phút | Đảm bảo data tương đối fresh |
| **Session** | 30 phút 2 giờ | Theo session timeout của app |
| **OTP / Verification** | 3 10 phút | Bảo mật |
| **Refresh Token** | 7 30 ngày | Theo chính sách auth |
| **Rate Limit Counter** | 1 60 phút | Theo window rate limit |
| **Distributed Lock** | 10 60 giây | Tránh deadlock |
| **Analytics / Counter** | Không expire hoặc 24h | Tùy yêu cầu business |
### ⚡ Luôn đặt TTL cho mọi cache key!
```csharp
// Luôn set expiration khi SET
await db.StringSetAsync("app:cache:product:detail:123", jsonData, TimeSpan.FromMinutes(10));
// Hoặc set TTL riêng
await db.KeyExpireAsync("app:cache:product:detail:123", TimeSpan.FromMinutes(10));
```
> ⚠️ **Cảnh báo:** Key không có TTL sẽ tồn tại mãi mãi → nguy cơ memory leak!
---
## 9. Cache Invalidation
Khi dữ liệu thay đổi trong database chính (SQL, MongoDB...), cần **xóa cache Redis tương ứng**:
### Pattern: Tag-based Invalidation
```
# Khi tạo cache, thêm key vào một Set quản lý
SADD app:tags:product app:cache:product:detail:123
SADD app:tags:product app:cache:product:list:abc
SADD app:tags:product app:cache:product:count
# Khi invalidate, duyệt Set và xóa tất cả
SMEMBERS app:tags:product → lấy tất cả key liên quan
DEL app:cache:product:detail:123 app:cache:product:list:abc ...
DEL app:tags:product
```
### Trong code C#:
```csharp
public async Task InvalidateCacheByTagAsync(string tag)
{
var db = _redis.GetDatabase();
var tagKey = $"app:tags:{tag}";
// Lấy tất cả cache key thuộc tag này
var members = await db.SetMembersAsync(tagKey);
if (members.Length > 0)
{
// Xóa tất cả cache key
var keys = members.Select(m => (RedisKey)m.ToString()).ToArray();
await db.KeyDeleteAsync(keys);
}
// Xóa luôn tag set
await db.KeyDeleteAsync(tagKey);
}
```
---
## 10. Ví Dụ Thực Tế Trong Dự Án
Áp dụng quy ước cho dự án **MyNewProjectName** (Clean Architecture):
### Entity: `SampleEntity`
```
# Cache chi tiết
app:cache:sample:detail:{id}
# Cache danh sách (hash = MD5 của query params)
app:cache:sample:list:{queryHash}
# Cache count
app:cache:sample:count
# Tag để invalidation
app:tags:sample → Set chứa tất cả key cache liên quan
# Lock khi cập nhật
app:lock:sample:update:{id}
```
### Authentication Flow
```
# Session sau khi login
app:session:{sessionId} → Hash { userId, role, loginAt, ip }
# Refresh token
app:token:refresh:{userId} → "eyJhbGciOi..."
# OTP xác thực email
app:temp:otp:{userId} → "123456" (TTL: 5 phút)
# Blacklist JWT đã revoke
app:token:blacklist:{jti} → "1" (TTL: thời gian còn lại của token)
# Rate limit login
app:rate:login:{ip} → counter (TTL: 15 phút, max: 5 lần)
```
### Constant class trong C#
```csharp
/// <summary>
/// Định nghĩa tất cả Redis key patterns sử dụng trong dự án.
/// Sử dụng dấu ':' làm namespace separator theo convention chuẩn Redis.
/// </summary>
public static class RedisKeyPatterns
{
private const string Prefix = "app";
// ── Cache ──────────────────────────────────
public static string CacheDetail(string entity, string id)
=> $"{Prefix}:cache:{entity}:detail:{id}";
public static string CacheList(string entity, string queryHash)
=> $"{Prefix}:cache:{entity}:list:{queryHash}";
public static string CacheCount(string entity)
=> $"{Prefix}:cache:{entity}:count";
// ── Tags (cho cache invalidation) ──────────
public static string Tag(string entity)
=> $"{Prefix}:tags:{entity}";
// ── Session ────────────────────────────────
public static string Session(string sessionId)
=> $"{Prefix}:session:{sessionId}";
// ── Token ──────────────────────────────────
public static string RefreshToken(string userId)
=> $"{Prefix}:token:refresh:{userId}";
public static string BlacklistToken(string jti)
=> $"{Prefix}:token:blacklist:{jti}";
// ── Temporary ──────────────────────────────
public static string Otp(string userId)
=> $"{Prefix}:temp:otp:{userId}";
// ── Rate Limiting ──────────────────────────
public static string RateLimit(string action, string identifier)
=> $"{Prefix}:rate:{action}:{identifier}";
// ── Distributed Lock ───────────────────────
public static string Lock(string resource, string id)
=> $"{Prefix}:lock:{resource}:{id}";
}
```
---
## 📋 Checklist Trước Khi Tạo Key Mới
- [ ] Key có sử dụng namespace với dấu `:` không?
- [ ] Key có phản ánh đúng layer/module không?
- [ ] Key có ngắn gọn nhưng vẫn dễ hiểu không? (< 50 ký tự)
- [ ] Đã chọn đúng data structure (String/Hash/List/Set/Sorted Set)?
- [ ] Đã đặt TTL phù hợp cho key?
- [ ] Đã có chiến lược invalidation khi data thay đổi?
- [ ] Đã thêm key pattern vào class `RedisKeyPatterns`?
- [ ] Không dùng `KEYS` command trong code production?
---
> **💡 Ghi nhớ:** *"Luôn namespace key bằng dấu `:`, giữ key ngắn gọn, chọn đúng data structure, dùng SCAN thay vì KEYS, và luôn đặt TTL!"*

View File

@@ -0,0 +1,126 @@
---
name: GenerateGitHubActions
description: Hướng dẫn tạo CI/CD pipeline tự động hóa Build, Test, Docker Build & Deploy bằng GitHub Actions.
---
# GenerateGitHubActions Skill
Khi user yêu cầu tạo CI/CD Pipelines (ví dụ: GitHub Actions, hoặc tương đương cho GitLab CI / Azure DevOps), bạn cần sinh ra file luồng tự động hóa theo các bước chuẩn sau đây.
## Mục đích
- Tự động hóa quá trình kiểm tra mã nguồn (CI) và triển khai (CD).
- Đảm bảo code push lên nhánh `main` luôn hoạt động đúng đắn và sẵn sàng lên production.
## Hướng dẫn sinh cấu hình (GitHub Actions)
Tạo file luồng công việc Workflow cho GitHub Actions.
### 1. Đường dẫn và tên file
- **Đường dẫn**: `.github/workflows/ci-cd.yml`
- (Hoặc theo định dạng của platform tương ứng: `.gitlab-ci.yml` cho GitLab, `azure-pipelines.yml` cho Azure DevOps).
### 2. Các bước cấu hình bắt buộc trong file YAML
Workflow cần trải qua các luồng chính sau (mẫu dưới dây cho GitHub Actions):
#### Phân đoạn 1: Build & Test (CI)
- **Triggers**: Lắng nghe sự kiện `push` hoặc `pull_request` vào nhánh `main`.
- **Setup môi trường**:
- Checkout mã nguồn (ví dụ dùng `actions/checkout@v4`).
- Cài đặt .NET SDK tương ứng với dự án (ví dụ `actions/setup-dotnet@v4` cho .NET 8.0). **Lưu ý: Bật tính năng cache Nuget để tăng tốc độ build.**
- **Run Tests**:
- Chạy khối lệnh `dotnet restore`, `dotnet build --no-restore`.
- Quan trọng nhất: Chạy `dotnet test --no-build --verbosity normal`. (Chỉ khi Test Xanh (Passed) thì các bước sau mới được chạy tiếp).
#### Phân đoạn 2: Docker Build & Push (Bắt đầu CD)
- **Cần điều kiện**: Chỉ chạy khi Job Build & Test thành công (`needs: build`).
- **Đăng nhập Container Registry**:
- Login vào Docker Hub hoặc Azure Container Registry (ACR) sử dụng System Secrets (ví dụ `DOCKER_USERNAME``DOCKER_PASSWORD`).
- **Build & Push Image**:
- Build Image từ Dockerfile (chú ý chỉ đường dẫn thư mục gốc nơi chứa dự án chính để `docker build` có thể truy cập qua các tầng thư mục Clean Architecture).
- Gắn tag cho Image (ví dụ: `latest` hoặc theo Commit SHA/phiên bản).
- Push Image lên Registry.
#### Phân đoạn 3: Deploy to Server (CD - Webhook / SSH)
- Dùng thư viện `appleboy/ssh-action` (hoặc tương tự) để SSH vào Server đích.
- Yêu cầu server pull file Image mới nhất từ Registry.
- **Quan trọng:** Ưu tiên sử dụng `docker compose` để deploy (pull và up) nếu cấu trúc dự án của user có file `docker-compose.yml`, giúp khởi động lại toàn bộ stack (API, DB, Redis...) thay vì chỉ chạy `docker run` độc lập.
## Mẫu File Mặc Định (`ci-cd.yml`)
Dưới đây là khung mẫu bạn cần căn cứ để thiết kế khi sinh file cho user:
```yaml
name: CI/CD Pipeline
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
cache: true # Bật cache Nuget, lần sau build nhanh gấp đôi
cache-dependency-path: '**/packages.lock.json'
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --no-restore
- name: Test
run: dotnet test --no-build --verbosity normal
docker-build-push:
needs: build-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/chi-tiet-ten-project-lowercase:latest
deploy:
needs: docker-build-push
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SERVER_SSH_KEY }}
script: |
cd /path/to/your/project/on/server # Trỏ tới thư mục chứa docker-compose.yml
docker compose pull # Kéo image mới nhất về (dựa theo file compose)
docker compose up -d --build # Khởi động lại các service có sự thay đổi
```
## Lưu ý cho AI Agent
- Khi User yêu cầu sinh pipeline, hãy yêu cầu User xác nhận về tên tài khoản Docker Hub, Server Credentials và nhắc họ cấu hình đầy đủ `Secrets` trên GitHub sau khi sinh file.
- **Hãy tự động thay thế chuỗi tên project (`chi-tiet-ten-project-lowercase` trong mẫu) bằng tên thật của Project / Repository mà User đang thao tác. Chuyển tất cả về chữ thường (lowercase) khi đặt tên Docker Image để tránh lỗi định dạng của Docker.**
- **Nếu user có dùng `docker-compose`, hãy ưu tiên sinh lệnh `docker compose up -d` thay vì `docker run` thuần.**

View File

@@ -0,0 +1,34 @@
---
name: GenerateCQRSFeature
description: Hướng dẫn tạo một feature theo chuẩn CQRS sử dụng MediatR (bao gồm Entity, Command/Query, Handler, và Controller).
---
# GenerateCQRSFeature Skill
Khi user yêu cầu tạo một feature theo luồng **CQRS** với đầu vào bao gồm **Tên Feature** (VD: `Order`) và **Action** (VD: `Create`), bạn **BẮT BUỘC** phải thực hiện các bước sau để sinh ra code và file tương ứng:
## 1. Đầu ra thư mục và file (Outputs)
Dựa trên {FeatureName} và {Action}, hãy tạo các file sau (nếu action thuộc loại Read/Get thì đổi 'Commands' thành 'Queries'):
1. **Domain Entity**
- **Đường dẫn**: `Domain/Entities/{FeatureName}.cs`
- **Nội dung**: Lớp Entity cơ bản định nghĩa các thuộc tính.
2. **Command / Query**
- **Đường dẫn**: `Application/Features/{FeatureName}s/Commands/{Action}{FeatureName}/{Action}{FeatureName}Command.cs`
- **Nội dung**: Input model kế thừa từ `IRequest<TResponse>` của MediatR.
3. **Command / Query Handler**
- **Đường dẫn**: `Application/Features/{FeatureName}s/Commands/{Action}{FeatureName}/{Action}{FeatureName}CommandHandler.cs`
- **Nội dung**: Xử lý logic nghiệp vụ, implements `IRequestHandler<{Action}{FeatureName}Command, TResponse>`. Inject Repository hoặc service cần thiết vào đây.
4. **WebAPI Controller**
- **Đường dẫn**: `WebAPI/Controllers/{FeatureName}sController.cs` (Lưu ý thêm số nhiều cho tên Controller nếu cần thiết).
- **Nội dung**: REST API endpoints. **Yêu cầu:** Nhận DI `IMediator` qua constructor để điều hướng Request (ví dụ gọi `await _mediator.Send(command)`).
## 2. Cấu hình Dependency Injection (KHÔNG CẦN LÀM)
⚠️ **Lưu ý:** Như nguyên tắc thiết lập project, luồng CQRS **KHÔNG CẦN** update file cấu hình Dependency Injection (DI configuration).
Thư viện MediatR đã tự động quét (Auto-register) tất cả các lớp Handler kế thừa từ `IRequestHandler`, vì thế bạn **TUYỆT ĐỐI BỎ QUA** việc cập nhật các file config DI cho phần Handler này.

View File

@@ -0,0 +1,40 @@
---
name: GenerateNTierFeature
description: Hướng dẫn tạo một feature theo chuẩn N-Tier (bao gồm Entity, Interface, Service, Controller và cấu hình Dependency Injection).
---
# GenerateNTierFeature Skill
Khi user yêu cầu tạo một feature theo luồng **N-Tier** với đầu vào là **Tên Feature** (VD: `Category`), bạn **BẮT BUỘC** phải thực hiện các bước sau để sinh ra code và file tương ứng:
## 1. Đầu ra thư mục và file (Outputs)
Hãy tạo các file sau với nội dung phù hợp cho {FeatureName}:
1. **Domain Entity**
- **Đường dẫn**: `Domain/Entities/{FeatureName}.cs`
- **Nội dung**: Lớp Entity cơ bản định nghĩa các thuộc tính.
2. **Service Interface**
- **Đường dẫn**: `Application/Interfaces/I{FeatureName}Service.cs`
- **Nội dung**: Các interface định nghĩa hợp đồng hàm cho {FeatureName}.
3. **Service Implementation**
- **Đường dẫn**: `Application/Services/{FeatureName}Service.cs`
- **Nội dung**: Lớp kế thừa từ `I{FeatureName}Service`. **Yêu cầu:** Nhận Dependency Injection (DI) thông qua constructor (ví dụ: `IRepository<{FeatureName}>`).
4. **WebAPI Controller**
- **Đường dẫn**: `WebAPI/Controllers/{FeatureName}sController.cs` (Lưu ý thêm số nhiều cho tên Controller).
- **Nội dung**: Lớp Controller. **Yêu cầu:** Phải nhận DI `I{FeatureName}Service` thông qua constructor và định nghĩa các endpoint tương ứng.
## 2. Cấu hình Dependency Injection (BƯỚC BẮT BUỘC THỰC HIỆN)
⚠️ **Quan trọng:** Không giống như CQRS với MediatR ở trên, luồng N-Tier **đòi hỏi** bạn phải chèn thủ công service mới tạo vào Container IoC.
Bạn **BẮT BUỘC** phải sử dụng tool để mở file cấu hình DI của project (có thể là `DependencyInjection.cs` hoặc `ServiceCollectionExtensions.cs` tùy cấu trúc thư mục) và chèn đoạn mã sau vào hàm cấu hình service liên quan:
```csharp
services.AddScoped<I{FeatureName}Service, {FeatureName}Service>();
```
Hãy đảm bảo bạn dùng công cụ sửa file chính xác (`replace_file_content` hoặc `multi_replace_file_content`) để không làm hỏng cú pháp của file DI.

View File

@@ -0,0 +1,49 @@
---
name: GenerateArchitectureTest
description: Hướng dẫn tạo Architecture Test sử dụng NetArchTest.Rules để bảo vệ kiến trúc Clean Architecture.
---
# GenerateArchitectureTest Skill
Khi user yêu cầu kiểm tra hoặc khởi tạo **Architecture Test**, bạn cần sử dụng thư viện `NetArchTest.Rules` để sinh luận kiểm điểm nhằm bảo vệ chặt chẽ cấu trúc "Clean Architecture" của dự án.
## Mục đích
- Ngăn chặn Dev code ẩu, import sai library/module giữa các tầng (layer).
- Nếu vi phạm (VD: import Entity Framework vào tầng Domain), bài test này sẽ báo ĐỎ ngay lập tức lúc build code. Bằng chứng thép giúp kiến trúc được bảo vệ tuyệt đối!
## Hướng dẫn viết Test Rules
Bạn cần viết các test method (dùng `[Fact]` với xUnit hoặc NUnit) sử dụng Fluent API của `NetArchTest.Rules`. Dưới đây là các luật phổ biến bắt buộc:
1. **Domain Layer Rules (Luật tầng Domain):**
- Domain không được phụ thuộc vào bất cứ thứ gì từ Infrastructure, Application hay WebAPI.
```csharp
[Fact]
public void DomainLayer_ShouldNot_HaveDependencyOn_OtherLayers()
{
var result = Types.InAssembly(DomainAssembly)
.ShouldNot()
.HaveDependencyOnAny(
"MyNewProjectName.Application",
"MyNewProjectName.Infrastructure",
"MyNewProjectName.WebAPI"
)
.GetResult();
Assert.True(result.IsSuccessful);
}
```
2. **Application Layer Rules (Luật tầng Application):**
- Application Layer chỉ được phép giao tiếp với Domain, KHÔNG ĐƯỢC có dependency vào `Infrastructure` hoặc `WebAPI`.
3. **Controller Rules (Luật đặt tên/vị trí API):**
- Controller bắt buộc phải kế thừa class BaseAPIController, và có hậu tố là "Controller".
- Không được phép truy vấn Database trực tiếp từ Controller (ngăn không cho Inject `DbContext` hay `IRepository` vào Controller, kiểm duyệt dependencies của Constructor).
4. **Handler Rules (CQRS):**
- Các Handler xử lý logic phải implements interface `IRequestHandler` và kết thúc bằng `CommandHandler` hoặc `QueryHandler`. Nó chỉ nằm ở Application Layer.
## Định dạng file đầu ra
- **Đường dẫn:** Chứa trong test project như `tests/MyNewProjectName.ArchitectureTests/`.
- **Tên file:** Thường đặt tên theo phạm vi test như `LayerTests.cs`, `DesignConventionTests.cs`, `NamingRulesTests.cs`, v.v.

View File

@@ -0,0 +1,34 @@
---
name: GenerateIntegrationTest
description: Hướng dẫn tạo Integration Test (người thật việc thật) sử dụng WebApplicationFactory và Testcontainers.
---
# GenerateIntegrationTest Skill
Khi user yêu cầu tạo **Integration Test** để kiểm tra API endpoint từ đầu đến cuối, bạn cần sinh ra code theo hướng dẫn sau:
## Mục đích
- Test xem các mảnh ghép lắp vào ghép với nhau có chạy đúng không.
- Flow: Client gọi API -> Middleware -> Controller -> CQRS Handler/Service -> Ghi/Đọc Database thật.
## Hướng dẫn thực hiện
1. **Setup WebApplicationFactory:**
- Tự động setup `WebApplicationFactory<Program>` (tạo một test server ngay trong RAM của .NET).
- Override cấu hình ứng dụng nếu cần thiết (ví dụ thay đổi ConnectionString trỏ sang test container).
2. **Setup Testcontainers (Real Database):**
- Sử dụng thư viện `Testcontainers` (hoặc cấu hình tương tự) để tự động spin up một Docker container chứa Database thật (ví dụ: PostgreSQL, SQL Server).
- Đảm bảo database container này được start trước khi chạy test và tự động xóa (dispose) sau khi test xong. Tránh dùng SQLite in-memory vì hay bị lỗi vặt và không tương đương với database production.
3. **Viết kịch bản Test gọi API (Arrange - Act - Assert):**
- Tạo đối tượng `HttpClient` từ `WebApplicationFactory.CreateClient()`.
- **Arrange:** Chuẩn bị payload data dạng JSON objects hoặc tạo trước data base records nếu là API GET/PUT/DELETE.
- **Act:** Gọi thẳng vào API endpoint tương ứng bằng code. VD: `await client.PostAsJsonAsync("/api/v1/samples", payload);`.
- **Assert:** Kiểm tra kết quả trả về:
- Check HTTP Status: có phải `200 OK` hay `400 Bad Request` không.
- Deserialize response body để check chính xác object.
- (Tùy chọn) Query thẳng vào database container xem bản ghi đã được sinh ra/cập nhật thật chưa.
## Định dạng file đầu ra
- **Đường dẫn:** Chứa trong project test tương ứng như `tests/MyNewProjectName.IntegrationTests/Controllers/...`.
- **Tên file:** `[ControllerName]Tests.cs` (ví dụ: `OrdersControllerTests.cs`).

View File

@@ -0,0 +1,32 @@
---
name: GenerateUnitTest
description: Hướng dẫn tạo Unit Test cô lập (tốc độ cao) sử dụng Mocking (Moq hoặc NSubstitute).
---
# GenerateUnitTest Skill
Khi user yêu cầu tạo **Unit Test** cho một class/method, bạn cần tuân thủ các nguyên tắc sau để sinh ra code test:
## Mục đích
- Chỉ test duy nhất 1 class/method.
- Bỏ qua hoàn toàn Database thật, Redis hay HTTP.
- Tốc độ chạy cực nhanh.
## 1. Với CQRS Handlers hoặc Services
- **Nhận diện Dependencies:** Tự động nhận diện các Interface (ví dụ: `IRepository`, `IUnitOfWork`, `ILogger`, `IMediator`) được inject vào constructor.
- **Tạo Mock Object:** Sử dụng thư viện Mocking (như `Moq` hoặc `NSubstitute`) để tạo instance giả của các Interface này.
- **Kịch bản Test (Arrange - Act - Assert):**
- **Arrange:** Cấp data giả (Mock data) cho các hàm của Interface.
- **Act:** Gọi hàm thực thi (ví dụ `Handle()` của CQRS hoặc các method của Service).
- **Assert:** Kiểm tra kết quả trả về, HOẶC verify xem một method của Mock object có được gọi đúng số lần không (ví dụ kiểm tra xem `_repository.AddAsync()` có được gọi không), HOẶC kiểm tra xem nó có ném ra `ValidationException` khi input sai không.
## 2. Với Domain Entities
- **Mục tiêu:** Kiểm tra các logic kinh doanh, tính toán nội bộ của Entity.
- **Kịch bản:**
- Khởi tạo Entity với các trạng thái cụ thể.
- Gọi method thay đổi trạng thái hoặc tính toán (ví dụ: `Order.CalculateTotal()`).
- Kiểm tra xem giá trị biến đổi có đúng với quy tắc nghiệp vụ không (ví dụ: `Total` phải bằng `Price * Quantity`).
## Định dạng file đầu ra
- **Đường dẫn:** Đặt trong project `tests/MyNewProjectName.UnitTests/...` (tương ứng với thư mục gốc của class bị test).
- **Tên file:** `[ClassName]Tests.cs` (ví dụ: `CreateOrderCommandHandlerTests.cs`).

View File

@@ -0,0 +1 @@
/home/visssoft/.agents/skills/ui-ux-pro-max