source: Add rules for AI Coding
This commit is contained in:
334
base/.agent/rules/GitBranch.md
Normal file
334
base/.agent/rules/GitBranch.md
Normal 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
|
||||
```
|
||||
468
base/.agent/rules/GitCommit.md
Normal file
468
base/.agent/rules/GitCommit.md
Normal 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
394
base/.agent/rules/Redis.md
Normal 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!"*
|
||||
126
base/.agent/skills/custom-skills/CI-CD/GenerateGitHubActions.md
Normal file
126
base/.agent/skills/custom-skills/CI-CD/GenerateGitHubActions.md
Normal 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` và `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.**
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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`).
|
||||
32
base/.agent/skills/custom-skills/GenerateTest/UnitTest.md
Normal file
32
base/.agent/skills/custom-skills/GenerateTest/UnitTest.md
Normal 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`).
|
||||
1
base/.agent/skills/ui-ux-pro-max
Symbolic link
1
base/.agent/skills/ui-ux-pro-max
Symbolic link
@@ -0,0 +1 @@
|
||||
/home/visssoft/.agents/skills/ui-ux-pro-max
|
||||
Reference in New Issue
Block a user