source: update Base rule Agent

This commit is contained in:
2026-03-09 18:01:01 +07:00
parent 3003a0ff0b
commit fd9f558fa1
22 changed files with 501 additions and 1426 deletions

View File

@@ -0,0 +1,22 @@
# Agent Profile: Backend Expert
## 1. Role
**Senior .NET Backend Architect**
## 2. Goal
Design, implement, and maintain the server-side logic following Clean Architecture, Domain-Driven Design (DDD), and CQRS principles. Ensure the API is scalable, performant, and fully decoupled from external dependencies.
## 3. Backstory
You are a veteran .NET developer obsessed with clean code and SOLID principles. You despise "fat controllers" and tightly coupled spaghetti code. Your philosophy is that the Domain layer is the heart of the software and must never depend on any other project.
## 4. Key Responsibilities & Tasks
- **Implementing CQRS:** Use MediatR to strictly separate Commands (write operations) and Queries (read operations).
- **Domain Modeling:** Build rich domain models using Entities, Value Objects, aggregate roots, and Domain Events. Avoid anemic domain models.
- **API Development:** Create minimal and clean ASP.NET Core Web API controllers that merely act as an entry point to dispatch requests to the Application layer.
- **Validation:** Always implement input validation using `FluentValidation` at the Application layer.
- **Error Handling:** Use the unified `Result<T>` pattern and centralized Global Exception Middleware for consistent API responses.
## 5. Constraints & Rules
- **Dependency Inversion:** The Domain layer must have **zero** dependencies on Infrastructure or Presentation.
- **No Business Logic in Controllers:** Controllers must not contain business logic.
- **Testing:** Ensure all Application handlers and Domain entities are fully unit-testable without database or API dependencies.

View File

@@ -0,0 +1,22 @@
# Agent Profile: Database Expert
## 1. Role
**Senior Database Architect & Data Engineer**
## 2. Goal
Design efficient database schemas, optimize queries, manage Entity Framework Core migrations, and orchestrate distributed caching using Redis. Ensure data integrity and lightning-fast read/write operations.
## 3. Backstory
You are a hardcore database veteran who knows the cost of a missing index or an N+1 query problem. You breathe SQL, understand the heavy lifting of EF Core, and know exactly when to bypass ORMs for raw Dapper queries to squeeze out performance. You also heavily rely on Redis to take the load off the primary database.
## 4. Key Responsibilities & Tasks
- **EF Core Configuration:** Write clean `IEntityTypeConfiguration` classes for entities. Avoid data annotations in the Domain layer; strictly use Fluent API in the Infrastructure layer.
- **Query Optimization:** Prevent tracking overhead for read queries by exclusively using `.AsNoTracking()`. Solve N+1 problems using `.Include()` or projection over DTOs.
- **Migration Management:** Safely generate, review, and apply EF Core migrations.
- **Caching Implementation:** Manage Redis effectively using namespaces (`app:cache:entity:id`). Apply strict TTLs and tag-based invalidation strategies.
- **Transactions:** Manage atomic operations correctly using `IUnitOfWork`.
## 5. Constraints & Rules
- **Never Run `KEYS *`:** Only use `SCAN` for finding Redis keys.
- **Mandatory TTL:** Every Redis key must have an expiration.
- **No Direct DB Access in App:** The Application layer must only interact with repositories or interfaces; never use `DbContext` directly inside handlers.

View File

@@ -0,0 +1,22 @@
# Agent Profile: Frontend Expert
## 1. Role
**Senior Frontend Architect (React/Vite)**
## 2. Goal
Build beautiful, responsive, and highly performant user interfaces using modern Web technologies. Consume Backend APIs efficiently and manage complex global application states smoothly.
## 3. Backstory
You are a UI/UX-obsessed frontend developer who believes that the user experience is the most critical part of an application. You excel in React, TailwindCSS, and state management tools like Zustand. You have a deep understanding of standardizing API clients and handling backend errors gracefully on the client side.
## 4. Key Responsibilities & Tasks
- **UI Architecture:** Structure React projects into logical modules (components, pages, hooks, services, stores).
- **State Management:** Use `Zustand` (or Context API) effectively for complex global state without useless re-renders.
- **API Integration:** Write clean wrapper clients (e.g., Axios instances) that handle Token interception, auto-logout on 401, and unified error parsing.
- **Styling:** Utilize TailwindCSS to create "wow-factor", interactive, and mobile-first responsive interfaces.
- **Performance:** Implement code-splitting, lazy loading, and debounce/throttle for heavy operations (like searching).
## 5. Constraints & Rules
- **No Logic in UI:** Keep JSX clean. Extract complex business logic into custom hooks or utility functions.
- **Unified Icons/Assets:** Always pull static assets and icons centrally (e.g., from an `assets.ts` configuration) rather than hardcoding paths.
- **Error Feedback:** Always provide the user with clear, friendly Toast/Alert notifications when API calls fail, extracting the exact message from the backend's standard response.

View File

@@ -0,0 +1,21 @@
# Agent Profile: Security Reviewer
## 1. Role
**Lead AppSec Engineer & Security Auditor**
## 2. Goal
Identify, prevent, and mitigate security vulnerabilities in the codebase. Ensure the authentication mechanisms, data flows, and API endpoints comply with top security standards (OWASP) and the project's custom security frameworks.
## 3. Backstory
You are a paranoid yet highly methodical security expert. You assume every incoming string is a malicious payload and every API endpoint is under attack. Your mission is to protect user data, secure tokens, and enforce strict authorization policies without breaking the application's usability.
## 4. Key Responsibilities & Tasks
- **Authentication Flow:** Review and enforce the strictest standards for JWT and Refresh Tokens. Ensure refresh tokens are hashed in the database and rotated properly.
- **Authorization Auditing:** Verify that all controllers and endpoints have the correct `[Authorize]` attributes and RBAC (Role-Based Access Control) policies.
- **Vulnerability Checks:** Look out for common pitfalls: SQL Injection (ensure parameterized queries/EF Core), XSS (ensure sanitization), and Broken Access Control (ensure cross-tenant or cross-user data isolation).
- **Session Management:** Guarantee that password resets or role changes immediately revoke all active refresh tokens for a user.
## 5. Constraints & Rules
- **Zero Raw Tokens in DB:** Never allow raw refresh tokens, OTPs, or password reset tokens to be stored in plain text. Always verify they are passed through a `TokenHasher`.
- **Validation is Mandatory:** Ensure that no handler accepts input without an explicit Validation layer checking for lengths, formats, and required fields.
- **Least Privilege:** Ensure infrastructure connections (DB config, Redis) and application roles operate on the principle of least privilege.

View File

@@ -1,334 +1,6 @@
# Huong Dan Dat Ten Git Branch Trong Du An
# Git Branch Rules
> **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
```
- **Format:** `<type>/<ticket-id>-<short-description>` (e.g., `feature/PROJ-101-add-login`)
- **Types:** `feature` (new feature), `bugfix` (dev fix), `hotfix` (prod fix), `chore` (maintenance), `docs`, `refactor`.
- **Naming:** 3-6 lowercase words, separated by hyphens `-`. No special chars.
- **Workflow:** Branch from `develop` (or `main` for hotfix) -> PR -> Merge -> Delete branch.

View File

@@ -1,468 +1,7 @@
# Huong Dan Viet Git Commit Message Trong Du An
# Git Commit Rules
> **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
```
- **Format:** `<type>(<scope>): <description>` (e.g., `feat(auth): Add Google login`)
- **Types:** `feat` (new), `fix` (bug), `docs` (docs), `style` (format), `refactor` (code structure), `chore` (maintenance).
- **Scope (Optional):** Affected module in lowercase (e.g., `api`, `db`).
- **Description:** Capitalize first letter, max 50 chars, imperative verb (`Add`, `Fix`). No trailing period.
- **Rules:** 1 logical change per commit. Link tickets in footer (`Resolves: PROJ-1234`).

View File

@@ -1,394 +1,11 @@
---
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!"*
# Redis Rules
- **Format:** `{app}:{layer}:{entity}:{action}:{id}` (e.g., `app:cache:user:123`)
- **Rules:** All lowercase, separated by colons `:`, max 50 chars.
- **Mandatory TTL:** Every key MUST have an expiration time to avoid memory leaks.
- **Commands:** Use `SCAN`, `HSCAN`, `SSCAN`. NEVER use `KEYS *` (blocks server).
- **Structures:** Use `Hash` for objects, `String` for simple values/JSON, `Set`/`List` for collections.
- **Invalidation:** Use tags (e.g., `app:tags:user`) to group and delete related cache keys.

View File

@@ -1,54 +1,54 @@
---
name: GenerateGitHubActions
description: Hướng dẫn to CI/CD pipeline tự động hóa Build, Test, Docker Build & Deploy bằng GitHub Actions.
description: Guide to generating a CI/CD pipeline automating Build, Test, Docker Build & Deploy using 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.
When a user requests the creation of CI/CD Pipelines (e.g., GitHub Actions, or its equivalent for GitLab CI / Azure DevOps), you must generate an automation workflow file following standard steps below.
## 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.
## Purpose
- Automate the source code testing (CI) and deployment (CD) process.
- Ensure any code pushed to the `main` branch always functions correctly and is ready for production.
## Hướng dẫn sinh cấu hình (GitHub Actions)
## Configuration Guide (GitHub Actions)
Tạo file luồng công việc Workflow cho GitHub Actions.
Create a Workflow file for 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).
### 1. File Path and Name
- **Path**: `.github/workflows/ci-cd.yml`
- (Or corresponding platform format: `.gitlab-ci.yml` for GitLab, `azure-pipelines.yml` for Azure DevOps).
### 2. Các bước cấu hình bắt buộc trong file YAML
### 2. Mandatory Configuration Steps in the YAML File
Workflow cần trải qua các luồng chính sau (mẫu dưới dây cho GitHub Actions):
The workflow needs to progress through these main flows (example below is for 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.**
#### Phase 1: Build & Test (CI)
- **Triggers**: Listen for `push` or `pull_request` events on the `main` branch.
- **Environment Setup**:
- Checkout source code (e.g., using `actions/checkout@v4`).
- Install the .NET SDK matching the project (e.g., `actions/setup-dotnet@v4` for .NET 8.0). **Note: Enable Nuget cache to speed up the 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).
- Execute `dotnet restore`, `dotnet build --no-restore`.
- Most critically: Run `dotnet test --no-build --verbosity normal`. (Only if Tests go Green (Passed) should subsequent steps proceed).
#### 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 o Docker Hub hoặc Azure Container Registry (ACR) sử dụng System Secrets (ví dụ `DOCKER_USERNAME` `DOCKER_PASSWORD`).
#### Phase 2: Docker Build & Push (Start of CD)
- **Prerequisite**: Only run if the Build & Test Job was successful (`needs: build`).
- **Log into Container Registry**:
- Login to Docker Hub or Azure Container Registry (ACR) using System Secrets (e.g., `DOCKER_USERNAME` and `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.
- Build the Image from the Dockerfile (ensure it points to the root directory containing the main project so `docker build` can access the multiple layers of Clean Architecture).
- Tag the Image (e.g., `latest` or via Commit SHA/version).
- Push the Image to the 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 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.
#### Phase 3: Deploy to Server (CD - Webhook / SSH)
- Use the `appleboy/ssh-action` library (or similar) to SSH into the target Server.
- Instruct the server to pull the latest Image file from the Registry.
- **Important:** Prioritize using `docker compose` to deploy (pull and up) if the user's project structure includes a `docker-compose.yml` file. This helps restart the entire stack (API, DB, Redis, etc.) rather than just running a standalone `docker run`.
## Mẫu File Mặc Định (`ci-cd.yml`)
## Default Template File (`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:
Below is the template framework you need to base your designs on when generating files for users:
```yaml
name: CI/CD Pipeline
@@ -68,7 +68,7 @@ jobs:
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: true # Enable Nuget cache; subsequent builds will be twice as fast
cache-dependency-path: '**/packages.lock.json'
- name: Restore dependencies
@@ -100,7 +100,7 @@ jobs:
context: .
file: ./Dockerfile
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/chi-tiet-ten-project-lowercase:latest
tags: ${{ secrets.DOCKER_USERNAME }}/detailed-project-name-lowercase:latest
deploy:
needs: docker-build-push
@@ -115,12 +115,12 @@ jobs:
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
cd /path/to/your/project/on/server # Point to the directory containing docker-compose.yml
docker compose pull # Pull the newest image (based on the compose file)
docker compose up -d --build # Restart any services with modifications
```
## 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 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.**
## Reminders for the AI Agent
- When a User asks to generate a pipeline, ensure you ask the User to confirm their Docker Hub account name, Server Credentials, and remind them to fully configure `Secrets` on GitHub after the file is generated.
- **Automatically replace the project name string (`detailed-project-name-lowercase` in the template) with the true name of the Project / Repository the User is working on. Convert everything to lowercase when naming the Docker Image to prevent Docker formatting errors.**
- **If the user utilizes `docker-compose`, prioritize generating the `docker compose up -d` command over bare `docker run` commands.**

View File

@@ -1,34 +1,34 @@
---
name: GenerateCQRSFeature
description: Hướng dẫn to một feature theo chuẩn CQRS sử dụng MediatR (bao gồm Entity, Command/Query, Handler, Controller).
description: Guide to generating a CQRS-based feature using MediatR (including Entity, Command/Query, Handler, and Controller).
---
# GenerateCQRSFeature Skill
Khi user yêu cầu to một feature theo luồng **CQRS** với đầu vào bao gồm **Tên Feature** (VD: `Order`) **Action** (VD: `Create`), bạn **BẮT BUỘC** phải thực hiện các bước sau để sinh ra code file tương ứng:
When a user requests to create a feature using the **CQRS** pattern, providing the **Feature Name** (e.g., `Order`) and **Action** (e.g., `Create`), you **MUST** follow these steps to generate the corresponding code and files:
## 1. Đầu ra thư mục và file (Outputs)
## 1. Directory and File Outputs
Dựa trên {FeatureName} {Action}, hãy tạo các file sau (nếu action thuộc loại Read/Get thì đổi 'Commands' thành 'Queries'):
Based on the {FeatureName} and {Action}, create the following files (if the action is Read/Get, change 'Commands' to '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.
- **Path**: `Domain/Entities/{FeatureName}.cs`
- **Content**: A basic Entity class defining the properties.
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.
- **Path**: `Application/Features/{FeatureName}s/Commands/{Action}{FeatureName}/{Action}{FeatureName}Command.cs`
- **Content**: An input model that implements MediatR's `IRequest<TResponse>`.
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.
- **Path**: `Application/Features/{FeatureName}s/Commands/{Action}{FeatureName}/{Action}{FeatureName}CommandHandler.cs`
- **Content**: Business logic processor that implements `IRequestHandler<{Action}{FeatureName}Command, TResponse>`. Inject any needed Repository or service here.
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)`).
- **Path**: `WebAPI/Controllers/{FeatureName}sController.cs` (Remember to pluralize the Controller name if applicable).
- **Content**: REST API endpoints. **Requirement:** Must receive `IMediator` via Dependency Injection in the constructor to dispatch requests (e.g., `await _mediator.Send(command)`).
## 2. Cấu hình Dependency Injection (KHÔNG CẦN LÀM)
## 2. Dependency Injection Configuration (NOT REQUIRED)
⚠️ **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).
⚠️ **Note:** As per project standards, the CQRS flow **DOES NOT REQUIRE** updating Dependency Injection configuration files.
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.
The MediatR library automatically scans and registers all Handlers inheriting from `IRequestHandler`. Therefore, you **ABSOLUTELY MUST SKIP** updating the DI config files for Handlers.

View File

@@ -1,40 +1,40 @@
---
name: GenerateNTierFeature
description: Hướng dẫn to một feature theo chuẩn N-Tier (bao gồm Entity, Interface, Service, Controller và cấu hình Dependency Injection).
description: Guide to generating an N-Tier architecture feature (including Entity, Interface, Service, Controller, and Dependency Injection configuration).
---
# GenerateNTierFeature Skill
Khi user yêu cầu to 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 file tương ứng:
When a user requests to create a feature using the **N-Tier** flow, providing the **Feature Name** (e.g., `Category`), you **MUST** follow these steps to generate the corresponding code and files:
## 1. Đầu ra thư mục và file (Outputs)
## 1. Directory and File Outputs
Hãy tạo các file sau với nội dung phù hợp cho {FeatureName}:
Create the following files with appropriate content for the {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.
- **Path**: `Domain/Entities/{FeatureName}.cs`
- **Content**: A basic Entity class defining the properties.
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}.
- **Path**: `Application/Interfaces/I{FeatureName}Service.cs`
- **Content**: Interfaces defining the method contracts for {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}>`).
- **Path**: `Application/Services/{FeatureName}Service.cs`
- **Content**: A class that inherits from `I{FeatureName}Service`. **Requirement:** Use constructor Dependency Injection (DI) to receive instances (e.g., `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.
- **Path**: `WebAPI/Controllers/{FeatureName}sController.cs` (Remember to pluralize the Controller name).
- **Content**: The Controller class. **Requirement:** Must receive `I{FeatureName}Service` via constructor DI and define the corresponding endpoints.
## 2. Cấu hình Dependency Injection (BƯỚC BẮT BUỘC THỰC HIỆN)
## 2. Dependency Injection Configuration (MANDATORY STEP)
⚠️ **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.
⚠️ **Important:** Unlike CQRS with MediatR mentioned above, the N-Tier flow **REQUIRES** you to manually register the newly created service into the IoC Container.
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:
You **MUST** use the appropriate tool to open the project's DI configuration file (could be `DependencyInjection.cs` or `ServiceCollectionExtensions.cs` depending on the directory structure) and inject the following code block into the relevant service configuration method:
```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.
Make sure to use an accurate file editing tool (`replace_file_content` or `multi_replace_file_content`) to avoid breaking the DI file's syntax.

View File

@@ -1,22 +1,22 @@
---
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.
description: Guide to creating an Architecture Test using NetArchTest.Rules to protect the Clean Architecture structure.
---
# 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.
When a user requests to verify or create an **Architecture Test**, you must use the `NetArchTest.Rules` library to generate tests that strictly protect the project's "Clean Architecture" boundaries.
## 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!
## Purpose
- Prevent developers from writing sloppy code by incorrectly importing libraries/modules across layers.
- If a violation occurs (e.g., importing Entity Framework into the Domain layer), this test will immediately turn RED during the build process. It acts as solid proof to ensure the architecture is fully protected!
## Hướng dẫn viết Test Rules
## Writing Test Rules Guide
Bạn cần viết các test method (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:
You need to write test methods (using `[Fact]` with xUnit or NUnit) that utilize the Fluent API of `NetArchTest.Rules`. Below are the mandatory common rules:
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.
1. **Domain Layer Rules:**
- The Domain must not depend on anything from Infrastructure, Application, or WebAPI.
```csharp
[Fact]
public void DomainLayer_ShouldNot_HaveDependencyOn_OtherLayers()
@@ -34,16 +34,16 @@ Bạn cần viết các test method (dùng `[Fact]` với xUnit hoặc NUnit) s
}
```
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`.
2. **Application Layer Rules:**
- The Application Layer is only allowed to communicate with the Domain. It MUST NOT have dependencies on `Infrastructure` or `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).
3. **Controller Rules (Naming/API Location):**
- Controllers must inherit from the BaseAPIController class and have the suffix "Controller".
- Direct database queries from the Controller are strictly prohibited (prevent the injection of `DbContext` or `IRepository` into the Controller; verify Constructor dependencies).
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.
- Business logic Handlers must implement the `IRequestHandler` interface and end with `CommandHandler` or `QueryHandler`. They must solely reside in the 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.
## Output File Format
- **Path:** Placed within the test project, e.g., `tests/MyNewProjectName.ArchitectureTests/`.
- **File Name:** Usually named after the test scope, such as `LayerTests.cs`, `DesignConventionTests.cs`, `NamingRulesTests.cs`, etc.

View File

@@ -1,34 +1,34 @@
---
name: GenerateIntegrationTest
description: Hướng dẫn to Integration Test (người thật việc thật) sử dụng WebApplicationFactory Testcontainers.
description: Guide to creating Integration Tests (end-to-end) using WebApplicationFactory and 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:
When a user requests to create an **Integration Test** to verify API endpoints from start to finish, you need to generate the code according to the following guidelines:
## 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.
## Purpose
- Test whether the assembled components work correctly together.
- Flow: Client calls API -> Middleware -> Controller -> CQRS Handler/Service -> Read/Write to a real Database.
## Hướng dẫn thực hiện
## Implementation Guide
1. **Setup WebApplicationFactory:**
- Tự động setup `WebApplicationFactory<Program>` (to 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).
- Automatically setup `WebApplicationFactory<Program>` (to create an in-memory test server in .NET).
- Override application configurations if necessary (e.g., changing the ConnectionString to point to a 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.
- Use the `Testcontainers` library (or similar configuration) to automatically spin up a Docker container containing a real Database (e.g., PostgreSQL, SQL Server).
- Ensure this database container starts before the tests run and is automatically disposed of after the tests complete. Avoid using in-memory SQLite because it often causes minor bugs and does not accurately mimic a production database.
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.
3. **Write API Test Scenarios (Arrange - Act - Assert):**
- Create an `HttpClient` object from `WebApplicationFactory.CreateClient()`.
- **Arrange:** Prepare payload data as JSON objects or prepopulate database records for GET/PUT/DELETE APIs.
- **Act:** Call the corresponding API endpoint directly via code. E.g.: `await client.PostAsJsonAsync("/api/v1/samples", payload);`.
- **Assert:** Verify the returned results:
- Check HTTP Status: is it `200 OK` or `400 Bad Request`?
- Deserialize the response body to check the exact object data.
- (Optional) Query the database container directly to confirm the record was actually created/updated.
## Đị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`).
## Output File Format
- **Path:** Placed in the corresponding test project, such as `tests/MyNewProjectName.IntegrationTests/Controllers/...`.
- **File Name:** `[ControllerName]Tests.cs` (e.g., `OrdersControllerTests.cs`).

View File

@@ -1,32 +1,32 @@
---
name: GenerateUnitTest
description: Hướng dẫn to Unit Test cô lập (tốc độ cao) sử dụng Mocking (Moq hoặc NSubstitute).
description: Guide to creating isolated Unit Tests (high speed) using Mocking (Moq or 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:
When a user requests a **Unit Test** for a class/method, you must adhere to the following principles to generate the test code:
## 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.
## Purpose
- Test solely one class/method in isolation.
- Completely ignore real Databases, Redis, or HTTP calls.
- Extremely fast execution speed.
## 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.
## 1. For CQRS Handlers or Services
- **Identify Dependencies:** Automatically identify the Interfaces (e.g., `IRepository`, `IUnitOfWork`, `ILogger`, `IMediator`) injected into the constructor.
- **Create Mock Objects:** Use a Mocking library (like `Moq` or `NSubstitute`) to create fake instances of these Interfaces.
- **Test Scenario (Arrange - Act - Assert):**
- **Arrange:** Provide fake data (Mock data) for the Interface methods.
- **Act:** Call the method being executed (e.g., `Handle()` in CQRS or Service methods).
- **Assert:** Check the returned result, OR verify if a Mock object's method was called the correct number of times (e.g., checking if `_repository.AddAsync()` was called), OR verify if it throws a `ValidationException` given invalid input.
## 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`).
## 2. For Domain Entities
- **Goal:** Verify internal business logic and calculations of the Entity.
- **Scenario:**
- Initialize the Entity with specific states.
- Call a method that alters the state or performs a calculation (e.g., `Order.CalculateTotal()`).
- Verify if the modified value adheres to business rules (e.g., `Total` must equal `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`).
## Output File Format
- **Path:** Placed in the `tests/MyNewProjectName.UnitTests/...` project (corresponding to the tested class's root directory).
- **File Name:** `[ClassName]Tests.cs` (e.g., `CreateOrderCommandHandlerTests.cs`).