Refactor auth-service to iam-service and update related documentation

- Renamed auth-service to iam-service across various files for consistency.
- Updated Dockerfiles, deployment configurations, and documentation to reflect the service name change.
- Enhanced testing commands in documentation to point to the new iam-service.
- Removed outdated auth-service files and configurations to streamline the project structure.
- Improved bilingual documentation for clarity on the new service structure and usage.
This commit is contained in:
Ho Ngoc Hai
2025-12-30 20:54:21 +07:00
parent 7a4bda8da7
commit b104fafa85
246 changed files with 35630 additions and 2867 deletions

View File

@@ -11,13 +11,15 @@ docs/
│ ├── architecture/
│ ├── guides/
│ ├── onboarding/
── runbooks/
── runbooks/
│ └── skills/ # Cursor AI skills documentation
├── vi/ # Vietnamese documentation (Tiếng Việt)
│ ├── api/
│ ├── architecture/
│ ├── guides/
│ ├── onboarding/
── runbooks/
── runbooks/
│ └── skills/ # Tài liệu Cursor AI skills
└── README.md # This file
```
@@ -29,6 +31,7 @@ docs/
- **Guides**: Development, deployment, getting started, troubleshooting
- **Onboarding**: New developer guide
- **Runbooks**: Incident response and rollback procedures
- **Skills**: Cursor AI skills documentation (API design, testing, security, etc.)
### Vietnamese (`/vi`)
- **API**: OpenAPI specifications
@@ -36,6 +39,23 @@ docs/
- **Guides**: Development, deployment, bắt đầu, xử lý sự cố
- **Onboarding**: Hướng dẫn cho developer mới
- **Runbooks**: Phản ứng sự cố và quy trình rollback
- **Skills**: Tài liệu Cursor AI skills (API design, testing, security, v.v.)
## Cursor Skills
The project uses **Cursor AI Skills** to guide AI assistants in following project-specific patterns and standards. See the [Skills Documentation](./en/skills/) for detailed information about each skill:
- [API Design](./en/skills/api-design.md) - RESTful API standards
- [Database & Prisma](./en/skills/database-prisma.md) - Database patterns
- [Testing Patterns](./en/skills/testing-patterns.md) - Testing best practices
- [Code Comments](./en/skills/comment-code.md) - Bilingual commenting guidelines
- [Kubernetes Deployment](./en/skills/deployment-kubernetes.md) - K8s deployment patterns
- [Observability & Monitoring](./en/skills/observability-monitoring.md) - Monitoring patterns
- [Project Rules](./en/skills/project-rules.md) - Coding standards
- [Security](./en/skills/security.md) - Security best practices
- [Documentation](./en/skills/documentation.md) - Documentation guidelines
See [Skills Index](./en/skills/README.md) for complete list and quick reference.
## Contributing
@@ -43,3 +63,8 @@ When adding new documentation:
1. Add the English version to `/en`
2. Add the Vietnamese translation to `/vi`
3. Keep both versions in sync
When updating Cursor Skills:
1. Update the skill source file in `.cursor/skills/{skill-name}/SKILL.md`
2. Update the documentation in `docs/en/skills/{skill-name}.md` and `docs/vi/skills/{skill-name}.md`
3. Update the skills index files if needed

View File

@@ -0,0 +1,339 @@
# Đề Xuất Kiến Trúc IAM Service
Tài liệu này mô tả đề xuất kiến trúc cho IAM Service (Identity and Access Management Service), mở rộng từ auth-service hiện tại.
## Tổng Quan: Auth Service → IAM Service
**Auth Service hiện tại** tập trung vào:
- Authentication (xác thực)
- Authorization (phân quyền)
- Session & Token management
- RBAC/ABAC
**IAM Service** mở rộng thêm:
- **Identity Management** (quản lý danh tính toàn diện)
- **Access Governance** (quản trị truy cập)
- **Compliance & Reporting** (tuân thủ và báo cáo)
- **Lifecycle Management** (quản lý vòng đời tài khoản)
---
## 1. Phạm Vi IAM Service
### 1.1 Identity Management (Quản Lý Danh Tính)
#### A. User Lifecycle Management
- User CRUD operations
- User provisioning/deprovisioning workflows
- Bulk user operations (import/export)
- User deactivation/reactivation với approval workflow
- Account merging/deduplication
- User archival (soft delete với retention policy)
#### B. Profile Management
- Extended attributes (custom fields)
- Profile picture upload & management
- Contact information (phone, address)
- Preferences & settings
- Profile versioning/audit trail
#### C. Identity Verification
- Email verification
- Phone/SMS verification
- Identity document verification (KYC)
- Multi-level verification (verified, pending, rejected)
#### D. Organizations & Groups
- Organization management (multi-tenant)
- Group/Team management
- Organization hierarchy
- Group-based access control
- Organization-level policies
### 1.2 Access Management (Quản Lý Truy Cập)
#### A. Advanced Access Control
- Just-In-Time (JIT) access provisioning
- Privileged Access Management (PAM)
- Temporary access grants
- Access request/approval workflows
- Delegation & impersonation (admin view)
- Conditional access policies (location, time, device)
#### B. Access Reviews & Certifications
- Periodic access reviews
- Access certification campaigns
- Access analytics & reporting
- Risk scoring for access decisions
- Anomaly detection (unusual access patterns)
### 1.3 Governance & Compliance (Quản Trị & Tuân Thủ)
#### A. Audit & Logging
- Compliance reporting (GDPR, SOC2, ISO 27001)
- Data retention policies
- Audit log search & analytics
- Export audit logs
#### B. Policy Governance
- Policy versioning & rollback
- Policy templates library
- Policy testing & validation
- Policy compliance checks
#### C. Risk Management
- Risk scoring engine
- Risk-based authentication
- Threat detection
- Incident response workflows
- Security posture dashboard
---
## 2. Kiến Trúc Module Structure
```
services/iam-service/
├── src/
│ ├── config/ # Configuration files
│ ├── core/
│ │ ├── cache/ # Multi-layer cache
│ │ ├── security/ # Zero-trust, encryption
│ │ ├── events/ # Event sourcing
│ │ └── workflows/ # Workflow engine (NEW)
│ ├── modules/
│ │ ├── auth/ # ✅ Core authentication
│ │ ├── rbac/ # ✅ RBAC system
│ │ ├── social/ # ✅ Social authentication
│ │ ├── oidc/ # ✅ OIDC implementation
│ │ ├── token/ # ✅ JWT & Cookie management
│ │ ├── session/ # ✅ Session management
│ │ ├── mfa/ # ✅ Multi-factor auth
│ │ │
│ │ ├── identity/ # 🆕 Identity Management
│ │ │ ├── user/ # User lifecycle
│ │ │ ├── profile/ # Profile management
│ │ │ ├── verification/ # Identity verification
│ │ │ └── organization/ # Organizations & groups
│ │ │
│ │ ├── access/ # 🆕 Access Management
│ │ │ ├── request/ # Access requests
│ │ │ ├── review/ # Access reviews
│ │ │ ├── pam/ # Privileged access
│ │ │ └── analytics/ # Access analytics
│ │ │
│ │ ├── governance/ # 🆕 Governance & Compliance
│ │ │ ├── compliance/ # Compliance reporting
│ │ │ ├── policy/ # Policy governance
│ │ │ ├── risk/ # Risk management
│ │ │ └── reporting/ # Reporting & dashboards
│ │ │
│ │ └── workflow/ # 🆕 Workflow Engine
│ │ ├── engine/ # Workflow engine
│ │ ├── approval/ # Approval workflows
│ │ └── automation/ # Automated workflows
│ │
│ ├── middlewares/ # Express middlewares
│ ├── repositories/ # Data access layer
│ └── routes/ # Route definitions
└── prisma/
└── schema.prisma # Database schema (mở rộng)
```
---
## 3. Database Schema Mở Rộng
### 3.1 Identity Management Models
- **Organization**: Quản lý tổ chức với hierarchy
- **Group**: Quản lý nhóm trong organization
- **GroupMember**: Thành viên của group
- **GroupPermission**: Permissions cho group
- **UserProfile**: Thông tin profile mở rộng của user
- **IdentityVerification**: Xác thực danh tính (email, phone, document)
### 3.2 Access Management Models
- **AccessRequest**: Yêu cầu truy cập
- **AccessRequestApprover**: Người phê duyệt request
- **AccessReview**: Đánh giá truy cập định kỳ
- **AccessReviewItem**: Item trong review
### 3.3 Governance Models
- **ComplianceReport**: Báo cáo tuân thủ (GDPR, SOC2, ISO27001)
- **PolicyTemplate**: Template cho policies
- **RiskScore**: Điểm rủi ro của user
---
## 4. API Endpoints Mở Rộng
### 4.1 Identity Management APIs
```
# User Management
GET /api/v1/identity/users
POST /api/v1/identity/users
GET /api/v1/identity/users/:id
PUT /api/v1/identity/users/:id
DELETE /api/v1/identity/users/:id
POST /api/v1/identity/users/bulk-import
GET /api/v1/identity/users/bulk-export
# Profile Management
GET /api/v1/identity/users/:id/profile
PUT /api/v1/identity/users/:id/profile
POST /api/v1/identity/users/:id/profile/avatar
# Identity Verification
POST /api/v1/identity/verification/email/request
POST /api/v1/identity/verification/email/verify
POST /api/v1/identity/verification/phone/request
POST /api/v1/identity/verification/phone/verify
# Organizations & Groups
GET /api/v1/identity/organizations
POST /api/v1/identity/organizations
GET /api/v1/identity/organizations/:id/groups
POST /api/v1/identity/organizations/:id/groups
GET /api/v1/identity/groups/:id/members
POST /api/v1/identity/groups/:id/members
```
### 4.2 Access Management APIs
```
# Access Requests
GET /api/v1/access/requests
POST /api/v1/access/requests
PUT /api/v1/access/requests/:id/approve
PUT /api/v1/access/requests/:id/reject
# Access Reviews
GET /api/v1/access/reviews
POST /api/v1/access/reviews
POST /api/v1/access/reviews/:id/start
POST /api/v1/access/reviews/:id/complete
GET /api/v1/access/reviews/:id/items
# Access Analytics
GET /api/v1/access/analytics/usage
GET /api/v1/access/analytics/permissions
GET /api/v1/access/analytics/risks
```
### 4.3 Governance APIs
```
# Compliance Reports
GET /api/v1/governance/compliance/reports
POST /api/v1/governance/compliance/reports/generate
GET /api/v1/governance/compliance/reports/:id/export
# Policy Governance
GET /api/v1/governance/policies/templates
POST /api/v1/governance/policies/templates
GET /api/v1/governance/policies/:id/versions
POST /api/v1/governance/policies/:id/test
# Risk Management
GET /api/v1/governance/risk/scores
GET /api/v1/governance/risk/scores/:userId
POST /api/v1/governance/risk/calculate
# Reporting
GET /api/v1/governance/reports/access-summary
GET /api/v1/governance/reports/user-activity
GET /api/v1/governance/reports/security-events
```
---
## 5. Implementation Roadmap
### Phase 1: Foundation (Weeks 1-4)
- ✅ Migrate từ auth-service sang iam-service
- 🔄 Tổ chức lại modules theo IAM structure
- 🔄 Mở rộng database schema với identity models
- 🔄 Implement User Profile module
### Phase 2: Identity Management (Weeks 5-8)
- 🔄 User lifecycle management
- 🔄 Identity verification (email, phone, document)
- 🔄 Organization & Group management
- 🔄 Profile management with extended attributes
### Phase 3: Access Management (Weeks 9-12)
- 🔄 Access request/approval workflows
- 🔄 Access review & certification system
- 🔄 Access analytics
- 🔄 Privileged Access Management (PAM)
### Phase 4: Governance (Weeks 13-16)
- 🔄 Compliance reporting engine
- 🔄 Policy governance & versioning
- 🔄 Risk scoring & management
- 🔄 Reporting dashboards
### Phase 5: Advanced Features (Weeks 17-20)
- 🔄 Workflow engine
- 🔄 Advanced analytics & ML-based insights
- 🔄 Integration APIs (SCIM, LDAP sync)
- 🔄 Performance optimization & scaling
---
## 6. Lợi Ích Của IAM Service
### 6.1 Cho Doanh Nghiệp
- ✅ Tuân thủ (GDPR, SOC2, ISO 27001)
- ✅ Quản lý rủi ro bảo mật tốt hơn
- ✅ Tự động hóa quy trình quản lý truy cập
- ✅ Báo cáo và audit trail đầy đủ
- ✅ Hỗ trợ multi-tenant/organization
### 6.2 Cho Developers
- ✅ API thống nhất cho identity & access
- ✅ Workflow engine linh hoạt
- ✅ Extensible architecture
- ✅ Comprehensive documentation
- ✅ SDK support
### 6.3 Cho End Users
- ✅ Self-service profile management
- ✅ Transparent access requests
- ✅ Better user experience
- ✅ Enhanced security với MFA & verification
---
## 7. Migration Strategy
### Từ Auth Service → IAM Service
1. **Rename Service**: `services/auth-service``services/iam-service`
2. **Update Package Name**: `@goodgo/auth-service``@goodgo/iam-service`
3. **Update Routes**:
- Giữ backward compatibility với `/api/v1/auth/*`
- Thêm routes mới cho `/api/v1/identity/*`, `/api/v1/access/*`, `/api/v1/governance/*`
4. **Database Migration**:
- Thêm schema mới cho identity, access, governance
- Giữ nguyên các tables hiện có (backward compatible)
5. **Gradual Rollout**:
- Phase 1: Deploy cùng auth-service (dual deployment)
- Phase 2: Migrate clients dần dần
- Phase 3: Deprecate auth-service khi migration hoàn tất
---
## Kết Luận
Đề xuất này mở rộng `auth-service` thành `IAM Service` với đầy đủ các tính năng:
- **Identity Management** đầy đủ
- **Access Management** nâng cao
- **Governance & Compliance** toàn diện
- **Workflow automation** linh hoạt
Điều này biến service từ authentication/authorization cơ bản thành một IAM platform toàn diện, phù hợp cho enterprise.

View File

@@ -38,7 +38,7 @@ docker-compose up -d
```bash
# Create Kubernetes secret
kubectl create secret generic auth-service-secrets \
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://user:pass@ep-xxx.region.neon.tech/dbname?sslmode=require&pgbouncer=true' \
--from-literal=jwt-secret='your-staging-jwt-secret' \
--from-literal=jwt-refresh-secret='your-staging-refresh-secret' \
@@ -72,7 +72,7 @@ kubectl apply -f deployments/staging/kubernetes/
```bash
# Create Kubernetes secret
kubectl create secret generic auth-service-secrets \
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://user:pass@ep-xxx.region.neon.tech/dbname?sslmode=require&pgbouncer=true' \
--from-literal=jwt-secret='your-production-jwt-secret' \
--from-literal=jwt-refresh-secret='your-production-refresh-secret' \
@@ -90,7 +90,7 @@ kubectl create secret generic auth-service-secrets \
### Rollback
```bash
kubectl rollout undo deployment/auth-service -n production
kubectl rollout undo deployment/iam-service -n production
```
## Health Checks

View File

@@ -33,7 +33,7 @@ git checkout -b feature/my-feature
pnpm test
# Specific service
pnpm --filter @goodgo/auth-service test
pnpm --filter @goodgo/iam-service test
```
### 4. Lint and Format
@@ -75,14 +75,14 @@ pnpm format
```bash
# Create migration (dev)
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
# Apply migrations (production)
./scripts/db/migrate.sh auth-service deploy
./scripts/db/migrate.sh iam-service deploy
```
## Debugging
- Use logger from `@goodgo/logger`
- Check Traefik logs: `docker logs traefik-local`
- Check service logs: `./scripts/dev/logs.sh auth-service`
- Check service logs: `./scripts/dev/logs.sh iam-service`

View File

@@ -44,12 +44,12 @@
5. **Run database migrations**
```bash
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
```
6. **Seed the database**
```bash
./scripts/db/seed.sh auth-service
./scripts/db/seed.sh iam-service
```
7. **Start all services**

View File

@@ -0,0 +1,209 @@
# Migration Guide: Auth Service → IAM Service
Tài liệu này hướng dẫn cách migrate từ `auth-service` sang `iam-service`.
## Tổng Quan
IAM Service là phiên bản mở rộng của Auth Service với các tính năng bổ sung về Identity Management, Access Management, và Governance & Compliance. Tất cả các API endpoints của Auth Service vẫn được giữ nguyên để đảm bảo backward compatibility.
## Backward Compatibility
**Tất cả các endpoints hiện tại vẫn hoạt động bình thường:**
- `/api/v1/auth/*` - Authentication endpoints
- `/api/v1/rbac/*` - RBAC endpoints
- `/api/v1/mfa/*` - MFA endpoints
- `/api/v1/sessions/*` - Session management endpoints
- `/api/v1/oidc/*` - OIDC endpoints
Không có breaking changes. Các clients hiện tại có thể tiếp tục sử dụng các endpoints này mà không cần thay đổi.
## Các Thay Đổi
### 1. Service Name
- **Cũ**: `auth-service`
- **Mới**: `iam-service`
### 2. Package Name
- **Cũ**: `@goodgo/auth-service`
- **Mới**: `@goodgo/iam-service`
### 3. Database Schema
Database schema được mở rộng với các models mới nhưng **không xóa hoặc thay đổi** các models hiện có:
**Models mới được thêm:**
- `Organization` - Quản lý tổ chức
- `Group` - Quản lý nhóm
- `GroupMember` - Thành viên nhóm
- `GroupPermission` - Quyền nhóm
- `UserProfile` - Profile mở rộng
- `IdentityVerification` - Xác thực danh tính
- `AccessRequest` - Yêu cầu truy cập
- `AccessReview` - Đánh giá truy cập
- `ComplianceReport` - Báo cáo tuân thủ
- `PolicyTemplate` - Template policy
- `RiskScore` - Điểm rủi ro
**User model được mở rộng:**
- Thêm field `organizationId` (optional)
- Thêm các relations mới (optional)
### 4. API Endpoints Mới
#### Identity Management
- `/api/v1/identity/users/*` - User lifecycle management
- `/api/v1/identity/users/:id/profile` - Profile management
- `/api/v1/identity/verification/*` - Identity verification
- `/api/v1/identity/organizations/*` - Organization management
- `/api/v1/identity/groups/*` - Group management
#### Access Management
- `/api/v1/access/requests/*` - Access requests
- `/api/v1/access/reviews/*` - Access reviews
- `/api/v1/access/analytics/*` - Access analytics
#### Governance
- `/api/v1/governance/compliance/*` - Compliance reports
- `/api/v1/governance/policies/*` - Policy governance
- `/api/v1/governance/risk/*` - Risk management
- `/api/v1/governance/reports/*` - Reporting dashboard
### 5. Environment Variables
Một số biến môi trường mới có thể được thêm trong tương lai cho các tính năng IAM nâng cao (email service, SMS service, file storage), nhưng không ảnh hưởng đến các biến hiện tại.
### 6. Deployment Configuration
**Docker Compose:**
- Service name: `auth-service``iam-service`
- Container name: `auth-service-local``iam-service-local`
- Traefik labels: Thêm routes mới cho `/api/v1/identity/*`, `/api/v1/access/*`, `/api/v1/governance/*`
**Kubernetes:**
- Deployment name: `auth-service``iam-service`
- Service name: `auth-service``iam-service`
- ConfigMap: `auth-service-config``iam-service-config`
- Secrets: `auth-service-secrets``iam-service-secrets`
## Migration Steps
### Bước 1: Backup
```bash
# Backup database
pg_dump $DATABASE_URL > auth-service-backup.sql
# Backup code
cp -r services/auth-service services/auth-service.backup
```
### Bước 2: Database Migration
```bash
cd services/iam-service
# Generate Prisma client với schema mới
pnpm prisma generate
# Tạo migration
pnpm prisma migrate dev --name add_iam_models
# Verify migration
pnpm prisma studio # Check database structure
```
### Bước 3: Update Dependencies
```bash
# Install dependencies (nếu có package mới)
pnpm install
# Verify types compile
pnpm typecheck
```
### Bước 4: Update Deployment
**Local Development:**
```bash
cd deployments/local
# Update docker-compose.yml (đã được cập nhật)
docker-compose up -d iam-service
```
**Staging/Production:**
- Update Kubernetes manifests
- Update ingress routes
- Update ConfigMaps và Secrets
### Bước 5: Verify Backward Compatibility
Test tất cả các endpoints cũ vẫn hoạt động:
```bash
# Test auth endpoints
curl http://localhost/api/v1/auth/me
# Test RBAC endpoints
curl http://localhost/api/v1/rbac/permissions
# Test MFA endpoints
curl http://localhost/api/v1/mfa/devices
```
### Bước 6: Gradual Rollout
1. **Dual Deployment** (Optional):
- Deploy cả `auth-service``iam-service` cùng lúc
- Route traffic dần dần sang `iam-service`
- Monitor errors và performance
2. **Update Clients**:
- Update clients để sử dụng các endpoints mới nếu cần
- Clients không cần update nếu chỉ dùng endpoints cũ
3. **Deprecate Old Service**:
- Sau khi verify mọi thứ hoạt động tốt, có thể deprecate `auth-service`
- Đảm bảo tất cả clients đã migrate sang `iam-service`
## Rollback Plan
Nếu cần rollback:
1. **Database Rollback**:
```bash
# Revert Prisma migration
cd services/iam-service
pnpm prisma migrate resolve --rolled-back <migration_name>
# Hoặc restore từ backup
psql $DATABASE_URL < auth-service-backup.sql
```
2. **Service Rollback**:
```bash
# Switch back to auth-service in docker-compose
# Hoặc revert Kubernetes deployment
kubectl rollout undo deployment/auth-service
```
## Breaking Changes
**Không có breaking changes** trong migration này. Tất cả các API endpoints và database models hiện có đều được giữ nguyên.
## Notes
- Migration này là **additive** - chỉ thêm các tính năng mới, không xóa hoặc thay đổi tính năng cũ
- Database migrations là **non-destructive** - không xóa hoặc modify dữ liệu hiện có
- Clients có thể tiếp tục sử dụng các endpoints cũ mà không cần thay đổi
## Support
Nếu gặp vấn đề trong quá trình migration, vui lòng:
1. Check logs: `docker-compose logs iam-service`
2. Verify database connection
3. Check environment variables
4. Review error messages và stack traces

View File

@@ -38,7 +38,7 @@ docker-compose logs -f
### Backend Services
- **auth-service** (Port 5001): Authentication and user management
- **iam-service** (Port 5001): Authentication and user management
- Routes: `/api/v1/auth`, `/api/v1/users`
- Health: http://localhost/api/v1/auth/health
@@ -84,7 +84,7 @@ CORS_ORIGIN=http://localhost:3000,http://localhost:3001
docker-compose up -d
# Start specific service
docker-compose up -d auth-service
docker-compose up -d iam-service
# Stop all services
docker-compose down
@@ -96,19 +96,19 @@ docker-compose down -v
docker-compose logs -f
# View logs (specific service)
docker-compose logs -f auth-service
docker-compose logs -f iam-service
# Restart service
docker-compose restart auth-service
docker-compose restart iam-service
# Rebuild service
docker-compose up -d --build auth-service
docker-compose up -d --build iam-service
# Check service status
docker-compose ps
# Execute command in container
docker-compose exec auth-service sh
docker-compose exec iam-service sh
```
## Adding New Service
@@ -196,7 +196,7 @@ docker-compose up -d service-name
cat .env.local | grep DATABASE_URL
# Test connection from service
docker-compose exec auth-service sh
docker-compose exec iam-service sh
# Inside container:
# curl $DATABASE_URL (won't work, but shows if var is set)
```
@@ -242,7 +242,7 @@ docker-compose logs traefik
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
auth-service │ │ web-admin │ │ web-client │
iam-service │ │ web-admin │ │ web-client │
│ :5001 │ │ :3000 │ │ :3001 │
└──────┬───────┘ └──────────────┘ └──────────────┘

View File

@@ -64,13 +64,13 @@ JWT_REFRESH_SECRET=dev-refresh-secret-change-in-production
### 4. Run Database Migrations
```bash
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
```
### 5. Seed Database (Optional)
```bash
./scripts/db/seed.sh auth-service
./scripts/db/seed.sh iam-service
```
## Ways to Run the Project
@@ -107,10 +107,10 @@ Best when working on a single service:
```bash
# Using script
./scripts/dev/start-service.sh auth-service
./scripts/dev/start-service.sh iam-service
# Or run directly
cd services/auth-service
cd services/iam-service
pnpm dev
```
@@ -124,7 +124,7 @@ pnpm --filter "./services/*" dev
pnpm --filter "./apps/*" dev
# Run specific service
pnpm --filter @goodgo/auth-service dev
pnpm --filter @goodgo/iam-service dev
```
### Method 4: Run With Docker Compose (Full Stack)
@@ -147,8 +147,11 @@ When services are running, you can access:
| Service | URL | Description |
|---------|-----|-------------|
| **API Gateway** | http://localhost/api/v1 | Main entry point via Traefik |
| **Auth Service** | http://localhost:5001 | Direct auth service access |
| **Auth API** | http://localhost/api/v1/auth | Auth API via gateway |
| **IAM Service** | http://localhost:5001 | Direct IAM service access |
| **Auth API** | http://localhost/api/v1/auth | Auth API via gateway (backward compatible) |
| **Identity API** | http://localhost/api/v1/identity | Identity management API |
| **Access API** | http://localhost/api/v1/access | Access management API |
| **Governance API** | http://localhost/api/v1/governance | Governance API |
| **Web Admin** | http://admin.localhost or http://localhost:3000 | Admin dashboard |
| **Web Client** | http://localhost or http://localhost:3001 | Client web app |
| **Traefik Dashboard** | http://localhost:8080 | View routing and services |
@@ -160,9 +163,9 @@ When services are running, you can access:
Backend services use `tsx watch` or `nodemon` for automatic restart on code changes:
```bash
# In services/auth-service/package.json
# In services/iam-service/package.json
"scripts": {
"dev": "tsx watch src/index.ts"
"dev": "tsx watch src/main.ts"
}
```
@@ -209,7 +212,7 @@ pnpm --filter @goodgo/logger dev
**Terminal 2: View Logs**
```bash
# View specific service logs
./scripts/dev/logs.sh auth-service
./scripts/dev/logs.sh iam-service
# Or view Docker logs
docker logs -f redis-cache-local
@@ -219,10 +222,10 @@ docker logs -f traefik-local
**Terminal 3: Development Tasks**
```bash
# Run tests
pnpm --filter @goodgo/auth-service test --watch
pnpm --filter @goodgo/iam-service test --watch
# Run migrations
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
# Format code
pnpm format
@@ -257,7 +260,7 @@ Access http://localhost:8080 to view:
```bash
# 1. Edit prisma/schema.prisma
# 2. Create and apply migration
cd services/auth-service
cd services/iam-service
pnpm prisma migrate dev --name add_new_field
# 3. Prisma Client auto-regenerates
@@ -266,7 +269,7 @@ pnpm prisma migrate dev --name add_new_field
### Reset Database (Development Only!)
```bash
cd services/auth-service
cd services/iam-service
pnpm prisma migrate reset
```
@@ -274,7 +277,7 @@ pnpm prisma migrate reset
```bash
# Open Prisma Studio
cd services/auth-service
cd services/iam-service
pnpm prisma studio
# Access: http://localhost:5555
```
@@ -294,7 +297,7 @@ Create `.vscode/launch.json`:
"type": "node",
"request": "launch",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["--filter", "@goodgo/auth-service", "dev"],
"runtimeArgs": ["--filter", "@goodgo/iam-service", "dev"],
"skipFiles": ["<node_internals>/**"],
"console": "integratedTerminal"
}
@@ -306,10 +309,10 @@ Create `.vscode/launch.json`:
```bash
# Service logs
./scripts/dev/logs.sh auth-service
./scripts/dev/logs.sh iam-service
# Docker logs
docker logs -f auth-service-local
docker logs -f iam-service-local
docker logs -f redis-cache-local
docker logs -f traefik-local
@@ -352,7 +355,7 @@ docker-compose -f deployments/local/docker-compose.yml restart
cat deployments/local/.env.local | grep DATABASE_URL
# Test connection
cd services/auth-service
cd services/iam-service
pnpm prisma db pull
```
@@ -379,7 +382,7 @@ pnpm install
pnpm dev
# Or restart Docker container
docker-compose -f deployments/local/docker-compose.yml restart auth-service
docker-compose -f deployments/local/docker-compose.yml restart iam-service
```
## Tips & Best Practices
@@ -401,18 +404,18 @@ pnpm dev
No need to run everything if working on one service:
```bash
# Run only auth-service
pnpm --filter @goodgo/auth-service dev
# Run only iam-service
pnpm --filter @goodgo/iam-service dev
# Run auth-service with dependencies
pnpm --filter @goodgo/auth-service... dev
# Run iam-service with dependencies
pnpm --filter @goodgo/iam-service... dev
```
### 3. Watch Tests
```bash
# Run tests automatically on code changes
pnpm --filter @goodgo/auth-service test --watch
pnpm --filter @goodgo/iam-service test --watch
```
### 4. Auto-format Code
@@ -452,7 +455,7 @@ LOG_LEVEL=debug
Create `.env.local` file in service directory:
```bash
# services/auth-service/.env.local
# services/iam-service/.env.local
PORT=5001
LOG_LEVEL=debug
```
@@ -472,9 +475,9 @@ pnpm clean # Remove build artifacts
./scripts/utils/cleanup.sh # Full cleanup
# Database
./scripts/db/migrate.sh auth-service dev # Migration
./scripts/db/seed.sh auth-service # Seed data
./scripts/db/backup.sh auth-service # Backup
./scripts/db/migrate.sh iam-service dev # Migration
./scripts/db/seed.sh iam-service # Seed data
./scripts/db/backup.sh iam-service # Backup
# Docker
docker-compose -f deployments/local/docker-compose.yml up -d # Start

View File

@@ -44,7 +44,7 @@ DATABASE_URL=postgresql://user:pass@ep-xxx.region.neon.tech/dbname?sslmode=requi
### 5. Run Migrations
```bash
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
```
## Connection String Format
@@ -73,7 +73,7 @@ Store in GitHub Secrets: `NEON_DATABASE_URL_STAGING`
Or in Kubernetes:
```bash
kubectl create secret generic auth-service-secrets \
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://...' \
-n staging
```
@@ -84,7 +84,7 @@ Store in GitHub Secrets: `NEON_DATABASE_URL_PRODUCTION`
Or in Kubernetes:
```bash
kubectl create secret generic auth-service-secrets \
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://...' \
-n production
```
@@ -95,7 +95,7 @@ kubectl create secret generic auth-service-secrets \
```bash
# Create new migration
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
# This will:
# 1. Create migration file
@@ -111,7 +111,7 @@ Migrations run automatically in CI/CD:
Manual migration:
```bash
./scripts/db/migrate.sh auth-service deploy
./scripts/db/migrate.sh iam-service deploy
```
## Backup & Restore
@@ -126,7 +126,7 @@ Neon provides automatic backups. Access via Neon Console:
### Manual Backup
```bash
./scripts/db/backup.sh auth-service
./scripts/db/backup.sh iam-service
```
This creates a SQL dump file in `backups/` directory.

View File

@@ -66,13 +66,13 @@ In the **Explore** view with **Loki** selected:
1. Click **Label browser**.
2. Select a label, e.g., `container`.
3. Choose a specific container (e.g., `auth-service` or `traefik`).
3. Choose a specific container (e.g., `iam-service` or `traefik`).
4. Click **Show logs**.
You can also write LogQL queries manually, for example:
```logql
{container="auth-service"}
{container="iam-service"}
```
### Viewing Metrics (Prometheus)

View File

@@ -27,7 +27,7 @@
**Solutions**:
```bash
cd services/auth-service
cd services/iam-service
pnpm prisma generate
```

View File

@@ -51,13 +51,13 @@ Welcome to the GoodGo Microservices Platform team!
./scripts/dev/start-all.sh
# Start specific service
./scripts/dev/start-service.sh auth-service
./scripts/dev/start-service.sh iam-service
# View logs
./scripts/dev/logs.sh auth-service
./scripts/dev/logs.sh iam-service
# Run migrations
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
# Run tests
pnpm test

View File

@@ -13,17 +13,17 @@
1. **Identify current version**
```bash
kubectl get deployment auth-service -n production -o jsonpath='{.spec.template.spec.containers[0].image}'
kubectl get deployment iam-service -n production -o jsonpath='{.spec.template.spec.containers[0].image}'
```
2. **Rollback to previous version**
```bash
kubectl rollout undo deployment/auth-service -n production
kubectl rollout undo deployment/iam-service -n production
```
3. **Verify rollback**
```bash
kubectl rollout status deployment/auth-service -n production
kubectl rollout status deployment/iam-service -n production
```
4. **Check service health**
@@ -37,7 +37,7 @@
1. Create reverse migration:
```bash
cd services/auth-service
cd services/iam-service
pnpm prisma migrate dev --name rollback_previous_change
```

129
docs/en/skills/README.md Normal file
View File

@@ -0,0 +1,129 @@
# Cursor Skills Documentation
> **EN**: Comprehensive documentation for all Cursor AI skills used in the GoodGo Microservices Platform
> **VI**: Tài liệu đầy đủ cho tất cả Cursor AI skills được sử dụng trong GoodGo Microservices Platform
## Overview / Tổng Quan
**EN**: Cursor Skills are specialized knowledge modules that guide AI assistants in following project-specific patterns, standards, and best practices. This directory contains detailed documentation for each skill, including when to use them, key concepts, common patterns, and real-world examples from the codebase.
**VI**: Cursor Skills là các module kiến thức chuyên biệt hướng dẫn AI assistants tuân theo các patterns, tiêu chuẩn và best practices cụ thể của dự án. Thư mục này chứa tài liệu chi tiết cho từng skill, bao gồm khi nào sử dụng, khái niệm chính, các pattern thường dùng, và ví dụ thực tế từ codebase.
## Available Skills / Các Skills Có Sẵn
The GoodGo platform includes **9 Cursor Skills** organized by category:
### API & Data Layer
#### [API Design](./api-design.md)
**EN**: RESTful API design standards for GoodGo microservices. Use when creating new API endpoints, designing DTOs, implementing controllers, writing OpenAPI documentation, or standardizing API responses.
**VI**: Tiêu chuẩn thiết kế RESTful API cho GoodGo microservices. Sử dụng khi tạo API endpoints mới, thiết kế DTOs, implement controllers, viết OpenAPI documentation, hoặc chuẩn hóa API responses.
#### [Database & Prisma](./database-prisma.md)
**EN**: Prisma ORM and database patterns for GoodGo microservices. Use when working with databases, creating Prisma schemas, writing migrations, implementing repositories, or optimizing queries.
**VI**: Prisma ORM và database patterns cho GoodGo microservices. Sử dụng khi làm việc với databases, tạo Prisma schemas, viết migrations, implement repositories, hoặc optimize queries.
### Code Quality & Testing
#### [Testing Patterns](./testing-patterns.md)
**EN**: Testing best practices for GoodGo microservices. Use when writing unit tests, integration tests, E2E tests, setting up Jest, mocking dependencies, or debugging test failures.
**VI**: Best practices về testing cho GoodGo microservices. Sử dụng khi viết unit tests, integration tests, E2E tests, setup Jest, mocking dependencies, hoặc debug test failures.
#### [Code Comments](./comment-code.md)
**EN**: Add bilingual code comments in Vietnamese and English for better documentation. Use when adding comments to code, documenting functions/classes, or when user requests Vietnamese/English documentation.
**VI**: Thêm code comments song ngữ bằng tiếng Việt và tiếng Anh để tài liệu tốt hơn. Sử dụng khi thêm comments vào code, document functions/classes, hoặc khi user yêu cầu tài liệu tiếng Việt/Anh.
### Infrastructure & Operations
#### [Kubernetes Deployment](./deployment-kubernetes.md)
**EN**: Kubernetes deployment patterns for GoodGo microservices. Use when deploying to staging/production, creating K8s manifests, configuring HPA, setting up ingress, or troubleshooting K8s deployments.
**VI**: Kubernetes deployment patterns cho GoodGo microservices. Sử dụng khi deploy lên staging/production, tạo K8s manifests, config HPA, setup ingress, hoặc troubleshoot K8s deployments.
#### [Observability & Monitoring](./observability-monitoring.md)
**EN**: Observability and monitoring patterns for GoodGo microservices. Use when adding metrics, implementing logging, setting up tracing, creating health checks, or debugging production issues.
**VI**: Observability và monitoring patterns cho GoodGo microservices. Sử dụng khi thêm metrics, implement logging, setup tracing, tạo health checks, hoặc debug production issues.
### Standards & Security
#### [Project Rules](./project-rules.md)
**EN**: GoodGo Microservices Platform coding standards and architecture patterns. Use when working with services, apps, packages, or infrastructure.
**VI**: Tiêu chuẩn coding và architecture patterns của GoodGo Microservices Platform. Sử dụng khi làm việc với services, apps, packages, hoặc infrastructure.
#### [Security](./security.md)
**EN**: Security best practices and patterns for GoodGo microservices platform. Use when implementing authentication, authorization, data protection, input validation, rate limiting, secrets management, or security testing across all services.
**VI**: Security best practices và patterns cho GoodGo microservices platform. Sử dụng khi implement authentication, authorization, data protection, input validation, rate limiting, secrets management, hoặc security testing trên tất cả services.
#### [Documentation](./documentation.md)
**EN**: Guidelines for writing technical documentation in the GoodGo project. Use when creating or updating README files, guides, architecture docs, or API documentation. Ensures bilingual (EN/VI) consistency and proper structure.
**VI**: Hướng dẫn viết technical documentation trong dự án GoodGo. Sử dụng khi tạo hoặc cập nhật README files, guides, architecture docs, hoặc API documentation. Đảm bảo tính nhất quán song ngữ (EN/VI) và cấu trúc phù hợp.
## Quick Reference / Tham Khảo Nhanh
### By Use Case / Theo Use Case
| Task | Recommended Skills |
|------|-------------------|
| Creating a new API endpoint | API Design, Security, Testing Patterns |
| Setting up a new service | Project Rules, Database & Prisma, Observability |
| Writing tests | Testing Patterns, Comment Code |
| Deploying to production | Kubernetes Deployment, Observability, Security |
| Debugging production issues | Observability & Monitoring, Security |
| Writing documentation | Documentation, Comment Code |
| Implementing authentication | Security, API Design, Database & Prisma |
| Optimizing database queries | Database & Prisma, Observability |
### Skill Dependencies / Phụ Thuộc Giữa Các Skills
```
Project Rules (Foundation)
├── API Design
├── Database & Prisma
├── Security
└── Testing Patterns
└── Comment Code
Documentation (Cross-cutting)
└── All skills
Observability (Cross-cutting)
└── All services
Kubernetes Deployment (Infrastructure)
└── All services
```
## How to Use Skills / Cách Sử Dụng Skills
1. **When starting a new task**: Review relevant skills in this directory
2. **During development**: Reference skill documentation for patterns and examples
3. **When stuck**: Check skill docs for best practices and common solutions
4. **For code review**: Use skills as checklist for standards compliance
## Related Documentation / Tài Liệu Liên Quan
- [Architecture Overview](../architecture/system-design.md) - System design patterns
- [Development Guide](../guides/development.md) - Development workflow
- [Deployment Guide](../guides/deployment.md) - Deployment procedures
- [API Documentation](../api/openapi/) - OpenAPI specifications
## Contributing / Đóng Góp
When updating or adding new skills:
1. Update the skill source file in `.cursor/skills/{skill-name}/SKILL.md`
2. Update the corresponding documentation in `docs/en/skills/{skill-name}.md`
3. Update the Vietnamese translation in `docs/vi/skills/{skill-name}.md`
4. Update this index file with any changes
5. Ensure bilingual consistency
## Resources / Tài Nguyên
- [Cursor Skills Documentation](https://cursor.sh/docs) - Official Cursor documentation
- [Cursor AI](https://cursor.sh) - Cursor IDE homepage
- Project Skills: `.cursor/skills/` - Source skill files

View File

@@ -0,0 +1,455 @@
# RESTful API Design / Thiết Kế API RESTful
> **EN**: RESTful API design standards for GoodGo microservices. Use when creating new API endpoints, designing DTOs, implementing controllers, writing OpenAPI documentation, or standardizing API responses.
> **VI**: Tiêu chuẩn thiết kế API RESTful cho các microservices của GoodGo. Sử dụng khi tạo endpoint API mới, thiết kế DTOs, triển khai controllers, viết tài liệu OpenAPI, hoặc chuẩn hóa response API.
## Overview / Tổng Quan
**EN**: This skill covers the RESTful API design patterns and standards used across all GoodGo microservices. It ensures consistency, predictability, and maintainability of APIs through standardized URL structures, HTTP methods, response formats, error handling, and DTO validation.
**VI**: Skill này bao gồm các pattern và tiêu chuẩn thiết kế API RESTful được sử dụng trong tất cả các microservices của GoodGo. Nó đảm bảo tính nhất quán, dự đoán được và dễ bảo trì của APIs thông qua cấu trúc URL chuẩn hóa, HTTP methods, định dạng response, xử lý lỗi và validation DTO.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Creating new API endpoints
- Designing request/response DTOs
- Implementing controllers and routes
- Writing OpenAPI/Swagger documentation
- Standardizing error responses
- Implementing pagination, filtering, and sorting
- Setting up API versioning
- Designing resource relationships
**VI**: Sử dụng skill này khi:
- Tạo endpoint API mới
- Thiết kế DTOs cho request/response
- Triển khai controllers và routes
- Viết tài liệu OpenAPI/Swagger
- Chuẩn hóa error responses
- Triển khai pagination, filtering và sorting
- Thiết lập API versioning
- Thiết kế quan hệ giữa các resources
## Key Concepts / Khái Niệm Chính
### 1. URL Structure / Cấu Trúc URL
**EN**: URLs follow a hierarchical resource-based structure with versioning.
**VI**: URLs tuân theo cấu trúc phân cấp dựa trên resource với versioning.
```
https://api.goodgo.com/v1/{resource}/{id}/{sub-resource}
Examples:
GET /v1/users # List users
POST /v1/users # Create user
GET /v1/users/123 # Get user by ID
PUT /v1/users/123 # Update user
DELETE /v1/users/123 # Delete user
GET /v1/users/123/orders # Get user's orders
POST /v1/users/123/orders # Create order for user
```
### 2. HTTP Methods / Phương Thức HTTP
- **GET**: Retrieve resource(s) - Safe, Idempotent
- **POST**: Create new resource - Not idempotent
- **PUT**: Full update - Idempotent
- **PATCH**: Partial update - Idempotent
- **DELETE**: Remove resource - Idempotent
### 3. Standard Response Format / Định Dạng Response Chuẩn
All API responses follow a consistent structure with `success`, `data`, and optional `metadata` fields.
Tất cả API responses tuân theo cấu trúc nhất quán với các trường `success`, `data`, và `metadata` tùy chọn.
## Common Patterns / Các Pattern Thường Dùng
### Success Response Pattern
```typescript
interface SuccessResponse<T> {
success: true;
data: T;
message?: string;
timestamp?: string;
pagination?: {
total: number;
skip: number;
take: number;
};
}
```
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/identity/user/user.controller.ts
res.json({
success: true,
data: {
users: result.users,
pagination: {
total: result.total,
skip: filters.skip,
take: filters.take,
},
},
});
```
### Error Response Pattern
```typescript
interface ErrorResponse {
success: false;
error: {
code: string;
message: string;
details?: any;
field?: string;
};
timestamp?: string;
}
```
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/identity/user/user.controller.ts
if (error instanceof z.ZodError) {
res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid filters',
details: error.errors,
},
});
return;
}
```
### HTTP Status Codes / Mã Trạng Thái HTTP
```typescript
// Success codes
200 OK // GET, PUT, PATCH success
201 Created // POST success with resource creation
204 No Content // DELETE success
// Client errors
400 Bad Request // Invalid request data
401 Unauthorized // Missing/invalid authentication
403 Forbidden // Valid auth but no permission
404 Not Found // Resource doesn't exist
409 Conflict // Resource conflict (duplicate)
422 Unprocessable // Validation errors
// Server errors
500 Internal Error // Unexpected server error
502 Bad Gateway // External service error
503 Service Unavailable // Service temporarily down
```
### DTOs with Zod Validation / DTOs với Zod Validation
**EN**: DTOs use Zod for runtime validation with bilingual error messages.
**VI**: DTOs sử dụng Zod cho validation runtime với thông báo lỗi song ngữ.
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/identity/identity.dto.ts
import { z } from 'zod';
export const CreateOrganizationDto = z.object({
name: z.string().min(1, 'Organization name is required / Tên tổ chức là bắt buộc').max(255),
domain: z.string().email().optional().or(z.string().min(1).max(255).optional()),
parentId: z.string().optional(),
settings: z.record(z.any()).optional(),
});
export type CreateOrganizationDto = z.infer<typeof CreateOrganizationDto>;
export const UserFiltersDto = z.object({
organizationId: z.string().optional(),
isActive: z.boolean().optional(),
emailVerified: z.boolean().optional(),
search: z.string().optional(),
skip: z.number().int().min(0).default(0),
take: z.number().int().min(1).max(100).default(20),
});
```
### Controller Implementation Pattern / Pattern Triển Khai Controller
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/identity/user/user.controller.ts
export class UserManagementController {
/**
* EN: List users
* VI: Liệt kê users
*/
async list(req: Request, res: Response): Promise<void> {
try {
const filters = UserFiltersDto.parse({
organizationId: req.query.organizationId as string,
isActive: req.query.isActive === 'true' ? true : req.query.isActive === 'false' ? false : undefined,
emailVerified: req.query.emailVerified === 'true' ? true : req.query.emailVerified === 'false' ? false : undefined,
search: req.query.search as string,
skip: parseInt(req.query.skip as string) || 0,
take: parseInt(req.query.take as string) || 20,
});
const result = await userManagementService.searchUsers(filters);
res.json({
success: true,
data: {
users: result.users,
pagination: {
total: result.total,
skip: filters.skip,
take: filters.take,
},
},
});
} catch (error: any) {
if (error instanceof z.ZodError) {
res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid filters',
details: error.errors,
},
});
return;
}
res.status(500).json({
success: false,
error: {
code: 'LIST_USERS_FAILED',
message: error.message || 'Failed to list users',
},
});
}
}
/**
* EN: Get user by ID
* VI: Lấy user theo ID
*/
async get(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params;
const user = await userManagementService.getUser(id);
res.json({
success: true,
data: user,
});
} catch (error: any) {
if (error instanceof NotFoundError) {
res.status(404).json(error.toApiResponse());
return;
}
res.status(500).json({
success: false,
error: {
code: 'GET_USER_FAILED',
message: error.message || 'Failed to get user',
},
});
}
}
}
```
### Error Handling with Custom Error Classes / Xử Lý Lỗi với Custom Error Classes
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/errors/http-error.ts
export class HttpError extends Error {
public readonly statusCode: number;
public readonly errorCode: string;
public readonly isOperational: boolean;
public readonly details?: any;
constructor(
message: string,
statusCode: number = 500,
errorCode: string = 'INTERNAL_ERROR',
isOperational: boolean = true,
details?: any
) {
super(message);
this.name = this.constructor.name;
this.statusCode = statusCode;
this.errorCode = errorCode;
this.isOperational = isOperational;
this.details = details;
Error.captureStackTrace(this, this.constructor);
}
toApiResponse() {
return {
success: false,
error: {
code: this.errorCode,
message: this.message,
...(this.details && { details: this.details }),
},
timestamp: new Date().toISOString(),
};
}
}
export class NotFoundError extends HttpError {
constructor(resource: string = 'Resource / Tài nguyên', details?: any) {
super(`${resource} not found / ${resource} không tìm thấy`, 404, 'NOT_FOUND', true, details);
}
}
export class ValidationError extends HttpError {
constructor(message: string = 'Validation failed / Validation thất bại', details?: any) {
super(message, 422, 'VALIDATION_ERROR', true, details);
}
}
```
## Best Practices / Thực Hành Tốt Nhất
### 1. Resource Naming / Đặt Tên Resource
- ✅ Use plural nouns (`/users` not `/user`)
- ✅ Use kebab-case for multi-word resources (`/user-profiles`)
- ✅ Keep URLs as short as possible
- ❌ Avoid verbs in URLs (use HTTP methods instead)
### 2. Versioning / Phiên Bản Hóa
- ✅ Include version in URL (`/v1/users`)
- ✅ Maintain backward compatibility
- ✅ Deprecate old versions gracefully with warnings
### 3. Security / Bảo Mật
- ✅ Always use HTTPS
- ✅ Implement rate limiting
- ✅ Validate all inputs with DTOs
- ✅ Use proper authentication/authorization middleware
- ✅ Never expose sensitive data in responses
### 4. Performance / Hiệu Năng
- ✅ Implement pagination for lists (use `skip` and `take`)
- ✅ Use field filtering when possible (`select` in Prisma)
- ✅ Cache responses appropriately
- ✅ Compress responses (gzip)
### 5. Documentation / Tài Liệu
- ✅ Keep OpenAPI spec up to date
- ✅ Include examples in documentation
- ✅ Document error responses
- ✅ Version your documentation
### 6. Error Handling / Xử Lý Lỗi
- ✅ Use consistent error response format
- ✅ Provide actionable error messages
- ✅ Include error codes for programmatic handling
- ✅ Log errors server-side, don't expose stack traces in production
## Examples from Project / Ví Dụ Từ Dự Án
### Controller Examples / Ví Dụ Controller
- **User Management**: [`services/iam-service/src/modules/identity/user/user.controller.ts`](../../../services/iam-service/src/modules/identity/user/user.controller.ts)
- **Feature Controller**: [`services/iam-service/src/modules/feature/feature.controller.ts`](../../../services/iam-service/src/modules/feature/feature.controller.ts)
- **RBAC Controller**: [`services/iam-service/src/modules/rbac/rbac.controller.ts`](../../../services/iam-service/src/modules/rbac/rbac.controller.ts)
### DTO Examples / Ví Dụ DTO
- **Identity DTOs**: [`services/iam-service/src/modules/identity/identity.dto.ts`](../../../services/iam-service/src/modules/identity/identity.dto.ts)
- **Auth DTOs**: [`services/iam-service/src/modules/auth/auth.dto.ts`](../../../services/iam-service/src/modules/auth/auth.dto.ts)
- **RBAC DTOs**: [`services/iam-service/src/modules/rbac/rbac.dto.ts`](../../../services/iam-service/src/modules/rbac/rbac.dto.ts)
### Error Handling Examples / Ví Dụ Xử Lý Lỗi
- **HTTP Error Classes**: [`services/iam-service/src/errors/http-error.ts`](../../../services/iam-service/src/errors/http-error.ts)
- **Error Middleware**: [`services/iam-service/src/middlewares/error.middleware.ts`](../../../services/iam-service/src/middlewares/error.middleware.ts)
## Quick Reference / Tham Khảo Nhanh
### Response Format Cheat Sheet / Bảng Tra Cứu Định Dạng Response
| Scenario | Status Code | Response Structure |
|----------|-------------|-------------------|
| Success (GET) | 200 | `{ success: true, data: {...} }` |
| Success (POST) | 201 | `{ success: true, data: {...} }` |
| Success (DELETE) | 200 | `{ success: true, message: "..." }` |
| Validation Error | 400/422 | `{ success: false, error: { code, message, details } }` |
| Not Found | 404 | `{ success: false, error: { code: "NOT_FOUND", message } }` |
| Unauthorized | 401 | `{ success: false, error: { code: "UNAUTHORIZED", message } }` |
| Forbidden | 403 | `{ success: false, error: { code: "FORBIDDEN", message } }` |
| Server Error | 500 | `{ success: false, error: { code: "INTERNAL_ERROR", message } }` |
### Common DTO Patterns / Pattern DTO Thường Dùng
```typescript
// Create DTO
const CreateDto = z.object({
requiredField: z.string().min(1),
optionalField: z.string().optional(),
});
// Update DTO (all fields optional)
const UpdateDto = z.object({
field1: z.string().optional(),
field2: z.number().optional(),
});
// Query/Filter DTO
const QueryDto = z.object({
page: z.number().int().min(1).default(1),
limit: z.number().int().min(1).max(100).default(20),
search: z.string().optional(),
sortBy: z.string().optional(),
order: z.enum(['asc', 'desc']).default('desc'),
});
```
## Related Skills / Skills Liên Quan
- **[Database Prisma](./database-prisma.md)**: For database operations and repository patterns
- **[Security](./security.md)**: For authentication, authorization, and security best practices
- **[Testing Patterns](./testing-patterns.md)**: For testing API endpoints
- **[Documentation](./documentation.md)**: For writing API documentation
## Resources / Tài Nguyên
### External Documentation / Tài Liệu Bên Ngoài
- [REST API Design Best Practices](https://restfulapi.net/)
- [HTTP Status Codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
- [Zod Documentation](https://zod.dev/)
- [OpenAPI Specification](https://swagger.io/specification/)
### Internal Documentation / Tài Liệu Nội Bộ
- [API Reference](../api/openapi/iam-service.yaml)
- [Service Communication](../architecture/service-communication.md)
- [Project Rules](./project-rules.md)

View File

@@ -0,0 +1,562 @@
# Comment Code / Viết Comment Code
> **EN**: Guidelines for adding comprehensive bilingual code comments (English and Vietnamese) to improve code readability for international and Vietnamese teams.
> **VI**: Hướng dẫn thêm comments song ngữ (tiếng Anh và tiếng Việt) để cải thiện khả năng đọc code cho các đội quốc tế và Việt Nam.
## Overview / Tổng Quan
**EN**: Code comments are essential for maintaining and understanding codebase, especially in a bilingual development environment. This guide provides comprehensive patterns for writing clear, consistent, and helpful comments in both English and Vietnamese across the GoodGo microservices platform. It covers JSDoc documentation, inline comments, special comment types, and best practices for effective code documentation.
**VI**: Comments code là điều cần thiết để bảo trì và hiểu codebase, đặc biệt trong môi trường phát triển song ngữ. Hướng dẫn này cung cấp các patterns toàn diện để viết comments rõ ràng, nhất quán và hữu ích bằng cả tiếng Anh và tiếng Việt trên nền tảng microservices GoodGo. Nó bao gồm tài liệu JSDoc, inline comments, các loại comment đặc biệt, và best practices cho tài liệu code hiệu quả.
## When to Use / Khi Nào Sử Dụng
**EN**: Use bilingual commenting patterns when:
- Adding comments to new code
- Documenting existing code
- Creating JSDoc/TSDoc documentation
- Writing function/class descriptions
- Explaining complex logic or algorithms
- Adding inline comments for clarification
- Documenting API endpoints and interfaces
- Explaining configuration and setup code
- Writing security-critical code documentation
- Creating error handling documentation
**VI**: Sử dụng các patterns comment song ngữ khi:
- Thêm comments vào code mới
- Tài liệu hóa code hiện có
- Tạo tài liệu JSDoc/TSDoc
- Viết mô tả functions/classes
- Giải thích logic hoặc thuật toán phức tạp
- Thêm inline comments để làm rõ
- Tài liệu hóa API endpoints và interfaces
- Giải thích code cấu hình và setup
- Viết tài liệu code bảo mật quan trọng
- Tạo tài liệu xử lý lỗi
## Key Concepts / Khái Niệm Chính
### Comment Format / Định Dạng Comment
All comments in the GoodGo project should be bilingual, with English (EN) followed by Vietnamese (VI) translations.
**Pattern**:
```
// EN: [English explanation]
// VI: [Vietnamese explanation]
```
### Comment Types / Các Loại Comment
1. **Single-line Comments** (`//`): For brief explanations
2. **Multi-line Comments** (`/* */`): For longer explanations
3. **JSDoc Comments** (`/** */`): For function, class, and API documentation
4. **Prisma Comments** (`///`): For database schema documentation
## Common Patterns / Các Pattern Thường Dùng
### Single-line Comments / Comments Một Dòng
Use single-line comments for brief explanations of code behavior.
```typescript
// EN: Initialize database connection
// VI: Khởi tạo kết nối database
const db = await createConnection();
// EN: Enable detailed logging in development, minimal in production
// VI: Bật ghi log chi tiết trong development, tối thiểu trong production
const logLevel = process.env.NODE_ENV === 'development' ? 'debug' : 'error';
```
**Real Example**: [`services/iam-service/src/config/database.config.ts`](../../../services/iam-service/src/config/database.config.ts)
### Multi-line Comments / Comments Nhiều Dòng
Use multi-line comments for detailed explanations or step-by-step processes.
```typescript
/**
* EN: Validates user credentials and returns JWT token
* VI: Xác thực thông tin đăng nhập và trả về JWT token
*
* @param email - User email address / Địa chỉ email người dùng
* @param password - User password / Mật khẩu người dùng
* @returns JWT token / Mã JWT token
* @throws AuthenticationError if credentials invalid / Lỗi xác thực nếu thông tin không hợp lệ
*/
async function login(email: string, password: string): Promise<string> {
// EN: Implementation here
// VI: Implementation ở đây
}
```
### Function Documentation / Tài Liệu Function
Use JSDoc format for all public functions with bilingual descriptions.
```typescript
/**
* EN: Calculates the total price including tax and discount
* VI: Tính tổng giá bao gồm thuế và giảm giá
*
* @param basePrice - Original price / Giá gốc
* @param taxRate - Tax rate (0-1) / Tỷ lệ thuế (0-1)
* @param discount - Discount amount / Số tiền giảm giá
* @returns Final price / Giá cuối cùng
*/
function calculateTotal(
basePrice: number,
taxRate: number,
discount: number
): number {
// EN: Apply discount first
// VI: Áp dụng giảm giá trước
const discountedPrice = basePrice - discount;
// EN: Then calculate tax
// VI: Sau đó tính thuế
const tax = discountedPrice * taxRate;
return discountedPrice + tax;
}
```
**Real Example**: [`services/iam-service/src/modules/feature/feature.service.ts`](../../../services/iam-service/src/modules/feature/feature.service.ts)
### Class Documentation / Tài Liệu Class
Document classes with bilingual descriptions and explain their purpose.
```typescript
/**
* EN: Service for managing features in the system
* VI: Service để quản lý các features trong hệ thống
*/
export class FeatureService {
/**
* EN: Create a new feature
* VI: Tạo một feature mới
*
* @param data - Feature data / Dữ liệu feature
* @returns Created feature / Feature đã tạo
*/
async create(data: { name: string; title?: string }) {
// Implementation
}
}
```
**Real Example**: [`services/iam-service/src/modules/feature/feature.service.ts`](../../../services/iam-service/src/modules/feature/feature.service.ts)
### Interface/Type Documentation / Tài Liệu Interface/Type
Document interfaces and types to explain their structure and purpose.
```typescript
/**
* EN: User data transfer object
* VI: Đối tượng truyền dữ liệu người dùng
*/
interface UserDto {
/** EN: Unique user identifier / VI: Mã định danh duy nhất */
id: string;
/** EN: User email address / VI: Địa chỉ email người dùng */
email: string;
/** EN: User display name / VI: Tên hiển thị người dùng */
name: string;
/** EN: User role for authorization / VI: Vai trò người dùng để phân quyền */
role: 'admin' | 'user' | 'guest';
}
```
### Configuration Comments / Comments Cấu Hình
Document configuration files and environment variables with clear explanations.
```typescript
/**
* EN: Prisma client instance configured for the application
* VI: Instance Prisma client được cấu hình cho ứng dụng
*/
export const prisma = new PrismaClient({
// EN: Enable detailed logging in development, minimal in production
// VI: Bật ghi log chi tiết trong development, tối thiểu trong production
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
});
/**
* EN: Establish database connection on application startup
* VI: Thiết lập kết nối database khi khởi động ứng dụng
*/
export const connectDatabase = async (): Promise<void> => {
try {
// EN: Connect to database using Prisma
// VI: Kết nối tới database sử dụng Prisma
await prisma.$connect();
logger.info('Database connected successfully / Kết nối database thành công');
} catch (error) {
// EN: Log error and exit if database connection fails
// VI: Ghi log lỗi và thoát nếu kết nối database thất bại
logger.error('Database connection failed / Kết nối database thất bại', { error });
process.exit(1);
}
};
```
**Real Example**: [`services/iam-service/src/config/database.config.ts`](../../../services/iam-service/src/config/database.config.ts)
### Middleware Documentation / Tài Liệu Middleware
Document middleware functions with their purpose and behavior.
```typescript
/**
* EN: Authentication middleware to verify JWT tokens
* VI: Middleware xác thực để kiểm tra JWT token
*/
export function authMiddleware(
req: Request,
res: Response,
next: NextFunction
) {
// EN: Extract token from Authorization header
// VI: Lấy token từ header Authorization
const authHeader = req.headers.authorization;
const token = authHeader?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
success: false,
error: {
code: 'NO_TOKEN',
message: 'Authentication required / Yêu cầu xác thực',
},
});
}
try {
// EN: Verify token and extract payload
// VI: Xác minh token và lấy payload
const payload = jwt.verify(token, JWT_SECRET);
req.user = payload;
next();
} catch (error) {
return res.status(401).json({
success: false,
error: {
code: 'INVALID_TOKEN',
message: 'Invalid or expired token / Token không hợp lệ hoặc hết hạn',
},
});
}
}
```
### Prisma Schema Comments / Comments Schema Prisma
Use triple-slash comments (`///`) for Prisma schema documentation.
```prisma
/// EN: User model for authentication and profile
/// VI: Model người dùng cho xác thực và hồ sơ
model User {
/// EN: Unique identifier / VI: Mã định danh duy nhất
id String @id @default(cuid())
/// EN: User email (unique) / VI: Email người dùng (duy nhất)
email String @unique
/// EN: Hashed password / VI: Mật khẩu đã mã hóa
password String
/// EN: Display name / VI: Tên hiển thị
name String
/// EN: Account creation timestamp / VI: Thời gian tạo tài khoản
createdAt DateTime @default(now())
/// EN: Last update timestamp / VI: Thời gian cập nhật cuối
updatedAt DateTime @updatedAt
@@map("users")
}
```
### Test Comments / Comments Test
Document test setup and explain test scenarios in both languages.
```typescript
// EN: Mock environment variables for tests
// VI: Mock biến môi trường cho tests
process.env.NODE_ENV = 'test';
process.env.DATABASE_URL = 'postgresql://test:test@localhost:5432/test_db';
// EN: Mock external services to avoid real network calls
// VI: Mock các service bên ngoài để tránh gọi mạng thật
jest.mock('@goodgo/logger', () => ({
logger: {
info: jest.fn(),
error: jest.fn(),
},
}));
describe('FeatureService', () => {
it('should create a feature successfully', async () => {
// EN: Arrange
// VI: Chuẩn bị
const testData = { name: 'test-feature' };
// EN: Act
// VI: Thực hiện
const result = await service.create(testData);
// EN: Assert
// VI: Kiểm tra
expect(result).toBeDefined();
});
});
```
**Real Example**: [`services/iam-service/src/__tests__/setupTests.ts`](../../../services/iam-service/src/__tests__/setupTests.ts)
### Complex Logic Comments / Comments Logic Phức Tạp
When explaining complex algorithms or business logic, break it down into steps.
```typescript
// EN: Step 1: Validate input parameters
// VI: Bước 1: Xác thực tham số đầu vào
if (!email || !password) {
throw new ValidationError('Email and password required');
}
// EN: Step 2: Check if user exists in database
// VI: Bước 2: Kiểm tra xem người dùng có tồn tại trong database
const user = await prisma.user.findUnique({ where: { email } });
if (!user) {
throw new NotFoundError('User not found');
}
// EN: Step 3: Verify password hash
// VI: Bước 3: Xác minh hash mật khẩu
const isValidPassword = await bcrypt.compare(password, user.password);
if (!isValidPassword) {
throw new AuthenticationError('Invalid credentials');
}
// EN: Step 4: Generate and return JWT token
// VI: Bước 4: Tạo và trả về JWT token
const token = jwt.sign({ userId: user.id }, JWT_SECRET);
return { token, user };
```
## Special Comment Types / Các Loại Comment Đặc Biệt
### TODO Comments / Comments TODO
Use TODO comments for future improvements with bilingual descriptions.
```typescript
// TODO EN: Implement caching for better performance
// TODO VI: Triển khai caching để cải thiện hiệu suất
// TODO EN: Add rate limiting to prevent abuse
// TODO VI: Thêm rate limiting để ngăn chặn lạm dụng
```
### FIXME Comments / Comments FIXME
Use FIXME comments for code that needs fixing.
```typescript
// FIXME EN: This causes memory leak, needs refactoring
// FIXME VI: Đoạn này gây rò rỉ bộ nhớ, cần refactor
// FIXME EN: Temporary workaround, should implement proper solution
// FIXME VI: Giải pháp tạm thời, nên triển khai giải pháp đúng đắn
```
### WARNING Comments / Comments CẢNH BÁO
Use WARNING comments for code that requires special attention.
```typescript
// WARNING EN: Do not modify this without updating the database schema
// WARNING VI: Không sửa đổi phần này mà không cập nhật schema database
// WARNING EN: This function modifies global state, use with caution
// WARNING VI: Function này thay đổi global state, sử dụng cẩn thận
```
### NOTE Comments / Comments GHI CHÚ
Use NOTE comments for important information or explanations.
```typescript
// NOTE EN: This is intentionally async to avoid blocking the event loop
// NOTE VI: Đây là async có chủ ý để tránh block event loop
// NOTE EN: Priority: Docker Compose > .env.local > .env > System environment
// NOTE VI: Ưu tiên: Docker Compose > .env.local > .env > Môi trường hệ thống
```
## Best Practices / Thực Hành Tốt Nhất
### Comment Placement / Vị Trí Comment
- ✅ Place bilingual comments together (EN first, then VI) / Đặt comments song ngữ cùng nhau (EN trước, sau đó VI)
- ✅ Keep comments close to the code they describe / Giữ comments gần với code mà chúng mô tả
- ✅ Use JSDoc format for functions and classes / Sử dụng format JSDoc cho functions và classes
- ✅ Update comments when code changes / Cập nhật comments khi code thay đổi
### Comment Content / Nội Dung Comment
-**DO**: Explain WHY, not WHAT (code shows what) / Giải thích TẠI SAO, không phải CÁI GÌ
-**DO**: Document complex logic and business rules / Tài liệu hóa logic phức tạp và quy tắc nghiệp vụ
-**DO**: Include parameter descriptions and return types / Bao gồm mô tả tham số và kiểu trả về
-**DO**: Document error conditions and exceptions / Tài liệu hóa điều kiện lỗi và ngoại lệ
-**DON'T**: State the obvious / Không nói điều hiển nhiên
-**DON'T**: Write redundant comments / Không viết comments thừa
-**DON'T**: Comment out code (use version control instead) / Không comment code (sử dụng version control)
### Language Guidelines / Hướng Dẫn Ngôn Ngữ
**English / Tiếng Anh**:
- Use clear, concise technical English / Sử dụng tiếng Anh kỹ thuật rõ ràng, ngắn gọn
- Use proper technical terminology / Sử dụng thuật ngữ kỹ thuật đúng
- Be specific and actionable / Cụ thể và có thể thực hiện
**Vietnamese / Tiếng Việt**:
- Use proper Vietnamese technical terms / Sử dụng thuật ngữ kỹ thuật tiếng Việt đúng
- Keep translations accurate and natural / Giữ bản dịch chính xác và tự nhiên
- Use consistent terminology across codebase / Sử dụng thuật ngữ nhất quán trên codebase
- Prefer technical Vietnamese terms over literal translations / Ưu tiên thuật ngữ kỹ thuật Việt hơn dịch theo nghĩa đen
### Documentation Priority / Ưu Tiên Tài Liệu
**High Priority** (Always document / Luôn tài liệu hóa):
- Public APIs and exported functions / API công khai và functions được export
- Complex algorithms and business logic / Thuật toán phức tạp và logic nghiệp vụ
- Security-critical code / Code bảo mật quan trọng
- Configuration and environment setup / Cấu hình và thiết lập môi trường
- Error handling strategies / Chiến lược xử lý lỗi
**Medium Priority** (Document when helpful / Tài liệu khi hữu ích):
- Helper functions with non-obvious behavior / Helper functions có hành vi không rõ ràng
- Data transformations / Chuyển đổi dữ liệu
- Integration points with external services / Điểm tích hợp với services bên ngoài
**Low Priority** (Optional / Tùy chọn):
- Simple getters/setters / Getters/setters đơn giản
- Self-explanatory code / Code tự giải thích
- Standard CRUD operations / Các thao tác CRUD tiêu chuẩn
## Examples from Project / Ví Dụ Từ Dự Án
### Real Comment Examples / Ví Dụ Comment Thực Tế
1. **Service Comments**: [`services/iam-service/src/modules/feature/feature.service.ts`](../../../services/iam-service/src/modules/feature/feature.service.ts)
2. **Config Comments**: [`services/iam-service/src/config/database.config.ts`](../../../services/iam-service/src/config/database.config.ts)
3. **Test Comments**: [`services/iam-service/src/__tests__/setupTests.ts`](../../../services/iam-service/src/__tests__/setupTests.ts)
4. **Jest Config Comments**: [`services/iam-service/jest.config.ts`](../../../services/iam-service/jest.config.ts)
### Comment Patterns in Different Contexts / Patterns Comment Trong Các Ngữ Cảnh Khác Nhau
- **Controllers**: Document API endpoints and request/response handling
- **Services**: Document business logic and data processing
- **Middleware**: Document authentication, authorization, and request processing
- **Repositories**: Document database operations and query logic
- **Config Files**: Document configuration options and environment variables
- **Tests**: Document test scenarios and setup procedures
## Quick Reference / Tham Khảo Nhanh
### Function Comment Template / Template Comment Function
```typescript
/**
* EN: [Brief description in English]
* VI: [Mô tả ngắn gọn bằng tiếng Việt]
*
* @param paramName - EN description / VI mô tả
* @returns EN description / VI mô tả
* @throws ErrorType EN when / VI khi nào
*/
```
### Inline Comment Template / Template Inline Comment
```typescript
// EN: [English explanation]
// VI: [Giải thích tiếng Việt]
```
### Complex Block Template / Template Block Phức Tạp
```typescript
// EN: Step N: [What this block does]
// VI: Bước N: [Block này làm gì]
```
### Class Comment Template / Template Comment Class
```typescript
/**
* EN: [Class purpose in English]
* VI: [Mục đích class bằng tiếng Việt]
*/
export class ClassName {
/**
* EN: [Property description]
* VI: [Mô tả property]
*/
private property: string;
}
```
### Interface Comment Template / Template Comment Interface
```typescript
/**
* EN: [Interface purpose in English]
* VI: [Mục đích interface bằng tiếng Việt]
*/
interface InterfaceName {
/** EN: Property description / VI: Mô tả property */
property: string;
}
```
## Related Skills / Skills Liên Quan
- **[Testing Patterns](./testing-patterns.md)**: Writing comments in test files / Viết comments trong file test
- **[API Design](./api-design.md)**: Documenting API endpoints / Tài liệu hóa API endpoints
- **[Documentation](./documentation.md)**: Writing technical documentation / Viết tài liệu kỹ thuật
- **[Project Rules](./project-rules.md)**: Code organization and standards / Tổ chức code và tiêu chuẩn
## Resources / Tài Nguyên
### Documentation Standards / Tiêu Chuẩn Tài Liệu
- [JSDoc Documentation](https://jsdoc.app/)
- [TypeScript JSDoc](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)
- [TSDoc Specification](https://tsdoc.org/)
### Internal Documentation / Tài Liệu Nội Bộ
- [Documentation Writing Guidelines](./documentation.md)
- [API Design Standards](./api-design.md)
- [Project Coding Standards](./project-rules.md)
### Tools / Công Cụ
- **JSDoc**: Generate API documentation from comments
- **ESLint**: Enforce comment style and completeness
- **Prettier**: Format comments consistently
- **VS Code**: IntelliSense uses JSDoc comments for better autocomplete

View File

@@ -0,0 +1,584 @@
# Database & Prisma / Cơ Sở Dữ Liệu & Prisma
> **EN**: Prisma ORM and database patterns for GoodGo microservices. Use when working with databases, creating Prisma schemas, writing migrations, implementing repositories, or optimizing queries.
> **VI**: Pattern Prisma ORM và database cho các microservices của GoodGo. Sử dụng khi làm việc với databases, tạo Prisma schemas, viết migrations, triển khai repositories, hoặc tối ưu queries.
## Overview / Tổng Quan
**EN**: This skill covers Prisma ORM patterns, database schema design, repository patterns, query optimization, and transaction handling used across GoodGo microservices. It ensures type-safe database operations, consistent data access patterns, and optimal performance.
**VI**: Skill này bao gồm các pattern Prisma ORM, thiết kế database schema, repository patterns, tối ưu queries, và xử lý transactions được sử dụng trong các microservices của GoodGo. Nó đảm bảo các thao tác database type-safe, pattern truy cập dữ liệu nhất quán, và hiệu năng tối ưu.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Setting up Prisma for a new service
- Creating or modifying database schemas
- Writing database migrations
- Implementing repository patterns
- Optimizing database queries
- Setting up database connections
- Implementing transactions
- Working with Neon PostgreSQL
**VI**: Sử dụng skill này khi:
- Thiết lập Prisma cho service mới
- Tạo hoặc sửa đổi database schemas
- Viết database migrations
- Triển khai repository patterns
- Tối ưu database queries
- Thiết lập kết nối database
- Triển khai transactions
- Làm việc với Neon PostgreSQL
## Key Concepts / Khái Niệm Chính
### 1. Repository Pattern / Pattern Repository
**EN**: All database operations go through repository classes that extend `BaseRepository`, providing consistent CRUD operations and error handling.
**VI**: Tất cả các thao tác database đi qua các repository classes kế thừa `BaseRepository`, cung cấp các CRUD operations nhất quán và xử lý lỗi.
### 2. Prisma Schema / Schema Prisma
**EN**: Database schema is defined in `prisma/schema.prisma` with models, relations, indexes, and constraints.
**VI**: Database schema được định nghĩa trong `prisma/schema.prisma` với models, relations, indexes, và constraints.
### 3. Type Safety / An Toàn Kiểu
**EN**: Prisma generates TypeScript types from schema, ensuring type-safe database operations.
**VI**: Prisma generate TypeScript types từ schema, đảm bảo các thao tác database type-safe.
## Common Patterns / Các Pattern Thường Dùng
### Prisma Schema Pattern / Pattern Schema Prisma
**Example from codebase / Ví dụ từ codebase**:
```prisma
// services/iam-service/prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// EN: User model - Core user entity
// VI: Model User - Entity người dùng cốt lõi
model User {
id String @id @default(cuid())
email String @unique
username String? @unique
passwordHash String? // Nullable for social-only users
isActive Boolean @default(true)
emailVerified Boolean @default(false)
mfaEnabled Boolean @default(false)
mfaSecret String?
lastLoginAt DateTime?
loginCount Int @default(0)
organizationId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relations
userRoles UserRole[]
userPermissions UserPermission[]
sessions Session[]
organization Organization? @relation(fields: [organizationId], references: [id])
profile UserProfile?
@@index([email])
@@index([username])
@@index([createdAt])
@@index([organizationId])
@@map("users")
}
```
### Database Connection Pattern / Pattern Kết Nối Database
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/config/database.config.ts
import { PrismaClient } from '@prisma/client';
import { logger } from '@goodgo/logger';
/**
* EN: Prisma client instance configured for the application
* VI: Instance Prisma client được cấu hình cho ứng dụng
*/
export const prisma = new PrismaClient({
// EN: Enable detailed logging in development, minimal in production
// VI: Bật ghi log chi tiết trong development, tối thiểu trong production
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
});
/**
* EN: Establish database connection on application startup
* VI: Thiết lập kết nối database khi khởi động ứng dụng
*/
export const connectDatabase = async (): Promise<void> => {
try {
await prisma.$connect();
logger.info('Database connected successfully / Kết nối database thành công');
} catch (error) {
logger.error('Database connection failed / Kết nối database thất bại', { error });
process.exit(1);
}
};
/**
* EN: Close database connection on application shutdown
* VI: Đóng kết nối database khi tắt ứng dụng
*/
export const disconnectDatabase = async (): Promise<void> => {
await prisma.$disconnect();
logger.info('Database disconnected / Đã ngắt kết nối database');
};
```
### Base Repository Pattern / Pattern Base Repository
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/common/repository.ts
import { PrismaClient } from '@prisma/client';
import { logger } from '@goodgo/logger';
import { DatabaseError } from '../../errors/http-error';
/**
* EN: Base repository class providing common database operations
* VI: Base repository class cung cấp các thao tác database chung
*/
export abstract class BaseRepository<T, CreateInput, UpdateInput> {
protected prisma: PrismaClient;
protected modelName: string;
constructor(prisma: PrismaClient, modelName: string) {
this.prisma = prisma;
this.modelName = modelName;
}
/**
* EN: Find entity by ID
* VI: Tìm entity theo ID
*/
async findById(id: string): Promise<T | null> {
try {
logger.debug(`Finding ${this.modelName} by ID / Tìm ${this.modelName} theo ID`, { id });
const entity = await (this.prisma as any)[this.modelName].findUnique({
where: { id },
});
logger.debug(`${this.modelName} ${entity ? 'found' : 'not found'} / ${this.modelName} ${entity ? 'đã tìm thấy' : 'không tìm thấy'}`, { id });
return entity;
} catch (error: any) {
logger.error(`Failed to find ${this.modelName} by ID / Không thể tìm ${this.modelName} theo ID`, { error, id });
throw new DatabaseError(`Failed to find ${this.modelName}`, { id, originalError: error });
}
}
/**
* EN: Find all entities with optional filtering
* VI: Tìm tất cả entities với filtering tùy chọn
*/
async findAll(options?: {
where?: any;
orderBy?: any;
skip?: number;
take?: number;
include?: any;
}): Promise<T[]> {
try {
logger.debug(`Finding all ${this.modelName} / Tìm tất cả ${this.modelName}`, options);
const entities = await (this.prisma as any)[this.modelName].findMany(options || {});
logger.debug(`Found ${entities.length} ${this.modelName} entities / Đã tìm thấy ${entities.length} ${this.modelName} entities`);
return entities;
} catch (error: any) {
logger.error(`Failed to find all ${this.modelName} / Không thể tìm tất cả ${this.modelName}`, { error, options });
throw new DatabaseError(`Failed to find ${this.modelName} entities`, { options, originalError: error });
}
}
/**
* EN: Create new entity
* VI: Tạo entity mới
*/
async create(data: CreateInput): Promise<T> {
try {
logger.debug(`Creating new ${this.modelName} / Tạo ${this.modelName} mới`, { data });
const entity = await (this.prisma as any)[this.modelName].create({
data,
});
logger.debug(`${this.modelName} created successfully / ${this.modelName} đã được tạo thành công`, { id: (entity as any).id });
return entity;
} catch (error: any) {
logger.error(`Failed to create ${this.modelName} / Không thể tạo ${this.modelName}`, { error, data });
throw new DatabaseError(`Failed to create ${this.modelName}`, { data, originalError: error });
}
}
/**
* EN: Update entity by ID
* VI: Cập nhật entity theo ID
*/
async update(id: string, data: UpdateInput): Promise<T> {
try {
logger.debug(`Updating ${this.modelName} / Cập nhật ${this.modelName}`, { id, data });
const entity = await (this.prisma as any)[this.modelName].update({
where: { id },
data,
});
logger.debug(`${this.modelName} updated successfully / ${this.modelName} đã được cập nhật thành công`, { id });
return entity;
} catch (error: any) {
if (error.code === 'P2025') {
logger.warn(`${this.modelName} not found for update / ${this.modelName} không tìm thấy để cập nhật`, { id });
throw new DatabaseError(`${this.modelName} not found`, { id });
}
logger.error(`Failed to update ${this.modelName} / Không thể cập nhật ${this.modelName}`, { error, id, data });
throw new DatabaseError(`Failed to update ${this.modelName}`, { id, data, originalError: error });
}
}
/**
* EN: Execute transaction with multiple operations
* VI: Thực thi transaction với nhiều operations
*/
async transaction<R>(callback: (tx: any) => Promise<R>): Promise<R> {
try {
logger.debug(`Starting ${this.modelName} transaction / Bắt đầu transaction ${this.modelName}`);
const result = await this.prisma.$transaction(async (tx) => {
return await callback(tx);
});
logger.debug(`${this.modelName} transaction completed successfully / Transaction ${this.modelName} đã hoàn thành thành công`);
return result;
} catch (error: any) {
logger.error(`${this.modelName} transaction failed / Transaction ${this.modelName} thất bại`, { error });
throw new DatabaseError(`${this.modelName} transaction failed`, { originalError: error });
}
}
}
```
### Specific Repository Implementation / Triển Khai Repository Cụ Thể
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/repositories/user.repository.ts
import { PrismaClient, User } from '@prisma/client';
import { BaseRepository } from '../modules/common/repository';
/**
* EN: User repository for database operations
* VI: Repository người dùng cho các thao tác database
*/
export class UserRepository extends BaseRepository<User, any, any> {
constructor(prisma: PrismaClient) {
super(prisma, 'user');
}
/**
* EN: Find user by email
* VI: Tìm người dùng theo email
*/
async findByEmail(email: string): Promise<User | null> {
return this.prisma.user.findUnique({
where: { email },
include: {
userRoles: {
include: { role: true },
},
userPermissions: {
include: { permission: true },
},
},
});
}
/**
* EN: Find user by username
* VI: Tìm người dùng theo username
*/
async findByUsername(username: string): Promise<User | null> {
return this.prisma.user.findUnique({
where: { username },
});
}
/**
* EN: Find user with roles and permissions
* VI: Tìm người dùng với roles và permissions
*/
async findWithPermissions(userId: string): Promise<User | null> {
return this.prisma.user.findUnique({
where: { id: userId },
include: {
userRoles: {
where: {
OR: [
{ expiresAt: null },
{ expiresAt: { gte: new Date() } },
],
},
include: {
role: {
include: {
permissions: {
include: { permission: true },
},
},
},
},
},
userPermissions: {
where: {
OR: [
{ expiresAt: null },
{ expiresAt: { gte: new Date() } },
],
},
include: { permission: true },
},
},
});
}
}
```
### Upsert Pattern / Pattern Upsert
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/repositories/user-profile.repository.ts
export class UserProfileRepository extends BaseRepository<UserProfile, any, any> {
/**
* EN: Create or update profile for user
* VI: Tạo hoặc cập nhật profile cho user
*/
async upsert(userId: string, data: any): Promise<UserProfile> {
return this.prisma.userProfile.upsert({
where: { userId },
update: {
...data,
updatedAt: new Date(),
},
create: {
userId,
...data,
},
include: {
user: {
select: {
id: true,
email: true,
username: true,
},
},
},
});
}
}
```
### Query Optimization Patterns / Pattern Tối Ưu Query
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/feature/feature.repository.ts
export class FeatureRepository extends BaseRepository<Feature, CreateFeatureInput, UpdateFeatureInput> {
/**
* EN: Find features by tags
* VI: Tìm features theo tags
*/
async findByTags(tags: string[]): Promise<Feature[]> {
try {
logger.debug('Finding features by tags / Tìm features theo tags', { tags });
const features = await this.prisma.feature.findMany({
where: {
tags: {
hasSome: tags,
},
},
orderBy: { createdAt: 'desc' },
});
logger.debug(`Found ${features.length} features by tags / Đã tìm thấy ${features.length} features theo tags`, { tags });
return features;
} catch (error) {
logger.error('Failed to find features by tags / Không thể tìm features theo tags', { error, tags });
throw this.handleDatabaseError(error, { tags });
}
}
}
```
## Best Practices / Thực Hành Tốt Nhất
### 1. Schema Design / Thiết Kế Schema
- ✅ Use appropriate field types (String, Int, Boolean, DateTime, Json)
- ✅ Add indexes for frequently queried fields (`@@index([email])`)
- ✅ Use relations instead of storing JSON when possible
- ✅ Implement soft deletes with `deletedAt` field when needed
- ✅ Use `@default()` for default values
- ✅ Use `@updatedAt` for automatic timestamp updates
### 2. Repository Pattern / Pattern Repository
- ✅ Extend `BaseRepository` for common CRUD operations
- ✅ Add custom methods for domain-specific queries
- ✅ Use `include` and `select` to control data fetching
- ✅ Handle Prisma errors and convert to domain errors
- ✅ Log database operations for debugging
### 3. Query Optimization / Tối Ưu Query
- ✅ Use `select` to fetch only needed fields
- ✅ Implement pagination with `skip` and `take`
- ✅ Use indexes for frequently queried fields
- ✅ Avoid N+1 queries by using `include` strategically
- ✅ Use `findUnique` instead of `findFirst` when possible
- ✅ Use transactions for multiple related operations
### 4. Error Handling / Xử Lý Lỗi
- ✅ Catch Prisma errors and convert to domain errors
- ✅ Handle unique constraint violations (P2002)
- ✅ Handle record not found (P2025)
- ✅ Log errors with context
- ✅ Provide meaningful error messages
### 5. Migrations / Migrations
- ✅ Keep migrations small and focused
- ✅ Test migrations before production
- ✅ Backup before major changes
- ✅ Use descriptive migration names
- ✅ Review generated SQL before applying
### 6. Connection Management / Quản Lý Kết Nối
- ✅ Use connection pooling for production
- ✅ Close connections on application shutdown
- ✅ Handle connection errors gracefully
- ✅ Monitor connection pool usage
## Examples from Project / Ví Dụ Từ Dự Án
### Schema Examples / Ví Dụ Schema
- **IAM Service Schema**: [`services/iam-service/prisma/schema.prisma`](../../../services/iam-service/prisma/schema.prisma)
- **Auth Service Schema**: [`services/iam-service/prisma/schema.prisma`](../../../services/iam-service/prisma/schema.prisma)
### Repository Examples / Ví Dụ Repository
- **Base Repository**: [`services/iam-service/src/modules/common/repository.ts`](../../../services/iam-service/src/modules/common/repository.ts)
- **User Repository**: [`services/iam-service/src/repositories/user.repository.ts`](../../../services/iam-service/src/repositories/user.repository.ts)
- **User Profile Repository**: [`services/iam-service/src/repositories/user-profile.repository.ts`](../../../services/iam-service/src/repositories/user-profile.repository.ts)
- **Feature Repository**: [`services/iam-service/src/modules/feature/feature.repository.ts`](../../../services/iam-service/src/modules/feature/feature.repository.ts)
### Database Config Examples / Ví Dụ Cấu Hình Database
- **Database Config**: [`services/iam-service/src/config/database.config.ts`](../../../services/iam-service/src/config/database.config.ts)
## Quick Reference / Tham Khảo Nhanh
### Common Prisma Operations / Các Thao Tác Prisma Thường Dùng
```typescript
// Find by ID / Tìm theo ID
const user = await prisma.user.findUnique({ where: { id } });
// Find with relations / Tìm với relations
const user = await prisma.user.findUnique({
where: { id },
include: { profile: true, roles: true },
});
// Find many with filters / Tìm nhiều với filters
const users = await prisma.user.findMany({
where: { isActive: true },
skip: 0,
take: 10,
orderBy: { createdAt: 'desc' },
});
// Create / Tạo
const user = await prisma.user.create({
data: { email, passwordHash },
});
// Update / Cập nhật
const user = await prisma.user.update({
where: { id },
data: { isActive: false },
});
// Delete / Xóa
await prisma.user.delete({ where: { id } });
// Upsert / Tạo hoặc cập nhật
const profile = await prisma.userProfile.upsert({
where: { userId },
update: { ...data },
create: { userId, ...data },
});
// Transaction / Transaction
await prisma.$transaction(async (tx) => {
const user = await tx.user.create({ data: userData });
await tx.userProfile.create({ data: { userId: user.id, ...profileData } });
});
```
### Prisma Error Codes / Mã Lỗi Prisma
| Code | Description / Mô Tả |
|------|-------------------|
| P2002 | Unique constraint violation / Vi phạm ràng buộc duy nhất |
| P2025 | Record not found / Không tìm thấy bản ghi |
| P2003 | Foreign key constraint violation / Vi phạm ràng buộc khóa ngoại |
| P2014 | Required relation violation / Vi phạm quan hệ bắt buộc |
## Related Skills / Skills Liên Quan
- **[API Design](./api-design.md)**: For designing API endpoints that use repositories
- **[Testing Patterns](./testing-patterns.md)**: For testing database operations
- **[Security](./security.md)**: For securing database operations and preventing SQL injection
- **[Observability](./observability-monitoring.md)**: For monitoring database performance
## Resources / Tài Nguyên
### External Documentation / Tài Liệu Bên Ngoài
- [Prisma Documentation](https://www.prisma.io/docs)
- [Prisma Schema Reference](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference)
- [Prisma Client API](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference)
- [PostgreSQL Documentation](https://www.postgresql.org/docs/)
- [Neon Documentation](https://neon.tech/docs)
### Internal Documentation / Tài Liệu Nội Bộ
- [Neon Database Guide](../guides/neon-database.md)
- [Development Guide](../guides/development.md)

View File

@@ -0,0 +1,468 @@
# Kubernetes Deployment / Triển Khai Kubernetes
> **EN**: Kubernetes deployment patterns for GoodGo microservices. Use when deploying to staging/production, creating K8s manifests, configuring HPA, setting up ingress, or troubleshooting K8s deployments.
> **VI**: Các pattern triển khai Kubernetes cho microservices GoodGo. Sử dụng khi triển khai lên staging/production, tạo K8s manifests, cấu hình HPA, thiết lập ingress, hoặc xử lý sự cố triển khai K8s.
## Overview / Tổng Quan
**EN**: This skill covers Kubernetes deployment patterns and best practices for GoodGo microservices. It includes creating deployment manifests, configuring autoscaling, managing secrets and configmaps, setting up ingress, and implementing health checks.
**VI**: Skill này bao gồm các pattern triển khai Kubernetes và best practices cho microservices GoodGo. Nó bao gồm tạo deployment manifests, cấu hình autoscaling, quản lý secrets và configmaps, thiết lập ingress, và triển khai health checks.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Deploying services to staging/production environments
- Creating or updating Kubernetes manifests
- Configuring autoscaling (HPA/VPA)
- Setting up ingress and load balancing
- Managing secrets and configmaps
- Troubleshooting deployment issues
- Implementing health checks and probes
- Setting up monitoring and logging
**VI**: Sử dụng skill này khi:
- Triển khai services lên môi trường staging/production
- Tạo hoặc cập nhật Kubernetes manifests
- Cấu hình autoscaling (HPA/VPA)
- Thiết lập ingress và load balancing
- Quản lý secrets và configmaps
- Xử lý sự cố triển khai
- Triển khai health checks và probes
- Thiết lập monitoring và logging
## Key Concepts / Khái Niệm Chính
### Deployment Strategy / Chiến Lược Triển Khai
**EN**:
- Rolling updates for zero-downtime deployments
- Resource limits and requests for stability
- Health checks (liveness/readiness probes)
- Horizontal Pod Autoscaler (HPA) for auto-scaling
- ConfigMaps for configuration
- Secrets for sensitive data
**VI**:
- Rolling updates để triển khai không downtime
- Resource limits và requests để đảm bảo ổn định
- Health checks (liveness/readiness probes)
- Horizontal Pod Autoscaler (HPA) để tự động scale
- ConfigMaps cho cấu hình
- Secrets cho dữ liệu nhạy cảm
## Common Patterns / Các Pattern Thường Dùng
### Service Deployment Manifest / Manifest Triển Khai Service
**EN**: Standard deployment manifest structure for GoodGo services.
**VI**: Cấu trúc deployment manifest chuẩn cho các services GoodGo.
**Example from codebase**: [`deployments/production/kubernetes/iam-service.yaml`](../../../deployments/production/kubernetes/iam-service.yaml)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: iam-service
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: iam-service
template:
metadata:
labels:
app: iam-service
spec:
containers:
- name: iam-service
image: goodgo/iam-service:latest
imagePullPolicy: Always
ports:
- containerPort: 5001
envFrom:
- configMapRef:
name: iam-service-config
- secretRef:
name: iam-service-secrets
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /health/live
port: 5001
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: 5001
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: iam-service
namespace: production
spec:
selector:
app: iam-service
ports:
- protocol: TCP
port: 5001
targetPort: 5001
type: ClusterIP
```
### Horizontal Pod Autoscaler / Tự Động Scale Pod
**EN**: Configure HPA to automatically scale pods based on CPU and memory utilization.
**VI**: Cấu hình HPA để tự động scale pods dựa trên CPU và memory utilization.
**Example from codebase**: [`deployments/production/kubernetes/iam-service.yaml`](../../../deployments/production/kubernetes/iam-service.yaml)
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: iam-service-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: iam-service
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
```
### ConfigMap & Secrets / ConfigMap và Secrets
**EN**: Use ConfigMaps for non-sensitive configuration and Secrets for sensitive data.
**VI**: Sử dụng ConfigMaps cho cấu hình không nhạy cảm và Secrets cho dữ liệu nhạy cảm.
**Example from codebase**:
- ConfigMap: [`deployments/production/kubernetes/iam-service-configmap.yaml`](../../../deployments/production/kubernetes/iam-service-configmap.yaml)
- Secrets: [`deployments/production/kubernetes/secrets.yaml.example`](../../../deployments/production/kubernetes/secrets.yaml.example)
```yaml
# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: iam-service-config
namespace: production
data:
NODE_ENV: "production"
PORT: "5001"
API_VERSION: "v1"
CORS_ORIGIN: "https://goodgo.vn"
LOG_LEVEL: "warn"
SERVICE_NAME: "iam-service"
TRACING_ENABLED: "true"
---
# Secret (example - use sealed-secrets in production)
apiVersion: v1
kind: Secret
metadata:
name: iam-service-secrets
namespace: production
type: Opaque
stringData:
database-url: "postgresql://user:password@ep-xxx.region.neon.tech/dbname?sslmode=require&pgbouncer=true"
jwt-secret: "your-production-jwt-secret-min-32-chars"
jwt-refresh-secret: "your-production-refresh-secret-min-32-chars"
redis-password: ""
```
### Ingress Configuration / Cấu Hình Ingress
**EN**: Configure ingress for external access with TLS and path-based routing.
**VI**: Cấu hình ingress để truy cập từ bên ngoài với TLS và path-based routing.
**Example from codebase**: [`deployments/production/kubernetes/ingress.yaml`](../../../deployments/production/kubernetes/ingress.yaml)
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
namespace: production
annotations:
traefik.ingress.kubernetes.io/rule-type: PathPrefix
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: traefik
tls:
- hosts:
- api.goodgo.vn
secretName: api-tls-cert
rules:
- host: api.goodgo.vn
http:
paths:
- path: /api/v1/auth
pathType: Prefix
backend:
service:
name: iam-service
port:
number: 5001
```
## Best Practices / Thực Hành Tốt Nhất
### Resource Management / Quản Lý Tài Nguyên
**EN**:
- Always set resource requests and limits
- Monitor actual usage and adjust accordingly
- Use HPA for automatic scaling
- Set appropriate CPU and memory based on service requirements
**VI**:
- Luôn đặt resource requests và limits
- Theo dõi sử dụng thực tế và điều chỉnh phù hợp
- Sử dụng HPA để tự động scale
- Đặt CPU và memory phù hợp dựa trên yêu cầu service
### Configuration / Cấu Hình
**EN**:
- Use ConfigMaps for non-sensitive config
- Use Secrets for sensitive data
- Never hardcode configuration in images
- Use `envFrom` to load entire ConfigMap/Secret
**VI**:
- Sử dụng ConfigMaps cho cấu hình không nhạy cảm
- Sử dụng Secrets cho dữ liệu nhạy cảm
- Không bao giờ hardcode cấu hình trong images
- Sử dụng `envFrom` để load toàn bộ ConfigMap/Secret
### Health Checks / Kiểm Tra Sức Khỏe
**EN**:
- Implement both liveness and readiness probes
- Set appropriate timeouts and thresholds
- Include dependency checks in readiness probe
- Use HTTP probes for web services
**VI**:
- Triển khai cả liveness và readiness probes
- Đặt timeouts và thresholds phù hợp
- Bao gồm kiểm tra dependencies trong readiness probe
- Sử dụng HTTP probes cho web services
**Example from codebase**: [`services/iam-service/src/modules/health/health.controller.ts`](../../../services/iam-service/src/modules/health/health.controller.ts)
```typescript
// Liveness probe - is the service alive?
health = async (_req: Request, res: Response): Promise<void> => {
res.json({
success: true,
data: { status: 'ok', timestamp: new Date().toISOString() },
});
};
// Readiness probe - is the service ready to accept traffic?
ready = async (_req: Request, res: Response): Promise<void> => {
try {
// Check database connection
await prisma.$queryRaw`SELECT 1`;
res.json({
success: true,
data: { status: 'ready' },
});
} catch (error) {
res.status(503).json({
success: false,
error: { code: 'HEALTH_001', message: 'Service not ready' },
});
}
};
```
### Deployment / Triển Khai
**EN**:
- Use rolling updates for zero-downtime
- Set maxSurge and maxUnavailable appropriately
- Test deployments in staging first
- Use image tags instead of `latest` in production
**VI**:
- Sử dụng rolling updates để không downtime
- Đặt maxSurge và maxUnavailable phù hợp
- Test triển khai trong staging trước
- Sử dụng image tags thay vì `latest` trong production
### Security / Bảo Mật
**EN**:
- Run containers as non-root user
- Use network policies to restrict traffic
- Regularly update base images
- Use sealed-secrets or external secret manager
- Never commit secrets to Git
**VI**:
- Chạy containers với user không phải root
- Sử dụng network policies để hạn chế traffic
- Cập nhật base images thường xuyên
- Sử dụng sealed-secrets hoặc external secret manager
- Không bao giờ commit secrets vào Git
### Monitoring / Giám Sát
**EN**:
- Expose metrics endpoint (`/metrics`)
- Set up alerts for critical issues
- Monitor resource usage and performance
- Use ServiceMonitor for Prometheus integration
**VI**:
- Expose metrics endpoint (`/metrics`)
- Thiết lập alerts cho các vấn đề quan trọng
- Theo dõi sử dụng tài nguyên và hiệu suất
- Sử dụng ServiceMonitor cho tích hợp Prometheus
## Examples from Project / Ví Dụ Từ Dự Án
### Production Deployment / Triển Khai Production
- **IAM Service**: [`deployments/production/kubernetes/iam-service.yaml`](../../../deployments/production/kubernetes/iam-service.yaml)
- **ConfigMap**: [`deployments/production/kubernetes/iam-service-configmap.yaml`](../../../deployments/production/kubernetes/iam-service-configmap.yaml)
- **Ingress**: [`deployments/production/kubernetes/ingress.yaml`](../../../deployments/production/kubernetes/ingress.yaml)
### Staging Deployment / Triển Khai Staging
- **IAM Service**: [`deployments/staging/kubernetes/iam-service.yaml`](../../../deployments/staging/kubernetes/iam-service.yaml)
- **ConfigMap**: [`deployments/staging/kubernetes/iam-service-configmap.yaml`](../../../deployments/staging/kubernetes/iam-service-configmap.yaml)
### Health Check Implementation / Triển Khai Health Check
- **Health Controller**: [`services/iam-service/src/modules/health/health.controller.ts`](../../../services/iam-service/src/modules/health/health.controller.ts)
## Quick Reference / Tham Khảo Nhanh
### Common Commands / Lệnh Thường Dùng
```bash
# Deploy to production
kubectl apply -f deployments/production/kubernetes/ -n production
# Check deployment status
kubectl get deployments -n production
kubectl get pods -n production
kubectl get svc -n production
# View logs
kubectl logs -f deployment/iam-service -n production
kubectl logs -f pod-name -n production --tail=100
# Scale manually
kubectl scale deployment iam-service --replicas=5 -n production
# Update image
kubectl set image deployment/iam-service iam-service=goodgo/iam-service:v1.2.3 -n production
# Rollback
kubectl rollout undo deployment/iam-service -n production
# Port forward for debugging
kubectl port-forward service/iam-service 5001:5001 -n production
# Execute command in pod
kubectl exec -it pod-name -n production -- /bin/sh
# View HPA status
kubectl get hpa -n production
kubectl describe hpa iam-service-hpa -n production
# View resource usage
kubectl top nodes
kubectl top pods -n production
```
### Troubleshooting / Xử Lý Sự Cố
**Pod Not Starting / Pod Không Khởi Động**:
```bash
# Check pod status
kubectl describe pod pod-name -n production
# Check events
kubectl get events -n production --sort-by='.lastTimestamp'
# Check logs
kubectl logs pod-name -n production --previous
```
**ImagePullBackOff**:
```bash
# Check image name and tag
kubectl describe pod pod-name -n production | grep -i image
# Check image pull secrets
kubectl get secrets -n production
```
**CrashLoopBackOff**:
```bash
# Check logs of crashed container
kubectl logs pod-name -n production --previous
# Check resource limits
kubectl describe pod pod-name -n production | grep -A 5 Limits
```
## Related Skills / Skills Liên Quan
- [Observability & Monitoring](./observability-monitoring.md) - For monitoring deployed services
- [Security](./security.md) - For securing Kubernetes deployments
- [Project Rules](./project-rules.md) - For service structure and standards
## Resources / Tài Nguyên
### Official Documentation / Tài Liệu Chính Thức
- [Kubernetes Documentation](https://kubernetes.io/docs/)
- [Kubernetes API Reference](https://kubernetes.io/docs/reference/kubernetes-api/)
- [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
### GoodGo Resources / Tài Nguyên GoodGo
- [Deployment Guide](../guides/deployment.md)
- [Local Deployment Guide](../guides/local-deployment.md)
- [Troubleshooting Guide](../guides/troubleshooting.md)

View File

@@ -0,0 +1,535 @@
# Documentation / Tài Liệu
> **EN**: Guidelines for writing technical documentation in the GoodGo project. Use when creating or updating README files, guides, architecture docs, or API documentation. Ensures bilingual (EN/VI) consistency and proper structure.
> **VI**: Hướng dẫn viết tài liệu kỹ thuật trong dự án GoodGo. Sử dụng khi tạo hoặc cập nhật file README, hướng dẫn, tài liệu kiến trúc hoặc tài liệu API. Đảm bảo tính nhất quán song ngữ (EN/VI) và cấu trúc phù hợp.
## Overview / Tổng Quan
**EN**: The Documentation skill provides comprehensive guidelines for writing, structuring, and maintaining technical documentation in the GoodGo Microservices Platform. It covers documentation structure, bilingual formatting, templates, writing style, and best practices for maintaining documentation quality.
**VI**: Skill Documentation cung cấp hướng dẫn toàn diện để viết, cấu trúc và duy trì tài liệu kỹ thuật trong GoodGo Microservices Platform. Nó bao gồm cấu trúc tài liệu, định dạng song ngữ, template, phong cách viết và thực hành tốt nhất để duy trì chất lượng tài liệu.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Creating new documentation files
- Updating existing documentation
- Writing README files for services or packages
- Creating guides or tutorials
- Documenting API endpoints
- Writing architecture documentation
- Creating deployment documentation
- Writing runbooks or operational guides
- Ensuring bilingual consistency
**VI**: Sử dụng skill này khi:
- Tạo file tài liệu mới
- Cập nhật tài liệu hiện có
- Viết file README cho services hoặc packages
- Tạo hướng dẫn hoặc tutorial
- Tài liệu hóa API endpoints
- Viết tài liệu kiến trúc
- Tạo tài liệu triển khai
- Viết runbook hoặc hướng dẫn vận hành
- Đảm bảo tính nhất quán song ngữ
## Key Concepts / Khái Niệm Chính
### Documentation Structure / Cấu Trúc Tài Liệu
**EN**: The project follows a structured documentation hierarchy:
```
docs/
├── en/ # English documentation
│ ├── guides/ # How-to guides
│ ├── architecture/ # System design docs
│ ├── api/ # API documentation
│ ├── onboarding/ # New developer guides
│ ├── runbooks/ # Operational guides
│ └── skills/ # Skill documentation
├── vi/ # Vietnamese documentation (mirror structure)
└── README.md # Documentation index
```
**VI**: Dự án tuân theo hệ thống phân cấp tài liệu có cấu trúc:
```
docs/
├── en/ # Tài liệu tiếng Anh
│ ├── guides/ # Hướng dẫn cách làm
│ ├── architecture/ # Tài liệu thiết kế hệ thống
│ ├── api/ # Tài liệu API
│ ├── onboarding/ # Hướng dẫn cho developer mới
│ ├── runbooks/ # Hướng dẫn vận hành
│ └── skills/ # Tài liệu skills
├── vi/ # Tài liệu tiếng Việt (cấu trúc tương tự)
└── README.md # Mục lục tài liệu
```
### Bilingual Documentation Rules / Quy Tắc Tài Liệu Song Ngữ
**EN**: The project maintains bilingual documentation (English and Vietnamese). Three formats are used:
1. **Side-by-side**: Short content with EN and VI on the same line
2. **Separate files**: Long content in separate EN and VI files
3. **Sections**: Mixed content with separate EN and VI sections
**VI**: Dự án duy trì tài liệu song ngữ (Tiếng Anh và Tiếng Việt). Ba định dạng được sử dụng:
1. **Side-by-side**: Nội dung ngắn với EN và VI trên cùng một dòng
2. **Separate files**: Nội dung dài trong các file EN và VI riêng biệt
3. **Sections**: Nội dung hỗn hợp với các phần EN và VI riêng biệt
## Common Patterns / Các Pattern Thường Dùng
### Service README Template / Template README Service
**EN**: Example structure from `services/iam-service/README.md`:
```markdown
# Service Name / Tên Dịch Vụ
> **EN**: Brief description in English
> **VI**: Mô tả ngắn gọn bằng tiếng Việt
## Features / Tính Năng
- Feature 1 / Tính năng 1
- Feature 2 / Tính năng 2
## Prerequisites / Yêu Cầu
- Node.js 20+
- PostgreSQL (Neon)
- Redis
## Quick Start / Bắt Đầu Nhanh
```bash
# Install dependencies / Cài đặt dependencies
pnpm install
# Setup environment / Thiết lập môi trường
cp .env.example .env
# Start service / Khởi động service
pnpm dev
```
## Configuration / Cấu Hình
| Variable | Description / Mô Tả | Default | Required |
|----------|---------------------|---------|----------|
| PORT | Server port / Cổng server | 5000 | No |
## API Endpoints
See [API Documentation](../api/openapi/iam-service.yaml)
```
**VI**: Ví dụ cấu trúc từ `services/iam-service/README.md`:
```markdown
# Service Name / Tên Dịch Vụ
> **EN**: Brief description in English
> **VI**: Mô tả ngắn gọn bằng tiếng Việt
## Features / Tính Năng
- Feature 1 / Tính năng 1
- Feature 2 / Tính năng 2
## Prerequisites / Yêu Cầu
- Node.js 20+
- PostgreSQL (Neon)
- Redis
## Quick Start / Bắt Đầu Nhanh
```bash
# Install dependencies / Cài đặt dependencies
pnpm install
# Setup environment / Thiết lập môi trường
cp .env.example .env
# Start service / Khởi động service
pnpm dev
```
## Configuration / Cấu Hình
| Variable | Description / Mô Tả | Default | Required |
|----------|---------------------|---------|----------|
| PORT | Server port / Cổng server | 5000 | No |
## API Endpoints
See [API Documentation](../api/openapi/iam-service.yaml)
```
### Guide Template / Template Hướng Dẫn
**EN**: Example from `docs/en/guides/getting-started.md`:
```markdown
# Getting Started
## Prerequisites
- Node.js >= 20.0.0
- PNPM >= 8.0.0
- Docker & Docker Compose
- Git
- Neon account (https://neon.tech) - for database
## Initial Setup
1. **Clone the repository**
```bash
git clone <repository-url>
cd Base
```
2. **Setup Neon Database**
```bash
# Run setup script
./scripts/db/setup-neon.sh
```
See [Neon Setup Guide](../../../infra/databases/neon/README.md) for details.
3. **Initialize the project**
```bash
./scripts/setup/init-project.sh
```
## Next Steps
- Read [Development Guide](../guides/development.md)
- Check [API Documentation](../api/openapi/)
- Review [Architecture Overview](../architecture/system-design.md)
```
**VI**: Ví dụ từ `docs/vi/guides/getting-started.md`:
```markdown
# Bắt Đầu
## Yêu Cầu
- Node.js >= 20.0.0
- PNPM >= 8.0.0
- Docker & Docker Compose
- Git
- Tài khoản Neon (https://neon.tech) - cho database
## Thiết Lập Ban Đầu
1. **Clone repository**
```bash
git clone <repository-url>
cd Base
```
2. **Thiết lập Neon Database**
```bash
# Chạy script setup
./scripts/db/setup-neon.sh
```
Xem [Hướng Dẫn Thiết Lập Neon](../../../infra/databases/neon/README.md) để biết chi tiết.
3. **Khởi tạo dự án**
```bash
./scripts/setup/init-project.sh
```
## Bước Tiếp Theo
- Đọc [Hướng Dẫn Phát Triển](../guides/development.md)
- Xem [Tài Liệu API](../api/openapi/)
- Xem lại [Tổng Quan Kiến Trúc](../architecture/system-design.md)
```
### Architecture Document Template / Template Tài Liệu Kiến Trúc
**EN**: Example from `docs/en/architecture/system-design.md`:
```markdown
# System Design
## Overview
GoodGo Microservices Platform is built using a microservices architecture pattern with the following principles:
- **Service Independence**: Each service has its own database and can be deployed independently
- **API Gateway**: Traefik handles routing, load balancing, and cross-cutting concerns
- **Shared Libraries**: Common functionality is extracted into shared packages
- **Infrastructure as Code**: All infrastructure configurations are versioned
- **Observability**: Full monitoring, logging, and tracing capabilities
## Architecture Diagram
```
┌─────────────┐ ┌─────────────┐
│ Web App │ │ Mobile App │
│ (Next.js) │ │ (React Native)
└──────┬──────┘ └──────┬──────┘
│ │
└──────────┬────────┘
┌────────▼────────┐
│ Traefik │
│ (API Gateway) │
└────────┬─────────┘
```
## Components
### Frontend Layer
- **Web App**: Next.js application with App Router
- **Mobile App**: React Native application
### API Gateway
- **Traefik**: Reverse proxy, load balancer, SSL termination
```
**VI**: Ví dụ từ `docs/vi/architecture/system-design.md`:
```markdown
# Thiết Kế Hệ Thống
## Tổng Quan
GoodGo Microservices Platform được xây dựng bằng mẫu kiến trúc microservices với các nguyên tắc sau:
- **Độc Lập Dịch Vụ**: Mỗi service có database riêng và có thể triển khai độc lập
- **API Gateway**: Traefik xử lý routing, load balancing và các mối quan tâm chéo
- **Thư Viện Dùng Chung**: Chức năng chung được trích xuất thành packages dùng chung
- **Infrastructure as Code**: Tất cả cấu hình infrastructure được version
- **Observability**: Khả năng giám sát, logging và tracing đầy đủ
## Sơ Đồ Kiến Trúc
```
┌─────────────┐ ┌─────────────┐
│ Web App │ │ Mobile App │
│ (Next.js) │ │ (React Native)
└──────┬──────┘ └──────┬──────┘
│ │
└──────────┬────────┘
┌────────▼────────┐
│ Traefik │
│ (API Gateway) │
└────────┬─────────┘
```
## Thành Phần
### Lớp Frontend
- **Web App**: Ứng dụng Next.js với App Router
- **Mobile App**: Ứng dụng React Native
### API Gateway
- **Traefik**: Reverse proxy, load balancer, SSL termination
```
## Best Practices / Thực Hành Tốt Nhất
### Writing Style / Phong Cách Viết
**EN**:
1. **Clear and Concise**: Use simple language, avoid jargon
2. **Action-Oriented**: Start with verbs (Install, Configure, Deploy)
3. **Structured**: Use headings, lists, and tables
4. **Examples**: Provide code examples and commands
5. **Visual**: Use diagrams where helpful
**VI**:
1. **Rõ Ràng và Súc Tích**: Sử dụng ngôn ngữ đơn giản, tránh thuật ngữ
2. **Hướng Hành Động**: Bắt đầu bằng động từ (Cài đặt, Cấu hình, Triển khai)
3. **Có Cấu Trúc**: Sử dụng tiêu đề, danh sách và bảng
4. **Ví Dụ**: Cung cấp ví dụ code và lệnh
5. **Trực Quan**: Sử dụng sơ đồ khi hữu ích
### Code Examples / Ví Dụ Code
**EN**: Always provide context and explanation:
```markdown
# Good: With context and explanation
Install dependencies using pnpm:
```bash
pnpm install
```
# Bad: No context
```bash
pnpm install
```
```
**VI**: Luôn cung cấp ngữ cảnh và giải thích:
```markdown
# Tốt: Có ngữ cảnh và giải thích
Cài đặt dependencies sử dụng pnpm:
```bash
pnpm install
```
# Không tốt: Không có ngữ cảnh
```bash
pnpm install
```
```
### Links / Liên Kết
**EN**:
- Use relative links for internal docs
- Use descriptive link text (not "click here")
- Example: `See the [Deployment Guide](../guides/deployment.md) for details.`
**VI**:
- Sử dụng liên kết tương đối cho tài liệu nội bộ
- Sử dụng văn bản liên kết mô tả (không phải "click here")
- Ví dụ: `Xem [Hướng Dẫn Triển Khai](../guides/deployment.md) để biết chi tiết.`
## Examples from Project / Ví Dụ Từ Dự Án
### Good Documentation Examples / Ví Dụ Tài Liệu Tốt
**EN**:
- `docs/en/guides/getting-started.md` - Clear step-by-step guide
- `services/iam-service/README.md` - Comprehensive service README
- `docs/en/architecture/system-design.md` - Architecture documentation
- `docs/README.md` - Documentation index
**VI**:
- `docs/vi/guides/getting-started.md` - Hướng dẫn từng bước rõ ràng
- `services/iam-service/README.md` - README service toàn diện
- `docs/vi/architecture/system-design.md` - Tài liệu kiến trúc
- `docs/README.md` - Mục lục tài liệu
### Documentation Locations Reference / Tham Chiếu Vị Trí Tài Liệu
**EN**:
| Content Type | Location | Format |
|--------------|----------|--------|
| Getting Started | `docs/en/guides/getting-started.md` | Separate files |
| Service Setup | `services/[name]/README.md` | Side-by-side |
| Deployment | `docs/en/guides/deployment.md` | Separate files |
| Architecture | `docs/en/architecture/` | Separate files |
| API Specs | `docs/en/api/openapi/` | OpenAPI YAML |
| Runbooks | `docs/en/runbooks/` | Separate files |
| Infrastructure | `infra/[component]/README.md` | Side-by-side |
**VI**:
| Loại Nội Dung | Vị Trí | Định Dạng |
|--------------|--------|----------|
| Bắt Đầu | `docs/vi/guides/getting-started.md` | File riêng biệt |
| Thiết Lập Service | `services/[name]/README.md` | Side-by-side |
| Triển Khai | `docs/vi/guides/deployment.md` | File riêng biệt |
| Kiến Trúc | `docs/vi/architecture/` | File riêng biệt |
| Spec API | `docs/vi/api/openapi/` | OpenAPI YAML |
| Runbooks | `docs/vi/runbooks/` | File riêng biệt |
| Infrastructure | `infra/[component]/README.md` | Side-by-side |
## Quick Reference / Tham Khảo Nhanh
### File Naming / Đặt Tên File
**EN**:
- Use kebab-case: `getting-started.md`
- Be descriptive: `local-development.md` not `dev.md`
- Match EN and VI filenames
**VI**:
- Sử dụng kebab-case: `getting-started.md`
- Mô tả rõ ràng: `local-development.md` không phải `dev.md`
- Khớp tên file EN và VI
### Heading Levels / Cấp Độ Tiêu Đề
```markdown
# H1: Document Title (only one per file)
## H2: Major Sections
### H3: Subsections
#### H4: Details (use sparingly)
```
### Bilingual Patterns / Mẫu Song Ngữ
```markdown
# Pattern 1: Inline
Description / Mô tả
# Pattern 2: After slash
PORT=5000 # Server port / Cổng server
# Pattern 3: Table
| Variable | Description / Mô Tả |
# Pattern 4: Code comments
# EN: Install dependencies
# VI: Cài đặt dependencies
pnpm install
```
### Documentation Checklist / Danh Sách Kiểm Tra Tài Liệu
**EN**: Before publishing documentation:
- [ ] Determine correct location (docs/ vs service README)
- [ ] Choose bilingual format (side-by-side vs separate)
- [ ] Review existing docs for consistency
- [ ] Use clear, concise language
- [ ] Include code examples
- [ ] Add diagrams where helpful
- [ ] Provide troubleshooting section
- [ ] Link to related documentation
- [ ] Test all commands and code examples
- [ ] Check all links work
- [ ] Ensure bilingual consistency
- [ ] Update documentation index
**VI**: Trước khi xuất bản tài liệu:
- [ ] Xác định vị trí đúng (docs/ vs service README)
- [ ] Chọn định dạng song ngữ (side-by-side vs separate)
- [ ] Xem lại tài liệu hiện có để đảm bảo tính nhất quán
- [ ] Sử dụng ngôn ngữ rõ ràng, súc tích
- [ ] Bao gồm ví dụ code
- [ ] Thêm sơ đồ khi hữu ích
- [ ] Cung cấp phần xử lý sự cố
- [ ] Liên kết đến tài liệu liên quan
- [ ] Kiểm tra tất cả lệnh và ví dụ code
- [ ] Kiểm tra tất cả liên kết hoạt động
- [ ] Đảm bảo tính nhất quán song ngữ
- [ ] Cập nhật mục lục tài liệu
## Related Skills / Skills Liên Quan
- **[Project Rules](./project-rules.md)** - Project structure and standards
- **[API Design](./api-design.md)** - API documentation patterns
- **[Comment Code](./comment-code.md)** - Code commenting guidelines
## Resources / Tài Nguyên
**EN**:
- [Markdown Guide](https://www.markdownguide.org/)
- [Mermaid Diagrams](https://mermaid.js.org/)
- [Documentation Best Practices](https://www.writethedocs.org/guide/)
**VI**:
- [Hướng Dẫn Markdown](https://www.markdownguide.org/)
- [Sơ Đồ Mermaid](https://mermaid.js.org/)
- [Thực Hành Tốt Nhất Tài Liệu](https://www.writethedocs.org/guide/)

View File

@@ -0,0 +1,565 @@
# Observability & Monitoring / Khả Năng Quan Sát & Giám Sát
> **EN**: Observability and monitoring patterns for GoodGo microservices. Use when adding metrics, implementing logging, setting up tracing, creating health checks, or debugging production issues.
> **VI**: Các pattern observability và monitoring cho microservices GoodGo. Sử dụng khi thêm metrics, triển khai logging, thiết lập tracing, tạo health checks, hoặc debug các vấn đề production.
## Overview / Tổng Quan
**EN**: This skill covers the three pillars of observability (logs, metrics, traces) and how to implement them in GoodGo microservices. It includes structured logging, Prometheus metrics, distributed tracing with OpenTelemetry, health checks, and error tracking.
**VI**: Skill này bao gồm ba trụ cột của observability (logs, metrics, traces) và cách triển khai chúng trong microservices GoodGo. Nó bao gồm structured logging, Prometheus metrics, distributed tracing với OpenTelemetry, health checks, và error tracking.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Setting up logging infrastructure
- Implementing metrics collection
- Adding distributed tracing
- Creating health check endpoints
- Setting up monitoring dashboards
- Debugging production issues
- Implementing alerting rules
- Analyzing performance bottlenecks
**VI**: Sử dụng skill này khi:
- Thiết lập hạ tầng logging
- Triển khai thu thập metrics
- Thêm distributed tracing
- Tạo health check endpoints
- Thiết lập monitoring dashboards
- Debug các vấn đề production
- Triển khai alerting rules
- Phân tích performance bottlenecks
## Key Concepts / Khái Niệm Chính
### Three Pillars of Observability / Ba Trụ Cột Của Observability
**EN**:
1. **Logs**: Event records for debugging and auditing
2. **Metrics**: Numerical measurements over time (counters, gauges, histograms)
3. **Traces**: Request flow across services (distributed tracing)
**VI**:
1. **Logs**: Bản ghi sự kiện để debug và audit
2. **Metrics**: Đo lường số học theo thời gian (counters, gauges, histograms)
3. **Traces**: Luồng request qua các services (distributed tracing)
### Tech Stack / Công Nghệ
**EN**:
- **Logging**: `@goodgo/logger` (Pino-based structured logging)
- **Metrics**: Prometheus + Grafana
- **Tracing**: OpenTelemetry + Jaeger (`@goodgo/tracing`)
- **Correlation IDs**: Request tracking across services
**VI**:
- **Logging**: `@goodgo/logger` (structured logging dựa trên Pino)
- **Metrics**: Prometheus + Grafana
- **Tracing**: OpenTelemetry + Jaeger (`@goodgo/tracing`)
- **Correlation IDs**: Theo dõi request qua các services
## Common Patterns / Các Pattern Thường Dùng
### Structured Logging / Logging Có Cấu Trúc
**EN**: Use structured logging with correlation IDs for request tracking.
**VI**: Sử dụng structured logging với correlation IDs để theo dõi request.
**Example from codebase**: [`services/iam-service/src/middlewares/logger.middleware.ts`](../../../services/iam-service/src/middlewares/logger.middleware.ts)
```typescript
import { Request, Response, NextFunction } from 'express';
import { logger } from '@goodgo/logger';
import { getCorrelationId, getRequestId } from './correlation.middleware';
export const requestLogger = (req: Request, res: Response, next: NextFunction): void => {
// Skip detailed logging for health checks and metrics
if (req.path.startsWith('/health') || req.path.startsWith('/metrics')) {
return next();
}
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
const correlationId = getCorrelationId(req);
const requestId = getRequestId(req);
logger.info('Request processed / Request đã xử lý', {
correlationId,
requestId,
method: req.method,
path: req.path,
query: req.query,
statusCode: res.statusCode,
duration: `${duration}ms`,
contentLength: res.get('Content-Length') || 0,
userAgent: req.get('User-Agent'),
ip: req.ip,
userId: (req as any).user?.userId,
});
});
next();
};
```
### Correlation IDs / Correlation IDs
**EN**: Use correlation IDs to track requests across services.
**VI**: Sử dụng correlation IDs để theo dõi request qua các services.
**Example from codebase**: [`services/iam-service/src/middlewares/correlation.middleware.ts`](../../../services/iam-service/src/middlewares/correlation.middleware.ts)
```typescript
import { Request, Response, NextFunction } from 'express';
import { randomUUID } from 'crypto';
import { logger } from '@goodgo/logger';
export const CORRELATION_ID_HEADER = 'x-correlation-id';
export const REQUEST_ID_HEADER = 'x-request-id';
export const correlationMiddleware = (
options: {
headerName?: string;
generateId?: () => string;
skipPaths?: string[];
} = {}
) => {
const {
headerName = CORRELATION_ID_HEADER,
generateId = randomUUID,
skipPaths = ['/health', '/metrics', '/favicon.ico'],
} = options;
return (req: Request, res: Response, next: NextFunction) => {
// Get correlation ID from header or generate new one
const correlationId = req.headers[headerName.toLowerCase()] as string || generateId();
const requestId = generateId();
// Attach to request object
req.correlationId = correlationId;
req.requestId = requestId;
// Add to response headers
res.setHeader(headerName, correlationId);
res.setHeader(REQUEST_ID_HEADER, requestId);
// Log request start
logger.info('Request started / Request bắt đầu', {
correlationId,
requestId,
method: req.method,
url: req.url,
userAgent: req.get('User-Agent'),
ip: req.ip,
});
next();
};
};
```
### Metrics Collection / Thu Thập Metrics
**EN**: Expose Prometheus metrics for monitoring and alerting.
**VI**: Expose Prometheus metrics để monitoring và alerting.
**Example from codebase**: [`services/iam-service/src/middlewares/metrics.middleware.ts`](../../../services/iam-service/src/middlewares/metrics.middleware.ts)
```typescript
import { Request, Response, NextFunction } from 'express';
import client from 'prom-client';
import { getCorrelationId } from './correlation.middleware';
// Create a Registry which registers the metrics
const register = client.register;
// Collect default metrics
client.collectDefaultMetrics({ register });
// Create histogram for HTTP request duration
const httpRequestDurationSeconds = new client.Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status_code', 'correlation_id'],
buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 2, 5, 10],
});
// Create counter for total HTTP requests
const httpRequestsTotal = new client.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
});
// Create gauge for active requests
const activeRequests = new client.Gauge({
name: 'http_active_requests',
help: 'Number of active HTTP requests',
});
// Create counter for HTTP request errors
const httpRequestErrors = new client.Counter({
name: 'http_request_errors_total',
help: 'Total number of HTTP request errors',
labelNames: ['method', 'route', 'error_type'],
});
export const metricsMiddleware = (req: Request, res: Response, next: NextFunction) => {
// Increment active requests
activeRequests.inc();
// Start timer
const start = process.hrtime.bigint();
res.on('finish', () => {
// Decrement active requests
activeRequests.dec();
// Calculate duration
const end = process.hrtime.bigint();
const durationInSeconds = Number(end - start) / 1e9;
// Normalize path to avoid high cardinality
const route = normalizeRoutePath(req);
const correlationId = getCorrelationId(req) || 'unknown';
// Record duration
httpRequestDurationSeconds
.labels(req.method, route, res.statusCode.toString(), correlationId)
.observe(durationInSeconds);
// Increment request counter
httpRequestsTotal
.labels(req.method, route, res.statusCode.toString())
.inc();
// Track errors
if (res.statusCode >= 400) {
const errorType = res.statusCode >= 500 ? 'server_error' : 'client_error';
httpRequestErrors
.labels(req.method, route, errorType)
.inc();
}
});
next();
};
// Normalize route path to prevent high cardinality metrics
function normalizeRoutePath(req: Request): string {
if (req.route && req.route.path) {
return req.route.path;
}
let path = req.path;
// Replace UUIDs and numeric IDs with placeholders
path = path.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, ':uuid');
path = path.replace(/\d+/g, ':id');
return path;
}
```
### Distributed Tracing / Distributed Tracing
**EN**: Use OpenTelemetry for distributed tracing across services.
**VI**: Sử dụng OpenTelemetry cho distributed tracing qua các services.
**Example from codebase**: [`packages/tracing/src/index.ts`](../../../packages/tracing/src/index.ts)
```typescript
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
import { Resource } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
export interface TracingConfig {
serviceName: string;
jaegerEndpoint?: string;
enabled?: boolean;
}
export const initTracing = (config: TracingConfig): NodeSDK | null => {
if (config.enabled === false) {
return null;
}
// Create Jaeger exporter if endpoint is provided
const jaegerExporter = config.jaegerEndpoint
? new JaegerExporter({
endpoint: config.jaegerEndpoint,
})
: undefined;
// Initialize OpenTelemetry NodeSDK with auto-instrumentations
const sdk = new NodeSDK({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: config.serviceName,
}),
traceExporter: jaegerExporter,
instrumentations: [getNodeAutoInstrumentations()],
});
// Start the tracing SDK
sdk.start();
return sdk;
};
```
**Usage in service**:
```typescript
// services/iam-service/src/main.ts
import { initTracing } from '@goodgo/tracing';
// Initialize tracing
if (process.env.TRACING_ENABLED === 'true') {
initTracing({
serviceName: process.env.SERVICE_NAME || 'iam-service',
jaegerEndpoint: process.env.JAEGER_ENDPOINT,
enabled: true,
});
}
```
### Health Checks / Kiểm Tra Sức Khỏe
**EN**: Implement liveness and readiness probes for Kubernetes.
**VI**: Triển khai liveness và readiness probes cho Kubernetes.
**Example from codebase**: [`services/iam-service/src/modules/health/health.controller.ts`](../../../services/iam-service/src/modules/health/health.controller.ts)
```typescript
import { Request, Response } from 'express';
import { prisma } from '../../config/database.config';
import { ApiResponse } from '@goodgo/types';
export class HealthController {
/**
* EN: Basic liveness probe
* VI: Kiểm tra liveness cơ bản
*/
health = async (_req: Request, res: Response): Promise<void> => {
const response: ApiResponse<{ status: string; timestamp: string }> = {
success: true,
data: {
status: 'ok',
timestamp: new Date().toISOString(),
},
timestamp: new Date().toISOString(),
};
res.json(response);
};
/**
* EN: Readiness probe (checks database connection)
* VI: Kiểm tra readiness (kiểm tra kết nối database)
*/
ready = async (_req: Request, res: Response): Promise<void> => {
try {
// Check database connection
await prisma.$queryRaw`SELECT 1`;
res.json({
success: true,
data: { status: 'ready' },
timestamp: new Date().toISOString(),
});
} catch (error) {
// Return 503 if database is not ready
res.status(503).json({
success: false,
error: {
code: 'HEALTH_001',
message: 'Service not ready',
},
timestamp: new Date().toISOString(),
});
}
};
/**
* EN: Alias for health check
* VI: Alias cho kiểm tra sức khỏe
*/
live = async (_req: Request, res: Response): Promise<void> => {
res.json({
success: true,
data: { status: 'live' },
timestamp: new Date().toISOString(),
});
};
}
```
## Best Practices / Thực Hành Tốt Nhất
### Logging / Logging
**EN**:
- Use structured logging (JSON format)
- Include correlation IDs for request tracing
- Log at appropriate levels (ERROR, WARN, INFO, DEBUG)
- Avoid logging sensitive data (passwords, tokens, PII)
- Use consistent log format across services
**VI**:
- Sử dụng structured logging (định dạng JSON)
- Bao gồm correlation IDs để theo dõi request
- Log ở mức độ phù hợp (ERROR, WARN, INFO, DEBUG)
- Tránh log dữ liệu nhạy cảm (mật khẩu, tokens, PII)
- Sử dụng format log nhất quán giữa các services
### Metrics / Metrics
**EN**:
- Use standard metric types (Counter, Gauge, Histogram)
- Keep cardinality low (avoid high-cardinality labels)
- Define SLIs and SLOs for critical paths
- Monitor business metrics, not just technical ones
- Normalize route paths to prevent high cardinality
**VI**:
- Sử dụng các loại metric chuẩn (Counter, Gauge, Histogram)
- Giữ cardinality thấp (tránh high-cardinality labels)
- Định nghĩa SLIs và SLOs cho các đường dẫn quan trọng
- Giám sát business metrics, không chỉ technical metrics
- Chuẩn hóa route paths để tránh high cardinality
### Tracing / Tracing
**EN**:
- Add traces for critical operations
- Include relevant context in spans
- Sample appropriately to control costs
- Use distributed tracing for microservices
- Propagate correlation IDs across service boundaries
**VI**:
- Thêm traces cho các thao tác quan trọng
- Bao gồm context liên quan trong spans
- Sample phù hợp để kiểm soát chi phí
- Sử dụng distributed tracing cho microservices
- Truyền correlation IDs qua ranh giới service
### Alerting / Cảnh Báo
**EN**:
- Alert on symptoms, not causes
- Include runbook links in alerts
- Avoid alert fatigue with proper thresholds
- Test alerting rules regularly
- Use correlation IDs in alert context
**VI**:
- Cảnh báo về triệu chứng, không phải nguyên nhân
- Bao gồm links runbook trong alerts
- Tránh alert fatigue với thresholds phù hợp
- Test alerting rules thường xuyên
- Sử dụng correlation IDs trong alert context
## Examples from Project / Ví Dụ Từ Dự Án
### Logging Implementation / Triển Khai Logging
- **Request Logger**: [`services/iam-service/src/middlewares/logger.middleware.ts`](../../../services/iam-service/src/middlewares/logger.middleware.ts)
- **Correlation Middleware**: [`services/iam-service/src/middlewares/correlation.middleware.ts`](../../../services/iam-service/src/middlewares/correlation.middleware.ts)
### Metrics Implementation / Triển Khai Metrics
- **Metrics Middleware**: [`services/iam-service/src/middlewares/metrics.middleware.ts`](../../../services/iam-service/src/middlewares/metrics.middleware.ts)
- **Metrics Endpoint**: Exposed at `/metrics` in all services
### Tracing Implementation / Triển Khai Tracing
- **Tracing Package**: [`packages/tracing/src/index.ts`](../../../packages/tracing/src/index.ts)
- **Service Integration**: [`services/iam-service/src/main.ts`](../../../services/iam-service/src/main.ts)
### Health Checks / Health Checks
- **Health Controller**: [`services/iam-service/src/modules/health/health.controller.ts`](../../../services/iam-service/src/modules/health/health.controller.ts)
## Quick Reference / Tham Khảo Nhanh
### Log Levels / Mức Độ Log
**EN**:
- `ERROR`: Errors that require immediate attention
- `WARN`: Warnings that may indicate issues
- `INFO`: Informational messages (default)
- `DEBUG`: Detailed debugging information
**VI**:
- `ERROR`: Lỗi cần chú ý ngay lập tức
- `WARN`: Cảnh báo có thể chỉ ra vấn đề
- `INFO`: Thông điệp thông tin (mặc định)
- `DEBUG`: Thông tin debug chi tiết
### Metric Types / Loại Metrics
**EN**:
- **Counter**: Monotonically increasing value (e.g., request count)
- **Gauge**: Value that can go up or down (e.g., active connections)
- **Histogram**: Distribution of values (e.g., request duration)
**VI**:
- **Counter**: Giá trị tăng đơn điệu (ví dụ: số lượng request)
- **Gauge**: Giá trị có thể tăng hoặc giảm (ví dụ: kết nối đang hoạt động)
- **Histogram**: Phân phối giá trị (ví dụ: thời lượng request)
### Health Check Endpoints / Endpoints Health Check
**EN**:
- `/health` or `/health/live`: Liveness probe (service is running)
- `/health/ready`: Readiness probe (service is ready to accept traffic)
**VI**:
- `/health` hoặc `/health/live`: Liveness probe (service đang chạy)
- `/health/ready`: Readiness probe (service sẵn sàng nhận traffic)
### Prometheus Queries / Truy Vấn Prometheus
```promql
# Request rate
rate(http_requests_total[5m])
# Error rate
rate(http_requests_total{status_code=~"5.."}[5m])
# 95th percentile latency
histogram_quantile(0.95, http_request_duration_seconds)
# Active requests
http_active_requests
```
## Related Skills / Skills Liên Quan
- [Kubernetes Deployment](./deployment-kubernetes.md) - For configuring health checks in K8s
- [Security](./security.md) - For secure logging and monitoring
- [Project Rules](./project-rules.md) - For service structure and standards
## Resources / Tài Nguyên
### Official Documentation / Tài Liệu Chính Thức
- [OpenTelemetry Documentation](https://opentelemetry.io/docs/)
- [Prometheus Documentation](https://prometheus.io/docs/)
- [Jaeger Documentation](https://www.jaegertracing.io/docs/)
### GoodGo Resources / Tài Nguyên GoodGo
- [Observability Guide](../guides/observability.md)
- [Troubleshooting Guide](../guides/troubleshooting.md)
- [Logger Package](../../../packages/logger/README.md)
- [Tracing Package](../../../packages/tracing/README.md)

View File

@@ -0,0 +1,425 @@
# Project Rules / Quy Tắc Dự Án
> **EN**: GoodGo Microservices Platform coding standards and architecture patterns. Use when working with services, apps, packages, or infrastructure.
> **VI**: Tiêu chuẩn mã hóa và mẫu kiến trúc của GoodGo Microservices Platform. Sử dụng khi làm việc với services, apps, packages, hoặc infrastructure.
## Overview / Tổng Quan
**EN**: The Project Rules skill provides comprehensive guidelines for the GoodGo Microservices Platform architecture, coding standards, naming conventions, workflows, and best practices. This skill ensures consistency across all services, packages, and applications in the monorepo.
**VI**: Skill Project Rules cung cấp hướng dẫn toàn diện về kiến trúc GoodGo Microservices Platform, tiêu chuẩn mã hóa, quy ước đặt tên, quy trình làm việc và thực hành tốt nhất. Skill này đảm bảo tính nhất quán trên tất cả services, packages và applications trong monorepo.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Creating a new service or package
- Setting up project structure
- Following naming conventions
- Understanding deployment patterns
- Working with dependencies
- Configuring Docker containers
- Setting up CI/CD workflows
- Understanding the monorepo structure
**VI**: Sử dụng skill này khi:
- Tạo service hoặc package mới
- Thiết lập cấu trúc dự án
- Tuân theo quy ước đặt tên
- Hiểu các mẫu triển khai
- Làm việc với dependencies
- Cấu hình Docker containers
- Thiết lập CI/CD workflows
- Hiểu cấu trúc monorepo
## Key Concepts / Khái Niệm Chính
### Architecture / Kiến Trúc
**EN**: The platform follows a microservices architecture with:
- **Apps**: Next.js (web) + Flutter (mobile)
- **Services**: Node.js/TypeScript microservices (Express)
- **Packages**: Shared libraries (logger, types, http-client, auth-sdk, tracing)
- **Infrastructure**: Traefik (API Gateway), Redis, Neon PostgreSQL, Observability
- **Deployments**: Local (Docker Compose), Staging/Production (Kubernetes)
**VI**: Nền tảng tuân theo kiến trúc microservices với:
- **Apps**: Next.js (web) + Flutter (mobile)
- **Services**: Node.js/TypeScript microservices (Express)
- **Packages**: Thư viện dùng chung (logger, types, http-client, auth-sdk, tracing)
- **Infrastructure**: Traefik (API Gateway), Redis, Neon PostgreSQL, Observability
- **Deployments**: Local (Docker Compose), Staging/Production (Kubernetes)
### Tech Stack / Công Nghệ
**Frontend:**
- Next.js 14+ (App Router), TypeScript, Tailwind CSS, Zustand
- Flutter 3.x with Provider pattern
- Use `@goodgo/types` and `@goodgo/http-client`
**Backend:**
- Node.js 20+, TypeScript 5+, Express
- Prisma ORM + Neon PostgreSQL
- Zod validation, `@goodgo/logger`, `@goodgo/tracing`, `@goodgo/auth-sdk`
**Infrastructure:**
- Traefik (path-based routing), Redis (cache), Prometheus + Grafana + Loki
## Common Patterns / Các Pattern Thường Dùng
### Service Structure / Cấu Trúc Service
**EN**: Standard service structure:
```
services/[service-name]/
├── src/
│ ├── config/ # Configuration files
│ ├── modules/ # Feature modules
│ ├── middlewares/ # Express middlewares
│ ├── repositories/ # Data access layer
│ ├── routes/ # Route definitions
│ └── main.ts # Entry point
├── prisma/ # Database schema
├── Dockerfile # Container definition
└── package.json # Dependencies
```
**VI**: Cấu trúc service chuẩn:
```
services/[service-name]/
├── src/
│ ├── config/ # File cấu hình
│ ├── modules/ # Module tính năng
│ ├── middlewares/ # Express middlewares
│ ├── repositories/ # Lớp truy cập dữ liệu
│ ├── routes/ # Định nghĩa routes
│ └── main.ts # Điểm vào
├── prisma/ # Database schema
├── Dockerfile # Định nghĩa container
└── package.json # Dependencies
```
### Module Pattern / Pattern Module
**EN**: Controller → Service → Repository pattern:
```typescript
// DTO with Zod
export const CreateFeatureDto = z.object({
name: z.string().min(1),
email: z.string().email()
});
export type CreateFeatureDto = z.infer<typeof CreateFeatureDto>;
// Controller
export class FeatureController {
constructor(private service: FeatureService) {}
async create(req: Request, res: Response, next: NextFunction) {
try {
const dto = CreateFeatureDto.parse(req.body);
const result = await this.service.create(dto);
res.json({ success: true, data: result });
} catch (error) { next(error); }
}
}
// Service
export class FeatureService {
constructor(private repository: FeatureRepository) {}
async create(dto: CreateFeatureDto) {
return this.repository.create(dto);
}
}
// Repository
export class FeatureRepository extends BaseRepository<Feature> {
async create(data: CreateFeatureDto) {
return this.prisma.feature.create({ data });
}
}
```
**VI**: Pattern Controller → Service → Repository:
```typescript
// DTO với Zod
export const CreateFeatureDto = z.object({
name: z.string().min(1),
email: z.string().email()
});
export type CreateFeatureDto = z.infer<typeof CreateFeatureDto>;
// Controller
export class FeatureController {
constructor(private service: FeatureService) {}
async create(req: Request, res: Response, next: NextFunction) {
try {
const dto = CreateFeatureDto.parse(req.body);
const result = await this.service.create(dto);
res.json({ success: true, data: result });
} catch (error) { next(error); }
}
}
// Service
export class FeatureService {
constructor(private repository: FeatureRepository) {}
async create(dto: CreateFeatureDto) {
return this.repository.create(dto);
}
}
// Repository
export class FeatureRepository extends BaseRepository<Feature> {
async create(data: CreateFeatureDto) {
return this.prisma.feature.create({ data });
}
}
```
### API Response Pattern / Pattern Phản Hồi API
**EN**: Standardized API responses:
```typescript
// Success response
{
success: true,
data: any,
timestamp: string
}
// Error response
{
success: false,
error: {
code: string,
message: string,
details?: any
},
timestamp: string
}
```
**VI**: Phản hồi API chuẩn hóa:
```typescript
// Phản hồi thành công
{
success: true,
data: any,
timestamp: string
}
// Phản hồi lỗi
{
success: false,
error: {
code: string,
message: string,
details?: any
},
timestamp: string
}
```
## Best Practices / Thực Hành Tốt Nhất
### Naming Conventions / Quy Ước Đặt Tên
**EN**:
- **Services/Packages**: `kebab-case` (e.g., `iam-service`, `http-client`)
- **Files**: `kebab-case.type.ts` (e.g., `user.controller.ts`)
- **Components**: `PascalCase.tsx` (React), `snake_case.dart` (Flutter)
- **Classes**: `PascalCase`
- **Functions**: `camelCase`
- **Constants**: `UPPER_SNAKE_CASE`
- **Package Names**: `@goodgo/package-name`
**VI**:
- **Services/Packages**: `kebab-case` (ví dụ: `iam-service`, `http-client`)
- **Files**: `kebab-case.type.ts` (ví dụ: `user.controller.ts`)
- **Components**: `PascalCase.tsx` (React), `snake_case.dart` (Flutter)
- **Classes**: `PascalCase`
- **Functions**: `camelCase`
- **Constants**: `UPPER_SNAKE_CASE`
- **Package Names**: `@goodgo/package-name`
### TypeScript Standards / Tiêu Chuẩn TypeScript
**EN**:
- Strict mode enabled
- No `any` type (use `unknown` instead)
- Zod for runtime validation
- Export shared types from `@goodgo/types`
**VI**:
- Bật strict mode
- Không dùng type `any` (dùng `unknown` thay thế)
- Zod cho runtime validation
- Export shared types từ `@goodgo/types`
### Logging / Ghi Log
**EN**: Use `@goodgo/logger`:
```typescript
import { logger } from '@goodgo/logger';
logger.info('Message', { context });
logger.error('Error', { error, context });
```
**VI**: Sử dụng `@goodgo/logger`:
```typescript
import { logger } from '@goodgo/logger';
logger.info('Message', { context });
logger.error('Error', { error, context });
```
### Environment Variables / Biến Môi Trường
**EN**:
- Use `.env.example` template
- Never commit `.env` files
- Validate with Zod at startup
- Document all variables in README
**VI**:
- Sử dụng template `.env.example`
- Không bao giờ commit file `.env`
- Validate với Zod khi khởi động
- Tài liệu hóa tất cả biến trong README
## Examples from Project / Ví Dụ Từ Dự Án
### Service Template / Template Service
**EN**: See `services/_template/` for a complete service template with:
- Standard structure
- Middleware setup
- Error handling
- Health checks
- Swagger documentation
**VI**: Xem `services/_template/` để có template service hoàn chỉnh với:
- Cấu trúc chuẩn
- Thiết lập middleware
- Xử lý lỗi
- Health checks
- Tài liệu Swagger
### Traefik Configuration / Cấu Hình Traefik
**EN**: Services are registered in `deployments/local/docker-compose.yml`:
```yaml
services:
my-service:
build:
context: ../..
dockerfile: services/my-service/Dockerfile
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-service.rule=PathPrefix(`/api/v1/my-service`)"
- "traefik.http.services.my-service.loadbalancer.server.port=5002"
- "traefik.http.services.my-service.loadbalancer.healthcheck.path=/health/live"
```
**VI**: Services được đăng ký trong `deployments/local/docker-compose.yml`:
```yaml
services:
my-service:
build:
context: ../..
dockerfile: services/my-service/Dockerfile
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-service.rule=PathPrefix(`/api/v1/my-service`)"
- "traefik.http.services.my-service.loadbalancer.server.port=5002"
- "traefik.http.services.my-service.loadbalancer.healthcheck.path=/health/live"
```
### Real Service Examples / Ví Dụ Service Thực Tế
**EN**:
- `services/iam-service/` - Identity and Access Management service (RBAC, OIDC, MFA, Identity, Access, Governance)
- `packages/logger/` - Shared logging package
- `packages/types/` - Shared TypeScript types
**VI**:
- `services/iam-service/` - Service quản lý danh tính và quyền truy cập (RBAC, OIDC, MFA, Identity, Access, Governance)
- `packages/logger/` - Package logging dùng chung
- `packages/types/` - TypeScript types dùng chung
## Quick Reference / Tham Khảo Nhanh
### Creating New Service / Tạo Service Mới
```bash
# 1. Copy template
cp -r services/_template services/my-service
# 2. Update package.json name
# Change to: "@goodgo/my-service"
# 3. Add to docker-compose.yml
# Add service configuration with Traefik labels
# 4. Configure Prisma schema
cd services/my-service
pnpm prisma migrate dev
# 5. Add health check endpoint
# Already included in template
```
### Working with Dependencies / Làm Việc Với Dependencies
```bash
# Add external package
pnpm --filter @goodgo/service-name add package-name
# Add workspace package
pnpm --filter @goodgo/service-name add @goodgo/logger
# Add dev dependency
pnpm --filter @goodgo/service-name add -D @types/pkg
```
### Database Commands / Lệnh Database
```bash
# Run migrations
pnpm --filter @goodgo/service-name prisma migrate dev
# Generate Prisma client
pnpm --filter @goodgo/service-name prisma generate
# Seed database
pnpm --filter @goodgo/service-name prisma db seed
```
## Related Skills / Skills Liên Quan
- **[API Design](./api-design.md)** - RESTful API design standards
- **[Database Prisma](./database-prisma.md)** - Prisma ORM patterns
- **[Security](./security.md)** - Security best practices
- **[Testing Patterns](./testing-patterns.md)** - Testing guidelines
- **[Documentation](./documentation.md)** - Documentation writing guidelines
## Resources / Tài Nguyên
**EN**:
- [Architecture Docs](../architecture/system-design.md)
- [API Specs](../api/openapi/)
- [Development Guide](../guides/development.md)
- [Deployment Guide](../guides/deployment.md)
- [Contributing Guide](../../../CONTRIBUTING.md)
**VI**:
- [Tài Liệu Kiến Trúc](../architecture/system-design.md)
- [Spec API](../api/openapi/)
- [Hướng Dẫn Phát Triển](../guides/development.md)
- [Hướng Dẫn Triển Khai](../guides/deployment.md)
- [Hướng Dẫn Đóng Góp](../../../CONTRIBUTING.md)

742
docs/en/skills/security.md Normal file
View File

@@ -0,0 +1,742 @@
# Security / Bảo Mật
> **EN**: Security best practices and patterns for GoodGo microservices platform. Use when implementing authentication, authorization, data protection, input validation, rate limiting, secrets management, or security testing across all services.
> **VI**: Thực hành và mẫu bảo mật tốt nhất cho nền tảng microservices GoodGo. Sử dụng khi triển khai xác thực, phân quyền, bảo vệ dữ liệu, xác thực đầu vào, giới hạn tốc độ, quản lý bí mật hoặc kiểm tra bảo mật trên tất cả các dịch vụ.
## Overview / Tổng Quan
**EN**: The Security skill provides comprehensive security patterns, best practices, and implementation examples for protecting GoodGo microservices. It covers authentication, authorization, data protection, input validation, rate limiting, secrets management, and security testing.
**VI**: Skill Security cung cấp các mẫu bảo mật toàn diện, thực hành tốt nhất và ví dụ triển khai để bảo vệ các microservices GoodGo. Nó bao gồm xác thực, phân quyền, bảo vệ dữ liệu, xác thực đầu vào, giới hạn tốc độ, quản lý bí mật và kiểm tra bảo mật.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Implementing authentication and authorization in any service
- Protecting sensitive data (PII, credentials, tokens)
- Validating user inputs and file uploads
- Implementing rate limiting and DDoS protection
- Setting up audit logging and security monitoring
- Encrypting data at rest and in transit
- Managing secrets and credentials
- Implementing security testing
- Handling security incidents
- Designing secure API endpoints
**VI**: Sử dụng skill này khi:
- Triển khai xác thực và phân quyền trong bất kỳ service nào
- Bảo vệ dữ liệu nhạy cảm (PII, thông tin đăng nhập, token)
- Xác thực đầu vào người dùng và tải lên tệp
- Triển khai giới hạn tốc độ và bảo vệ DDoS
- Thiết lập ghi nhật ký kiểm toán và giám sát bảo mật
- Mã hóa dữ liệu khi nghỉ và khi truyền
- Quản lý bí mật và thông tin đăng nhập
- Triển khai kiểm tra bảo mật
- Xử lý sự cố bảo mật
- Thiết kế các endpoint API an toàn
## Key Concepts / Khái Niệm Chính
### Core Security Principles / Nguyên Tắc Bảo Mật Cốt Lõi
**EN**:
1. **Defense in Depth**: Multiple layers of security controls
2. **Least Privilege**: Grant minimum required permissions
3. **Fail Secure**: Default to deny access
4. **Separation of Duties**: Critical operations require multiple approvals
5. **Audit Everything**: Log all security-relevant events
6. **Encrypt Sensitive Data**: PII, tokens, credentials must be encrypted
7. **Validate All Inputs**: Never trust user input
8. **Principle of Least Exposure**: Minimize attack surface
9. **Secure by Default**: Security built-in, not bolted on
10. **Assume Breach**: Design for detection and response
**VI**:
1. **Defense in Depth**: Nhiều lớp kiểm soát bảo mật
2. **Least Privilege**: Cấp quyền tối thiểu cần thiết
3. **Fail Secure**: Mặc định từ chối truy cập
4. **Separation of Duties**: Các thao tác quan trọng yêu cầu nhiều phê duyệt
5. **Audit Everything**: Ghi log tất cả sự kiện liên quan đến bảo mật
6. **Encrypt Sensitive Data**: PII, token, thông tin đăng nhập phải được mã hóa
7. **Validate All Inputs**: Không bao giờ tin tưởng đầu vào người dùng
8. **Principle of Least Exposure**: Giảm thiểu bề mặt tấn công
9. **Secure by Default**: Bảo mật được tích hợp sẵn, không phải thêm vào sau
10. **Assume Breach**: Thiết kế để phát hiện và phản ứng
## Common Patterns / Các Pattern Thường Dùng
### Authentication & Authorization / Xác Thực & Phân Quyền
#### JWT Token Validation / Xác Thực Token JWT
**EN**: Example from `services/iam-service/src/middlewares/auth.middleware.ts`:
```typescript
import { jwtService } from '../modules/token/jwt.service';
import { logger } from '@goodgo/logger';
export const authenticate = () => {
return async (req: Request, res: Response, next: NextFunction) => {
try {
// Extract token from Authorization header or cookie
let token: string | null = null;
const authHeader = req.headers.authorization;
if (authHeader?.startsWith('Bearer ')) {
token = authHeader.substring(7);
} else if (req.cookies?.access_token) {
token = req.cookies.access_token;
}
if (!token) {
return res.status(401).json({
success: false,
error: { code: 'AUTH_001', message: 'Authentication required' }
});
}
// Verify token
const payload = await jwtService.verifyAccessToken(token);
// Attach user to request
req.user = {
id: payload.sub,
userId: payload.sub,
email: payload.email,
roles: payload.roles || [],
permissions: payload.permissions || []
};
next();
} catch (error) {
logger.warn('Authentication failed', { error: error.message });
return res.status(401).json({
success: false,
error: { code: 'AUTH_002', message: 'Invalid or expired token' }
});
}
};
};
```
**VI**: Ví dụ từ `services/iam-service/src/middlewares/auth.middleware.ts`:
```typescript
import { jwtService } from '../modules/token/jwt.service';
import { logger } from '@goodgo/logger';
export const authenticate = () => {
return async (req: Request, res: Response, next: NextFunction) => {
try {
// Trích xuất token từ header Authorization hoặc cookie
let token: string | null = null;
const authHeader = req.headers.authorization;
if (authHeader?.startsWith('Bearer ')) {
token = authHeader.substring(7);
} else if (req.cookies?.access_token) {
token = req.cookies.access_token;
}
if (!token) {
return res.status(401).json({
success: false,
error: { code: 'AUTH_001', message: 'Yêu cầu xác thực' }
});
}
// Xác minh token
const payload = await jwtService.verifyAccessToken(token);
// Gắn user vào request
req.user = {
id: payload.sub,
userId: payload.sub,
email: payload.email,
roles: payload.roles || [],
permissions: payload.permissions || []
};
next();
} catch (error) {
logger.warn('Xác thực thất bại', { error: error.message });
return res.status(401).json({
success: false,
error: { code: 'AUTH_002', message: 'Token không hợp lệ hoặc hết hạn' }
});
}
};
};
```
#### Permission-Based Authorization / Phân Quyền Dựa Trên Quyền
**EN**: Example from `services/iam-service/src/middlewares/rbac.middleware.ts`:
```typescript
export const requirePermission = (
resource: string,
action: string,
scope?: string
) => {
return async (req: Request, res: Response, next: NextFunction) => {
const userId = req.user?.id || req.user?.sub;
if (!userId) {
return res.status(401).json({
success: false,
error: { code: 'UNAUTHORIZED', message: 'Authentication required' }
});
}
const hasPermission = await rbacService.hasPermission(
userId,
resource,
action,
scope
);
if (!hasPermission) {
return res.status(403).json({
success: false,
error: {
code: 'INSUFFICIENT_PERMISSIONS',
message: `Requires ${action} permission on ${resource}`
}
});
}
next();
};
};
```
**VI**: Ví dụ từ `services/iam-service/src/middlewares/rbac.middleware.ts`:
```typescript
export const requirePermission = (
resource: string,
action: string,
scope?: string
) => {
return async (req: Request, res: Response, next: NextFunction) => {
const userId = req.user?.id || req.user?.sub;
if (!userId) {
return res.status(401).json({
success: false,
error: { code: 'UNAUTHORIZED', message: 'Yêu cầu xác thực' }
});
}
const hasPermission = await rbacService.hasPermission(
userId,
resource,
action,
scope
);
if (!hasPermission) {
return res.status(403).json({
success: false,
error: {
code: 'INSUFFICIENT_PERMISSIONS',
message: `Yêu cầu quyền ${action} trên ${resource}`
}
});
}
next();
};
};
```
### Input Validation / Xác Thực Đầu Vào
**EN**: Example from `services/iam-service/src/middlewares/validation.middleware.ts`:
```typescript
import { AnyZodObject, ZodError } from 'zod';
export const validateDto = (
schema: AnyZodObject,
property: 'body' | 'query' | 'params' = 'body'
) => {
return (req: Request, res: Response, next: NextFunction) => {
try {
// Sanitize input by trimming strings
const sanitizedData = sanitizeInput(req[property]);
// Validate the sanitized data
const validatedData = schema.parse(sanitizedData);
// Replace original data with validated data
(req as any)[property] = validatedData;
next();
} catch (error) {
if (error instanceof ZodError) {
return res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid request data',
details: error.errors.map(err => ({
field: err.path.join('.'),
message: err.message,
code: err.code
}))
}
});
}
throw error;
}
};
};
function sanitizeInput(data: any): any {
if (typeof data === 'string') {
return data.trim();
}
if (Array.isArray(data)) {
return data.map(sanitizeInput);
}
if (data !== null && typeof data === 'object') {
const sanitized: any = {};
for (const [key, value] of Object.entries(data)) {
sanitized[key] = sanitizeInput(value);
}
return sanitized;
}
return data;
}
```
**VI**: Ví dụ từ `services/iam-service/src/middlewares/validation.middleware.ts`:
```typescript
import { AnyZodObject, ZodError } from 'zod';
export const validateDto = (
schema: AnyZodObject,
property: 'body' | 'query' | 'params' = 'body'
) => {
return (req: Request, res: Response, next: NextFunction) => {
try {
// Làm sạch đầu vào bằng cách cắt chuỗi
const sanitizedData = sanitizeInput(req[property]);
// Xác thực dữ liệu đã được làm sạch
const validatedData = schema.parse(sanitizedData);
// Thay thế dữ liệu gốc bằng dữ liệu đã xác thực
(req as any)[property] = validatedData;
next();
} catch (error) {
if (error instanceof ZodError) {
return res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Dữ liệu request không hợp lệ',
details: error.errors.map(err => ({
field: err.path.join('.'),
message: err.message,
code: err.code
}))
}
});
}
throw error;
}
};
};
function sanitizeInput(data: any): any {
if (typeof data === 'string') {
return data.trim();
}
if (Array.isArray(data)) {
return data.map(sanitizeInput);
}
if (data !== null && typeof data === 'object') {
const sanitized: any = {};
for (const [key, value] of Object.entries(data)) {
sanitized[key] = sanitizeInput(value);
}
return sanitized;
}
return data;
}
```
### Rate Limiting / Giới Hạn Tốc Độ
**EN**: Example from `services/iam-service/src/middlewares/rate-limit.middleware.ts`:
```typescript
import rateLimit from 'express-rate-limit';
import { RateLimiterRedis } from 'rate-limit-redis';
import { getRedisClient } from '../config/redis.config';
export const dynamicRateLimit = async (
req: Request,
res: Response,
next: NextFunction
) => {
const userId = req.user?.id || req.user?.sub;
// Default limits
let windowMs = 15 * 60 * 1000; // 15 minutes
let max = 100; // 100 requests
if (userId) {
const roles = await rbacService.getUserRoles(userId);
// Set limits based on role
if (roles.includes('SUPER_ADMIN')) {
max = 1000;
} else if (roles.includes('ADMIN')) {
max = 500;
} else if (roles.includes('MODERATOR')) {
max = 300;
}
} else {
// Unauthenticated users - stricter limits
max = 50;
}
const limiter = rateLimit({
windowMs,
max,
store: new RateLimiterRedis({
client: getRedisClient(),
prefix: 'rl:'
}),
handler: (req, res) => {
res.status(429).json({
success: false,
error: {
code: 'RATE_LIMIT_EXCEEDED',
message: 'Too many requests, please try again later'
}
});
}
});
limiter(req, res, next);
};
```
**VI**: Ví dụ từ `services/iam-service/src/middlewares/rate-limit.middleware.ts`:
```typescript
import rateLimit from 'express-rate-limit';
import { RateLimiterRedis } from 'rate-limit-redis';
import { getRedisClient } from '../config/redis.config';
export const dynamicRateLimit = async (
req: Request,
res: Response,
next: NextFunction
) => {
const userId = req.user?.id || req.user?.sub;
// Giới hạn mặc định
let windowMs = 15 * 60 * 1000; // 15 phút
let max = 100; // 100 requests
if (userId) {
const roles = await rbacService.getUserRoles(userId);
// Đặt giới hạn dựa trên vai trò
if (roles.includes('SUPER_ADMIN')) {
max = 1000;
} else if (roles.includes('ADMIN')) {
max = 500;
} else if (roles.includes('MODERATOR')) {
max = 300;
}
} else {
// Người dùng chưa xác thực - giới hạn nghiêm ngặt hơn
max = 50;
}
const limiter = rateLimit({
windowMs,
max,
store: new RateLimiterRedis({
client: getRedisClient(),
prefix: 'rl:'
}),
handler: (req, res) => {
res.status(429).json({
success: false,
error: {
code: 'RATE_LIMIT_EXCEEDED',
message: 'Quá nhiều yêu cầu, vui lòng thử lại sau'
}
});
}
});
limiter(req, res, next);
};
```
### Security Headers / Header Bảo Mật
**EN**: Example from `services/iam-service/src/main.ts`:
```typescript
import helmet from 'helmet';
import cors from 'cors';
// Security middleware
app.use(helmet());
app.use(cors({
origin: appConfig.corsOrigin,
credentials: true
}));
```
**VI**: Ví dụ từ `services/iam-service/src/main.ts`:
```typescript
import helmet from 'helmet';
import cors from 'cors';
// Middleware bảo mật
app.use(helmet());
app.use(cors({
origin: appConfig.corsOrigin,
credentials: true
}));
```
**EN**: Traefik security headers from `infra/traefik/dynamic/middlewares.yml`:
```yaml
http:
middlewares:
secure-headers:
headers:
sslRedirect: true
stsSeconds: 31536000
contentTypeNosniff: true
browserXssFilter: true
frameDeny: true
customRequestHeaders:
X-Forwarded-Proto: "https"
```
**VI**: Header bảo mật Traefik từ `infra/traefik/dynamic/middlewares.yml`:
```yaml
http:
middlewares:
secure-headers:
headers:
sslRedirect: true
stsSeconds: 31536000
contentTypeNosniff: true
browserXssFilter: true
frameDeny: true
customRequestHeaders:
X-Forwarded-Proto: "https"
```
### Audit Logging / Ghi Log Kiểm Toán
**EN**: Example from `services/iam-service/src/core/events/audit.service.ts`:
```typescript
export class AuditService {
async logAuthEvent(
eventType: string,
data: {
userId?: string;
success: boolean;
errorMessage?: string;
ipAddress?: string;
userAgent?: string;
metadata?: any;
}
): Promise<void> {
await this.prisma.authEvent.create({
data: {
userId: data.userId || null,
eventType,
eventData: data.metadata || {},
ipAddress: data.ipAddress,
userAgent: data.userAgent,
success: data.success,
errorMessage: data.errorMessage
}
});
}
}
```
**VI**: Ví dụ từ `services/iam-service/src/core/events/audit.service.ts`:
```typescript
export class AuditService {
async logAuthEvent(
eventType: string,
data: {
userId?: string;
success: boolean;
errorMessage?: string;
ipAddress?: string;
userAgent?: string;
metadata?: any;
}
): Promise<void> {
await this.prisma.authEvent.create({
data: {
userId: data.userId || null,
eventType,
eventData: data.metadata || {},
ipAddress: data.ipAddress,
userAgent: data.userAgent,
success: data.success,
errorMessage: data.errorMessage
}
});
}
}
```
## Best Practices / Thực Hành Tốt Nhất
### Password Security / Bảo Mật Mật Khẩu
**EN**:
- Always use bcrypt with cost factor 12+ in production
- Never log passwords or password hashes
- Use strong password requirements (min 8 chars, uppercase, lowercase, number, special char)
- Implement password reset with secure tokens
**VI**:
- Luôn sử dụng bcrypt với hệ số chi phí 12+ trong production
- Không bao giờ ghi log mật khẩu hoặc hash mật khẩu
- Sử dụng yêu cầu mật khẩu mạnh (tối thiểu 8 ký tự, chữ hoa, chữ thường, số, ký tự đặc biệt)
- Triển khai đặt lại mật khẩu với token an toàn
### Token Security / Bảo Mật Token
**EN**:
- Hash tokens before storing in database
- Use short-lived access tokens (15 minutes)
- Use longer-lived refresh tokens (7 days) with rotation
- Store refresh tokens securely (httpOnly cookies)
- Implement token revocation
**VI**:
- Hash token trước khi lưu vào database
- Sử dụng access token có thời gian sống ngắn (15 phút)
- Sử dụng refresh token có thời gian sống dài hơn (7 ngày) với xoay vòng
- Lưu trữ refresh token an toàn (httpOnly cookies)
- Triển khai thu hồi token
### SQL Injection Prevention / Ngăn Chặn SQL Injection
**EN**:
- Always use Prisma parameterized queries (automatic)
- Never use string concatenation for queries
- Validate and sanitize all inputs
**VI**:
- Luôn sử dụng truy vấn tham số hóa của Prisma (tự động)
- Không bao giờ sử dụng nối chuỗi cho truy vấn
- Xác thực và làm sạch tất cả đầu vào
## Examples from Project / Ví Dụ Từ Dự Án
### Authentication Middleware / Middleware Xác Thực
**EN**: See `services/iam-service/src/middlewares/auth.middleware.ts` for complete authentication implementation.
**VI**: Xem `services/iam-service/src/middlewares/auth.middleware.ts` để có implementation xác thực hoàn chỉnh.
### RBAC Middleware / Middleware RBAC
**EN**: See `services/iam-service/src/middlewares/rbac.middleware.ts` for permission-based authorization.
**VI**: Xem `services/iam-service/src/middlewares/rbac.middleware.ts` để có phân quyền dựa trên quyền.
### Validation Middleware / Middleware Xác Thực
**EN**: See `services/iam-service/src/middlewares/validation.middleware.ts` for input validation patterns.
**VI**: Xem `services/iam-service/src/middlewares/validation.middleware.ts` để có các mẫu xác thực đầu vào.
### Rate Limiting / Giới Hạn Tốc Độ
**EN**: See `services/iam-service/src/middlewares/rate-limit.middleware.ts` for dynamic rate limiting.
**VI**: Xem `services/iam-service/src/middlewares/rate-limit.middleware.ts` để có giới hạn tốc độ động.
## Quick Reference / Tham Khảo Nhanh
### Security Checklist / Danh Sách Kiểm Tra Bảo Mật
**EN**: Before deploying any service:
- [ ] All endpoints require authentication (except public)
- [ ] Authorization checks implemented (RBAC/ABAC)
- [ ] Input validation with Zod schemas
- [ ] Rate limiting configured
- [ ] Error messages sanitized (no info disclosure)
- [ ] PII encrypted at rest
- [ ] Passwords hashed with bcrypt (cost 12+)
- [ ] Tokens hashed before storing
- [ ] Secrets in environment variables (never hardcoded)
- [ ] HTTPS enforced (TLS 1.2+)
- [ ] CORS configured correctly
- [ ] Security headers set (helmet)
- [ ] Audit logging enabled
- [ ] SQL injection prevented (use Prisma)
- [ ] XSS prevention (input sanitization)
- [ ] File upload validation
- [ ] Security tests passing
**VI**: Trước khi triển khai bất kỳ service nào:
- [ ] Tất cả endpoint yêu cầu xác thực (trừ public)
- [ ] Kiểm tra phân quyền đã triển khai (RBAC/ABAC)
- [ ] Xác thực đầu vào với Zod schemas
- [ ] Giới hạn tốc độ đã cấu hình
- [ ] Thông báo lỗi đã được làm sạch (không tiết lộ thông tin)
- [ ] PII được mã hóa khi nghỉ
- [ ] Mật khẩu được hash với bcrypt (chi phí 12+)
- [ ] Token được hash trước khi lưu
- [ ] Bí mật trong biến môi trường (không bao giờ hardcode)
- [ ] HTTPS được bắt buộc (TLS 1.2+)
- [ ] CORS được cấu hình đúng
- [ ] Header bảo mật được đặt (helmet)
- [ ] Ghi log kiểm toán được bật
- [ ] SQL injection được ngăn chặn (sử dụng Prisma)
- [ ] Ngăn chặn XSS (làm sạch đầu vào)
- [ ] Xác thực tải lên tệp
- [ ] Kiểm tra bảo mật đã vượt qua
## Related Skills / Skills Liên Quan
- **[Project Rules](./project-rules.md)** - Coding standards and architecture
- **[API Design](./api-design.md)** - Secure API design patterns
- **[Testing Patterns](./testing-patterns.md)** - Security testing
## Resources / Tài Nguyên
**EN**:
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [OWASP API Security Top 10](https://owasp.org/www-project-api-security/)
- [Node.js Security Best Practices](https://nodejs.org/en/docs/guides/security/)
- [Express Security Best Practices](https://expressjs.com/en/advanced/best-practice-security.html)
**VI**:
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [OWASP API Security Top 10](https://owasp.org/www-project-api-security/)
- [Thực Hành Bảo Mật Node.js](https://nodejs.org/en/docs/guides/security/)
- [Thực Hành Bảo Mật Express](https://expressjs.com/en/advanced/best-practice-security.html)

View File

@@ -0,0 +1,738 @@
# Testing Patterns
> **EN**: Comprehensive testing best practices for GoodGo microservices including unit tests, integration tests, E2E tests, Jest configuration, mocking strategies, and debugging techniques.
> **VI**: Các thực hành tốt nhất về testing cho microservices GoodGo bao gồm unit tests, integration tests, E2E tests, cấu hình Jest, strategies mocking, và kỹ thuật debugging.
## Overview / Tổng Quan
**EN**: Testing is a critical component of the GoodGo microservices platform. This guide provides comprehensive patterns and best practices for writing maintainable, reliable tests across all services. It covers test types, Jest configuration, mocking strategies, test utilities, and debugging techniques that ensure code quality and reliability.
**VI**: Testing là thành phần quan trọng của nền tảng microservices GoodGo. Hướng dẫn này cung cấp các patterns và best practices toàn diện để viết các test có thể bảo trì và đáng tin cậy trên tất cả các services. Nó bao gồm các loại test, cấu hình Jest, strategies mocking, test utilities, và kỹ thuật debugging để đảm bảo chất lượng và độ tin cậy của code.
## When to Use / Khi Nào Sử Dụng
**EN**: Use these testing patterns when:
- Writing unit tests for services, controllers, or repositories
- Creating integration tests for middleware chains
- Building E2E tests for API endpoints
- Setting up Jest configuration for a new service
- Mocking external dependencies (Prisma, Redis, Auth SDK)
- Debugging test failures
- Improving test coverage
- Creating test utilities and factories
**VI**: Sử dụng các testing patterns này khi:
- Viết unit tests cho services, controllers, hoặc repositories
- Tạo integration tests cho middleware chains
- Xây dựng E2E tests cho API endpoints
- Thiết lập cấu hình Jest cho service mới
- Mocking các dependencies bên ngoài (Prisma, Redis, Auth SDK)
- Debugging test failures
- Cải thiện test coverage
- Tạo test utilities và factories
## Key Concepts / Khái Niệm Chính
### Test Types / Các Loại Test
#### 1. Unit Tests / Unit Tests
**EN**: Test individual functions or classes in isolation with all dependencies mocked.
**VI**: Test các functions hoặc classes riêng lẻ một cách cô lập với tất cả dependencies được mock.
**Characteristics**:
- **Location**: Next to source files (`*.test.ts`) or in `__tests__/` directory
- **Scope**: Single function, method, or class
- **Dependencies**: All external dependencies mocked
- **Speed**: Fast (<1s per test)
- **Purpose**: Verify logic correctness
**Example**: [`services/iam-service/src/modules/feature/__tests__/feature.service.test.ts`](../../../services/iam-service/src/modules/feature/__tests__/feature.service.test.ts)
#### 2. Integration Tests / Integration Tests
**EN**: Test multiple components working together with some real dependencies.
**VI**: Test nhiều components làm việc cùng nhau với một số dependencies thật.
**Characteristics**:
- **Location**: `__tests__/` directory (`*.test.ts`)
- **Scope**: Multiple components interacting
- **Dependencies**: Mix of real and mocked dependencies
- **Speed**: Medium (1-5s per test)
- **Purpose**: Verify component integration
**Example**: [`services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts`](../../../services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts)
#### 3. E2E Tests / E2E Tests
**EN**: Test complete request/response cycles through the entire application stack.
**VI**: Test các chu kỳ request/response hoàn chỉnh qua toàn bộ application stack.
**Characteristics**:
- **Location**: `__tests__/*.e2e.ts`
- **Scope**: Full API workflow from HTTP request to response
- **Dependencies**: Test database, mocked external services
- **Speed**: Slow (5-10s per test)
- **Purpose**: Verify end-to-end functionality
**Example**: [`services/iam-service/src/__tests__/feature.e2e.ts`](../../../services/iam-service/src/__tests__/feature.e2e.ts)
## Jest Configuration / Cấu Hình Jest
### Standard Configuration
The standard Jest configuration for GoodGo services includes TypeScript support, coverage thresholds, and proper test environment setup.
**Location**: [`services/iam-service/jest.config.ts`](../../../services/iam-service/jest.config.ts)
```typescript
import type { Config } from 'jest';
const config: Config = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: [
'**/__tests__/**/*.test.ts',
'**/__tests__/**/*.spec.ts',
'**/__tests__/**/*.e2e.ts',
'**/?(*.)+(spec|test).ts'
],
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.d.ts',
'!src/main.ts',
'!src/config/**/*.ts',
'!src/**/*.config.ts'
],
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov', 'html'],
coverageThreshold: {
global: {
branches: 70,
functions: 70,
lines: 70,
statements: 70
}
},
setupFilesAfterEnv: ['<rootDir>/src/__tests__/setupTests.ts'],
testTimeout: 10000,
clearMocks: true,
resetModules: true
};
export default config;
```
### Key Configuration Points
- **preset: 'ts-jest'**: Enables TypeScript support
- **testEnvironment: 'node'**: Sets Node.js environment (not browser)
- **coverageThreshold**: Enforces minimum 70% coverage across all metrics
- **setupFilesAfterEnv**: Loads test setup file before each test suite
- **clearMocks**: Automatically clears mock calls between tests
- **resetModules**: Resets module cache for test isolation
## Setup Files / Files Thiết Lập
### Test Setup File
The setup file (`setupTests.ts`) configures global mocks and test utilities that are available across all tests.
**Location**: [`services/iam-service/src/__tests__/setupTests.ts`](../../../services/iam-service/src/__tests__/setupTests.ts)
**Key Features**:
- Mock external services (logger, tracing, database, Redis)
- Configure test environment variables
- Set up global test utilities
- Initialize Prometheus mocks
**Example**:
```typescript
import { jest } from '@jest/globals';
// EN: Mock environment variables for tests
// VI: Mock biến môi trường cho tests
process.env.NODE_ENV = 'test';
process.env.DATABASE_URL = 'postgresql://test:test@localhost:5432/test_db';
process.env.REDIS_URL = 'redis://localhost:6379/1';
// EN: Mock external services to avoid real network calls
// VI: Mock các service bên ngoài để tránh gọi mạng thật
jest.mock('@goodgo/logger', () => ({
logger: {
info: jest.fn(),
error: jest.fn(),
warn: jest.fn(),
debug: jest.fn(),
},
}));
// EN: Global test utilities
// VI: Utilities test toàn cục
global.testUtils = {
createMockReq: (overrides = {}) => ({
body: {},
params: {},
query: {},
headers: {},
...overrides,
}),
createMockRes: () => {
const res: any = {};
res.status = jest.fn().mockReturnValue(res);
res.json = jest.fn().mockReturnValue(res);
res.send = jest.fn().mockReturnValue(res);
return res;
},
createMockNext: () => jest.fn(),
};
```
## Common Patterns / Các Pattern Thường Dùng
### Unit Test Pattern
**Structure**: Follow the AAA (Arrange-Act-Assert) pattern for clarity.
```typescript
describe('FeatureService', () => {
let service: FeatureService;
let mockRepository: any;
beforeEach(() => {
// EN: Clear all mocks before each test
// VI: Xóa tất cả mocks trước mỗi test
jest.clearAllMocks();
mockRepository = {
findById: jest.fn(),
create: jest.fn(),
};
service = new FeatureService(mockRepository);
});
describe('create', () => {
it('should create a feature successfully', async () => {
// EN: Arrange
// VI: Chuẩn bị
const testData = { name: 'test-feature', title: 'Test Feature' };
const mockFeature = {
id: 'test-id',
name: testData.name,
// ... other fields
};
mockRepository.create.mockResolvedValue(mockFeature);
// EN: Act
// VI: Thực hiện
const result = await service.create(testData);
// EN: Assert
// VI: Kiểm tra
expect(mockRepository.create).toHaveBeenCalledWith(testData);
expect(result).toEqual(mockFeature);
});
});
});
```
**Real Example**: [`services/iam-service/src/modules/feature/__tests__/feature.service.test.ts`](../../../services/iam-service/src/modules/feature/__tests__/feature.service.test.ts)
### Integration Test Pattern
Integration tests verify that multiple components work together correctly.
```typescript
describe('Auth Middleware', () => {
const mockNext = jest.fn();
beforeEach(() => {
jest.clearAllMocks();
});
it('should authenticate valid token and attach user to request', () => {
// EN: Arrange
// VI: Chuẩn bị
const mockReq = createMockReq({
headers: { authorization: 'Bearer valid-token' },
});
const mockRes = createMockRes();
// EN: Act
// VI: Thực hiện
const middleware = authenticate({ secret: jwtSecret });
middleware(mockReq as Request, mockRes as Response, mockNext);
// EN: Assert
// VI: Kiểm tra
expect(mockNext).toHaveBeenCalled();
expect(mockReq.user).toBeDefined();
});
});
```
**Real Example**: [`services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts`](../../../services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts)
### E2E Test Pattern
E2E tests use supertest to test complete HTTP request/response cycles.
```typescript
import request from 'supertest';
import express from 'express';
import { createRouter } from '../routes';
describe('Feature Endpoints E2E', () => {
let app: express.Application;
beforeAll(() => {
// EN: Set up test environment
// VI: Thiết lập môi trường test
process.env.NODE_ENV = 'test';
app = express();
app.use(express.json());
app.use(createRouter());
});
describe('POST /api/v1/features', () => {
it('should create a feature successfully', async () => {
// EN: Arrange
// VI: Chuẩn bị
const featureData = {
name: 'test-feature',
title: 'Test Feature',
description: 'A test feature for E2E testing'
};
// EN: Act
// VI: Thực hiện
const response = await request(app)
.post('/api/v1/features')
.send(featureData)
.expect(201);
// EN: Assert
// VI: Kiểm tra
expect(response.body).toMatchObject({
success: true,
message: 'Feature created successfully / Feature đã được tạo thành công',
});
});
});
});
```
**Real Example**: [`services/iam-service/src/__tests__/feature.e2e.ts`](../../../services/iam-service/src/__tests__/feature.e2e.ts)
## Mocking Strategies / Chiến Lược Mocking
### Mock Prisma Database
Mock Prisma client to avoid real database connections in unit tests.
```typescript
// In setupTests.ts or individual test files
jest.mock('../config/database.config', () => ({
connectDatabase: jest.fn(),
prisma: {
$queryRaw: jest.fn(),
$disconnect: jest.fn(),
feature: {
create: jest.fn(),
findMany: jest.fn(),
findUnique: jest.fn(),
update: jest.fn(),
delete: jest.fn(),
},
},
}));
// Usage in tests
const { prisma } = require('../config/database.config');
test('should create user', async () => {
prisma.feature.create.mockResolvedValue({
id: 'test-id',
name: 'test-feature',
// ... other fields
});
const result = await createFeature({ name: 'test-feature' });
expect(result).toBeDefined();
});
```
### Mock Redis
Mock Redis client for caching and session management tests.
```typescript
jest.mock('../config/redis.config', () => ({
getRedisClient: jest.fn().mockReturnValue({
call: jest.fn(),
connect: jest.fn(),
disconnect: jest.fn(),
}),
}));
```
### Mock External APIs
Mock external HTTP calls using Jest mocks.
```typescript
jest.mock('axios');
import axios from 'axios';
const mockedAxios = axios as jest.Mocked<typeof axios>;
test('should fetch external data', async () => {
mockedAxios.get.mockResolvedValue({
data: { result: 'success' }
});
const result = await fetchExternalData();
expect(result).toEqual({ result: 'success' });
});
```
### Mock Auth SDK
Mock authentication SDK functions for middleware and service tests.
```typescript
jest.mock('@goodgo/auth-sdk', () => ({
createToken: jest.fn(),
verifyToken: jest.fn(),
extractTokenFromHeader: jest.fn(),
}));
// Setup mock implementations
(verifyToken as jest.Mock).mockImplementation((token) => {
if (token === 'valid-token') {
return { userId: '123', role: 'user' };
}
throw new Error('Invalid token');
});
```
## Testing Utilities / Utilities Test
### Test Factory Pattern
Create reusable test data factories for consistent test data.
```typescript
export class TestFactory {
static createUser(overrides = {}) {
return {
id: 'test-user-1',
email: 'test@example.com',
name: 'Test User',
createdAt: new Date(),
...overrides
};
}
static createAuthToken(userId: string) {
return jwt.sign({ userId }, 'test-secret');
}
static async cleanDatabase() {
await prisma.user.deleteMany();
await prisma.feature.deleteMany();
}
}
// Usage
const user = TestFactory.createUser({ name: 'Custom Name' });
const token = TestFactory.createAuthToken(user.id);
```
### Mock Request/Response Helpers
Use global test utilities for creating mock Express request/response objects.
```typescript
// Available via global.testUtils (from setupTests.ts)
const mockReq = global.testUtils.createMockReq({
headers: { authorization: 'Bearer token' },
params: { id: '123' },
});
const mockRes = global.testUtils.createMockRes();
const mockNext = global.testUtils.createMockNext();
```
## Common Test Scenarios / Các Tình Huống Test Thường Gặp
### Testing Error Handling
```typescript
it('should handle database errors gracefully', async () => {
// EN: Arrange - Mock database error
// VI: Chuẩn bị - Mock lỗi database
prismaMock.user.findUnique.mockRejectedValue(
new Error('Database connection failed')
);
// EN: Act & Assert
// VI: Thực hiện & Kiểm tra
await expect(userService.findById('123')).rejects.toThrow();
// Or for HTTP endpoints
const response = await request(app)
.get('/api/users/123')
.expect(500);
expect(response.body).toEqual({
success: false,
error: {
code: 'INTERNAL_ERROR',
message: 'Internal server error / Lỗi máy chủ nội bộ',
},
});
});
```
### Testing Validation
```typescript
describe('Validation', () => {
it('should reject invalid email', async () => {
const response = await request(app)
.post('/api/auth/register')
.send({ email: 'invalid-email', password: '123456' })
.expect(400);
expect(response.body.error.code).toBe('VALIDATION_ERROR');
});
});
```
### Testing Authorization
```typescript
it('should deny access for user with incorrect role', () => {
const mockReq = createMockReq({
user: { userId: 'user-123', role: 'user' },
});
const middleware = authorize('admin');
middleware(mockReq as Request, mockRes as Response, mockNext);
expect(mockNext).not.toHaveBeenCalled();
expect(mockStatus).toHaveBeenCalledWith(403);
});
```
## Test Commands / Lệnh Test
Add these scripts to `package.json`:
```json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:unit": "jest --testPathPattern=\\.test\\.ts$",
"test:e2e": "jest --testPathPattern=\\.e2e\\.ts$",
"test:ci": "jest --coverage --silent --maxWorkers=2"
}
}
```
**Usage**:
- `pnpm test`: Run all tests
- `pnpm test:watch`: Run tests in watch mode
- `pnpm test:coverage`: Generate coverage report
- `pnpm test:unit`: Run only unit tests
- `pnpm test:e2e`: Run only E2E tests
- `pnpm test:ci`: Run tests optimized for CI/CD
## Debugging Tests / Debugging Tests
### VS Code Debug Configuration
Create `.vscode/launch.json` for debugging tests:
```json
{
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Jest Tests",
"runtimeExecutable": "npm",
"runtimeArgs": ["test", "--", "--runInBand"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
```
### Debug Tips
1. **Use `test.only()`** to run a single test:
```typescript
it.only('should test specific behavior', () => {
// Only this test will run
});
```
2. **Use `--detectOpenHandles`** for async issues:
```bash
pnpm test --detectOpenHandles
```
3. **Use `--runInBand`** for sequential execution:
```bash
pnpm test --runInBand
```
4. **Add temporary console.log**:
```typescript
console.log('Debug value:', someValue);
```
5. **Use debugger breakpoints** in VS Code
## Best Practices / Thực Hành Tốt Nhất
### Test Organization
- ✅ Each test is independent and isolated
- ✅ Tests follow AAA pattern (Arrange-Act-Assert)
- ✅ Use descriptive test names that explain what is being tested
- ✅ Group related tests using `describe` blocks
- ✅ Use `beforeEach`/`afterEach` for setup/cleanup
### Mocking
- ✅ Mock external dependencies (database, APIs, services)
- ✅ Use `jest.clearAllMocks()` in `beforeEach` to reset mocks
- ✅ Verify mock calls to ensure correct behavior
- ✅ Keep mocks simple and focused
### Coverage
- ✅ Maintain >70% code coverage (as per Jest config)
- ✅ Focus on covering critical business logic
- ✅ Don't sacrifice test quality for coverage percentage
- ✅ Review coverage reports regularly
### Test Data
- ✅ Use factories for creating test data
- ✅ Keep test data realistic and representative
- ✅ Clean up test data after tests (if using real database)
- ✅ Use meaningful test values, not just `'test'` or `123`
### Error Testing
- ✅ Test both success and error scenarios
- ✅ Test edge cases and boundary conditions
- ✅ Test validation errors
- ✅ Test error messages and error codes
### Performance
- ✅ Keep unit tests fast (<1s each)
- ✅ Avoid unnecessary async operations in unit tests
- ✅ Use `--maxWorkers` in CI for parallel execution
- ✅ Don't test implementation details, test behavior
## Examples from Project / Ví Dụ Từ Dự Án
### Real Test Examples
1. **Unit Test**: [`services/iam-service/src/modules/feature/__tests__/feature.service.test.ts`](../../../services/iam-service/src/modules/feature/__tests__/feature.service.test.ts)
2. **Integration Test**: [`services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts`](../../../services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts)
3. **E2E Test**: [`services/iam-service/src/__tests__/feature.e2e.ts`](../../../services/iam-service/src/__tests__/feature.e2e.ts)
4. **Setup File**: [`services/iam-service/src/__tests__/setupTests.ts`](../../../services/iam-service/src/__tests__/setupTests.ts)
5. **Jest Config**: [`services/iam-service/jest.config.ts`](../../../services/iam-service/jest.config.ts)
### Test Structure Examples
- **Repository Tests**: [`services/iam-service/src/modules/feature/__tests__/feature.repository.test.ts`](../../../services/iam-service/src/modules/feature/__tests__/feature.repository.test.ts)
- **Controller Tests**: [`services/iam-service/src/modules/health/__tests__/health.controller.test.ts`](../../../services/iam-service/src/modules/health/__tests__/health.controller.test.ts)
- **Middleware Tests**: [`services/iam-service/src/middlewares/__tests__/correlation.middleware.test.ts`](../../../services/iam-service/src/middlewares/__tests__/correlation.middleware.test.ts)
## Quick Reference / Tham Khảo Nhanh
### Test Type Decision Tree
```
Need to test complete HTTP flow?
├─ Yes → E2E Test (*.e2e.ts)
└─ No → Multiple components interacting?
├─ Yes → Integration Test (*.test.ts)
└─ No → Unit Test (*.test.ts)
```
### Common Jest Matchers
| Matcher | Purpose | Example |
|---------|---------|---------|
| `toBe()` | Exact equality | `expect(value).toBe(5)` |
| `toEqual()` | Deep equality | `expect(obj).toEqual({a: 1})` |
| `toMatchObject()` | Partial match | `expect(obj).toMatchObject({a: 1})` |
| `toHaveBeenCalled()` | Function called | `expect(mockFn).toHaveBeenCalled()` |
| `toHaveBeenCalledWith()` | Called with args | `expect(mockFn).toHaveBeenCalledWith('arg')` |
| `toThrow()` | Throws error | `expect(() => fn()).toThrow()` |
| `toBeDefined()` | Not undefined | `expect(value).toBeDefined()` |
| `toBeNull()` | Is null | `expect(value).toBeNull()` |
| `toContain()` | Array/string contains | `expect(array).toContain('item')` |
### Mock Function Helpers
```typescript
// Create mock
const mockFn = jest.fn();
// Set return value
mockFn.mockReturnValue('value');
mockFn.mockResolvedValue('async value');
mockFn.mockRejectedValue(new Error('error'));
// Set implementation
mockFn.mockImplementation((arg) => arg * 2);
// Clear/reset
mockFn.mockClear(); // Clear call history
mockFn.mockReset(); // Reset to initial state
jest.clearAllMocks(); // Clear all mocks
```
## Related Skills / Skills Liên Quan
- **[Comment Code](./comment-code.md)**: Writing bilingual comments in tests
- **[Security](./security.md)**: Testing security-critical code
- **[API Design](./api-design.md)**: Testing API endpoints and responses
- **[Project Rules](./project-rules.md)**: Code organization for tests
## Resources / Tài Nguyên
### Official Documentation
- [Jest Documentation](https://jestjs.io/docs/getting-started)
- [Supertest Documentation](https://github.com/visionmedia/supertest)
- [jest-mock-extended](https://github.com/marchaos/jest-mock-extended)
### Internal Documentation
- [Service Development Guide](../guides/development.md)
- [Local Development Setup](../guides/local-development.md)
- [Troubleshooting Guide](../guides/troubleshooting.md)
### Tools
- **Jest**: JavaScript testing framework
- **Supertest**: HTTP assertion library
- **jest-mock-extended**: Enhanced mocking for TypeScript
- **ioredis-mock**: Redis mock for testing

View File

@@ -0,0 +1,339 @@
# Đề Xuất Kiến Trúc IAM Service
Tài liệu này mô tả đề xuất kiến trúc cho IAM Service (Identity and Access Management Service), mở rộng từ auth-service hiện tại.
## Tổng Quan: Auth Service → IAM Service
**Auth Service hiện tại** tập trung vào:
- Authentication (xác thực)
- Authorization (phân quyền)
- Session & Token management
- RBAC/ABAC
**IAM Service** mở rộng thêm:
- **Identity Management** (quản lý danh tính toàn diện)
- **Access Governance** (quản trị truy cập)
- **Compliance & Reporting** (tuân thủ và báo cáo)
- **Lifecycle Management** (quản lý vòng đời tài khoản)
---
## 1. Phạm Vi IAM Service
### 1.1 Identity Management (Quản Lý Danh Tính)
#### A. User Lifecycle Management
- User CRUD operations
- User provisioning/deprovisioning workflows
- Bulk user operations (import/export)
- User deactivation/reactivation với approval workflow
- Account merging/deduplication
- User archival (soft delete với retention policy)
#### B. Profile Management
- Extended attributes (custom fields)
- Profile picture upload & management
- Contact information (phone, address)
- Preferences & settings
- Profile versioning/audit trail
#### C. Identity Verification
- Email verification
- Phone/SMS verification
- Identity document verification (KYC)
- Multi-level verification (verified, pending, rejected)
#### D. Organizations & Groups
- Organization management (multi-tenant)
- Group/Team management
- Organization hierarchy
- Group-based access control
- Organization-level policies
### 1.2 Access Management (Quản Lý Truy Cập)
#### A. Advanced Access Control
- Just-In-Time (JIT) access provisioning
- Privileged Access Management (PAM)
- Temporary access grants
- Access request/approval workflows
- Delegation & impersonation (admin view)
- Conditional access policies (location, time, device)
#### B. Access Reviews & Certifications
- Periodic access reviews
- Access certification campaigns
- Access analytics & reporting
- Risk scoring for access decisions
- Anomaly detection (unusual access patterns)
### 1.3 Governance & Compliance (Quản Trị & Tuân Thủ)
#### A. Audit & Logging
- Compliance reporting (GDPR, SOC2, ISO 27001)
- Data retention policies
- Audit log search & analytics
- Export audit logs
#### B. Policy Governance
- Policy versioning & rollback
- Policy templates library
- Policy testing & validation
- Policy compliance checks
#### C. Risk Management
- Risk scoring engine
- Risk-based authentication
- Threat detection
- Incident response workflows
- Security posture dashboard
---
## 2. Kiến Trúc Module Structure
```
services/iam-service/
├── src/
│ ├── config/ # Configuration files
│ ├── core/
│ │ ├── cache/ # Multi-layer cache
│ │ ├── security/ # Zero-trust, encryption
│ │ ├── events/ # Event sourcing
│ │ └── workflows/ # Workflow engine (NEW)
│ ├── modules/
│ │ ├── auth/ # ✅ Core authentication
│ │ ├── rbac/ # ✅ RBAC system
│ │ ├── social/ # ✅ Social authentication
│ │ ├── oidc/ # ✅ OIDC implementation
│ │ ├── token/ # ✅ JWT & Cookie management
│ │ ├── session/ # ✅ Session management
│ │ ├── mfa/ # ✅ Multi-factor auth
│ │ │
│ │ ├── identity/ # 🆕 Identity Management
│ │ │ ├── user/ # User lifecycle
│ │ │ ├── profile/ # Profile management
│ │ │ ├── verification/ # Identity verification
│ │ │ └── organization/ # Organizations & groups
│ │ │
│ │ ├── access/ # 🆕 Access Management
│ │ │ ├── request/ # Access requests
│ │ │ ├── review/ # Access reviews
│ │ │ ├── pam/ # Privileged access
│ │ │ └── analytics/ # Access analytics
│ │ │
│ │ ├── governance/ # 🆕 Governance & Compliance
│ │ │ ├── compliance/ # Compliance reporting
│ │ │ ├── policy/ # Policy governance
│ │ │ ├── risk/ # Risk management
│ │ │ └── reporting/ # Reporting & dashboards
│ │ │
│ │ └── workflow/ # 🆕 Workflow Engine
│ │ ├── engine/ # Workflow engine
│ │ ├── approval/ # Approval workflows
│ │ └── automation/ # Automated workflows
│ │
│ ├── middlewares/ # Express middlewares
│ ├── repositories/ # Data access layer
│ └── routes/ # Route definitions
└── prisma/
└── schema.prisma # Database schema (mở rộng)
```
---
## 3. Database Schema Mở Rộng
### 3.1 Identity Management Models
- **Organization**: Quản lý tổ chức với hierarchy
- **Group**: Quản lý nhóm trong organization
- **GroupMember**: Thành viên của group
- **GroupPermission**: Permissions cho group
- **UserProfile**: Thông tin profile mở rộng của user
- **IdentityVerification**: Xác thực danh tính (email, phone, document)
### 3.2 Access Management Models
- **AccessRequest**: Yêu cầu truy cập
- **AccessRequestApprover**: Người phê duyệt request
- **AccessReview**: Đánh giá truy cập định kỳ
- **AccessReviewItem**: Item trong review
### 3.3 Governance Models
- **ComplianceReport**: Báo cáo tuân thủ (GDPR, SOC2, ISO27001)
- **PolicyTemplate**: Template cho policies
- **RiskScore**: Điểm rủi ro của user
---
## 4. API Endpoints Mở Rộng
### 4.1 Identity Management APIs
```
# User Management
GET /api/v1/identity/users
POST /api/v1/identity/users
GET /api/v1/identity/users/:id
PUT /api/v1/identity/users/:id
DELETE /api/v1/identity/users/:id
POST /api/v1/identity/users/bulk-import
GET /api/v1/identity/users/bulk-export
# Profile Management
GET /api/v1/identity/users/:id/profile
PUT /api/v1/identity/users/:id/profile
POST /api/v1/identity/users/:id/profile/avatar
# Identity Verification
POST /api/v1/identity/verification/email/request
POST /api/v1/identity/verification/email/verify
POST /api/v1/identity/verification/phone/request
POST /api/v1/identity/verification/phone/verify
# Organizations & Groups
GET /api/v1/identity/organizations
POST /api/v1/identity/organizations
GET /api/v1/identity/organizations/:id/groups
POST /api/v1/identity/organizations/:id/groups
GET /api/v1/identity/groups/:id/members
POST /api/v1/identity/groups/:id/members
```
### 4.2 Access Management APIs
```
# Access Requests
GET /api/v1/access/requests
POST /api/v1/access/requests
PUT /api/v1/access/requests/:id/approve
PUT /api/v1/access/requests/:id/reject
# Access Reviews
GET /api/v1/access/reviews
POST /api/v1/access/reviews
POST /api/v1/access/reviews/:id/start
POST /api/v1/access/reviews/:id/complete
GET /api/v1/access/reviews/:id/items
# Access Analytics
GET /api/v1/access/analytics/usage
GET /api/v1/access/analytics/permissions
GET /api/v1/access/analytics/risks
```
### 4.3 Governance APIs
```
# Compliance Reports
GET /api/v1/governance/compliance/reports
POST /api/v1/governance/compliance/reports/generate
GET /api/v1/governance/compliance/reports/:id/export
# Policy Governance
GET /api/v1/governance/policies/templates
POST /api/v1/governance/policies/templates
GET /api/v1/governance/policies/:id/versions
POST /api/v1/governance/policies/:id/test
# Risk Management
GET /api/v1/governance/risk/scores
GET /api/v1/governance/risk/scores/:userId
POST /api/v1/governance/risk/calculate
# Reporting
GET /api/v1/governance/reports/access-summary
GET /api/v1/governance/reports/user-activity
GET /api/v1/governance/reports/security-events
```
---
## 5. Implementation Roadmap
### Phase 1: Foundation (Weeks 1-4)
- ✅ Migrate từ auth-service sang iam-service
- 🔄 Tổ chức lại modules theo IAM structure
- 🔄 Mở rộng database schema với identity models
- 🔄 Implement User Profile module
### Phase 2: Identity Management (Weeks 5-8)
- 🔄 User lifecycle management
- 🔄 Identity verification (email, phone, document)
- 🔄 Organization & Group management
- 🔄 Profile management with extended attributes
### Phase 3: Access Management (Weeks 9-12)
- 🔄 Access request/approval workflows
- 🔄 Access review & certification system
- 🔄 Access analytics
- 🔄 Privileged Access Management (PAM)
### Phase 4: Governance (Weeks 13-16)
- 🔄 Compliance reporting engine
- 🔄 Policy governance & versioning
- 🔄 Risk scoring & management
- 🔄 Reporting dashboards
### Phase 5: Advanced Features (Weeks 17-20)
- 🔄 Workflow engine
- 🔄 Advanced analytics & ML-based insights
- 🔄 Integration APIs (SCIM, LDAP sync)
- 🔄 Performance optimization & scaling
---
## 6. Lợi Ích Của IAM Service
### 6.1 Cho Doanh Nghiệp
- ✅ Tuân thủ (GDPR, SOC2, ISO 27001)
- ✅ Quản lý rủi ro bảo mật tốt hơn
- ✅ Tự động hóa quy trình quản lý truy cập
- ✅ Báo cáo và audit trail đầy đủ
- ✅ Hỗ trợ multi-tenant/organization
### 6.2 Cho Developers
- ✅ API thống nhất cho identity & access
- ✅ Workflow engine linh hoạt
- ✅ Extensible architecture
- ✅ Comprehensive documentation
- ✅ SDK support
### 6.3 Cho End Users
- ✅ Self-service profile management
- ✅ Transparent access requests
- ✅ Better user experience
- ✅ Enhanced security với MFA & verification
---
## 7. Migration Strategy
### Từ Auth Service → IAM Service
1. **Rename Service**: `services/auth-service``services/iam-service`
2. **Update Package Name**: `@goodgo/auth-service``@goodgo/iam-service`
3. **Update Routes**:
- Giữ backward compatibility với `/api/v1/auth/*`
- Thêm routes mới cho `/api/v1/identity/*`, `/api/v1/access/*`, `/api/v1/governance/*`
4. **Database Migration**:
- Thêm schema mới cho identity, access, governance
- Giữ nguyên các tables hiện có (backward compatible)
5. **Gradual Rollout**:
- Phase 1: Deploy cùng auth-service (dual deployment)
- Phase 2: Migrate clients dần dần
- Phase 3: Deprecate auth-service khi migration hoàn tất
---
## Kết Luận
Đề xuất này mở rộng `auth-service` thành `IAM Service` với đầy đủ các tính năng:
- **Identity Management** đầy đủ
- **Access Management** nâng cao
- **Governance & Compliance** toàn diện
- **Workflow automation** linh hoạt
Điều này biến service từ authentication/authorization cơ bản thành một IAM platform toàn diện, phù hợp cho enterprise.

View File

@@ -38,7 +38,7 @@ docker-compose up -d
```bash
# Tạo Kubernetes secret
kubectl create secret generic auth-service-secrets \
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://user:pass@ep-xxx.region.neon.tech/dbname?sslmode=require&pgbouncer=true' \
--from-literal=jwt-secret='your-staging-jwt-secret' \
--from-literal=jwt-refresh-secret='your-staging-refresh-secret' \
@@ -72,7 +72,7 @@ kubectl apply -f deployments/staging/kubernetes/
```bash
# Tạo Kubernetes secret
kubectl create secret generic auth-service-secrets \
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://user:pass@ep-xxx.region.neon.tech/dbname?sslmode=require&pgbouncer=true' \
--from-literal=jwt-secret='your-production-jwt-secret' \
--from-literal=jwt-refresh-secret='your-production-refresh-secret' \
@@ -90,7 +90,7 @@ kubectl create secret generic auth-service-secrets \
### Rollback
```bash
kubectl rollout undo deployment/auth-service -n production
kubectl rollout undo deployment/iam-service -n production
```
## Health Checks

View File

@@ -33,7 +33,7 @@ git checkout -b feature/my-feature
pnpm test
# Service cụ thể
pnpm --filter @goodgo/auth-service test
pnpm --filter @goodgo/iam-service test
```
### 4. Lint và Format
@@ -75,14 +75,14 @@ pnpm format
```bash
# Tạo migration (dev)
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
# Áp dụng migrations (production)
./scripts/db/migrate.sh auth-service deploy
./scripts/db/migrate.sh iam-service deploy
```
## Debugging
- Sử dụng logger từ `@goodgo/logger`
- Kiểm tra Traefik logs: `docker logs traefik-local`
- Kiểm tra service logs: `./scripts/dev/logs.sh auth-service`
- Kiểm tra service logs: `./scripts/dev/logs.sh iam-service`

View File

@@ -44,12 +44,12 @@
5. **Chạy database migrations**
```bash
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
```
6. **Seed database**
```bash
./scripts/db/seed.sh auth-service
./scripts/db/seed.sh iam-service
```
7. **Khởi động tất cả services**

View File

@@ -0,0 +1,204 @@
# Hướng Dẫn Migration: Auth Service → IAM Service
Tài liệu này hướng dẫn cách migrate từ `auth-service` sang `iam-service`.
## Tổng Quan
IAM Service là phiên bản mở rộng của Auth Service với các tính năng bổ sung về Identity Management, Access Management, và Governance & Compliance. Tất cả các API endpoints của Auth Service vẫn được giữ nguyên để đảm bảo backward compatibility.
## Backward Compatibility
**Tất cả các endpoints hiện tại vẫn hoạt động bình thường:**
- `/api/v1/auth/*` - Authentication endpoints
- `/api/v1/rbac/*` - RBAC endpoints
- `/api/v1/mfa/*` - MFA endpoints
- `/api/v1/sessions/*` - Session management endpoints
- `/api/v1/oidc/*` - OIDC endpoints
Không có breaking changes. Các clients hiện tại có thể tiếp tục sử dụng các endpoints này mà không cần thay đổi.
## Các Thay Đổi
### 1. Service Name
- **Cũ**: `auth-service`
- **Mới**: `iam-service`
### 2. Package Name
- **Cũ**: `@goodgo/auth-service`
- **Mới**: `@goodgo/iam-service`
### 3. Database Schema
Database schema được mở rộng với các models mới nhưng **không xóa hoặc thay đổi** các models hiện có:
**Models mới được thêm:**
- `Organization` - Quản lý tổ chức
- `Group` - Quản lý nhóm
- `GroupMember` - Thành viên nhóm
- `GroupPermission` - Quyền nhóm
- `UserProfile` - Profile mở rộng
- `IdentityVerification` - Xác thực danh tính
- `AccessRequest` - Yêu cầu truy cập
- `AccessReview` - Đánh giá truy cập
- `ComplianceReport` - Báo cáo tuân thủ
- `PolicyTemplate` - Template policy
- `RiskScore` - Điểm rủi ro
**User model được mở rộng:**
- Thêm field `organizationId` (optional)
- Thêm các relations mới (optional)
### 4. API Endpoints Mới
#### Identity Management
- `/api/v1/identity/users/*` - User lifecycle management
- `/api/v1/identity/users/:id/profile` - Profile management
- `/api/v1/identity/verification/*` - Identity verification
- `/api/v1/identity/organizations/*` - Organization management
- `/api/v1/identity/groups/*` - Group management
#### Access Management
- `/api/v1/access/requests/*` - Access requests
- `/api/v1/access/reviews/*` - Access reviews
- `/api/v1/access/analytics/*` - Access analytics
#### Governance
- `/api/v1/governance/compliance/*` - Compliance reports
- `/api/v1/governance/policies/*` - Policy governance
- `/api/v1/governance/risk/*` - Risk management
- `/api/v1/governance/reports/*` - Reporting dashboard
### 5. Environment Variables
Một số biến môi trường mới có thể được thêm trong tương lai cho các tính năng IAM nâng cao (email service, SMS service, file storage), nhưng không ảnh hưởng đến các biến hiện tại.
### 6. Deployment Configuration
**Docker Compose:**
- Service name: `auth-service``iam-service`
- Container name: `auth-service-local``iam-service-local`
**Kubernetes:**
- Deployment name: `auth-service``iam-service`
- Service name: `auth-service``iam-service`
- ConfigMap: `auth-service-config``iam-service-config`
- Secrets: `auth-service-secrets``iam-service-secrets`
## Migration Steps
### Step 1: Backup (Quan Trọng!)
```bash
# Backup database
pg_dump $DATABASE_URL > auth-service-backup.sql
# Backup code (nếu cần rollback)
cp -r services/auth-service services/auth-service.backup
```
### Step 2: Update Codebase
1. **Update package references:**
```bash
# Tìm và thay thế trong code
find . -type f -name "*.ts" -o -name "*.js" -o -name "*.json" | xargs sed -i '' 's/@goodgo\/auth-service/@goodgo\/iam-service/g'
```
2. **Update environment variables:**
- Update `SERVICE_NAME=iam-service` trong tất cả env files
- Update Docker Compose và Kubernetes configs
3. **Run Prisma migration:**
```bash
cd services/iam-service
pnpm prisma generate
pnpm prisma migrate dev --name add_iam_models
```
### Step 3: Deployment
#### Option A: Blue-Green Deployment (Khuyến Nghị)
1. **Deploy iam-service mới:**
```bash
kubectl apply -f deployments/staging/kubernetes/iam-service.yaml
```
2. **Verify iam-service hoạt động tốt**
3. **Switch traffic:**
- Update Ingress để point đến `iam-service`
- Hoặc dùng weighted routing để gradually migrate
4. **Monitor và verify**
5. **Decommission auth-service cũ sau khi verify**
#### Option B: In-Place Migration
1. **Deploy cả `auth-service` và `iam-service` cùng lúc**
2. **Gradually route traffic từ auth-service sang iam-service**
3. **Monitor performance và errors**
4. **Sau khi verify mọi thứ hoạt động tốt, có thể deprecate `auth-service`**
### Step 4: Rollback (Nếu Cần)
```bash
# Restore database
psql $DATABASE_URL < auth-service-backup.sql
# Switch back to auth-service in docker-compose
# hoặc
kubectl rollout undo deployment/auth-service
```
## Verification Checklist
- [ ] All existing endpoints still work
- [ ] Database migration successful
- [ ] New IAM endpoints working
- [ ] No breaking changes in responses
- [ ] Performance metrics acceptable
- [ ] Error rates normal
- [ ] All clients can connect successfully
## Troubleshooting
### Database Migration Issues
```bash
# Check migration status
pnpm prisma migrate status
# Reset migration (DEV ONLY!)
pnpm prisma migrate reset
```
### Service Connection Issues
```bash
# Check service health
curl http://localhost:5001/health
# Check logs
docker logs iam-service-local
# hoặc
kubectl logs deployment/iam-service
```
## Support
Nếu gặp vấn đề trong quá trình migration, vui lòng:
1. Check logs và error messages
2. Review migration guide này
3. Contact team lead hoặc DevOps team
---
**Last Updated**: 2024-12-30

View File

@@ -38,7 +38,7 @@ docker-compose logs -f
### Backend Services
- **auth-service** (Port 5001): Xác thực và quản lý người dùng
- **iam-service** (Port 5001): Xác thực và quản lý người dùng
- Routes: `/api/v1/auth`, `/api/v1/users`
- Health: http://localhost/api/v1/auth/health
@@ -84,7 +84,7 @@ CORS_ORIGIN=http://localhost:3000,http://localhost:3001
docker-compose up -d
# Khởi động service cụ thể
docker-compose up -d auth-service
docker-compose up -d iam-service
# Dừng tất cả services
docker-compose down
@@ -96,19 +96,19 @@ docker-compose down -v
docker-compose logs -f
# Xem logs (service cụ thể)
docker-compose logs -f auth-service
docker-compose logs -f iam-service
# Restart service
docker-compose restart auth-service
docker-compose restart iam-service
# Rebuild service
docker-compose up -d --build auth-service
docker-compose up -d --build iam-service
# Kiểm tra trạng thái service
docker-compose ps
# Thực thi lệnh trong container
docker-compose exec auth-service sh
docker-compose exec iam-service sh
```
## Thêm Service Mới
@@ -196,7 +196,7 @@ docker-compose up -d service-name
cat .env.local | grep DATABASE_URL
# Test connection từ service
docker-compose exec auth-service sh
docker-compose exec iam-service sh
```
### Vấn Đề Kết Nối Redis
@@ -240,7 +240,7 @@ docker-compose logs traefik
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
auth-service │ │ web-admin │ │ web-client │
iam-service │ │ web-admin │ │ web-client │
│ :5001 │ │ :3000 │ │ :3001 │
└──────┬───────┘ └──────────────┘ └──────────────┘

View File

@@ -75,18 +75,18 @@ Mỗi service cần file `.env.local` riêng cho DATABASE_URL và configs cụ t
```bash
# Ví dụ: Auth Service
cp services/auth-service/env.local.example services/auth-service/.env.local
cp services/iam-service/env.local.example services/iam-service/.env.local
```
Chỉnh sửa `services/auth-service/.env.local`:
Chỉnh sửa `services/iam-service/.env.local`:
```bash
# Database riêng cho auth-service
# Database riêng cho iam-service
DATABASE_URL=postgresql://user:password@ep-xxx.region.neon.tech/goodgo_auth_dev?sslmode=require&pgbouncer=true
# Service configs
PORT=5001
SERVICE_NAME=auth-service
SERVICE_NAME=iam-service
# Redis override (native dev - Redis in Docker)
REDIS_HOST=localhost
@@ -100,13 +100,13 @@ REDIS_HOST=localhost
### 4. Chạy Database Migrations
```bash
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
```
### 5. Seed Database (Tùy chọn)
```bash
./scripts/db/seed.sh auth-service
./scripts/db/seed.sh iam-service
```
## Các Cách Chạy Dự Án
@@ -143,10 +143,10 @@ Cách này phù hợp khi bạn chỉ làm việc với 1 service:
```bash
# Sử dụng script
./scripts/dev/start-service.sh auth-service
./scripts/dev/start-service.sh iam-service
# Hoặc chạy trực tiếp
cd services/auth-service
cd services/iam-service
pnpm dev
```
@@ -169,7 +169,7 @@ docker-compose up -d redis traefik
cd ../..
# Bước 2: Chạy service đang dev với native (hot reload nhanh)
pnpm --filter @goodgo/auth-service dev
pnpm --filter @goodgo/iam-service dev
# Bước 3: (Tùy chọn) Chạy services khác trong Docker nếu cần
docker-compose -f deployments/local/docker-compose.yml up -d user-service payment-service
@@ -178,17 +178,17 @@ docker-compose -f deployments/local/docker-compose.yml up -d user-service paymen
**Ví dụ workflow thực tế:**
```bash
# Scenario 1: Chỉ dev auth-service
# Scenario 1: Chỉ dev iam-service
cd deployments/local && docker-compose up -d redis traefik && cd ../..
pnpm --filter @goodgo/auth-service dev
pnpm --filter @goodgo/iam-service dev
# Scenario 2: Dev auth-service + cần web-admin để test
# Scenario 2: Dev iam-service + cần web-admin để test
cd deployments/local && docker-compose up -d redis traefik && cd ../..
pnpm --filter @goodgo/auth-service dev &
pnpm --filter @goodgo/iam-service dev &
pnpm --filter @goodgo/web-admin dev
# Scenario 3: Dev frontend, backend chạy Docker
cd deployments/local && docker-compose up -d redis traefik auth-service && cd ../..
cd deployments/local && docker-compose up -d redis traefik iam-service && cd ../..
pnpm --filter @goodgo/web-admin dev
```
@@ -208,7 +208,7 @@ pnpm --filter "./services/*" dev
pnpm --filter "./apps/*" dev
# Chạy service cụ thể với dependencies
pnpm --filter @goodgo/auth-service... dev
pnpm --filter @goodgo/iam-service... dev
```
### Cách 5: Chạy Với Docker Compose (Full Stack)
@@ -262,7 +262,7 @@ Khi các services đang chạy, bạn có thể truy cập:
Backend services sử dụng `tsx watch` hoặc `nodemon` để tự động restart khi code thay đổi:
```bash
# Trong services/auth-service/package.json
# Trong services/iam-service/package.json
"scripts": {
"dev": "tsx watch src/index.ts"
}
@@ -313,19 +313,19 @@ pnpm --filter @goodgo/logger dev
**Terminal 2: Watch Tests**
```bash
# Auto-run tests khi code thay đổi
pnpm --filter @goodgo/auth-service test --watch
pnpm --filter @goodgo/iam-service test --watch
```
**Terminal 3: Development Tasks**
```bash
# Prisma Studio
pnpm --filter @goodgo/auth-service prisma studio
pnpm --filter @goodgo/iam-service prisma studio
# Xem logs
./scripts/dev/logs.sh auth-service
./scripts/dev/logs.sh iam-service
# Migrations
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
```
#### Option B: Hybrid Development (Selective Services)
@@ -336,7 +336,7 @@ pnpm --filter @goodgo/auth-service prisma studio
cd deployments/local && docker-compose up -d redis traefik && cd ../..
# Dev service cụ thể với hot reload
pnpm --filter @goodgo/auth-service dev
pnpm --filter @goodgo/iam-service dev
```
**Terminal 2: Frontend (nếu cần)**
@@ -347,7 +347,7 @@ pnpm --filter @goodgo/web-admin dev
**Terminal 3: Tools & Logs**
```bash
# Watch tests
pnpm --filter @goodgo/auth-service test --watch
pnpm --filter @goodgo/iam-service test --watch
# Xem Docker logs
docker logs -f redis-cache-local
@@ -363,20 +363,20 @@ pnpm format
```bash
# Terminal 1
cd deployments/local && docker-compose up -d redis traefik && cd ../..
pnpm --filter @goodgo/auth-service dev
pnpm --filter @goodgo/iam-service dev
# Terminal 2
pnpm --filter @goodgo/auth-service test --watch
pnpm --filter @goodgo/iam-service test --watch
# Terminal 3
pnpm --filter @goodgo/auth-service prisma studio
pnpm --filter @goodgo/iam-service prisma studio
```
#### Use Case 2: Dev Frontend + Backend
```bash
# Terminal 1: Backend
pnpm --filter @goodgo/auth-service dev
pnpm --filter @goodgo/iam-service dev
# Terminal 2: Frontend
pnpm --filter @goodgo/web-admin dev
@@ -427,7 +427,7 @@ Truy cập http://localhost:8080 để xem:
```bash
# 1. Chỉnh sửa prisma/schema.prisma
# 2. Tạo và áp dụng migration
cd services/auth-service
cd services/iam-service
pnpm prisma migrate dev --name add_new_field
# 3. Prisma Client sẽ tự động regenerate
@@ -436,7 +436,7 @@ pnpm prisma migrate dev --name add_new_field
### Reset Database (Development Only!)
```bash
cd services/auth-service
cd services/iam-service
pnpm prisma migrate reset
```
@@ -444,7 +444,7 @@ pnpm prisma migrate reset
```bash
# Mở Prisma Studio
cd services/auth-service
cd services/iam-service
pnpm prisma studio
# Truy cập: http://localhost:5555
```
@@ -464,7 +464,7 @@ Tạo file `.vscode/launch.json`:
"type": "node",
"request": "launch",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["--filter", "@goodgo/auth-service", "dev"],
"runtimeArgs": ["--filter", "@goodgo/iam-service", "dev"],
"skipFiles": ["<node_internals>/**"],
"console": "integratedTerminal"
}
@@ -476,10 +476,10 @@ Tạo file `.vscode/launch.json`:
```bash
# Service logs
./scripts/dev/logs.sh auth-service
./scripts/dev/logs.sh iam-service
# Docker logs
docker logs -f auth-service-local
docker logs -f iam-service-local
docker logs -f redis-cache-local
docker logs -f traefik-local
@@ -519,16 +519,16 @@ docker-compose -f deployments/local/docker-compose.yml restart
```bash
# Kiểm tra DATABASE_URL trong service-specific env
cat services/auth-service/.env.local | grep DATABASE_URL
cat services/iam-service/.env.local | grep DATABASE_URL
# Nếu chưa có file .env.local, tạo từ example
cp services/auth-service/env.local.example services/auth-service/.env.local
cp services/iam-service/env.local.example services/iam-service/.env.local
# Chỉnh sửa DATABASE_URL với connection string từ Neon
# DATABASE_URL=postgresql://user:pass@ep-xxx.neon.tech/goodgo_auth_dev?sslmode=require&pgbouncer=true
# Test connection
cd services/auth-service
cd services/iam-service
pnpm prisma db pull
```
@@ -557,7 +557,7 @@ pnpm install
pnpm dev
# Hoặc restart Docker container
docker-compose -f deployments/local/docker-compose.yml restart auth-service
docker-compose -f deployments/local/docker-compose.yml restart iam-service
```
## Tips & Best Practices
@@ -579,18 +579,18 @@ pnpm dev
Không cần chạy tất cả nếu chỉ làm 1 service:
```bash
# Chỉ chạy auth-service
pnpm --filter @goodgo/auth-service dev
# Chỉ chạy iam-service
pnpm --filter @goodgo/iam-service dev
# Chạy auth-service và dependencies
pnpm --filter @goodgo/auth-service... dev
# Chạy iam-service và dependencies
pnpm --filter @goodgo/iam-service... dev
```
### 3. Watch Tests
```bash
# Chạy tests tự động khi code thay đổi
pnpm --filter @goodgo/auth-service test --watch
pnpm --filter @goodgo/iam-service test --watch
```
### 4. Format Code Tự Động
@@ -613,7 +613,7 @@ Kết hợp Docker và Native để tối ưu workflow:
cd deployments/local && docker-compose up -d redis traefik
# Service đang dev chạy native (hot reload nhanh)
pnpm --filter @goodgo/auth-service dev
pnpm --filter @goodgo/iam-service dev
# Services khác có thể chạy Docker nếu cần
docker-compose up -d user-service payment-service
@@ -629,7 +629,7 @@ docker-compose up -d user-service payment-service
```bash
# Chạy selective services với pnpm workspace
pnpm --filter "@goodgo/auth-service" --filter "@goodgo/user-service" dev
pnpm --filter "@goodgo/iam-service" --filter "@goodgo/user-service" dev
# Hoặc dùng pattern
pnpm --filter "./services/{auth,user}-service" dev
@@ -673,14 +673,14 @@ cp deployments/local/env.local.example deployments/local/.env.local
Configs riêng cho từng service:
```bash
# services/auth-service/.env.local
# services/iam-service/.env.local
# Database riêng cho service này
DATABASE_URL=postgresql://user:pass@ep-xxx.neon.tech/goodgo_auth_dev?sslmode=require&pgbouncer=true
# Service configs
PORT=5001
SERVICE_NAME=auth-service
SERVICE_NAME=iam-service
API_VERSION=v1
# Redis override (native dev - Redis in Docker)
@@ -693,7 +693,7 @@ PROMETHEUS_PORT=9090
**Tạo file:**
```bash
cp services/auth-service/env.local.example services/auth-service/.env.local
cp services/iam-service/env.local.example services/iam-service/.env.local
```
### Cách Hoạt Động
@@ -737,9 +737,9 @@ pnpm clean # Xóa build artifacts
./scripts/utils/cleanup.sh # Cleanup toàn bộ
# Database
./scripts/db/migrate.sh auth-service dev # Migration
./scripts/db/seed.sh auth-service # Seed data
./scripts/db/backup.sh auth-service # Backup
./scripts/db/migrate.sh iam-service dev # Migration
./scripts/db/seed.sh iam-service # Seed data
./scripts/db/backup.sh iam-service # Backup
# Docker
docker-compose -f deployments/local/docker-compose.yml up -d # Start

View File

@@ -44,7 +44,7 @@ DATABASE_URL=postgresql://user:pass@ep-xxx.region.neon.tech/dbname?sslmode=requi
### 5. Chạy Migrations
```bash
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
```
## Định Dạng Connection String
@@ -73,7 +73,7 @@ Lưu trong GitHub Secrets: `NEON_DATABASE_URL_STAGING`
Hoặc trong Kubernetes:
```bash
kubectl create secret generic auth-service-secrets \
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://...' \
-n staging
```
@@ -84,7 +84,7 @@ Lưu trong GitHub Secrets: `NEON_DATABASE_URL_PRODUCTION`
Hoặc trong Kubernetes:
```bash
kubectl create secret generic auth-service-secrets \
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://...' \
-n production
```
@@ -95,7 +95,7 @@ kubectl create secret generic auth-service-secrets \
```bash
# Tạo migration mới
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
# Điều này sẽ:
# 1. Tạo migration file
@@ -111,7 +111,7 @@ Migrations chạy tự động trong CI/CD:
Migration thủ công:
```bash
./scripts/db/migrate.sh auth-service deploy
./scripts/db/migrate.sh iam-service deploy
```
## Backup & Restore
@@ -126,7 +126,7 @@ Neon cung cấp backup tự động. Truy cập qua Neon Console:
### Backup Thủ Công
```bash
./scripts/db/backup.sh auth-service
./scripts/db/backup.sh iam-service
```
Điều này tạo file SQL dump trong thư mục `backups/`.

View File

@@ -66,13 +66,13 @@ Trong giao diện **Explore** với **Loki** đã chọn:
1. Nhấn nút **Label browser**.
2. Chọn một label, ví dụ: `container`.
3. Chọn tên container cụ thể (ví dụ: `auth-service` hoặc `traefik`).
3. Chọn tên container cụ thể (ví dụ: `iam-service` hoặc `traefik`).
4. Nhấn **Show logs**.
Bạn cũng có thể viết truy vấn LogQL thủ công, ví dụ:
```logql
{container="auth-service"}
{container="iam-service"}
```
### Xem Metrics (Prometheus)

View File

@@ -27,7 +27,7 @@
**Giải pháp**:
```bash
cd services/auth-service
cd services/iam-service
pnpm prisma generate
```

View File

@@ -51,13 +51,13 @@ Chào mừng đến với team GoodGo Microservices Platform!
./scripts/dev/start-all.sh
# Khởi động service cụ thể
./scripts/dev/start-service.sh auth-service
./scripts/dev/start-service.sh iam-service
# Xem logs
./scripts/dev/logs.sh auth-service
./scripts/dev/logs.sh iam-service
# Chạy migrations
./scripts/db/migrate.sh auth-service dev
./scripts/db/migrate.sh iam-service dev
# Chạy tests
pnpm test

View File

@@ -13,17 +13,17 @@
1. **Xác định phiên bản hiện tại**
```bash
kubectl get deployment auth-service -n production -o jsonpath='{.spec.template.spec.containers[0].image}'
kubectl get deployment iam-service -n production -o jsonpath='{.spec.template.spec.containers[0].image}'
```
2. **Rollback về phiên bản trước**
```bash
kubectl rollout undo deployment/auth-service -n production
kubectl rollout undo deployment/iam-service -n production
```
3. **Xác minh rollback**
```bash
kubectl rollout status deployment/auth-service -n production
kubectl rollout status deployment/iam-service -n production
```
4. **Kiểm tra health của service**
@@ -37,7 +37,7 @@
1. Tạo migration đảo ngược:
```bash
cd services/auth-service
cd services/iam-service
pnpm prisma migrate dev --name rollback_previous_change
```

129
docs/vi/skills/README.md Normal file
View File

@@ -0,0 +1,129 @@
# Tài Liệu Cursor Skills
> **EN**: Comprehensive documentation for all Cursor AI skills used in the GoodGo Microservices Platform
> **VI**: Tài liệu đầy đủ cho tất cả Cursor AI skills được sử dụng trong GoodGo Microservices Platform
## Overview / Tổng Quan
**EN**: Cursor Skills are specialized knowledge modules that guide AI assistants in following project-specific patterns, standards, and best practices. This directory contains detailed documentation for each skill, including when to use them, key concepts, common patterns, and real-world examples from the codebase.
**VI**: Cursor Skills là các module kiến thức chuyên biệt hướng dẫn AI assistants tuân theo các patterns, tiêu chuẩn và best practices cụ thể của dự án. Thư mục này chứa tài liệu chi tiết cho từng skill, bao gồm khi nào sử dụng, khái niệm chính, các pattern thường dùng, và ví dụ thực tế từ codebase.
## Available Skills / Các Skills Có Sẵn
GoodGo platform bao gồm **9 Cursor Skills** được tổ chức theo danh mục:
### API & Data Layer
#### [API Design](./api-design.md)
**EN**: RESTful API design standards for GoodGo microservices. Use when creating new API endpoints, designing DTOs, implementing controllers, writing OpenAPI documentation, or standardizing API responses.
**VI**: Tiêu chuẩn thiết kế RESTful API cho GoodGo microservices. Sử dụng khi tạo API endpoints mới, thiết kế DTOs, implement controllers, viết OpenAPI documentation, hoặc chuẩn hóa API responses.
#### [Database & Prisma](./database-prisma.md)
**EN**: Prisma ORM and database patterns for GoodGo microservices. Use when working with databases, creating Prisma schemas, writing migrations, implementing repositories, or optimizing queries.
**VI**: Prisma ORM và database patterns cho GoodGo microservices. Sử dụng khi làm việc với databases, tạo Prisma schemas, viết migrations, implement repositories, hoặc optimize queries.
### Code Quality & Testing
#### [Testing Patterns](./testing-patterns.md)
**EN**: Testing best practices for GoodGo microservices. Use when writing unit tests, integration tests, E2E tests, setting up Jest, mocking dependencies, or debugging test failures.
**VI**: Best practices về testing cho GoodGo microservices. Sử dụng khi viết unit tests, integration tests, E2E tests, setup Jest, mocking dependencies, hoặc debug test failures.
#### [Code Comments](./comment-code.md)
**EN**: Add bilingual code comments in Vietnamese and English for better documentation. Use when adding comments to code, documenting functions/classes, or when user requests Vietnamese/English documentation.
**VI**: Thêm code comments song ngữ bằng tiếng Việt và tiếng Anh để tài liệu tốt hơn. Sử dụng khi thêm comments vào code, document functions/classes, hoặc khi user yêu cầu tài liệu tiếng Việt/Anh.
### Infrastructure & Operations
#### [Kubernetes Deployment](./deployment-kubernetes.md)
**EN**: Kubernetes deployment patterns for GoodGo microservices. Use when deploying to staging/production, creating K8s manifests, configuring HPA, setting up ingress, or troubleshooting K8s deployments.
**VI**: Kubernetes deployment patterns cho GoodGo microservices. Sử dụng khi deploy lên staging/production, tạo K8s manifests, config HPA, setup ingress, hoặc troubleshoot K8s deployments.
#### [Observability & Monitoring](./observability-monitoring.md)
**EN**: Observability and monitoring patterns for GoodGo microservices. Use when adding metrics, implementing logging, setting up tracing, creating health checks, or debugging production issues.
**VI**: Observability và monitoring patterns cho GoodGo microservices. Sử dụng khi thêm metrics, implement logging, setup tracing, tạo health checks, hoặc debug production issues.
### Standards & Security
#### [Project Rules](./project-rules.md)
**EN**: GoodGo Microservices Platform coding standards and architecture patterns. Use when working with services, apps, packages, or infrastructure.
**VI**: Tiêu chuẩn coding và architecture patterns của GoodGo Microservices Platform. Sử dụng khi làm việc với services, apps, packages, hoặc infrastructure.
#### [Security](./security.md)
**EN**: Security best practices and patterns for GoodGo microservices platform. Use when implementing authentication, authorization, data protection, input validation, rate limiting, secrets management, or security testing across all services.
**VI**: Security best practices và patterns cho GoodGo microservices platform. Sử dụng khi implement authentication, authorization, data protection, input validation, rate limiting, secrets management, hoặc security testing trên tất cả services.
#### [Documentation](./documentation.md)
**EN**: Guidelines for writing technical documentation in the GoodGo project. Use when creating or updating README files, guides, architecture docs, or API documentation. Ensures bilingual (EN/VI) consistency and proper structure.
**VI**: Hướng dẫn viết technical documentation trong dự án GoodGo. Sử dụng khi tạo hoặc cập nhật README files, guides, architecture docs, hoặc API documentation. Đảm bảo tính nhất quán song ngữ (EN/VI) và cấu trúc phù hợp.
## Quick Reference / Tham Khảo Nhanh
### By Use Case / Theo Use Case
| Tác Vụ | Skills Đề Xuất |
|--------|----------------|
| Tạo API endpoint mới | API Design, Security, Testing Patterns |
| Setup service mới | Project Rules, Database & Prisma, Observability |
| Viết tests | Testing Patterns, Comment Code |
| Deploy lên production | Kubernetes Deployment, Observability, Security |
| Debug production issues | Observability & Monitoring, Security |
| Viết documentation | Documentation, Comment Code |
| Implement authentication | Security, API Design, Database & Prisma |
| Optimize database queries | Database & Prisma, Observability |
### Skill Dependencies / Phụ Thuộc Giữa Các Skills
```
Project Rules (Foundation)
├── API Design
├── Database & Prisma
├── Security
└── Testing Patterns
└── Comment Code
Documentation (Cross-cutting)
└── All skills
Observability (Cross-cutting)
└── All services
Kubernetes Deployment (Infrastructure)
└── All services
```
## How to Use Skills / Cách Sử Dụng Skills
1. **Khi bắt đầu task mới**: Xem lại các skills liên quan trong thư mục này
2. **Trong quá trình development**: Tham khảo skill documentation để xem patterns và examples
3. **Khi gặp khó khăn**: Kiểm tra skill docs để xem best practices và solutions thường dùng
4. **Khi code review**: Sử dụng skills như checklist để đảm bảo tuân thủ standards
## Related Documentation / Tài Liệu Liên Quan
- [Tổng Quan Kiến Trúc](../architecture/system-design.md) - System design patterns
- [Hướng Dẫn Development](../guides/development.md) - Development workflow
- [Hướng Dẫn Deployment](../guides/deployment.md) - Deployment procedures
- [Tài Liệu API](../api/openapi/) - OpenAPI specifications
## Contributing / Đóng Góp
Khi cập nhật hoặc thêm skills mới:
1. Cập nhật skill source file trong `.cursor/skills/{skill-name}/SKILL.md`
2. Cập nhật documentation tương ứng trong `docs/en/skills/{skill-name}.md`
3. Cập nhật bản dịch tiếng Việt trong `docs/vi/skills/{skill-name}.md`
4. Cập nhật file index này với mọi thay đổi
5. Đảm bảo tính nhất quán song ngữ
## Resources / Tài Nguyên
- [Cursor Skills Documentation](https://cursor.sh/docs) - Tài liệu chính thức của Cursor
- [Cursor AI](https://cursor.sh) - Trang chủ Cursor IDE
- Project Skills: `.cursor/skills/` - Source skill files

View File

@@ -0,0 +1,455 @@
# RESTful API Design / Thiết Kế API RESTful
> **EN**: RESTful API design standards for GoodGo microservices. Use when creating new API endpoints, designing DTOs, implementing controllers, writing OpenAPI documentation, or standardizing API responses.
> **VI**: Tiêu chuẩn thiết kế API RESTful cho các microservices của GoodGo. Sử dụng khi tạo endpoint API mới, thiết kế DTOs, triển khai controllers, viết tài liệu OpenAPI, hoặc chuẩn hóa response API.
## Overview / Tổng Quan
**EN**: This skill covers the RESTful API design patterns and standards used across all GoodGo microservices. It ensures consistency, predictability, and maintainability of APIs through standardized URL structures, HTTP methods, response formats, error handling, and DTO validation.
**VI**: Skill này bao gồm các pattern và tiêu chuẩn thiết kế API RESTful được sử dụng trong tất cả các microservices của GoodGo. Nó đảm bảo tính nhất quán, dự đoán được và dễ bảo trì của APIs thông qua cấu trúc URL chuẩn hóa, HTTP methods, định dạng response, xử lý lỗi và validation DTO.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Creating new API endpoints
- Designing request/response DTOs
- Implementing controllers and routes
- Writing OpenAPI/Swagger documentation
- Standardizing error responses
- Implementing pagination, filtering, and sorting
- Setting up API versioning
- Designing resource relationships
**VI**: Sử dụng skill này khi:
- Tạo endpoint API mới
- Thiết kế DTOs cho request/response
- Triển khai controllers và routes
- Viết tài liệu OpenAPI/Swagger
- Chuẩn hóa error responses
- Triển khai pagination, filtering và sorting
- Thiết lập API versioning
- Thiết kế quan hệ giữa các resources
## Key Concepts / Khái Niệm Chính
### 1. URL Structure / Cấu Trúc URL
**EN**: URLs follow a hierarchical resource-based structure with versioning.
**VI**: URLs tuân theo cấu trúc phân cấp dựa trên resource với versioning.
```
https://api.goodgo.com/v1/{resource}/{id}/{sub-resource}
Examples:
GET /v1/users # List users / Liệt kê users
POST /v1/users # Create user / Tạo user
GET /v1/users/123 # Get user by ID / Lấy user theo ID
PUT /v1/users/123 # Update user / Cập nhật user
DELETE /v1/users/123 # Delete user / Xóa user
GET /v1/users/123/orders # Get user's orders / Lấy orders của user
POST /v1/users/123/orders # Create order for user / Tạo order cho user
```
### 2. HTTP Methods / Phương Thức HTTP
- **GET**: Retrieve resource(s) - Safe, Idempotent / Lấy resource(s) - An toàn, Idempotent
- **POST**: Create new resource - Not idempotent / Tạo resource mới - Không idempotent
- **PUT**: Full update - Idempotent / Cập nhật toàn bộ - Idempotent
- **PATCH**: Partial update - Idempotent / Cập nhật một phần - Idempotent
- **DELETE**: Remove resource - Idempotent / Xóa resource - Idempotent
### 3. Standard Response Format / Định Dạng Response Chuẩn
**EN**: All API responses follow a consistent structure with `success`, `data`, and optional `metadata` fields.
**VI**: Tất cả API responses tuân theo cấu trúc nhất quán với các trường `success`, `data`, và `metadata` tùy chọn.
## Common Patterns / Các Pattern Thường Dùng
### Success Response Pattern / Pattern Response Thành Công
```typescript
interface SuccessResponse<T> {
success: true;
data: T;
message?: string;
timestamp?: string;
pagination?: {
total: number;
skip: number;
take: number;
};
}
```
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/identity/user/user.controller.ts
res.json({
success: true,
data: {
users: result.users,
pagination: {
total: result.total,
skip: filters.skip,
take: filters.take,
},
},
});
```
### Error Response Pattern / Pattern Response Lỗi
```typescript
interface ErrorResponse {
success: false;
error: {
code: string;
message: string;
details?: any;
field?: string;
};
timestamp?: string;
}
```
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/identity/user/user.controller.ts
if (error instanceof z.ZodError) {
res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid filters',
details: error.errors,
},
});
return;
}
```
### HTTP Status Codes / Mã Trạng Thái HTTP
```typescript
// Success codes / Mã thành công
200 OK // GET, PUT, PATCH success
201 Created // POST success with resource creation
204 No Content // DELETE success
// Client errors / Lỗi client
400 Bad Request // Invalid request data / Dữ liệu request không hợp lệ
401 Unauthorized // Missing/invalid authentication / Thiếu/sai xác thực
403 Forbidden // Valid auth but no permission / Xác thực hợp lệ nhưng không có quyền
404 Not Found // Resource doesn't exist / Resource không tồn tại
409 Conflict // Resource conflict (duplicate) / Xung đột resource (trùng lặp)
422 Unprocessable // Validation errors / Lỗi validation
// Server errors / Lỗi server
500 Internal Error // Unexpected server error / Lỗi server không mong đợi
502 Bad Gateway // External service error / Lỗi dịch vụ bên ngoài
503 Service Unavailable // Service temporarily down / Dịch vụ tạm thời không khả dụng
```
### DTOs with Zod Validation / DTOs với Zod Validation
**EN**: DTOs use Zod for runtime validation with bilingual error messages.
**VI**: DTOs sử dụng Zod cho validation runtime với thông báo lỗi song ngữ.
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/identity/identity.dto.ts
import { z } from 'zod';
export const CreateOrganizationDto = z.object({
name: z.string().min(1, 'Organization name is required / Tên tổ chức là bắt buộc').max(255),
domain: z.string().email().optional().or(z.string().min(1).max(255).optional()),
parentId: z.string().optional(),
settings: z.record(z.any()).optional(),
});
export type CreateOrganizationDto = z.infer<typeof CreateOrganizationDto>;
export const UserFiltersDto = z.object({
organizationId: z.string().optional(),
isActive: z.boolean().optional(),
emailVerified: z.boolean().optional(),
search: z.string().optional(),
skip: z.number().int().min(0).default(0),
take: z.number().int().min(1).max(100).default(20),
});
```
### Controller Implementation Pattern / Pattern Triển Khai Controller
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/identity/user/user.controller.ts
export class UserManagementController {
/**
* EN: List users
* VI: Liệt kê users
*/
async list(req: Request, res: Response): Promise<void> {
try {
const filters = UserFiltersDto.parse({
organizationId: req.query.organizationId as string,
isActive: req.query.isActive === 'true' ? true : req.query.isActive === 'false' ? false : undefined,
emailVerified: req.query.emailVerified === 'true' ? true : req.query.emailVerified === 'false' ? false : undefined,
search: req.query.search as string,
skip: parseInt(req.query.skip as string) || 0,
take: parseInt(req.query.take as string) || 20,
});
const result = await userManagementService.searchUsers(filters);
res.json({
success: true,
data: {
users: result.users,
pagination: {
total: result.total,
skip: filters.skip,
take: filters.take,
},
},
});
} catch (error: any) {
if (error instanceof z.ZodError) {
res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid filters',
details: error.errors,
},
});
return;
}
res.status(500).json({
success: false,
error: {
code: 'LIST_USERS_FAILED',
message: error.message || 'Failed to list users',
},
});
}
}
/**
* EN: Get user by ID
* VI: Lấy user theo ID
*/
async get(req: Request, res: Response): Promise<void> {
try {
const { id } = req.params;
const user = await userManagementService.getUser(id);
res.json({
success: true,
data: user,
});
} catch (error: any) {
if (error instanceof NotFoundError) {
res.status(404).json(error.toApiResponse());
return;
}
res.status(500).json({
success: false,
error: {
code: 'GET_USER_FAILED',
message: error.message || 'Failed to get user',
},
});
}
}
}
```
### Error Handling with Custom Error Classes / Xử Lý Lỗi với Custom Error Classes
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/errors/http-error.ts
export class HttpError extends Error {
public readonly statusCode: number;
public readonly errorCode: string;
public readonly isOperational: boolean;
public readonly details?: any;
constructor(
message: string,
statusCode: number = 500,
errorCode: string = 'INTERNAL_ERROR',
isOperational: boolean = true,
details?: any
) {
super(message);
this.name = this.constructor.name;
this.statusCode = statusCode;
this.errorCode = errorCode;
this.isOperational = isOperational;
this.details = details;
Error.captureStackTrace(this, this.constructor);
}
toApiResponse() {
return {
success: false,
error: {
code: this.errorCode,
message: this.message,
...(this.details && { details: this.details }),
},
timestamp: new Date().toISOString(),
};
}
}
export class NotFoundError extends HttpError {
constructor(resource: string = 'Resource / Tài nguyên', details?: any) {
super(`${resource} not found / ${resource} không tìm thấy`, 404, 'NOT_FOUND', true, details);
}
}
export class ValidationError extends HttpError {
constructor(message: string = 'Validation failed / Validation thất bại', details?: any) {
super(message, 422, 'VALIDATION_ERROR', true, details);
}
}
```
## Best Practices / Thực Hành Tốt Nhất
### 1. Resource Naming / Đặt Tên Resource
- ✅ Use plural nouns (`/users` not `/user`) / Sử dụng danh từ số nhiều
- ✅ Use kebab-case for multi-word resources (`/user-profiles`) / Sử dụng kebab-case cho resource nhiều từ
- ✅ Keep URLs as short as possible / Giữ URLs ngắn gọn nhất có thể
- ❌ Avoid verbs in URLs (use HTTP methods instead) / Tránh động từ trong URLs (dùng HTTP methods thay thế)
### 2. Versioning / Phiên Bản Hóa
- ✅ Include version in URL (`/v1/users`) / Bao gồm version trong URL
- ✅ Maintain backward compatibility / Duy trì tương thích ngược
- ✅ Deprecate old versions gracefully with warnings / Ngừng hỗ trợ các version cũ một cách lịch sự với cảnh báo
### 3. Security / Bảo Mật
- ✅ Always use HTTPS / Luôn sử dụng HTTPS
- ✅ Implement rate limiting / Triển khai rate limiting
- ✅ Validate all inputs with DTOs / Validate tất cả inputs với DTOs
- ✅ Use proper authentication/authorization middleware / Sử dụng middleware xác thực/ủy quyền phù hợp
- ✅ Never expose sensitive data in responses / Không bao giờ expose dữ liệu nhạy cảm trong responses
### 4. Performance / Hiệu Năng
- ✅ Implement pagination for lists (use `skip` and `take`) / Triển khai pagination cho danh sách
- ✅ Use field filtering when possible (`select` in Prisma) / Sử dụng field filtering khi có thể
- ✅ Cache responses appropriately / Cache responses phù hợp
- ✅ Compress responses (gzip) / Nén responses (gzip)
### 5. Documentation / Tài Liệu
- ✅ Keep OpenAPI spec up to date / Giữ OpenAPI spec cập nhật
- ✅ Include examples in documentation / Bao gồm ví dụ trong tài liệu
- ✅ Document error responses / Tài liệu hóa error responses
- ✅ Version your documentation / Phiên bản hóa tài liệu
### 6. Error Handling / Xử Lý Lỗi
- ✅ Use consistent error response format / Sử dụng định dạng error response nhất quán
- ✅ Provide actionable error messages / Cung cấp thông báo lỗi có thể hành động
- ✅ Include error codes for programmatic handling / Bao gồm error codes cho xử lý lập trình
- ✅ Log errors server-side, don't expose stack traces in production / Log lỗi phía server, không expose stack traces trong production
## Examples from Project / Ví Dụ Từ Dự Án
### Controller Examples / Ví Dụ Controller
- **User Management**: [`services/iam-service/src/modules/identity/user/user.controller.ts`](../../../services/iam-service/src/modules/identity/user/user.controller.ts)
- **Feature Controller**: [`services/iam-service/src/modules/feature/feature.controller.ts`](../../../services/iam-service/src/modules/feature/feature.controller.ts)
- **RBAC Controller**: [`services/iam-service/src/modules/rbac/rbac.controller.ts`](../../../services/iam-service/src/modules/rbac/rbac.controller.ts)
### DTO Examples / Ví Dụ DTO
- **Identity DTOs**: [`services/iam-service/src/modules/identity/identity.dto.ts`](../../../services/iam-service/src/modules/identity/identity.dto.ts)
- **Auth DTOs**: [`services/iam-service/src/modules/auth/auth.dto.ts`](../../../services/iam-service/src/modules/auth/auth.dto.ts)
- **RBAC DTOs**: [`services/iam-service/src/modules/rbac/rbac.dto.ts`](../../../services/iam-service/src/modules/rbac/rbac.dto.ts)
### Error Handling Examples / Ví Dụ Xử Lý Lỗi
- **HTTP Error Classes**: [`services/iam-service/src/errors/http-error.ts`](../../../services/iam-service/src/errors/http-error.ts)
- **Error Middleware**: [`services/iam-service/src/middlewares/error.middleware.ts`](../../../services/iam-service/src/middlewares/error.middleware.ts)
## Quick Reference / Tham Khảo Nhanh
### Response Format Cheat Sheet / Bảng Tra Cứu Định Dạng Response
| Scenario / Tình Huống | Status Code | Response Structure / Cấu Trúc Response |
|----------------------|-------------|----------------------------------------|
| Success (GET) | 200 | `{ success: true, data: {...} }` |
| Success (POST) | 201 | `{ success: true, data: {...} }` |
| Success (DELETE) | 200 | `{ success: true, message: "..." }` |
| Validation Error / Lỗi Validation | 400/422 | `{ success: false, error: { code, message, details } }` |
| Not Found | 404 | `{ success: false, error: { code: "NOT_FOUND", message } }` |
| Unauthorized | 401 | `{ success: false, error: { code: "UNAUTHORIZED", message } }` |
| Forbidden | 403 | `{ success: false, error: { code: "FORBIDDEN", message } }` |
| Server Error / Lỗi Server | 500 | `{ success: false, error: { code: "INTERNAL_ERROR", message } }` |
### Common DTO Patterns / Pattern DTO Thường Dùng
```typescript
// Create DTO / DTO Tạo
const CreateDto = z.object({
requiredField: z.string().min(1),
optionalField: z.string().optional(),
});
// Update DTO (all fields optional) / DTO Cập Nhật (tất cả fields tùy chọn)
const UpdateDto = z.object({
field1: z.string().optional(),
field2: z.number().optional(),
});
// Query/Filter DTO / DTO Query/Filter
const QueryDto = z.object({
page: z.number().int().min(1).default(1),
limit: z.number().int().min(1).max(100).default(20),
search: z.string().optional(),
sortBy: z.string().optional(),
order: z.enum(['asc', 'desc']).default('desc'),
});
```
## Related Skills / Skills Liên Quan
- **[Database Prisma](./database-prisma.md)**: For database operations and repository patterns / Cho các thao tác database và repository patterns
- **[Security](./security.md)**: For authentication, authorization, and security best practices / Cho xác thực, ủy quyền và thực hành bảo mật tốt nhất
- **[Testing Patterns](./testing-patterns.md)**: For testing API endpoints / Cho test API endpoints
- **[Documentation](./documentation.md)**: For writing API documentation / Cho viết tài liệu API
## Resources / Tài Nguyên
### External Documentation / Tài Liệu Bên Ngoài
- [REST API Design Best Practices](https://restfulapi.net/)
- [HTTP Status Codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
- [Zod Documentation](https://zod.dev/)
- [OpenAPI Specification](https://swagger.io/specification/)
### Internal Documentation / Tài Liệu Nội Bộ
- [API Reference](../api/openapi/iam-service.yaml)
- [Service Communication](../architecture/service-communication.md)
- [Project Rules](./project-rules.md)

View File

@@ -0,0 +1,562 @@
# Comment Code / Viết Comment Code
> **EN**: Guidelines for adding comprehensive bilingual code comments (English and Vietnamese) to improve code readability for international and Vietnamese teams.
> **VI**: Hướng dẫn thêm comments song ngữ (tiếng Anh và tiếng Việt) để cải thiện khả năng đọc code cho các đội quốc tế và Việt Nam.
## Overview / Tổng Quan
**EN**: Code comments are essential for maintaining and understanding codebase, especially in a bilingual development environment. This guide provides comprehensive patterns for writing clear, consistent, and helpful comments in both English and Vietnamese across the GoodGo microservices platform. It covers JSDoc documentation, inline comments, special comment types, and best practices for effective code documentation.
**VI**: Comments code là điều cần thiết để bảo trì và hiểu codebase, đặc biệt trong môi trường phát triển song ngữ. Hướng dẫn này cung cấp các patterns toàn diện để viết comments rõ ràng, nhất quán và hữu ích bằng cả tiếng Anh và tiếng Việt trên nền tảng microservices GoodGo. Nó bao gồm tài liệu JSDoc, inline comments, các loại comment đặc biệt, và best practices cho tài liệu code hiệu quả.
## When to Use / Khi Nào Sử Dụng
**EN**: Use bilingual commenting patterns when:
- Adding comments to new code
- Documenting existing code
- Creating JSDoc/TSDoc documentation
- Writing function/class descriptions
- Explaining complex logic or algorithms
- Adding inline comments for clarification
- Documenting API endpoints and interfaces
- Explaining configuration and setup code
- Writing security-critical code documentation
- Creating error handling documentation
**VI**: Sử dụng các patterns comment song ngữ khi:
- Thêm comments vào code mới
- Tài liệu hóa code hiện có
- Tạo tài liệu JSDoc/TSDoc
- Viết mô tả functions/classes
- Giải thích logic hoặc thuật toán phức tạp
- Thêm inline comments để làm rõ
- Tài liệu hóa API endpoints và interfaces
- Giải thích code cấu hình và setup
- Viết tài liệu code bảo mật quan trọng
- Tạo tài liệu xử lý lỗi
## Key Concepts / Khái Niệm Chính
### Comment Format / Định Dạng Comment
All comments in the GoodGo project should be bilingual, with English (EN) followed by Vietnamese (VI) translations.
**Pattern / Mẫu**:
```
// EN: [English explanation]
// VI: [Vietnamese explanation]
```
### Comment Types / Các Loại Comment
1. **Single-line Comments** (`//`) / **Comments Một Dòng**: For brief explanations / Cho giải thích ngắn gọn
2. **Multi-line Comments** (`/* */`) / **Comments Nhiều Dòng**: For longer explanations / Cho giải thích dài hơn
3. **JSDoc Comments** (`/** */`) / **Comments JSDoc**: For function, class, and API documentation / Cho tài liệu function, class và API
4. **Prisma Comments** (`///`) / **Comments Prisma**: For database schema documentation / Cho tài liệu schema database
## Common Patterns / Các Pattern Thường Dùng
### Single-line Comments / Comments Một Dòng
Use single-line comments for brief explanations of code behavior / Sử dụng single-line comments cho giải thích ngắn gọn về hành vi code.
```typescript
// EN: Initialize database connection
// VI: Khởi tạo kết nối database
const db = await createConnection();
// EN: Enable detailed logging in development, minimal in production
// VI: Bật ghi log chi tiết trong development, tối thiểu trong production
const logLevel = process.env.NODE_ENV === 'development' ? 'debug' : 'error';
```
**Real Example / Ví dụ Thực tế**: [`services/iam-service/src/config/database.config.ts`](../../../services/iam-service/src/config/database.config.ts)
### Multi-line Comments / Comments Nhiều Dòng
Use multi-line comments for detailed explanations or step-by-step processes / Sử dụng multi-line comments cho giải thích chi tiết hoặc quy trình từng bước.
```typescript
/**
* EN: Validates user credentials and returns JWT token
* VI: Xác thực thông tin đăng nhập và trả về JWT token
*
* @param email - User email address / Địa chỉ email người dùng
* @param password - User password / Mật khẩu người dùng
* @returns JWT token / Mã JWT token
* @throws AuthenticationError if credentials invalid / Lỗi xác thực nếu thông tin không hợp lệ
*/
async function login(email: string, password: string): Promise<string> {
// EN: Implementation here
// VI: Implementation ở đây
}
```
### Function Documentation / Tài Liệu Function
Use JSDoc format for all public functions with bilingual descriptions / Sử dụng format JSDoc cho tất cả public functions với mô tả song ngữ.
```typescript
/**
* EN: Calculates the total price including tax and discount
* VI: Tính tổng giá bao gồm thuế và giảm giá
*
* @param basePrice - Original price / Giá gốc
* @param taxRate - Tax rate (0-1) / Tỷ lệ thuế (0-1)
* @param discount - Discount amount / Số tiền giảm giá
* @returns Final price / Giá cuối cùng
*/
function calculateTotal(
basePrice: number,
taxRate: number,
discount: number
): number {
// EN: Apply discount first
// VI: Áp dụng giảm giá trước
const discountedPrice = basePrice - discount;
// EN: Then calculate tax
// VI: Sau đó tính thuế
const tax = discountedPrice * taxRate;
return discountedPrice + tax;
}
```
**Real Example / Ví dụ Thực tế**: [`services/iam-service/src/modules/feature/feature.service.ts`](../../../services/iam-service/src/modules/feature/feature.service.ts)
### Class Documentation / Tài Liệu Class
Document classes with bilingual descriptions and explain their purpose / Tài liệu hóa classes với mô tả song ngữ và giải thích mục đích của chúng.
```typescript
/**
* EN: Service for managing features in the system
* VI: Service để quản lý các features trong hệ thống
*/
export class FeatureService {
/**
* EN: Create a new feature
* VI: Tạo một feature mới
*
* @param data - Feature data / Dữ liệu feature
* @returns Created feature / Feature đã tạo
*/
async create(data: { name: string; title?: string }) {
// Implementation
}
}
```
**Real Example / Ví dụ Thực tế**: [`services/iam-service/src/modules/feature/feature.service.ts`](../../../services/iam-service/src/modules/feature/feature.service.ts)
### Interface/Type Documentation / Tài Liệu Interface/Type
Document interfaces and types to explain their structure and purpose / Tài liệu hóa interfaces và types để giải thích cấu trúc và mục đích của chúng.
```typescript
/**
* EN: User data transfer object
* VI: Đối tượng truyền dữ liệu người dùng
*/
interface UserDto {
/** EN: Unique user identifier / VI: Mã định danh duy nhất */
id: string;
/** EN: User email address / VI: Địa chỉ email người dùng */
email: string;
/** EN: User display name / VI: Tên hiển thị người dùng */
name: string;
/** EN: User role for authorization / VI: Vai trò người dùng để phân quyền */
role: 'admin' | 'user' | 'guest';
}
```
### Configuration Comments / Comments Cấu Hình
Document configuration files and environment variables with clear explanations / Tài liệu hóa file cấu hình và biến môi trường với giải thích rõ ràng.
```typescript
/**
* EN: Prisma client instance configured for the application
* VI: Instance Prisma client được cấu hình cho ứng dụng
*/
export const prisma = new PrismaClient({
// EN: Enable detailed logging in development, minimal in production
// VI: Bật ghi log chi tiết trong development, tối thiểu trong production
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
});
/**
* EN: Establish database connection on application startup
* VI: Thiết lập kết nối database khi khởi động ứng dụng
*/
export const connectDatabase = async (): Promise<void> => {
try {
// EN: Connect to database using Prisma
// VI: Kết nối tới database sử dụng Prisma
await prisma.$connect();
logger.info('Database connected successfully / Kết nối database thành công');
} catch (error) {
// EN: Log error and exit if database connection fails
// VI: Ghi log lỗi và thoát nếu kết nối database thất bại
logger.error('Database connection failed / Kết nối database thất bại', { error });
process.exit(1);
}
};
```
**Real Example / Ví dụ Thực tế**: [`services/iam-service/src/config/database.config.ts`](../../../services/iam-service/src/config/database.config.ts)
### Middleware Documentation / Tài Liệu Middleware
Document middleware functions with their purpose and behavior / Tài liệu hóa middleware functions với mục đích và hành vi của chúng.
```typescript
/**
* EN: Authentication middleware to verify JWT tokens
* VI: Middleware xác thực để kiểm tra JWT token
*/
export function authMiddleware(
req: Request,
res: Response,
next: NextFunction
) {
// EN: Extract token from Authorization header
// VI: Lấy token từ header Authorization
const authHeader = req.headers.authorization;
const token = authHeader?.replace('Bearer ', '');
if (!token) {
return res.status(401).json({
success: false,
error: {
code: 'NO_TOKEN',
message: 'Authentication required / Yêu cầu xác thực',
},
});
}
try {
// EN: Verify token and extract payload
// VI: Xác minh token và lấy payload
const payload = jwt.verify(token, JWT_SECRET);
req.user = payload;
next();
} catch (error) {
return res.status(401).json({
success: false,
error: {
code: 'INVALID_TOKEN',
message: 'Invalid or expired token / Token không hợp lệ hoặc hết hạn',
},
});
}
}
```
### Prisma Schema Comments / Comments Schema Prisma
Use triple-slash comments (`///`) for Prisma schema documentation / Sử dụng triple-slash comments (`///`) cho tài liệu Prisma schema.
```prisma
/// EN: User model for authentication and profile
/// VI: Model người dùng cho xác thực và hồ sơ
model User {
/// EN: Unique identifier / VI: Mã định danh duy nhất
id String @id @default(cuid())
/// EN: User email (unique) / VI: Email người dùng (duy nhất)
email String @unique
/// EN: Hashed password / VI: Mật khẩu đã mã hóa
password String
/// EN: Display name / VI: Tên hiển thị
name String
/// EN: Account creation timestamp / VI: Thời gian tạo tài khoản
createdAt DateTime @default(now())
/// EN: Last update timestamp / VI: Thời gian cập nhật cuối
updatedAt DateTime @updatedAt
@@map("users")
}
```
### Test Comments / Comments Test
Document test setup and explain test scenarios in both languages / Tài liệu hóa test setup và giải thích test scenarios bằng cả hai ngôn ngữ.
```typescript
// EN: Mock environment variables for tests
// VI: Mock biến môi trường cho tests
process.env.NODE_ENV = 'test';
process.env.DATABASE_URL = 'postgresql://test:test@localhost:5432/test_db';
// EN: Mock external services to avoid real network calls
// VI: Mock các service bên ngoài để tránh gọi mạng thật
jest.mock('@goodgo/logger', () => ({
logger: {
info: jest.fn(),
error: jest.fn(),
},
}));
describe('FeatureService', () => {
it('should create a feature successfully', async () => {
// EN: Arrange
// VI: Chuẩn bị
const testData = { name: 'test-feature' };
// EN: Act
// VI: Thực hiện
const result = await service.create(testData);
// EN: Assert
// VI: Kiểm tra
expect(result).toBeDefined();
});
});
```
**Real Example / Ví dụ Thực tế**: [`services/iam-service/src/__tests__/setupTests.ts`](../../../services/iam-service/src/__tests__/setupTests.ts)
### Complex Logic Comments / Comments Logic Phức Tạp
When explaining complex algorithms or business logic, break it down into steps / Khi giải thích thuật toán phức tạp hoặc logic nghiệp vụ, chia nhỏ thành các bước.
```typescript
// EN: Step 1: Validate input parameters
// VI: Bước 1: Xác thực tham số đầu vào
if (!email || !password) {
throw new ValidationError('Email and password required');
}
// EN: Step 2: Check if user exists in database
// VI: Bước 2: Kiểm tra xem người dùng có tồn tại trong database
const user = await prisma.user.findUnique({ where: { email } });
if (!user) {
throw new NotFoundError('User not found');
}
// EN: Step 3: Verify password hash
// VI: Bước 3: Xác minh hash mật khẩu
const isValidPassword = await bcrypt.compare(password, user.password);
if (!isValidPassword) {
throw new AuthenticationError('Invalid credentials');
}
// EN: Step 4: Generate and return JWT token
// VI: Bước 4: Tạo và trả về JWT token
const token = jwt.sign({ userId: user.id }, JWT_SECRET);
return { token, user };
```
## Special Comment Types / Các Loại Comment Đặc Biệt
### TODO Comments / Comments TODO
Use TODO comments for future improvements with bilingual descriptions / Sử dụng TODO comments cho cải tiến trong tương lai với mô tả song ngữ.
```typescript
// TODO EN: Implement caching for better performance
// TODO VI: Triển khai caching để cải thiện hiệu suất
// TODO EN: Add rate limiting to prevent abuse
// TODO VI: Thêm rate limiting để ngăn chặn lạm dụng
```
### FIXME Comments / Comments FIXME
Use FIXME comments for code that needs fixing / Sử dụng FIXME comments cho code cần sửa.
```typescript
// FIXME EN: This causes memory leak, needs refactoring
// FIXME VI: Đoạn này gây rò rỉ bộ nhớ, cần refactor
// FIXME EN: Temporary workaround, should implement proper solution
// FIXME VI: Giải pháp tạm thời, nên triển khai giải pháp đúng đắn
```
### WARNING Comments / Comments CẢNH BÁO
Use WARNING comments for code that requires special attention / Sử dụng WARNING comments cho code cần chú ý đặc biệt.
```typescript
// WARNING EN: Do not modify this without updating the database schema
// WARNING VI: Không sửa đổi phần này mà không cập nhật schema database
// WARNING EN: This function modifies global state, use with caution
// WARNING VI: Function này thay đổi global state, sử dụng cẩn thận
```
### NOTE Comments / Comments GHI CHÚ
Use NOTE comments for important information or explanations / Sử dụng NOTE comments cho thông tin hoặc giải thích quan trọng.
```typescript
// NOTE EN: This is intentionally async to avoid blocking the event loop
// NOTE VI: Đây là async có chủ ý để tránh block event loop
// NOTE EN: Priority: Docker Compose > .env.local > .env > System environment
// NOTE VI: Ưu tiên: Docker Compose > .env.local > .env > Môi trường hệ thống
```
## Best Practices / Thực Hành Tốt Nhất
### Comment Placement / Vị Trí Comment
- ✅ Place bilingual comments together (EN first, then VI) / Đặt comments song ngữ cùng nhau (EN trước, sau đó VI)
- ✅ Keep comments close to the code they describe / Giữ comments gần với code mà chúng mô tả
- ✅ Use JSDoc format for functions and classes / Sử dụng format JSDoc cho functions và classes
- ✅ Update comments when code changes / Cập nhật comments khi code thay đổi
### Comment Content / Nội Dung Comment
-**DO**: Explain WHY, not WHAT (code shows what) / Giải thích TẠI SAO, không phải CÁI GÌ
-**DO**: Document complex logic and business rules / Tài liệu hóa logic phức tạp và quy tắc nghiệp vụ
-**DO**: Include parameter descriptions and return types / Bao gồm mô tả tham số và kiểu trả về
-**DO**: Document error conditions and exceptions / Tài liệu hóa điều kiện lỗi và ngoại lệ
-**DON'T**: State the obvious / Không nói điều hiển nhiên
-**DON'T**: Write redundant comments / Không viết comments thừa
-**DON'T**: Comment out code (use version control instead) / Không comment code (sử dụng version control)
### Language Guidelines / Hướng Dẫn Ngôn Ngữ
**English / Tiếng Anh**:
- Use clear, concise technical English / Sử dụng tiếng Anh kỹ thuật rõ ràng, ngắn gọn
- Use proper technical terminology / Sử dụng thuật ngữ kỹ thuật đúng
- Be specific and actionable / Cụ thể và có thể thực hiện
**Vietnamese / Tiếng Việt**:
- Use proper Vietnamese technical terms / Sử dụng thuật ngữ kỹ thuật tiếng Việt đúng
- Keep translations accurate and natural / Giữ bản dịch chính xác và tự nhiên
- Use consistent terminology across codebase / Sử dụng thuật ngữ nhất quán trên codebase
- Prefer technical Vietnamese terms over literal translations / Ưu tiên thuật ngữ kỹ thuật Việt hơn dịch theo nghĩa đen
### Documentation Priority / Ưu Tiên Tài Liệu
**High Priority** (Always document / Luôn tài liệu hóa):
- Public APIs and exported functions / API công khai và functions được export
- Complex algorithms and business logic / Thuật toán phức tạp và logic nghiệp vụ
- Security-critical code / Code bảo mật quan trọng
- Configuration and environment setup / Cấu hình và thiết lập môi trường
- Error handling strategies / Chiến lược xử lý lỗi
**Medium Priority** (Document when helpful / Tài liệu khi hữu ích):
- Helper functions with non-obvious behavior / Helper functions có hành vi không rõ ràng
- Data transformations / Chuyển đổi dữ liệu
- Integration points with external services / Điểm tích hợp với services bên ngoài
**Low Priority** (Optional / Tùy chọn):
- Simple getters/setters / Getters/setters đơn giản
- Self-explanatory code / Code tự giải thích
- Standard CRUD operations / Các thao tác CRUD tiêu chuẩn
## Examples from Project / Ví Dụ Từ Dự Án
### Real Comment Examples / Ví Dụ Comment Thực Tế
1. **Service Comments**: [`services/iam-service/src/modules/feature/feature.service.ts`](../../../services/iam-service/src/modules/feature/feature.service.ts)
2. **Config Comments**: [`services/iam-service/src/config/database.config.ts`](../../../services/iam-service/src/config/database.config.ts)
3. **Test Comments**: [`services/iam-service/src/__tests__/setupTests.ts`](../../../services/iam-service/src/__tests__/setupTests.ts)
4. **Jest Config Comments**: [`services/iam-service/jest.config.ts`](../../../services/iam-service/jest.config.ts)
### Comment Patterns in Different Contexts / Patterns Comment Trong Các Ngữ Cảnh Khác Nhau
- **Controllers**: Document API endpoints and request/response handling / Tài liệu hóa API endpoints và xử lý request/response
- **Services**: Document business logic and data processing / Tài liệu hóa logic nghiệp vụ và xử lý dữ liệu
- **Middleware**: Document authentication, authorization, and request processing / Tài liệu hóa xác thực, phân quyền và xử lý request
- **Repositories**: Document database operations and query logic / Tài liệu hóa các thao tác database và logic query
- **Config Files**: Document configuration options and environment variables / Tài liệu hóa tùy chọn cấu hình và biến môi trường
- **Tests**: Document test scenarios and setup procedures / Tài liệu hóa test scenarios và quy trình setup
## Quick Reference / Tham Khảo Nhanh
### Function Comment Template / Template Comment Function
```typescript
/**
* EN: [Brief description in English]
* VI: [Mô tả ngắn gọn bằng tiếng Việt]
*
* @param paramName - EN description / VI mô tả
* @returns EN description / VI mô tả
* @throws ErrorType EN when / VI khi nào
*/
```
### Inline Comment Template / Template Inline Comment
```typescript
// EN: [English explanation]
// VI: [Giải thích tiếng Việt]
```
### Complex Block Template / Template Block Phức Tạp
```typescript
// EN: Step N: [What this block does]
// VI: Bước N: [Block này làm gì]
```
### Class Comment Template / Template Comment Class
```typescript
/**
* EN: [Class purpose in English]
* VI: [Mục đích class bằng tiếng Việt]
*/
export class ClassName {
/**
* EN: [Property description]
* VI: [Mô tả property]
*/
private property: string;
}
```
### Interface Comment Template / Template Comment Interface
```typescript
/**
* EN: [Interface purpose in English]
* VI: [Mục đích interface bằng tiếng Việt]
*/
interface InterfaceName {
/** EN: Property description / VI: Mô tả property */
property: string;
}
```
## Related Skills / Skills Liên Quan
- **[Testing Patterns](./testing-patterns.md)**: Writing comments in test files / Viết comments trong file test
- **[API Design](./api-design.md)**: Documenting API endpoints / Tài liệu hóa API endpoints
- **[Documentation](./documentation.md)**: Writing technical documentation / Viết tài liệu kỹ thuật
- **[Project Rules](./project-rules.md)**: Code organization and standards / Tổ chức code và tiêu chuẩn
## Resources / Tài Nguyên
### Documentation Standards / Tiêu Chuẩn Tài Liệu
- [JSDoc Documentation](https://jsdoc.app/)
- [TypeScript JSDoc](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html)
- [TSDoc Specification](https://tsdoc.org/)
### Internal Documentation / Tài Liệu Nội Bộ
- [Documentation Writing Guidelines](./documentation.md)
- [API Design Standards](./api-design.md)
- [Project Coding Standards](./project-rules.md)
### Tools / Công Cụ
- **JSDoc**: Generate API documentation from comments / Tạo tài liệu API từ comments
- **ESLint**: Enforce comment style and completeness / Thực thi style và tính đầy đủ của comments
- **Prettier**: Format comments consistently / Định dạng comments nhất quán
- **VS Code**: IntelliSense uses JSDoc comments for better autocomplete / IntelliSense sử dụng JSDoc comments cho autocomplete tốt hơn

View File

@@ -0,0 +1,584 @@
# Database & Prisma / Cơ Sở Dữ Liệu & Prisma
> **EN**: Prisma ORM and database patterns for GoodGo microservices. Use when working with databases, creating Prisma schemas, writing migrations, implementing repositories, or optimizing queries.
> **VI**: Pattern Prisma ORM và database cho các microservices của GoodGo. Sử dụng khi làm việc với databases, tạo Prisma schemas, viết migrations, triển khai repositories, hoặc tối ưu queries.
## Overview / Tổng Quan
**EN**: This skill covers Prisma ORM patterns, database schema design, repository patterns, query optimization, and transaction handling used across GoodGo microservices. It ensures type-safe database operations, consistent data access patterns, and optimal performance.
**VI**: Skill này bao gồm các pattern Prisma ORM, thiết kế database schema, repository patterns, tối ưu queries, và xử lý transactions được sử dụng trong các microservices của GoodGo. Nó đảm bảo các thao tác database type-safe, pattern truy cập dữ liệu nhất quán, và hiệu năng tối ưu.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Setting up Prisma for a new service
- Creating or modifying database schemas
- Writing database migrations
- Implementing repository patterns
- Optimizing database queries
- Setting up database connections
- Implementing transactions
- Working with Neon PostgreSQL
**VI**: Sử dụng skill này khi:
- Thiết lập Prisma cho service mới
- Tạo hoặc sửa đổi database schemas
- Viết database migrations
- Triển khai repository patterns
- Tối ưu database queries
- Thiết lập kết nối database
- Triển khai transactions
- Làm việc với Neon PostgreSQL
## Key Concepts / Khái Niệm Chính
### 1. Repository Pattern / Pattern Repository
**EN**: All database operations go through repository classes that extend `BaseRepository`, providing consistent CRUD operations and error handling.
**VI**: Tất cả các thao tác database đi qua các repository classes kế thừa `BaseRepository`, cung cấp các CRUD operations nhất quán và xử lý lỗi.
### 2. Prisma Schema / Schema Prisma
**EN**: Database schema is defined in `prisma/schema.prisma` with models, relations, indexes, and constraints.
**VI**: Database schema được định nghĩa trong `prisma/schema.prisma` với models, relations, indexes, và constraints.
### 3. Type Safety / An Toàn Kiểu
**EN**: Prisma generates TypeScript types from schema, ensuring type-safe database operations.
**VI**: Prisma generate TypeScript types từ schema, đảm bảo các thao tác database type-safe.
## Common Patterns / Các Pattern Thường Dùng
### Prisma Schema Pattern / Pattern Schema Prisma
**Example from codebase / Ví dụ từ codebase**:
```prisma
// services/iam-service/prisma/schema.prisma
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// EN: User model - Core user entity
// VI: Model User - Entity người dùng cốt lõi
model User {
id String @id @default(cuid())
email String @unique
username String? @unique
passwordHash String? // Nullable for social-only users
isActive Boolean @default(true)
emailVerified Boolean @default(false)
mfaEnabled Boolean @default(false)
mfaSecret String?
lastLoginAt DateTime?
loginCount Int @default(0)
organizationId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
// Relations
userRoles UserRole[]
userPermissions UserPermission[]
sessions Session[]
organization Organization? @relation(fields: [organizationId], references: [id])
profile UserProfile?
@@index([email])
@@index([username])
@@index([createdAt])
@@index([organizationId])
@@map("users")
}
```
### Database Connection Pattern / Pattern Kết Nối Database
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/config/database.config.ts
import { PrismaClient } from '@prisma/client';
import { logger } from '@goodgo/logger';
/**
* EN: Prisma client instance configured for the application
* VI: Instance Prisma client được cấu hình cho ứng dụng
*/
export const prisma = new PrismaClient({
// EN: Enable detailed logging in development, minimal in production
// VI: Bật ghi log chi tiết trong development, tối thiểu trong production
log: process.env.NODE_ENV === 'development' ? ['query', 'error', 'warn'] : ['error'],
});
/**
* EN: Establish database connection on application startup
* VI: Thiết lập kết nối database khi khởi động ứng dụng
*/
export const connectDatabase = async (): Promise<void> => {
try {
await prisma.$connect();
logger.info('Database connected successfully / Kết nối database thành công');
} catch (error) {
logger.error('Database connection failed / Kết nối database thất bại', { error });
process.exit(1);
}
};
/**
* EN: Close database connection on application shutdown
* VI: Đóng kết nối database khi tắt ứng dụng
*/
export const disconnectDatabase = async (): Promise<void> => {
await prisma.$disconnect();
logger.info('Database disconnected / Đã ngắt kết nối database');
};
```
### Base Repository Pattern / Pattern Base Repository
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/common/repository.ts
import { PrismaClient } from '@prisma/client';
import { logger } from '@goodgo/logger';
import { DatabaseError } from '../../errors/http-error';
/**
* EN: Base repository class providing common database operations
* VI: Base repository class cung cấp các thao tác database chung
*/
export abstract class BaseRepository<T, CreateInput, UpdateInput> {
protected prisma: PrismaClient;
protected modelName: string;
constructor(prisma: PrismaClient, modelName: string) {
this.prisma = prisma;
this.modelName = modelName;
}
/**
* EN: Find entity by ID
* VI: Tìm entity theo ID
*/
async findById(id: string): Promise<T | null> {
try {
logger.debug(`Finding ${this.modelName} by ID / Tìm ${this.modelName} theo ID`, { id });
const entity = await (this.prisma as any)[this.modelName].findUnique({
where: { id },
});
logger.debug(`${this.modelName} ${entity ? 'found' : 'not found'} / ${this.modelName} ${entity ? 'đã tìm thấy' : 'không tìm thấy'}`, { id });
return entity;
} catch (error: any) {
logger.error(`Failed to find ${this.modelName} by ID / Không thể tìm ${this.modelName} theo ID`, { error, id });
throw new DatabaseError(`Failed to find ${this.modelName}`, { id, originalError: error });
}
}
/**
* EN: Find all entities with optional filtering
* VI: Tìm tất cả entities với filtering tùy chọn
*/
async findAll(options?: {
where?: any;
orderBy?: any;
skip?: number;
take?: number;
include?: any;
}): Promise<T[]> {
try {
logger.debug(`Finding all ${this.modelName} / Tìm tất cả ${this.modelName}`, options);
const entities = await (this.prisma as any)[this.modelName].findMany(options || {});
logger.debug(`Found ${entities.length} ${this.modelName} entities / Đã tìm thấy ${entities.length} ${this.modelName} entities`);
return entities;
} catch (error: any) {
logger.error(`Failed to find all ${this.modelName} / Không thể tìm tất cả ${this.modelName}`, { error, options });
throw new DatabaseError(`Failed to find ${this.modelName} entities`, { options, originalError: error });
}
}
/**
* EN: Create new entity
* VI: Tạo entity mới
*/
async create(data: CreateInput): Promise<T> {
try {
logger.debug(`Creating new ${this.modelName} / Tạo ${this.modelName} mới`, { data });
const entity = await (this.prisma as any)[this.modelName].create({
data,
});
logger.debug(`${this.modelName} created successfully / ${this.modelName} đã được tạo thành công`, { id: (entity as any).id });
return entity;
} catch (error: any) {
logger.error(`Failed to create ${this.modelName} / Không thể tạo ${this.modelName}`, { error, data });
throw new DatabaseError(`Failed to create ${this.modelName}`, { data, originalError: error });
}
}
/**
* EN: Update entity by ID
* VI: Cập nhật entity theo ID
*/
async update(id: string, data: UpdateInput): Promise<T> {
try {
logger.debug(`Updating ${this.modelName} / Cập nhật ${this.modelName}`, { id, data });
const entity = await (this.prisma as any)[this.modelName].update({
where: { id },
data,
});
logger.debug(`${this.modelName} updated successfully / ${this.modelName} đã được cập nhật thành công`, { id });
return entity;
} catch (error: any) {
if (error.code === 'P2025') {
logger.warn(`${this.modelName} not found for update / ${this.modelName} không tìm thấy để cập nhật`, { id });
throw new DatabaseError(`${this.modelName} not found`, { id });
}
logger.error(`Failed to update ${this.modelName} / Không thể cập nhật ${this.modelName}`, { error, id, data });
throw new DatabaseError(`Failed to update ${this.modelName}`, { id, data, originalError: error });
}
}
/**
* EN: Execute transaction with multiple operations
* VI: Thực thi transaction với nhiều operations
*/
async transaction<R>(callback: (tx: any) => Promise<R>): Promise<R> {
try {
logger.debug(`Starting ${this.modelName} transaction / Bắt đầu transaction ${this.modelName}`);
const result = await this.prisma.$transaction(async (tx) => {
return await callback(tx);
});
logger.debug(`${this.modelName} transaction completed successfully / Transaction ${this.modelName} đã hoàn thành thành công`);
return result;
} catch (error: any) {
logger.error(`${this.modelName} transaction failed / Transaction ${this.modelName} thất bại`, { error });
throw new DatabaseError(`${this.modelName} transaction failed`, { originalError: error });
}
}
}
```
### Specific Repository Implementation / Triển Khai Repository Cụ Thể
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/repositories/user.repository.ts
import { PrismaClient, User } from '@prisma/client';
import { BaseRepository } from '../modules/common/repository';
/**
* EN: User repository for database operations
* VI: Repository người dùng cho các thao tác database
*/
export class UserRepository extends BaseRepository<User, any, any> {
constructor(prisma: PrismaClient) {
super(prisma, 'user');
}
/**
* EN: Find user by email
* VI: Tìm người dùng theo email
*/
async findByEmail(email: string): Promise<User | null> {
return this.prisma.user.findUnique({
where: { email },
include: {
userRoles: {
include: { role: true },
},
userPermissions: {
include: { permission: true },
},
},
});
}
/**
* EN: Find user by username
* VI: Tìm người dùng theo username
*/
async findByUsername(username: string): Promise<User | null> {
return this.prisma.user.findUnique({
where: { username },
});
}
/**
* EN: Find user with roles and permissions
* VI: Tìm người dùng với roles và permissions
*/
async findWithPermissions(userId: string): Promise<User | null> {
return this.prisma.user.findUnique({
where: { id: userId },
include: {
userRoles: {
where: {
OR: [
{ expiresAt: null },
{ expiresAt: { gte: new Date() } },
],
},
include: {
role: {
include: {
permissions: {
include: { permission: true },
},
},
},
},
},
userPermissions: {
where: {
OR: [
{ expiresAt: null },
{ expiresAt: { gte: new Date() } },
],
},
include: { permission: true },
},
},
});
}
}
```
### Upsert Pattern / Pattern Upsert
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/repositories/user-profile.repository.ts
export class UserProfileRepository extends BaseRepository<UserProfile, any, any> {
/**
* EN: Create or update profile for user
* VI: Tạo hoặc cập nhật profile cho user
*/
async upsert(userId: string, data: any): Promise<UserProfile> {
return this.prisma.userProfile.upsert({
where: { userId },
update: {
...data,
updatedAt: new Date(),
},
create: {
userId,
...data,
},
include: {
user: {
select: {
id: true,
email: true,
username: true,
},
},
},
});
}
}
```
### Query Optimization Patterns / Pattern Tối Ưu Query
**Example from codebase / Ví dụ từ codebase**:
```typescript
// services/iam-service/src/modules/feature/feature.repository.ts
export class FeatureRepository extends BaseRepository<Feature, CreateFeatureInput, UpdateFeatureInput> {
/**
* EN: Find features by tags
* VI: Tìm features theo tags
*/
async findByTags(tags: string[]): Promise<Feature[]> {
try {
logger.debug('Finding features by tags / Tìm features theo tags', { tags });
const features = await this.prisma.feature.findMany({
where: {
tags: {
hasSome: tags,
},
},
orderBy: { createdAt: 'desc' },
});
logger.debug(`Found ${features.length} features by tags / Đã tìm thấy ${features.length} features theo tags`, { tags });
return features;
} catch (error) {
logger.error('Failed to find features by tags / Không thể tìm features theo tags', { error, tags });
throw this.handleDatabaseError(error, { tags });
}
}
}
```
## Best Practices / Thực Hành Tốt Nhất
### 1. Schema Design / Thiết Kế Schema
- ✅ Use appropriate field types (String, Int, Boolean, DateTime, Json) / Sử dụng field types phù hợp
- ✅ Add indexes for frequently queried fields (`@@index([email])`) / Thêm indexes cho các fields thường query
- ✅ Use relations instead of storing JSON when possible / Sử dụng relations thay vì lưu JSON khi có thể
- ✅ Implement soft deletes with `deletedAt` field when needed / Triển khai soft deletes với field `deletedAt` khi cần
- ✅ Use `@default()` for default values / Sử dụng `@default()` cho giá trị mặc định
- ✅ Use `@updatedAt` for automatic timestamp updates / Sử dụng `@updatedAt` cho cập nhật timestamp tự động
### 2. Repository Pattern / Pattern Repository
- ✅ Extend `BaseRepository` for common CRUD operations / Kế thừa `BaseRepository` cho CRUD operations chung
- ✅ Add custom methods for domain-specific queries / Thêm methods tùy chỉnh cho queries đặc thù domain
- ✅ Use `include` and `select` to control data fetching / Sử dụng `include``select` để kiểm soát việc lấy dữ liệu
- ✅ Handle Prisma errors and convert to domain errors / Xử lý lỗi Prisma và chuyển đổi sang domain errors
- ✅ Log database operations for debugging / Log các thao tác database để debug
### 3. Query Optimization / Tối Ưu Query
- ✅ Use `select` to fetch only needed fields / Sử dụng `select` để chỉ lấy các fields cần thiết
- ✅ Implement pagination with `skip` and `take` / Triển khai pagination với `skip``take`
- ✅ Use indexes for frequently queried fields / Sử dụng indexes cho các fields thường query
- ✅ Avoid N+1 queries by using `include` strategically / Tránh N+1 queries bằng cách sử dụng `include` chiến lược
- ✅ Use `findUnique` instead of `findFirst` when possible / Sử dụng `findUnique` thay vì `findFirst` khi có thể
- ✅ Use transactions for multiple related operations / Sử dụng transactions cho nhiều operations liên quan
### 4. Error Handling / Xử Lý Lỗi
- ✅ Catch Prisma errors and convert to domain errors / Bắt lỗi Prisma và chuyển đổi sang domain errors
- ✅ Handle unique constraint violations (P2002) / Xử lý vi phạm ràng buộc duy nhất
- ✅ Handle record not found (P2025) / Xử lý không tìm thấy bản ghi
- ✅ Log errors with context / Log lỗi kèm context
- ✅ Provide meaningful error messages / Cung cấp thông báo lỗi có ý nghĩa
### 5. Migrations / Migrations
- ✅ Keep migrations small and focused / Giữ migrations nhỏ và tập trung
- ✅ Test migrations before production / Test migrations trước khi production
- ✅ Backup before major changes / Backup trước khi thay đổi lớn
- ✅ Use descriptive migration names / Sử dụng tên migration mô tả
- ✅ Review generated SQL before applying / Xem xét SQL được generate trước khi áp dụng
### 6. Connection Management / Quản Lý Kết Nối
- ✅ Use connection pooling for production / Sử dụng connection pooling cho production
- ✅ Close connections on application shutdown / Đóng kết nối khi tắt ứng dụng
- ✅ Handle connection errors gracefully / Xử lý lỗi kết nối một cách lịch sự
- ✅ Monitor connection pool usage / Giám sát việc sử dụng connection pool
## Examples from Project / Ví Dụ Từ Dự Án
### Schema Examples / Ví Dụ Schema
- **IAM Service Schema**: [`services/iam-service/prisma/schema.prisma`](../../../services/iam-service/prisma/schema.prisma)
- **Auth Service Schema**: [`services/iam-service/prisma/schema.prisma`](../../../services/iam-service/prisma/schema.prisma)
### Repository Examples / Ví Dụ Repository
- **Base Repository**: [`services/iam-service/src/modules/common/repository.ts`](../../../services/iam-service/src/modules/common/repository.ts)
- **User Repository**: [`services/iam-service/src/repositories/user.repository.ts`](../../../services/iam-service/src/repositories/user.repository.ts)
- **User Profile Repository**: [`services/iam-service/src/repositories/user-profile.repository.ts`](../../../services/iam-service/src/repositories/user-profile.repository.ts)
- **Feature Repository**: [`services/iam-service/src/modules/feature/feature.repository.ts`](../../../services/iam-service/src/modules/feature/feature.repository.ts)
### Database Config Examples / Ví Dụ Cấu Hình Database
- **Database Config**: [`services/iam-service/src/config/database.config.ts`](../../../services/iam-service/src/config/database.config.ts)
## Quick Reference / Tham Khảo Nhanh
### Common Prisma Operations / Các Thao Tác Prisma Thường Dùng
```typescript
// Find by ID / Tìm theo ID
const user = await prisma.user.findUnique({ where: { id } });
// Find with relations / Tìm với relations
const user = await prisma.user.findUnique({
where: { id },
include: { profile: true, roles: true },
});
// Find many with filters / Tìm nhiều với filters
const users = await prisma.user.findMany({
where: { isActive: true },
skip: 0,
take: 10,
orderBy: { createdAt: 'desc' },
});
// Create / Tạo
const user = await prisma.user.create({
data: { email, passwordHash },
});
// Update / Cập nhật
const user = await prisma.user.update({
where: { id },
data: { isActive: false },
});
// Delete / Xóa
await prisma.user.delete({ where: { id } });
// Upsert / Tạo hoặc cập nhật
const profile = await prisma.userProfile.upsert({
where: { userId },
update: { ...data },
create: { userId, ...data },
});
// Transaction / Transaction
await prisma.$transaction(async (tx) => {
const user = await tx.user.create({ data: userData });
await tx.userProfile.create({ data: { userId: user.id, ...profileData } });
});
```
### Prisma Error Codes / Mã Lỗi Prisma
| Code | Description / Mô Tả |
|------|-------------------|
| P2002 | Unique constraint violation / Vi phạm ràng buộc duy nhất |
| P2025 | Record not found / Không tìm thấy bản ghi |
| P2003 | Foreign key constraint violation / Vi phạm ràng buộc khóa ngoại |
| P2014 | Required relation violation / Vi phạm quan hệ bắt buộc |
## Related Skills / Skills Liên Quan
- **[API Design](./api-design.md)**: For designing API endpoints that use repositories / Cho thiết kế API endpoints sử dụng repositories
- **[Testing Patterns](./testing-patterns.md)**: For testing database operations / Cho test các thao tác database
- **[Security](./security.md)**: For securing database operations and preventing SQL injection / Cho bảo mật các thao tác database và ngăn chặn SQL injection
- **[Observability](./observability-monitoring.md)**: For monitoring database performance / Cho giám sát hiệu năng database
## Resources / Tài Nguyên
### External Documentation / Tài Liệu Bên Ngoài
- [Prisma Documentation](https://www.prisma.io/docs)
- [Prisma Schema Reference](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference)
- [Prisma Client API](https://www.prisma.io/docs/reference/api-reference/prisma-client-reference)
- [PostgreSQL Documentation](https://www.postgresql.org/docs/)
- [Neon Documentation](https://neon.tech/docs)
### Internal Documentation / Tài Liệu Nội Bộ
- [Neon Database Guide](../guides/neon-database.md)
- [Development Guide](../guides/development.md)

View File

@@ -0,0 +1,468 @@
# Kubernetes Deployment / Triển Khai Kubernetes
> **EN**: Kubernetes deployment patterns for GoodGo microservices. Use when deploying to staging/production, creating K8s manifests, configuring HPA, setting up ingress, or troubleshooting K8s deployments.
> **VI**: Các pattern triển khai Kubernetes cho microservices GoodGo. Sử dụng khi triển khai lên staging/production, tạo K8s manifests, cấu hình HPA, thiết lập ingress, hoặc xử lý sự cố triển khai K8s.
## Overview / Tổng Quan
**EN**: This skill covers Kubernetes deployment patterns and best practices for GoodGo microservices. It includes creating deployment manifests, configuring autoscaling, managing secrets and configmaps, setting up ingress, and implementing health checks.
**VI**: Skill này bao gồm các pattern triển khai Kubernetes và best practices cho microservices GoodGo. Nó bao gồm tạo deployment manifests, cấu hình autoscaling, quản lý secrets và configmaps, thiết lập ingress, và triển khai health checks.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Deploying services to staging/production environments
- Creating or updating Kubernetes manifests
- Configuring autoscaling (HPA/VPA)
- Setting up ingress and load balancing
- Managing secrets and configmaps
- Troubleshooting deployment issues
- Implementing health checks and probes
- Setting up monitoring and logging
**VI**: Sử dụng skill này khi:
- Triển khai services lên môi trường staging/production
- Tạo hoặc cập nhật Kubernetes manifests
- Cấu hình autoscaling (HPA/VPA)
- Thiết lập ingress và load balancing
- Quản lý secrets và configmaps
- Xử lý sự cố triển khai
- Triển khai health checks và probes
- Thiết lập monitoring và logging
## Key Concepts / Khái Niệm Chính
### Deployment Strategy / Chiến Lược Triển Khai
**EN**:
- Rolling updates for zero-downtime deployments
- Resource limits and requests for stability
- Health checks (liveness/readiness probes)
- Horizontal Pod Autoscaler (HPA) for auto-scaling
- ConfigMaps for configuration
- Secrets for sensitive data
**VI**:
- Rolling updates để triển khai không downtime
- Resource limits và requests để đảm bảo ổn định
- Health checks (liveness/readiness probes)
- Horizontal Pod Autoscaler (HPA) để tự động scale
- ConfigMaps cho cấu hình
- Secrets cho dữ liệu nhạy cảm
## Common Patterns / Các Pattern Thường Dùng
### Service Deployment Manifest / Manifest Triển Khai Service
**EN**: Standard deployment manifest structure for GoodGo services.
**VI**: Cấu trúc deployment manifest chuẩn cho các services GoodGo.
**Ví dụ từ codebase**: [`deployments/production/kubernetes/iam-service.yaml`](../../../deployments/production/kubernetes/iam-service.yaml)
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: iam-service
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: iam-service
template:
metadata:
labels:
app: iam-service
spec:
containers:
- name: iam-service
image: goodgo/iam-service:latest
imagePullPolicy: Always
ports:
- containerPort: 5001
envFrom:
- configMapRef:
name: iam-service-config
- secretRef:
name: iam-service-secrets
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /health/live
port: 5001
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health/ready
port: 5001
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: iam-service
namespace: production
spec:
selector:
app: iam-service
ports:
- protocol: TCP
port: 5001
targetPort: 5001
type: ClusterIP
```
### Horizontal Pod Autoscaler / Tự Động Scale Pod
**EN**: Configure HPA to automatically scale pods based on CPU and memory utilization.
**VI**: Cấu hình HPA để tự động scale pods dựa trên CPU và memory utilization.
**Ví dụ từ codebase**: [`deployments/production/kubernetes/iam-service.yaml`](../../../deployments/production/kubernetes/iam-service.yaml)
```yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: iam-service-hpa
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: iam-service
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
```
### ConfigMap & Secrets / ConfigMap và Secrets
**EN**: Use ConfigMaps for non-sensitive configuration and Secrets for sensitive data.
**VI**: Sử dụng ConfigMaps cho cấu hình không nhạy cảm và Secrets cho dữ liệu nhạy cảm.
**Ví dụ từ codebase**:
- ConfigMap: [`deployments/production/kubernetes/iam-service-configmap.yaml`](../../../deployments/production/kubernetes/iam-service-configmap.yaml)
- Secrets: [`deployments/production/kubernetes/secrets.yaml.example`](../../../deployments/production/kubernetes/secrets.yaml.example)
```yaml
# ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: iam-service-config
namespace: production
data:
NODE_ENV: "production"
PORT: "5001"
API_VERSION: "v1"
CORS_ORIGIN: "https://goodgo.vn"
LOG_LEVEL: "warn"
SERVICE_NAME: "iam-service"
TRACING_ENABLED: "true"
---
# Secret (example - use sealed-secrets in production)
apiVersion: v1
kind: Secret
metadata:
name: iam-service-secrets
namespace: production
type: Opaque
stringData:
database-url: "postgresql://user:password@ep-xxx.region.neon.tech/dbname?sslmode=require&pgbouncer=true"
jwt-secret: "your-production-jwt-secret-min-32-chars"
jwt-refresh-secret: "your-production-refresh-secret-min-32-chars"
redis-password: ""
```
### Ingress Configuration / Cấu Hình Ingress
**EN**: Configure ingress for external access with TLS and path-based routing.
**VI**: Cấu hình ingress để truy cập từ bên ngoài với TLS và path-based routing.
**Ví dụ từ codebase**: [`deployments/production/kubernetes/ingress.yaml`](../../../deployments/production/kubernetes/ingress.yaml)
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
namespace: production
annotations:
traefik.ingress.kubernetes.io/rule-type: PathPrefix
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: traefik
tls:
- hosts:
- api.goodgo.vn
secretName: api-tls-cert
rules:
- host: api.goodgo.vn
http:
paths:
- path: /api/v1/auth
pathType: Prefix
backend:
service:
name: iam-service
port:
number: 5001
```
## Best Practices / Thực Hành Tốt Nhất
### Resource Management / Quản Lý Tài Nguyên
**EN**:
- Always set resource requests and limits
- Monitor actual usage and adjust accordingly
- Use HPA for automatic scaling
- Set appropriate CPU and memory based on service requirements
**VI**:
- Luôn đặt resource requests và limits
- Theo dõi sử dụng thực tế và điều chỉnh phù hợp
- Sử dụng HPA để tự động scale
- Đặt CPU và memory phù hợp dựa trên yêu cầu service
### Configuration / Cấu Hình
**EN**:
- Use ConfigMaps for non-sensitive config
- Use Secrets for sensitive data
- Never hardcode configuration in images
- Use `envFrom` to load entire ConfigMap/Secret
**VI**:
- Sử dụng ConfigMaps cho cấu hình không nhạy cảm
- Sử dụng Secrets cho dữ liệu nhạy cảm
- Không bao giờ hardcode cấu hình trong images
- Sử dụng `envFrom` để load toàn bộ ConfigMap/Secret
### Health Checks / Kiểm Tra Sức Khỏe
**EN**:
- Implement both liveness and readiness probes
- Set appropriate timeouts and thresholds
- Include dependency checks in readiness probe
- Use HTTP probes for web services
**VI**:
- Triển khai cả liveness và readiness probes
- Đặt timeouts và thresholds phù hợp
- Bao gồm kiểm tra dependencies trong readiness probe
- Sử dụng HTTP probes cho web services
**Ví dụ từ codebase**: [`services/iam-service/src/modules/health/health.controller.ts`](../../../services/iam-service/src/modules/health/health.controller.ts)
```typescript
// Liveness probe - is the service alive?
health = async (_req: Request, res: Response): Promise<void> => {
res.json({
success: true,
data: { status: 'ok', timestamp: new Date().toISOString() },
});
};
// Readiness probe - is the service ready to accept traffic?
ready = async (_req: Request, res: Response): Promise<void> => {
try {
// Check database connection
await prisma.$queryRaw`SELECT 1`;
res.json({
success: true,
data: { status: 'ready' },
});
} catch (error) {
res.status(503).json({
success: false,
error: { code: 'HEALTH_001', message: 'Service not ready' },
});
}
};
```
### Deployment / Triển Khai
**EN**:
- Use rolling updates for zero-downtime
- Set maxSurge and maxUnavailable appropriately
- Test deployments in staging first
- Use image tags instead of `latest` in production
**VI**:
- Sử dụng rolling updates để không downtime
- Đặt maxSurge và maxUnavailable phù hợp
- Test triển khai trong staging trước
- Sử dụng image tags thay vì `latest` trong production
### Security / Bảo Mật
**EN**:
- Run containers as non-root user
- Use network policies to restrict traffic
- Regularly update base images
- Use sealed-secrets or external secret manager
- Never commit secrets to Git
**VI**:
- Chạy containers với user không phải root
- Sử dụng network policies để hạn chế traffic
- Cập nhật base images thường xuyên
- Sử dụng sealed-secrets hoặc external secret manager
- Không bao giờ commit secrets vào Git
### Monitoring / Giám Sát
**EN**:
- Expose metrics endpoint (`/metrics`)
- Set up alerts for critical issues
- Monitor resource usage and performance
- Use ServiceMonitor for Prometheus integration
**VI**:
- Expose metrics endpoint (`/metrics`)
- Thiết lập alerts cho các vấn đề quan trọng
- Theo dõi sử dụng tài nguyên và hiệu suất
- Sử dụng ServiceMonitor cho tích hợp Prometheus
## Examples from Project / Ví Dụ Từ Dự Án
### Production Deployment / Triển Khai Production
- **IAM Service**: [`deployments/production/kubernetes/iam-service.yaml`](../../../deployments/production/kubernetes/iam-service.yaml)
- **ConfigMap**: [`deployments/production/kubernetes/iam-service-configmap.yaml`](../../../deployments/production/kubernetes/iam-service-configmap.yaml)
- **Ingress**: [`deployments/production/kubernetes/ingress.yaml`](../../../deployments/production/kubernetes/ingress.yaml)
### Staging Deployment / Triển Khai Staging
- **IAM Service**: [`deployments/staging/kubernetes/iam-service.yaml`](../../../deployments/staging/kubernetes/iam-service.yaml)
- **ConfigMap**: [`deployments/staging/kubernetes/iam-service-configmap.yaml`](../../../deployments/staging/kubernetes/iam-service-configmap.yaml)
### Health Check Implementation / Triển Khai Health Check
- **Health Controller**: [`services/iam-service/src/modules/health/health.controller.ts`](../../../services/iam-service/src/modules/health/health.controller.ts)
## Quick Reference / Tham Khảo Nhanh
### Common Commands / Lệnh Thường Dùng
```bash
# Deploy to production
kubectl apply -f deployments/production/kubernetes/ -n production
# Check deployment status
kubectl get deployments -n production
kubectl get pods -n production
kubectl get svc -n production
# View logs
kubectl logs -f deployment/iam-service -n production
kubectl logs -f pod-name -n production --tail=100
# Scale manually
kubectl scale deployment iam-service --replicas=5 -n production
# Update image
kubectl set image deployment/iam-service iam-service=goodgo/iam-service:v1.2.3 -n production
# Rollback
kubectl rollout undo deployment/iam-service -n production
# Port forward for debugging
kubectl port-forward service/iam-service 5001:5001 -n production
# Execute command in pod
kubectl exec -it pod-name -n production -- /bin/sh
# View HPA status
kubectl get hpa -n production
kubectl describe hpa iam-service-hpa -n production
# View resource usage
kubectl top nodes
kubectl top pods -n production
```
### Troubleshooting / Xử Lý Sự Cố
**Pod Not Starting / Pod Không Khởi Động**:
```bash
# Check pod status
kubectl describe pod pod-name -n production
# Check events
kubectl get events -n production --sort-by='.lastTimestamp'
# Check logs
kubectl logs pod-name -n production --previous
```
**ImagePullBackOff**:
```bash
# Check image name and tag
kubectl describe pod pod-name -n production | grep -i image
# Check image pull secrets
kubectl get secrets -n production
```
**CrashLoopBackOff**:
```bash
# Check logs of crashed container
kubectl logs pod-name -n production --previous
# Check resource limits
kubectl describe pod pod-name -n production | grep -A 5 Limits
```
## Related Skills / Skills Liên Quan
- [Observability & Monitoring](./observability-monitoring.md) - Để giám sát các services đã triển khai
- [Security](./security.md) - Để bảo mật các triển khai Kubernetes
- [Project Rules](./project-rules.md) - Cho cấu trúc và tiêu chuẩn service
## Resources / Tài Nguyên
### Official Documentation / Tài Liệu Chính Thức
- [Kubernetes Documentation](https://kubernetes.io/docs/)
- [Kubernetes API Reference](https://kubernetes.io/docs/reference/kubernetes-api/)
- [Horizontal Pod Autoscaler](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/)
### GoodGo Resources / Tài Nguyên GoodGo
- [Deployment Guide](../guides/deployment.md)
- [Local Deployment Guide](../guides/local-deployment.md)
- [Troubleshooting Guide](../guides/troubleshooting.md)

View File

@@ -0,0 +1,535 @@
# Documentation / Tài Liệu
> **EN**: Guidelines for writing technical documentation in the GoodGo project. Use when creating or updating README files, guides, architecture docs, or API documentation. Ensures bilingual (EN/VI) consistency and proper structure.
> **VI**: Hướng dẫn viết tài liệu kỹ thuật trong dự án GoodGo. Sử dụng khi tạo hoặc cập nhật file README, hướng dẫn, tài liệu kiến trúc hoặc tài liệu API. Đảm bảo tính nhất quán song ngữ (EN/VI) và cấu trúc phù hợp.
## Overview / Tổng Quan
**EN**: The Documentation skill provides comprehensive guidelines for writing, structuring, and maintaining technical documentation in the GoodGo Microservices Platform. It covers documentation structure, bilingual formatting, templates, writing style, and best practices for maintaining documentation quality.
**VI**: Skill Documentation cung cấp hướng dẫn toàn diện để viết, cấu trúc và duy trì tài liệu kỹ thuật trong GoodGo Microservices Platform. Nó bao gồm cấu trúc tài liệu, định dạng song ngữ, template, phong cách viết và thực hành tốt nhất để duy trì chất lượng tài liệu.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Creating new documentation files
- Updating existing documentation
- Writing README files for services or packages
- Creating guides or tutorials
- Documenting API endpoints
- Writing architecture documentation
- Creating deployment documentation
- Writing runbooks or operational guides
- Ensuring bilingual consistency
**VI**: Sử dụng skill này khi:
- Tạo file tài liệu mới
- Cập nhật tài liệu hiện có
- Viết file README cho services hoặc packages
- Tạo hướng dẫn hoặc tutorial
- Tài liệu hóa API endpoints
- Viết tài liệu kiến trúc
- Tạo tài liệu triển khai
- Viết runbook hoặc hướng dẫn vận hành
- Đảm bảo tính nhất quán song ngữ
## Key Concepts / Khái Niệm Chính
### Documentation Structure / Cấu Trúc Tài Liệu
**EN**: The project follows a structured documentation hierarchy:
```
docs/
├── en/ # English documentation
│ ├── guides/ # How-to guides
│ ├── architecture/ # System design docs
│ ├── api/ # API documentation
│ ├── onboarding/ # New developer guides
│ ├── runbooks/ # Operational guides
│ └── skills/ # Skill documentation
├── vi/ # Vietnamese documentation (mirror structure)
└── README.md # Documentation index
```
**VI**: Dự án tuân theo hệ thống phân cấp tài liệu có cấu trúc:
```
docs/
├── en/ # Tài liệu tiếng Anh
│ ├── guides/ # Hướng dẫn cách làm
│ ├── architecture/ # Tài liệu thiết kế hệ thống
│ ├── api/ # Tài liệu API
│ ├── onboarding/ # Hướng dẫn cho developer mới
│ ├── runbooks/ # Hướng dẫn vận hành
│ └── skills/ # Tài liệu skills
├── vi/ # Tài liệu tiếng Việt (cấu trúc tương tự)
└── README.md # Mục lục tài liệu
```
### Bilingual Documentation Rules / Quy Tắc Tài Liệu Song Ngữ
**EN**: The project maintains bilingual documentation (English and Vietnamese). Three formats are used:
1. **Side-by-side**: Short content with EN and VI on the same line
2. **Separate files**: Long content in separate EN and VI files
3. **Sections**: Mixed content with separate EN and VI sections
**VI**: Dự án duy trì tài liệu song ngữ (Tiếng Anh và Tiếng Việt). Ba định dạng được sử dụng:
1. **Side-by-side**: Nội dung ngắn với EN và VI trên cùng một dòng
2. **Separate files**: Nội dung dài trong các file EN và VI riêng biệt
3. **Sections**: Nội dung hỗn hợp với các phần EN và VI riêng biệt
## Common Patterns / Các Pattern Thường Dùng
### Service README Template / Template README Service
**EN**: Example structure from `services/iam-service/README.md`:
```markdown
# Service Name / Tên Dịch Vụ
> **EN**: Brief description in English
> **VI**: Mô tả ngắn gọn bằng tiếng Việt
## Features / Tính Năng
- Feature 1 / Tính năng 1
- Feature 2 / Tính năng 2
## Prerequisites / Yêu Cầu
- Node.js 20+
- PostgreSQL (Neon)
- Redis
## Quick Start / Bắt Đầu Nhanh
```bash
# Install dependencies / Cài đặt dependencies
pnpm install
# Setup environment / Thiết lập môi trường
cp .env.example .env
# Start service / Khởi động service
pnpm dev
```
## Configuration / Cấu Hình
| Variable | Description / Mô Tả | Default | Required |
|----------|---------------------|---------|----------|
| PORT | Server port / Cổng server | 5000 | No |
## API Endpoints
See [API Documentation](../api/openapi/iam-service.yaml)
```
**VI**: Ví dụ cấu trúc từ `services/iam-service/README.md`:
```markdown
# Service Name / Tên Dịch Vụ
> **EN**: Brief description in English
> **VI**: Mô tả ngắn gọn bằng tiếng Việt
## Features / Tính Năng
- Feature 1 / Tính năng 1
- Feature 2 / Tính năng 2
## Prerequisites / Yêu Cầu
- Node.js 20+
- PostgreSQL (Neon)
- Redis
## Quick Start / Bắt Đầu Nhanh
```bash
# Install dependencies / Cài đặt dependencies
pnpm install
# Setup environment / Thiết lập môi trường
cp .env.example .env
# Start service / Khởi động service
pnpm dev
```
## Configuration / Cấu Hình
| Variable | Description / Mô Tả | Default | Required |
|----------|---------------------|---------|----------|
| PORT | Server port / Cổng server | 5000 | No |
## API Endpoints
See [API Documentation](../api/openapi/iam-service.yaml)
```
### Guide Template / Template Hướng Dẫn
**EN**: Example from `docs/en/guides/getting-started.md`:
```markdown
# Getting Started
## Prerequisites
- Node.js >= 20.0.0
- PNPM >= 8.0.0
- Docker & Docker Compose
- Git
- Neon account (https://neon.tech) - for database
## Initial Setup
1. **Clone the repository**
```bash
git clone <repository-url>
cd Base
```
2. **Setup Neon Database**
```bash
# Run setup script
./scripts/db/setup-neon.sh
```
See [Neon Setup Guide](../../../infra/databases/neon/README.md) for details.
3. **Initialize the project**
```bash
./scripts/setup/init-project.sh
```
## Next Steps
- Read [Development Guide](../guides/development.md)
- Check [API Documentation](../api/openapi/)
- Review [Architecture Overview](../architecture/system-design.md)
```
**VI**: Ví dụ từ `docs/vi/guides/getting-started.md`:
```markdown
# Bắt Đầu
## Yêu Cầu
- Node.js >= 20.0.0
- PNPM >= 8.0.0
- Docker & Docker Compose
- Git
- Tài khoản Neon (https://neon.tech) - cho database
## Thiết Lập Ban Đầu
1. **Clone repository**
```bash
git clone <repository-url>
cd Base
```
2. **Thiết lập Neon Database**
```bash
# Chạy script setup
./scripts/db/setup-neon.sh
```
Xem [Hướng Dẫn Thiết Lập Neon](../../../infra/databases/neon/README.md) để biết chi tiết.
3. **Khởi tạo dự án**
```bash
./scripts/setup/init-project.sh
```
## Bước Tiếp Theo
- Đọc [Hướng Dẫn Phát Triển](../guides/development.md)
- Xem [Tài Liệu API](../api/openapi/)
- Xem lại [Tổng Quan Kiến Trúc](../architecture/system-design.md)
```
### Architecture Document Template / Template Tài Liệu Kiến Trúc
**EN**: Example from `docs/en/architecture/system-design.md`:
```markdown
# System Design
## Overview
GoodGo Microservices Platform is built using a microservices architecture pattern with the following principles:
- **Service Independence**: Each service has its own database and can be deployed independently
- **API Gateway**: Traefik handles routing, load balancing, and cross-cutting concerns
- **Shared Libraries**: Common functionality is extracted into shared packages
- **Infrastructure as Code**: All infrastructure configurations are versioned
- **Observability**: Full monitoring, logging, and tracing capabilities
## Architecture Diagram
```
┌─────────────┐ ┌─────────────┐
│ Web App │ │ Mobile App │
│ (Next.js) │ │ (React Native)
└──────┬──────┘ └──────┬──────┘
│ │
└──────────┬────────┘
┌────────▼────────┐
│ Traefik │
│ (API Gateway) │
└────────┬─────────┘
```
## Components
### Frontend Layer
- **Web App**: Next.js application with App Router
- **Mobile App**: React Native application
### API Gateway
- **Traefik**: Reverse proxy, load balancer, SSL termination
```
**VI**: Ví dụ từ `docs/vi/architecture/system-design.md`:
```markdown
# Thiết Kế Hệ Thống
## Tổng Quan
GoodGo Microservices Platform được xây dựng bằng mẫu kiến trúc microservices với các nguyên tắc sau:
- **Độc Lập Dịch Vụ**: Mỗi service có database riêng và có thể triển khai độc lập
- **API Gateway**: Traefik xử lý routing, load balancing và các mối quan tâm chéo
- **Thư Viện Dùng Chung**: Chức năng chung được trích xuất thành packages dùng chung
- **Infrastructure as Code**: Tất cả cấu hình infrastructure được version
- **Observability**: Khả năng giám sát, logging và tracing đầy đủ
## Sơ Đồ Kiến Trúc
```
┌─────────────┐ ┌─────────────┐
│ Web App │ │ Mobile App │
│ (Next.js) │ │ (React Native)
└──────┬──────┘ └──────┬──────┘
│ │
└──────────┬────────┘
┌────────▼────────┐
│ Traefik │
│ (API Gateway) │
└────────┬─────────┘
```
## Thành Phần
### Lớp Frontend
- **Web App**: Ứng dụng Next.js với App Router
- **Mobile App**: Ứng dụng React Native
### API Gateway
- **Traefik**: Reverse proxy, load balancer, SSL termination
```
## Best Practices / Thực Hành Tốt Nhất
### Writing Style / Phong Cách Viết
**EN**:
1. **Clear and Concise**: Use simple language, avoid jargon
2. **Action-Oriented**: Start with verbs (Install, Configure, Deploy)
3. **Structured**: Use headings, lists, and tables
4. **Examples**: Provide code examples and commands
5. **Visual**: Use diagrams where helpful
**VI**:
1. **Rõ Ràng và Súc Tích**: Sử dụng ngôn ngữ đơn giản, tránh thuật ngữ
2. **Hướng Hành Động**: Bắt đầu bằng động từ (Cài đặt, Cấu hình, Triển khai)
3. **Có Cấu Trúc**: Sử dụng tiêu đề, danh sách và bảng
4. **Ví Dụ**: Cung cấp ví dụ code và lệnh
5. **Trực Quan**: Sử dụng sơ đồ khi hữu ích
### Code Examples / Ví Dụ Code
**EN**: Always provide context and explanation:
```markdown
# Good: With context and explanation
Install dependencies using pnpm:
```bash
pnpm install
```
# Bad: No context
```bash
pnpm install
```
```
**VI**: Luôn cung cấp ngữ cảnh và giải thích:
```markdown
# Tốt: Có ngữ cảnh và giải thích
Cài đặt dependencies sử dụng pnpm:
```bash
pnpm install
```
# Không tốt: Không có ngữ cảnh
```bash
pnpm install
```
```
### Links / Liên Kết
**EN**:
- Use relative links for internal docs
- Use descriptive link text (not "click here")
- Example: `See the [Deployment Guide](../guides/deployment.md) for details.`
**VI**:
- Sử dụng liên kết tương đối cho tài liệu nội bộ
- Sử dụng văn bản liên kết mô tả (không phải "click here")
- Ví dụ: `Xem [Hướng Dẫn Triển Khai](../guides/deployment.md) để biết chi tiết.`
## Examples from Project / Ví Dụ Từ Dự Án
### Good Documentation Examples / Ví Dụ Tài Liệu Tốt
**EN**:
- `docs/en/guides/getting-started.md` - Clear step-by-step guide
- `services/iam-service/README.md` - Comprehensive service README
- `docs/en/architecture/system-design.md` - Architecture documentation
- `docs/README.md` - Documentation index
**VI**:
- `docs/vi/guides/getting-started.md` - Hướng dẫn từng bước rõ ràng
- `services/iam-service/README.md` - README service toàn diện
- `docs/vi/architecture/system-design.md` - Tài liệu kiến trúc
- `docs/README.md` - Mục lục tài liệu
### Documentation Locations Reference / Tham Chiếu Vị Trí Tài Liệu
**EN**:
| Content Type | Location | Format |
|--------------|----------|--------|
| Getting Started | `docs/en/guides/getting-started.md` | Separate files |
| Service Setup | `services/[name]/README.md` | Side-by-side |
| Deployment | `docs/en/guides/deployment.md` | Separate files |
| Architecture | `docs/en/architecture/` | Separate files |
| API Specs | `docs/en/api/openapi/` | OpenAPI YAML |
| Runbooks | `docs/en/runbooks/` | Separate files |
| Infrastructure | `infra/[component]/README.md` | Side-by-side |
**VI**:
| Loại Nội Dung | Vị Trí | Định Dạng |
|--------------|--------|----------|
| Bắt Đầu | `docs/vi/guides/getting-started.md` | File riêng biệt |
| Thiết Lập Service | `services/[name]/README.md` | Side-by-side |
| Triển Khai | `docs/vi/guides/deployment.md` | File riêng biệt |
| Kiến Trúc | `docs/vi/architecture/` | File riêng biệt |
| Spec API | `docs/vi/api/openapi/` | OpenAPI YAML |
| Runbooks | `docs/vi/runbooks/` | File riêng biệt |
| Infrastructure | `infra/[component]/README.md` | Side-by-side |
## Quick Reference / Tham Khảo Nhanh
### File Naming / Đặt Tên File
**EN**:
- Use kebab-case: `getting-started.md`
- Be descriptive: `local-development.md` not `dev.md`
- Match EN and VI filenames
**VI**:
- Sử dụng kebab-case: `getting-started.md`
- Mô tả rõ ràng: `local-development.md` không phải `dev.md`
- Khớp tên file EN và VI
### Heading Levels / Cấp Độ Tiêu Đề
```markdown
# H1: Document Title (only one per file)
## H2: Major Sections
### H3: Subsections
#### H4: Details (use sparingly)
```
### Bilingual Patterns / Mẫu Song Ngữ
```markdown
# Pattern 1: Inline
Description / Mô tả
# Pattern 2: After slash
PORT=5000 # Server port / Cổng server
# Pattern 3: Table
| Variable | Description / Mô Tả |
# Pattern 4: Code comments
# EN: Install dependencies
# VI: Cài đặt dependencies
pnpm install
```
### Documentation Checklist / Danh Sách Kiểm Tra Tài Liệu
**EN**: Before publishing documentation:
- [ ] Determine correct location (docs/ vs service README)
- [ ] Choose bilingual format (side-by-side vs separate)
- [ ] Review existing docs for consistency
- [ ] Use clear, concise language
- [ ] Include code examples
- [ ] Add diagrams where helpful
- [ ] Provide troubleshooting section
- [ ] Link to related documentation
- [ ] Test all commands and code examples
- [ ] Check all links work
- [ ] Ensure bilingual consistency
- [ ] Update documentation index
**VI**: Trước khi xuất bản tài liệu:
- [ ] Xác định vị trí đúng (docs/ vs service README)
- [ ] Chọn định dạng song ngữ (side-by-side vs separate)
- [ ] Xem lại tài liệu hiện có để đảm bảo tính nhất quán
- [ ] Sử dụng ngôn ngữ rõ ràng, súc tích
- [ ] Bao gồm ví dụ code
- [ ] Thêm sơ đồ khi hữu ích
- [ ] Cung cấp phần xử lý sự cố
- [ ] Liên kết đến tài liệu liên quan
- [ ] Kiểm tra tất cả lệnh và ví dụ code
- [ ] Kiểm tra tất cả liên kết hoạt động
- [ ] Đảm bảo tính nhất quán song ngữ
- [ ] Cập nhật mục lục tài liệu
## Related Skills / Skills Liên Quan
- **[Project Rules](./project-rules.md)** - Project structure and standards
- **[API Design](./api-design.md)** - API documentation patterns
- **[Comment Code](./comment-code.md)** - Code commenting guidelines
## Resources / Tài Nguyên
**EN**:
- [Markdown Guide](https://www.markdownguide.org/)
- [Mermaid Diagrams](https://mermaid.js.org/)
- [Documentation Best Practices](https://www.writethedocs.org/guide/)
**VI**:
- [Hướng Dẫn Markdown](https://www.markdownguide.org/)
- [Sơ Đồ Mermaid](https://mermaid.js.org/)
- [Thực Hành Tốt Nhất Tài Liệu](https://www.writethedocs.org/guide/)

View File

@@ -0,0 +1,565 @@
# Observability & Monitoring / Khả Năng Quan Sát & Giám Sát
> **EN**: Observability and monitoring patterns for GoodGo microservices. Use when adding metrics, implementing logging, setting up tracing, creating health checks, or debugging production issues.
> **VI**: Các pattern observability và monitoring cho microservices GoodGo. Sử dụng khi thêm metrics, triển khai logging, thiết lập tracing, tạo health checks, hoặc debug các vấn đề production.
## Overview / Tổng Quan
**EN**: This skill covers the three pillars of observability (logs, metrics, traces) and how to implement them in GoodGo microservices. It includes structured logging, Prometheus metrics, distributed tracing with OpenTelemetry, health checks, and error tracking.
**VI**: Skill này bao gồm ba trụ cột của observability (logs, metrics, traces) và cách triển khai chúng trong microservices GoodGo. Nó bao gồm structured logging, Prometheus metrics, distributed tracing với OpenTelemetry, health checks, và error tracking.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Setting up logging infrastructure
- Implementing metrics collection
- Adding distributed tracing
- Creating health check endpoints
- Setting up monitoring dashboards
- Debugging production issues
- Implementing alerting rules
- Analyzing performance bottlenecks
**VI**: Sử dụng skill này khi:
- Thiết lập hạ tầng logging
- Triển khai thu thập metrics
- Thêm distributed tracing
- Tạo health check endpoints
- Thiết lập monitoring dashboards
- Debug các vấn đề production
- Triển khai alerting rules
- Phân tích performance bottlenecks
## Key Concepts / Khái Niệm Chính
### Three Pillars of Observability / Ba Trụ Cột Của Observability
**EN**:
1. **Logs**: Event records for debugging and auditing
2. **Metrics**: Numerical measurements over time (counters, gauges, histograms)
3. **Traces**: Request flow across services (distributed tracing)
**VI**:
1. **Logs**: Bản ghi sự kiện để debug và audit
2. **Metrics**: Đo lường số học theo thời gian (counters, gauges, histograms)
3. **Traces**: Luồng request qua các services (distributed tracing)
### Tech Stack / Công Nghệ
**EN**:
- **Logging**: `@goodgo/logger` (Pino-based structured logging)
- **Metrics**: Prometheus + Grafana
- **Tracing**: OpenTelemetry + Jaeger (`@goodgo/tracing`)
- **Correlation IDs**: Request tracking across services
**VI**:
- **Logging**: `@goodgo/logger` (structured logging dựa trên Pino)
- **Metrics**: Prometheus + Grafana
- **Tracing**: OpenTelemetry + Jaeger (`@goodgo/tracing`)
- **Correlation IDs**: Theo dõi request qua các services
## Common Patterns / Các Pattern Thường Dùng
### Structured Logging / Logging Có Cấu Trúc
**EN**: Use structured logging with correlation IDs for request tracking.
**VI**: Sử dụng structured logging với correlation IDs để theo dõi request.
**Ví dụ từ codebase**: [`services/iam-service/src/middlewares/logger.middleware.ts`](../../../services/iam-service/src/middlewares/logger.middleware.ts)
```typescript
import { Request, Response, NextFunction } from 'express';
import { logger } from '@goodgo/logger';
import { getCorrelationId, getRequestId } from './correlation.middleware';
export const requestLogger = (req: Request, res: Response, next: NextFunction): void => {
// Bỏ qua logging chi tiết cho health checks và metrics
if (req.path.startsWith('/health') || req.path.startsWith('/metrics')) {
return next();
}
const start = Date.now();
res.on('finish', () => {
const duration = Date.now() - start;
const correlationId = getCorrelationId(req);
const requestId = getRequestId(req);
logger.info('Request processed / Request đã xử lý', {
correlationId,
requestId,
method: req.method,
path: req.path,
query: req.query,
statusCode: res.statusCode,
duration: `${duration}ms`,
contentLength: res.get('Content-Length') || 0,
userAgent: req.get('User-Agent'),
ip: req.ip,
userId: (req as any).user?.userId,
});
});
next();
};
```
### Correlation IDs / Correlation IDs
**EN**: Use correlation IDs to track requests across services.
**VI**: Sử dụng correlation IDs để theo dõi request qua các services.
**Ví dụ từ codebase**: [`services/iam-service/src/middlewares/correlation.middleware.ts`](../../../services/iam-service/src/middlewares/correlation.middleware.ts)
```typescript
import { Request, Response, NextFunction } from 'express';
import { randomUUID } from 'crypto';
import { logger } from '@goodgo/logger';
export const CORRELATION_ID_HEADER = 'x-correlation-id';
export const REQUEST_ID_HEADER = 'x-request-id';
export const correlationMiddleware = (
options: {
headerName?: string;
generateId?: () => string;
skipPaths?: string[];
} = {}
) => {
const {
headerName = CORRELATION_ID_HEADER,
generateId = randomUUID,
skipPaths = ['/health', '/metrics', '/favicon.ico'],
} = options;
return (req: Request, res: Response, next: NextFunction) => {
// Lấy correlation ID từ header hoặc tạo mới
const correlationId = req.headers[headerName.toLowerCase()] as string || generateId();
const requestId = generateId();
// Gắn vào request object
req.correlationId = correlationId;
req.requestId = requestId;
// Thêm vào response headers
res.setHeader(headerName, correlationId);
res.setHeader(REQUEST_ID_HEADER, requestId);
// Log request start
logger.info('Request started / Request bắt đầu', {
correlationId,
requestId,
method: req.method,
url: req.url,
userAgent: req.get('User-Agent'),
ip: req.ip,
});
next();
};
};
```
### Metrics Collection / Thu Thập Metrics
**EN**: Expose Prometheus metrics for monitoring and alerting.
**VI**: Expose Prometheus metrics để monitoring và alerting.
**Ví dụ từ codebase**: [`services/iam-service/src/middlewares/metrics.middleware.ts`](../../../services/iam-service/src/middlewares/metrics.middleware.ts)
```typescript
import { Request, Response, NextFunction } from 'express';
import client from 'prom-client';
import { getCorrelationId } from './correlation.middleware';
// Tạo Registry để đăng ký các metrics
const register = client.register;
// Thu thập các metrics mặc định
client.collectDefaultMetrics({ register });
// Tạo histogram cho thời lượng request HTTP
const httpRequestDurationSeconds = new client.Histogram({
name: 'http_request_duration_seconds',
help: 'Duration of HTTP requests in seconds',
labelNames: ['method', 'route', 'status_code', 'correlation_id'],
buckets: [0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 2, 5, 10],
});
// Tạo counter cho tổng số request HTTP
const httpRequestsTotal = new client.Counter({
name: 'http_requests_total',
help: 'Total number of HTTP requests',
labelNames: ['method', 'route', 'status_code'],
});
// Tạo gauge cho active requests
const activeRequests = new client.Gauge({
name: 'http_active_requests',
help: 'Number of active HTTP requests',
});
// Tạo counter cho lỗi HTTP request
const httpRequestErrors = new client.Counter({
name: 'http_request_errors_total',
help: 'Total number of HTTP request errors',
labelNames: ['method', 'route', 'error_type'],
});
export const metricsMiddleware = (req: Request, res: Response, next: NextFunction) => {
// Tăng active requests
activeRequests.inc();
// Bắt đầu bấm giờ
const start = process.hrtime.bigint();
res.on('finish', () => {
// Giảm active requests
activeRequests.dec();
// Tính toán thời lượng
const end = process.hrtime.bigint();
const durationInSeconds = Number(end - start) / 1e9;
// Chuẩn hóa path để tránh high cardinality
const route = normalizeRoutePath(req);
const correlationId = getCorrelationId(req) || 'unknown';
// Ghi nhận thời lượng
httpRequestDurationSeconds
.labels(req.method, route, res.statusCode.toString(), correlationId)
.observe(durationInSeconds);
// Tăng bộ đếm request
httpRequestsTotal
.labels(req.method, route, res.statusCode.toString())
.inc();
// Theo dõi lỗi
if (res.statusCode >= 400) {
const errorType = res.statusCode >= 500 ? 'server_error' : 'client_error';
httpRequestErrors
.labels(req.method, route, errorType)
.inc();
}
});
next();
};
// Chuẩn hóa route path để ngăn high cardinality metrics
function normalizeRoutePath(req: Request): string {
if (req.route && req.route.path) {
return req.route.path;
}
let path = req.path;
// Thay thế UUIDs và numeric IDs bằng placeholders
path = path.replace(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi, ':uuid');
path = path.replace(/\d+/g, ':id');
return path;
}
```
### Distributed Tracing / Distributed Tracing
**EN**: Use OpenTelemetry for distributed tracing across services.
**VI**: Sử dụng OpenTelemetry cho distributed tracing qua các services.
**Ví dụ từ codebase**: [`packages/tracing/src/index.ts`](../../../packages/tracing/src/index.ts)
```typescript
import { NodeSDK } from '@opentelemetry/sdk-node';
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
import { JaegerExporter } from '@opentelemetry/exporter-jaeger';
import { Resource } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
export interface TracingConfig {
serviceName: string;
jaegerEndpoint?: string;
enabled?: boolean;
}
export const initTracing = (config: TracingConfig): NodeSDK | null => {
if (config.enabled === false) {
return null;
}
// Tạo Jaeger exporter nếu endpoint được cung cấp
const jaegerExporter = config.jaegerEndpoint
? new JaegerExporter({
endpoint: config.jaegerEndpoint,
})
: undefined;
// Khởi tạo OpenTelemetry NodeSDK với auto-instrumentations
const sdk = new NodeSDK({
resource: new Resource({
[SemanticResourceAttributes.SERVICE_NAME]: config.serviceName,
}),
traceExporter: jaegerExporter,
instrumentations: [getNodeAutoInstrumentations()],
});
// Khởi động tracing SDK
sdk.start();
return sdk;
};
```
**Cách sử dụng trong service**:
```typescript
// services/iam-service/src/main.ts
import { initTracing } from '@goodgo/tracing';
// Khởi tạo tracing
if (process.env.TRACING_ENABLED === 'true') {
initTracing({
serviceName: process.env.SERVICE_NAME || 'iam-service',
jaegerEndpoint: process.env.JAEGER_ENDPOINT,
enabled: true,
});
}
```
### Health Checks / Kiểm Tra Sức Khỏe
**EN**: Implement liveness and readiness probes for Kubernetes.
**VI**: Triển khai liveness và readiness probes cho Kubernetes.
**Ví dụ từ codebase**: [`services/iam-service/src/modules/health/health.controller.ts`](../../../services/iam-service/src/modules/health/health.controller.ts)
```typescript
import { Request, Response } from 'express';
import { prisma } from '../../config/database.config';
import { ApiResponse } from '@goodgo/types';
export class HealthController {
/**
* EN: Basic liveness probe
* VI: Kiểm tra liveness cơ bản
*/
health = async (_req: Request, res: Response): Promise<void> => {
const response: ApiResponse<{ status: string; timestamp: string }> = {
success: true,
data: {
status: 'ok',
timestamp: new Date().toISOString(),
},
timestamp: new Date().toISOString(),
};
res.json(response);
};
/**
* EN: Readiness probe (checks database connection)
* VI: Kiểm tra readiness (kiểm tra kết nối database)
*/
ready = async (_req: Request, res: Response): Promise<void> => {
try {
// Kiểm tra kết nối database
await prisma.$queryRaw`SELECT 1`;
res.json({
success: true,
data: { status: 'ready' },
timestamp: new Date().toISOString(),
});
} catch (error) {
// Trả về 503 nếu database chưa sẵn sàng
res.status(503).json({
success: false,
error: {
code: 'HEALTH_001',
message: 'Service not ready',
},
timestamp: new Date().toISOString(),
});
}
};
/**
* EN: Alias for health check
* VI: Alias cho kiểm tra sức khỏe
*/
live = async (_req: Request, res: Response): Promise<void> => {
res.json({
success: true,
data: { status: 'live' },
timestamp: new Date().toISOString(),
});
};
}
```
## Best Practices / Thực Hành Tốt Nhất
### Logging / Logging
**EN**:
- Use structured logging (JSON format)
- Include correlation IDs for request tracing
- Log at appropriate levels (ERROR, WARN, INFO, DEBUG)
- Avoid logging sensitive data (passwords, tokens, PII)
- Use consistent log format across services
**VI**:
- Sử dụng structured logging (định dạng JSON)
- Bao gồm correlation IDs để theo dõi request
- Log ở mức độ phù hợp (ERROR, WARN, INFO, DEBUG)
- Tránh log dữ liệu nhạy cảm (mật khẩu, tokens, PII)
- Sử dụng format log nhất quán giữa các services
### Metrics / Metrics
**EN**:
- Use standard metric types (Counter, Gauge, Histogram)
- Keep cardinality low (avoid high-cardinality labels)
- Define SLIs and SLOs for critical paths
- Monitor business metrics, not just technical ones
- Normalize route paths to prevent high cardinality
**VI**:
- Sử dụng các loại metric chuẩn (Counter, Gauge, Histogram)
- Giữ cardinality thấp (tránh high-cardinality labels)
- Định nghĩa SLIs và SLOs cho các đường dẫn quan trọng
- Giám sát business metrics, không chỉ technical metrics
- Chuẩn hóa route paths để tránh high cardinality
### Tracing / Tracing
**EN**:
- Add traces for critical operations
- Include relevant context in spans
- Sample appropriately to control costs
- Use distributed tracing for microservices
- Propagate correlation IDs across service boundaries
**VI**:
- Thêm traces cho các thao tác quan trọng
- Bao gồm context liên quan trong spans
- Sample phù hợp để kiểm soát chi phí
- Sử dụng distributed tracing cho microservices
- Truyền correlation IDs qua ranh giới service
### Alerting / Cảnh Báo
**EN**:
- Alert on symptoms, not causes
- Include runbook links in alerts
- Avoid alert fatigue with proper thresholds
- Test alerting rules regularly
- Use correlation IDs in alert context
**VI**:
- Cảnh báo về triệu chứng, không phải nguyên nhân
- Bao gồm links runbook trong alerts
- Tránh alert fatigue với thresholds phù hợp
- Test alerting rules thường xuyên
- Sử dụng correlation IDs trong alert context
## Examples from Project / Ví Dụ Từ Dự Án
### Logging Implementation / Triển Khai Logging
- **Request Logger**: [`services/iam-service/src/middlewares/logger.middleware.ts`](../../../services/iam-service/src/middlewares/logger.middleware.ts)
- **Correlation Middleware**: [`services/iam-service/src/middlewares/correlation.middleware.ts`](../../../services/iam-service/src/middlewares/correlation.middleware.ts)
### Metrics Implementation / Triển Khai Metrics
- **Metrics Middleware**: [`services/iam-service/src/middlewares/metrics.middleware.ts`](../../../services/iam-service/src/middlewares/metrics.middleware.ts)
- **Metrics Endpoint**: Exposed at `/metrics` in all services
### Tracing Implementation / Triển Khai Tracing
- **Tracing Package**: [`packages/tracing/src/index.ts`](../../../packages/tracing/src/index.ts)
- **Service Integration**: [`services/iam-service/src/main.ts`](../../../services/iam-service/src/main.ts)
### Health Checks / Health Checks
- **Health Controller**: [`services/iam-service/src/modules/health/health.controller.ts`](../../../services/iam-service/src/modules/health/health.controller.ts)
## Quick Reference / Tham Khảo Nhanh
### Log Levels / Mức Độ Log
**EN**:
- `ERROR`: Errors that require immediate attention
- `WARN`: Warnings that may indicate issues
- `INFO`: Informational messages (default)
- `DEBUG`: Detailed debugging information
**VI**:
- `ERROR`: Lỗi cần chú ý ngay lập tức
- `WARN`: Cảnh báo có thể chỉ ra vấn đề
- `INFO`: Thông điệp thông tin (mặc định)
- `DEBUG`: Thông tin debug chi tiết
### Metric Types / Loại Metrics
**EN**:
- **Counter**: Monotonically increasing value (e.g., request count)
- **Gauge**: Value that can go up or down (e.g., active connections)
- **Histogram**: Distribution of values (e.g., request duration)
**VI**:
- **Counter**: Giá trị tăng đơn điệu (ví dụ: số lượng request)
- **Gauge**: Giá trị có thể tăng hoặc giảm (ví dụ: kết nối đang hoạt động)
- **Histogram**: Phân phối giá trị (ví dụ: thời lượng request)
### Health Check Endpoints / Endpoints Health Check
**EN**:
- `/health` or `/health/live`: Liveness probe (service is running)
- `/health/ready`: Readiness probe (service is ready to accept traffic)
**VI**:
- `/health` hoặc `/health/live`: Liveness probe (service đang chạy)
- `/health/ready`: Readiness probe (service sẵn sàng nhận traffic)
### Prometheus Queries / Truy Vấn Prometheus
```promql
# Request rate
rate(http_requests_total[5m])
# Error rate
rate(http_requests_total{status_code=~"5.."}[5m])
# 95th percentile latency
histogram_quantile(0.95, http_request_duration_seconds)
# Active requests
http_active_requests
```
## Related Skills / Skills Liên Quan
- [Kubernetes Deployment](./deployment-kubernetes.md) - Để cấu hình health checks trong K8s
- [Security](./security.md) - Để logging và monitoring an toàn
- [Project Rules](./project-rules.md) - Cho cấu trúc và tiêu chuẩn service
## Resources / Tài Nguyên
### Official Documentation / Tài Liệu Chính Thức
- [OpenTelemetry Documentation](https://opentelemetry.io/docs/)
- [Prometheus Documentation](https://prometheus.io/docs/)
- [Jaeger Documentation](https://www.jaegertracing.io/docs/)
### GoodGo Resources / Tài Nguyên GoodGo
- [Observability Guide](../guides/observability.md)
- [Troubleshooting Guide](../guides/troubleshooting.md)
- [Logger Package](../../../packages/logger/README.md)
- [Tracing Package](../../../packages/tracing/README.md)

View File

@@ -0,0 +1,425 @@
# Project Rules / Quy Tắc Dự Án
> **EN**: GoodGo Microservices Platform coding standards and architecture patterns. Use when working with services, apps, packages, or infrastructure.
> **VI**: Tiêu chuẩn mã hóa và mẫu kiến trúc của GoodGo Microservices Platform. Sử dụng khi làm việc với services, apps, packages, hoặc infrastructure.
## Overview / Tổng Quan
**EN**: The Project Rules skill provides comprehensive guidelines for the GoodGo Microservices Platform architecture, coding standards, naming conventions, workflows, and best practices. This skill ensures consistency across all services, packages, and applications in the monorepo.
**VI**: Skill Project Rules cung cấp hướng dẫn toàn diện về kiến trúc GoodGo Microservices Platform, tiêu chuẩn mã hóa, quy ước đặt tên, quy trình làm việc và thực hành tốt nhất. Skill này đảm bảo tính nhất quán trên tất cả services, packages và applications trong monorepo.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Creating a new service or package
- Setting up project structure
- Following naming conventions
- Understanding deployment patterns
- Working with dependencies
- Configuring Docker containers
- Setting up CI/CD workflows
- Understanding the monorepo structure
**VI**: Sử dụng skill này khi:
- Tạo service hoặc package mới
- Thiết lập cấu trúc dự án
- Tuân theo quy ước đặt tên
- Hiểu các mẫu triển khai
- Làm việc với dependencies
- Cấu hình Docker containers
- Thiết lập CI/CD workflows
- Hiểu cấu trúc monorepo
## Key Concepts / Khái Niệm Chính
### Architecture / Kiến Trúc
**EN**: The platform follows a microservices architecture with:
- **Apps**: Next.js (web) + Flutter (mobile)
- **Services**: Node.js/TypeScript microservices (Express)
- **Packages**: Shared libraries (logger, types, http-client, auth-sdk, tracing)
- **Infrastructure**: Traefik (API Gateway), Redis, Neon PostgreSQL, Observability
- **Deployments**: Local (Docker Compose), Staging/Production (Kubernetes)
**VI**: Nền tảng tuân theo kiến trúc microservices với:
- **Apps**: Next.js (web) + Flutter (mobile)
- **Services**: Node.js/TypeScript microservices (Express)
- **Packages**: Thư viện dùng chung (logger, types, http-client, auth-sdk, tracing)
- **Infrastructure**: Traefik (API Gateway), Redis, Neon PostgreSQL, Observability
- **Deployments**: Local (Docker Compose), Staging/Production (Kubernetes)
### Tech Stack / Công Nghệ
**Frontend:**
- Next.js 14+ (App Router), TypeScript, Tailwind CSS, Zustand
- Flutter 3.x with Provider pattern
- Use `@goodgo/types` and `@goodgo/http-client`
**Backend:**
- Node.js 20+, TypeScript 5+, Express
- Prisma ORM + Neon PostgreSQL
- Zod validation, `@goodgo/logger`, `@goodgo/tracing`, `@goodgo/auth-sdk`
**Infrastructure:**
- Traefik (path-based routing), Redis (cache), Prometheus + Grafana + Loki
## Common Patterns / Các Pattern Thường Dùng
### Service Structure / Cấu Trúc Service
**EN**: Standard service structure:
```
services/[service-name]/
├── src/
│ ├── config/ # Configuration files
│ ├── modules/ # Feature modules
│ ├── middlewares/ # Express middlewares
│ ├── repositories/ # Data access layer
│ ├── routes/ # Route definitions
│ └── main.ts # Entry point
├── prisma/ # Database schema
├── Dockerfile # Container definition
└── package.json # Dependencies
```
**VI**: Cấu trúc service chuẩn:
```
services/[service-name]/
├── src/
│ ├── config/ # File cấu hình
│ ├── modules/ # Module tính năng
│ ├── middlewares/ # Express middlewares
│ ├── repositories/ # Lớp truy cập dữ liệu
│ ├── routes/ # Định nghĩa routes
│ └── main.ts # Điểm vào
├── prisma/ # Database schema
├── Dockerfile # Định nghĩa container
└── package.json # Dependencies
```
### Module Pattern / Pattern Module
**EN**: Controller → Service → Repository pattern:
```typescript
// DTO with Zod
export const CreateFeatureDto = z.object({
name: z.string().min(1),
email: z.string().email()
});
export type CreateFeatureDto = z.infer<typeof CreateFeatureDto>;
// Controller
export class FeatureController {
constructor(private service: FeatureService) {}
async create(req: Request, res: Response, next: NextFunction) {
try {
const dto = CreateFeatureDto.parse(req.body);
const result = await this.service.create(dto);
res.json({ success: true, data: result });
} catch (error) { next(error); }
}
}
// Service
export class FeatureService {
constructor(private repository: FeatureRepository) {}
async create(dto: CreateFeatureDto) {
return this.repository.create(dto);
}
}
// Repository
export class FeatureRepository extends BaseRepository<Feature> {
async create(data: CreateFeatureDto) {
return this.prisma.feature.create({ data });
}
}
```
**VI**: Pattern Controller → Service → Repository:
```typescript
// DTO với Zod
export const CreateFeatureDto = z.object({
name: z.string().min(1),
email: z.string().email()
});
export type CreateFeatureDto = z.infer<typeof CreateFeatureDto>;
// Controller
export class FeatureController {
constructor(private service: FeatureService) {}
async create(req: Request, res: Response, next: NextFunction) {
try {
const dto = CreateFeatureDto.parse(req.body);
const result = await this.service.create(dto);
res.json({ success: true, data: result });
} catch (error) { next(error); }
}
}
// Service
export class FeatureService {
constructor(private repository: FeatureRepository) {}
async create(dto: CreateFeatureDto) {
return this.repository.create(dto);
}
}
// Repository
export class FeatureRepository extends BaseRepository<Feature> {
async create(data: CreateFeatureDto) {
return this.prisma.feature.create({ data });
}
}
```
### API Response Pattern / Pattern Phản Hồi API
**EN**: Standardized API responses:
```typescript
// Success response
{
success: true,
data: any,
timestamp: string
}
// Error response
{
success: false,
error: {
code: string,
message: string,
details?: any
},
timestamp: string
}
```
**VI**: Phản hồi API chuẩn hóa:
```typescript
// Phản hồi thành công
{
success: true,
data: any,
timestamp: string
}
// Phản hồi lỗi
{
success: false,
error: {
code: string,
message: string,
details?: any
},
timestamp: string
}
```
## Best Practices / Thực Hành Tốt Nhất
### Naming Conventions / Quy Ước Đặt Tên
**EN**:
- **Services/Packages**: `kebab-case` (e.g., `iam-service`, `http-client`)
- **Files**: `kebab-case.type.ts` (e.g., `user.controller.ts`)
- **Components**: `PascalCase.tsx` (React), `snake_case.dart` (Flutter)
- **Classes**: `PascalCase`
- **Functions**: `camelCase`
- **Constants**: `UPPER_SNAKE_CASE`
- **Package Names**: `@goodgo/package-name`
**VI**:
- **Services/Packages**: `kebab-case` (ví dụ: `iam-service`, `http-client`)
- **Files**: `kebab-case.type.ts` (ví dụ: `user.controller.ts`)
- **Components**: `PascalCase.tsx` (React), `snake_case.dart` (Flutter)
- **Classes**: `PascalCase`
- **Functions**: `camelCase`
- **Constants**: `UPPER_SNAKE_CASE`
- **Package Names**: `@goodgo/package-name`
### TypeScript Standards / Tiêu Chuẩn TypeScript
**EN**:
- Strict mode enabled
- No `any` type (use `unknown` instead)
- Zod for runtime validation
- Export shared types from `@goodgo/types`
**VI**:
- Bật strict mode
- Không dùng type `any` (dùng `unknown` thay thế)
- Zod cho runtime validation
- Export shared types từ `@goodgo/types`
### Logging / Ghi Log
**EN**: Use `@goodgo/logger`:
```typescript
import { logger } from '@goodgo/logger';
logger.info('Message', { context });
logger.error('Error', { error, context });
```
**VI**: Sử dụng `@goodgo/logger`:
```typescript
import { logger } from '@goodgo/logger';
logger.info('Message', { context });
logger.error('Error', { error, context });
```
### Environment Variables / Biến Môi Trường
**EN**:
- Use `.env.example` template
- Never commit `.env` files
- Validate with Zod at startup
- Document all variables in README
**VI**:
- Sử dụng template `.env.example`
- Không bao giờ commit file `.env`
- Validate với Zod khi khởi động
- Tài liệu hóa tất cả biến trong README
## Examples from Project / Ví Dụ Từ Dự Án
### Service Template / Template Service
**EN**: See `services/_template/` for a complete service template with:
- Standard structure
- Middleware setup
- Error handling
- Health checks
- Swagger documentation
**VI**: Xem `services/_template/` để có template service hoàn chỉnh với:
- Cấu trúc chuẩn
- Thiết lập middleware
- Xử lý lỗi
- Health checks
- Tài liệu Swagger
### Traefik Configuration / Cấu Hình Traefik
**EN**: Services are registered in `deployments/local/docker-compose.yml`:
```yaml
services:
my-service:
build:
context: ../..
dockerfile: services/my-service/Dockerfile
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-service.rule=PathPrefix(`/api/v1/my-service`)"
- "traefik.http.services.my-service.loadbalancer.server.port=5002"
- "traefik.http.services.my-service.loadbalancer.healthcheck.path=/health/live"
```
**VI**: Services được đăng ký trong `deployments/local/docker-compose.yml`:
```yaml
services:
my-service:
build:
context: ../..
dockerfile: services/my-service/Dockerfile
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-service.rule=PathPrefix(`/api/v1/my-service`)"
- "traefik.http.services.my-service.loadbalancer.server.port=5002"
- "traefik.http.services.my-service.loadbalancer.healthcheck.path=/health/live"
```
### Real Service Examples / Ví Dụ Service Thực Tế
**EN**:
- `services/iam-service/` - Identity and Access Management service (RBAC, OIDC, MFA, Identity, Access, Governance)
- `packages/logger/` - Shared logging package
- `packages/types/` - Shared TypeScript types
**VI**:
- `services/iam-service/` - Service quản lý danh tính và quyền truy cập (RBAC, OIDC, MFA, Identity, Access, Governance)
- `packages/logger/` - Package logging dùng chung
- `packages/types/` - TypeScript types dùng chung
## Quick Reference / Tham Khảo Nhanh
### Creating New Service / Tạo Service Mới
```bash
# 1. Copy template
cp -r services/_template services/my-service
# 2. Update package.json name
# Change to: "@goodgo/my-service"
# 3. Add to docker-compose.yml
# Add service configuration with Traefik labels
# 4. Configure Prisma schema
cd services/my-service
pnpm prisma migrate dev
# 5. Add health check endpoint
# Already included in template
```
### Working with Dependencies / Làm Việc Với Dependencies
```bash
# Add external package
pnpm --filter @goodgo/service-name add package-name
# Add workspace package
pnpm --filter @goodgo/service-name add @goodgo/logger
# Add dev dependency
pnpm --filter @goodgo/service-name add -D @types/pkg
```
### Database Commands / Lệnh Database
```bash
# Run migrations
pnpm --filter @goodgo/service-name prisma migrate dev
# Generate Prisma client
pnpm --filter @goodgo/service-name prisma generate
# Seed database
pnpm --filter @goodgo/service-name prisma db seed
```
## Related Skills / Skills Liên Quan
- **[API Design](./api-design.md)** - RESTful API design standards
- **[Database Prisma](./database-prisma.md)** - Prisma ORM patterns
- **[Security](./security.md)** - Security best practices
- **[Testing Patterns](./testing-patterns.md)** - Testing guidelines
- **[Documentation](./documentation.md)** - Documentation writing guidelines
## Resources / Tài Nguyên
**EN**:
- [Architecture Docs](../architecture/system-design.md)
- [API Specs](../api/openapi/)
- [Development Guide](../guides/development.md)
- [Deployment Guide](../guides/deployment.md)
- [Contributing Guide](../../../CONTRIBUTING.md)
**VI**:
- [Tài Liệu Kiến Trúc](../architecture/system-design.md)
- [Spec API](../api/openapi/)
- [Hướng Dẫn Phát Triển](../guides/development.md)
- [Hướng Dẫn Triển Khai](../guides/deployment.md)
- [Hướng Dẫn Đóng Góp](../../../CONTRIBUTING.md)

742
docs/vi/skills/security.md Normal file
View File

@@ -0,0 +1,742 @@
# Security / Bảo Mật
> **EN**: Security best practices and patterns for GoodGo microservices platform. Use when implementing authentication, authorization, data protection, input validation, rate limiting, secrets management, or security testing across all services.
> **VI**: Thực hành và mẫu bảo mật tốt nhất cho nền tảng microservices GoodGo. Sử dụng khi triển khai xác thực, phân quyền, bảo vệ dữ liệu, xác thực đầu vào, giới hạn tốc độ, quản lý bí mật hoặc kiểm tra bảo mật trên tất cả các dịch vụ.
## Overview / Tổng Quan
**EN**: The Security skill provides comprehensive security patterns, best practices, and implementation examples for protecting GoodGo microservices. It covers authentication, authorization, data protection, input validation, rate limiting, secrets management, and security testing.
**VI**: Skill Security cung cấp các mẫu bảo mật toàn diện, thực hành tốt nhất và ví dụ triển khai để bảo vệ các microservices GoodGo. Nó bao gồm xác thực, phân quyền, bảo vệ dữ liệu, xác thực đầu vào, giới hạn tốc độ, quản lý bí mật và kiểm tra bảo mật.
## When to Use / Khi Nào Sử Dụng
**EN**: Use this skill when:
- Implementing authentication and authorization in any service
- Protecting sensitive data (PII, credentials, tokens)
- Validating user inputs and file uploads
- Implementing rate limiting and DDoS protection
- Setting up audit logging and security monitoring
- Encrypting data at rest and in transit
- Managing secrets and credentials
- Implementing security testing
- Handling security incidents
- Designing secure API endpoints
**VI**: Sử dụng skill này khi:
- Triển khai xác thực và phân quyền trong bất kỳ service nào
- Bảo vệ dữ liệu nhạy cảm (PII, thông tin đăng nhập, token)
- Xác thực đầu vào người dùng và tải lên tệp
- Triển khai giới hạn tốc độ và bảo vệ DDoS
- Thiết lập ghi nhật ký kiểm toán và giám sát bảo mật
- Mã hóa dữ liệu khi nghỉ và khi truyền
- Quản lý bí mật và thông tin đăng nhập
- Triển khai kiểm tra bảo mật
- Xử lý sự cố bảo mật
- Thiết kế các endpoint API an toàn
## Key Concepts / Khái Niệm Chính
### Core Security Principles / Nguyên Tắc Bảo Mật Cốt Lõi
**EN**:
1. **Defense in Depth**: Multiple layers of security controls
2. **Least Privilege**: Grant minimum required permissions
3. **Fail Secure**: Default to deny access
4. **Separation of Duties**: Critical operations require multiple approvals
5. **Audit Everything**: Log all security-relevant events
6. **Encrypt Sensitive Data**: PII, tokens, credentials must be encrypted
7. **Validate All Inputs**: Never trust user input
8. **Principle of Least Exposure**: Minimize attack surface
9. **Secure by Default**: Security built-in, not bolted on
10. **Assume Breach**: Design for detection and response
**VI**:
1. **Defense in Depth**: Nhiều lớp kiểm soát bảo mật
2. **Least Privilege**: Cấp quyền tối thiểu cần thiết
3. **Fail Secure**: Mặc định từ chối truy cập
4. **Separation of Duties**: Các thao tác quan trọng yêu cầu nhiều phê duyệt
5. **Audit Everything**: Ghi log tất cả sự kiện liên quan đến bảo mật
6. **Encrypt Sensitive Data**: PII, token, thông tin đăng nhập phải được mã hóa
7. **Validate All Inputs**: Không bao giờ tin tưởng đầu vào người dùng
8. **Principle of Least Exposure**: Giảm thiểu bề mặt tấn công
9. **Secure by Default**: Bảo mật được tích hợp sẵn, không phải thêm vào sau
10. **Assume Breach**: Thiết kế để phát hiện và phản ứng
## Common Patterns / Các Pattern Thường Dùng
### Authentication & Authorization / Xác Thực & Phân Quyền
#### JWT Token Validation / Xác Thực Token JWT
**EN**: Example from `services/iam-service/src/middlewares/auth.middleware.ts`:
```typescript
import { jwtService } from '../modules/token/jwt.service';
import { logger } from '@goodgo/logger';
export const authenticate = () => {
return async (req: Request, res: Response, next: NextFunction) => {
try {
// Extract token from Authorization header or cookie
let token: string | null = null;
const authHeader = req.headers.authorization;
if (authHeader?.startsWith('Bearer ')) {
token = authHeader.substring(7);
} else if (req.cookies?.access_token) {
token = req.cookies.access_token;
}
if (!token) {
return res.status(401).json({
success: false,
error: { code: 'AUTH_001', message: 'Authentication required' }
});
}
// Verify token
const payload = await jwtService.verifyAccessToken(token);
// Attach user to request
req.user = {
id: payload.sub,
userId: payload.sub,
email: payload.email,
roles: payload.roles || [],
permissions: payload.permissions || []
};
next();
} catch (error) {
logger.warn('Authentication failed', { error: error.message });
return res.status(401).json({
success: false,
error: { code: 'AUTH_002', message: 'Invalid or expired token' }
});
}
};
};
```
**VI**: Ví dụ từ `services/iam-service/src/middlewares/auth.middleware.ts`:
```typescript
import { jwtService } from '../modules/token/jwt.service';
import { logger } from '@goodgo/logger';
export const authenticate = () => {
return async (req: Request, res: Response, next: NextFunction) => {
try {
// Trích xuất token từ header Authorization hoặc cookie
let token: string | null = null;
const authHeader = req.headers.authorization;
if (authHeader?.startsWith('Bearer ')) {
token = authHeader.substring(7);
} else if (req.cookies?.access_token) {
token = req.cookies.access_token;
}
if (!token) {
return res.status(401).json({
success: false,
error: { code: 'AUTH_001', message: 'Yêu cầu xác thực' }
});
}
// Xác minh token
const payload = await jwtService.verifyAccessToken(token);
// Gắn user vào request
req.user = {
id: payload.sub,
userId: payload.sub,
email: payload.email,
roles: payload.roles || [],
permissions: payload.permissions || []
};
next();
} catch (error) {
logger.warn('Xác thực thất bại', { error: error.message });
return res.status(401).json({
success: false,
error: { code: 'AUTH_002', message: 'Token không hợp lệ hoặc hết hạn' }
});
}
};
};
```
#### Permission-Based Authorization / Phân Quyền Dựa Trên Quyền
**EN**: Example from `services/iam-service/src/middlewares/rbac.middleware.ts`:
```typescript
export const requirePermission = (
resource: string,
action: string,
scope?: string
) => {
return async (req: Request, res: Response, next: NextFunction) => {
const userId = req.user?.id || req.user?.sub;
if (!userId) {
return res.status(401).json({
success: false,
error: { code: 'UNAUTHORIZED', message: 'Authentication required' }
});
}
const hasPermission = await rbacService.hasPermission(
userId,
resource,
action,
scope
);
if (!hasPermission) {
return res.status(403).json({
success: false,
error: {
code: 'INSUFFICIENT_PERMISSIONS',
message: `Requires ${action} permission on ${resource}`
}
});
}
next();
};
};
```
**VI**: Ví dụ từ `services/iam-service/src/middlewares/rbac.middleware.ts`:
```typescript
export const requirePermission = (
resource: string,
action: string,
scope?: string
) => {
return async (req: Request, res: Response, next: NextFunction) => {
const userId = req.user?.id || req.user?.sub;
if (!userId) {
return res.status(401).json({
success: false,
error: { code: 'UNAUTHORIZED', message: 'Yêu cầu xác thực' }
});
}
const hasPermission = await rbacService.hasPermission(
userId,
resource,
action,
scope
);
if (!hasPermission) {
return res.status(403).json({
success: false,
error: {
code: 'INSUFFICIENT_PERMISSIONS',
message: `Yêu cầu quyền ${action} trên ${resource}`
}
});
}
next();
};
};
```
### Input Validation / Xác Thực Đầu Vào
**EN**: Example from `services/iam-service/src/middlewares/validation.middleware.ts`:
```typescript
import { AnyZodObject, ZodError } from 'zod';
export const validateDto = (
schema: AnyZodObject,
property: 'body' | 'query' | 'params' = 'body'
) => {
return (req: Request, res: Response, next: NextFunction) => {
try {
// Sanitize input by trimming strings
const sanitizedData = sanitizeInput(req[property]);
// Validate the sanitized data
const validatedData = schema.parse(sanitizedData);
// Replace original data with validated data
(req as any)[property] = validatedData;
next();
} catch (error) {
if (error instanceof ZodError) {
return res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Invalid request data',
details: error.errors.map(err => ({
field: err.path.join('.'),
message: err.message,
code: err.code
}))
}
});
}
throw error;
}
};
};
function sanitizeInput(data: any): any {
if (typeof data === 'string') {
return data.trim();
}
if (Array.isArray(data)) {
return data.map(sanitizeInput);
}
if (data !== null && typeof data === 'object') {
const sanitized: any = {};
for (const [key, value] of Object.entries(data)) {
sanitized[key] = sanitizeInput(value);
}
return sanitized;
}
return data;
}
```
**VI**: Ví dụ từ `services/iam-service/src/middlewares/validation.middleware.ts`:
```typescript
import { AnyZodObject, ZodError } from 'zod';
export const validateDto = (
schema: AnyZodObject,
property: 'body' | 'query' | 'params' = 'body'
) => {
return (req: Request, res: Response, next: NextFunction) => {
try {
// Làm sạch đầu vào bằng cách cắt chuỗi
const sanitizedData = sanitizeInput(req[property]);
// Xác thực dữ liệu đã được làm sạch
const validatedData = schema.parse(sanitizedData);
// Thay thế dữ liệu gốc bằng dữ liệu đã xác thực
(req as any)[property] = validatedData;
next();
} catch (error) {
if (error instanceof ZodError) {
return res.status(400).json({
success: false,
error: {
code: 'VALIDATION_ERROR',
message: 'Dữ liệu request không hợp lệ',
details: error.errors.map(err => ({
field: err.path.join('.'),
message: err.message,
code: err.code
}))
}
});
}
throw error;
}
};
};
function sanitizeInput(data: any): any {
if (typeof data === 'string') {
return data.trim();
}
if (Array.isArray(data)) {
return data.map(sanitizeInput);
}
if (data !== null && typeof data === 'object') {
const sanitized: any = {};
for (const [key, value] of Object.entries(data)) {
sanitized[key] = sanitizeInput(value);
}
return sanitized;
}
return data;
}
```
### Rate Limiting / Giới Hạn Tốc Độ
**EN**: Example from `services/iam-service/src/middlewares/rate-limit.middleware.ts`:
```typescript
import rateLimit from 'express-rate-limit';
import { RateLimiterRedis } from 'rate-limit-redis';
import { getRedisClient } from '../config/redis.config';
export const dynamicRateLimit = async (
req: Request,
res: Response,
next: NextFunction
) => {
const userId = req.user?.id || req.user?.sub;
// Default limits
let windowMs = 15 * 60 * 1000; // 15 minutes
let max = 100; // 100 requests
if (userId) {
const roles = await rbacService.getUserRoles(userId);
// Set limits based on role
if (roles.includes('SUPER_ADMIN')) {
max = 1000;
} else if (roles.includes('ADMIN')) {
max = 500;
} else if (roles.includes('MODERATOR')) {
max = 300;
}
} else {
// Unauthenticated users - stricter limits
max = 50;
}
const limiter = rateLimit({
windowMs,
max,
store: new RateLimiterRedis({
client: getRedisClient(),
prefix: 'rl:'
}),
handler: (req, res) => {
res.status(429).json({
success: false,
error: {
code: 'RATE_LIMIT_EXCEEDED',
message: 'Too many requests, please try again later'
}
});
}
});
limiter(req, res, next);
};
```
**VI**: Ví dụ từ `services/iam-service/src/middlewares/rate-limit.middleware.ts`:
```typescript
import rateLimit from 'express-rate-limit';
import { RateLimiterRedis } from 'rate-limit-redis';
import { getRedisClient } from '../config/redis.config';
export const dynamicRateLimit = async (
req: Request,
res: Response,
next: NextFunction
) => {
const userId = req.user?.id || req.user?.sub;
// Giới hạn mặc định
let windowMs = 15 * 60 * 1000; // 15 phút
let max = 100; // 100 requests
if (userId) {
const roles = await rbacService.getUserRoles(userId);
// Đặt giới hạn dựa trên vai trò
if (roles.includes('SUPER_ADMIN')) {
max = 1000;
} else if (roles.includes('ADMIN')) {
max = 500;
} else if (roles.includes('MODERATOR')) {
max = 300;
}
} else {
// Người dùng chưa xác thực - giới hạn nghiêm ngặt hơn
max = 50;
}
const limiter = rateLimit({
windowMs,
max,
store: new RateLimiterRedis({
client: getRedisClient(),
prefix: 'rl:'
}),
handler: (req, res) => {
res.status(429).json({
success: false,
error: {
code: 'RATE_LIMIT_EXCEEDED',
message: 'Quá nhiều yêu cầu, vui lòng thử lại sau'
}
});
}
});
limiter(req, res, next);
};
```
### Security Headers / Header Bảo Mật
**EN**: Example from `services/iam-service/src/main.ts`:
```typescript
import helmet from 'helmet';
import cors from 'cors';
// Security middleware
app.use(helmet());
app.use(cors({
origin: appConfig.corsOrigin,
credentials: true
}));
```
**VI**: Ví dụ từ `services/iam-service/src/main.ts`:
```typescript
import helmet from 'helmet';
import cors from 'cors';
// Middleware bảo mật
app.use(helmet());
app.use(cors({
origin: appConfig.corsOrigin,
credentials: true
}));
```
**EN**: Traefik security headers from `infra/traefik/dynamic/middlewares.yml`:
```yaml
http:
middlewares:
secure-headers:
headers:
sslRedirect: true
stsSeconds: 31536000
contentTypeNosniff: true
browserXssFilter: true
frameDeny: true
customRequestHeaders:
X-Forwarded-Proto: "https"
```
**VI**: Header bảo mật Traefik từ `infra/traefik/dynamic/middlewares.yml`:
```yaml
http:
middlewares:
secure-headers:
headers:
sslRedirect: true
stsSeconds: 31536000
contentTypeNosniff: true
browserXssFilter: true
frameDeny: true
customRequestHeaders:
X-Forwarded-Proto: "https"
```
### Audit Logging / Ghi Log Kiểm Toán
**EN**: Example from `services/iam-service/src/core/events/audit.service.ts`:
```typescript
export class AuditService {
async logAuthEvent(
eventType: string,
data: {
userId?: string;
success: boolean;
errorMessage?: string;
ipAddress?: string;
userAgent?: string;
metadata?: any;
}
): Promise<void> {
await this.prisma.authEvent.create({
data: {
userId: data.userId || null,
eventType,
eventData: data.metadata || {},
ipAddress: data.ipAddress,
userAgent: data.userAgent,
success: data.success,
errorMessage: data.errorMessage
}
});
}
}
```
**VI**: Ví dụ từ `services/iam-service/src/core/events/audit.service.ts`:
```typescript
export class AuditService {
async logAuthEvent(
eventType: string,
data: {
userId?: string;
success: boolean;
errorMessage?: string;
ipAddress?: string;
userAgent?: string;
metadata?: any;
}
): Promise<void> {
await this.prisma.authEvent.create({
data: {
userId: data.userId || null,
eventType,
eventData: data.metadata || {},
ipAddress: data.ipAddress,
userAgent: data.userAgent,
success: data.success,
errorMessage: data.errorMessage
}
});
}
}
```
## Best Practices / Thực Hành Tốt Nhất
### Password Security / Bảo Mật Mật Khẩu
**EN**:
- Always use bcrypt with cost factor 12+ in production
- Never log passwords or password hashes
- Use strong password requirements (min 8 chars, uppercase, lowercase, number, special char)
- Implement password reset with secure tokens
**VI**:
- Luôn sử dụng bcrypt với hệ số chi phí 12+ trong production
- Không bao giờ ghi log mật khẩu hoặc hash mật khẩu
- Sử dụng yêu cầu mật khẩu mạnh (tối thiểu 8 ký tự, chữ hoa, chữ thường, số, ký tự đặc biệt)
- Triển khai đặt lại mật khẩu với token an toàn
### Token Security / Bảo Mật Token
**EN**:
- Hash tokens before storing in database
- Use short-lived access tokens (15 minutes)
- Use longer-lived refresh tokens (7 days) with rotation
- Store refresh tokens securely (httpOnly cookies)
- Implement token revocation
**VI**:
- Hash token trước khi lưu vào database
- Sử dụng access token có thời gian sống ngắn (15 phút)
- Sử dụng refresh token có thời gian sống dài hơn (7 ngày) với xoay vòng
- Lưu trữ refresh token an toàn (httpOnly cookies)
- Triển khai thu hồi token
### SQL Injection Prevention / Ngăn Chặn SQL Injection
**EN**:
- Always use Prisma parameterized queries (automatic)
- Never use string concatenation for queries
- Validate and sanitize all inputs
**VI**:
- Luôn sử dụng truy vấn tham số hóa của Prisma (tự động)
- Không bao giờ sử dụng nối chuỗi cho truy vấn
- Xác thực và làm sạch tất cả đầu vào
## Examples from Project / Ví Dụ Từ Dự Án
### Authentication Middleware / Middleware Xác Thực
**EN**: See `services/iam-service/src/middlewares/auth.middleware.ts` for complete authentication implementation.
**VI**: Xem `services/iam-service/src/middlewares/auth.middleware.ts` để có implementation xác thực hoàn chỉnh.
### RBAC Middleware / Middleware RBAC
**EN**: See `services/iam-service/src/middlewares/rbac.middleware.ts` for permission-based authorization.
**VI**: Xem `services/iam-service/src/middlewares/rbac.middleware.ts` để có phân quyền dựa trên quyền.
### Validation Middleware / Middleware Xác Thực
**EN**: See `services/iam-service/src/middlewares/validation.middleware.ts` for input validation patterns.
**VI**: Xem `services/iam-service/src/middlewares/validation.middleware.ts` để có các mẫu xác thực đầu vào.
### Rate Limiting / Giới Hạn Tốc Độ
**EN**: See `services/iam-service/src/middlewares/rate-limit.middleware.ts` for dynamic rate limiting.
**VI**: Xem `services/iam-service/src/middlewares/rate-limit.middleware.ts` để có giới hạn tốc độ động.
## Quick Reference / Tham Khảo Nhanh
### Security Checklist / Danh Sách Kiểm Tra Bảo Mật
**EN**: Before deploying any service:
- [ ] All endpoints require authentication (except public)
- [ ] Authorization checks implemented (RBAC/ABAC)
- [ ] Input validation with Zod schemas
- [ ] Rate limiting configured
- [ ] Error messages sanitized (no info disclosure)
- [ ] PII encrypted at rest
- [ ] Passwords hashed with bcrypt (cost 12+)
- [ ] Tokens hashed before storing
- [ ] Secrets in environment variables (never hardcoded)
- [ ] HTTPS enforced (TLS 1.2+)
- [ ] CORS configured correctly
- [ ] Security headers set (helmet)
- [ ] Audit logging enabled
- [ ] SQL injection prevented (use Prisma)
- [ ] XSS prevention (input sanitization)
- [ ] File upload validation
- [ ] Security tests passing
**VI**: Trước khi triển khai bất kỳ service nào:
- [ ] Tất cả endpoint yêu cầu xác thực (trừ public)
- [ ] Kiểm tra phân quyền đã triển khai (RBAC/ABAC)
- [ ] Xác thực đầu vào với Zod schemas
- [ ] Giới hạn tốc độ đã cấu hình
- [ ] Thông báo lỗi đã được làm sạch (không tiết lộ thông tin)
- [ ] PII được mã hóa khi nghỉ
- [ ] Mật khẩu được hash với bcrypt (chi phí 12+)
- [ ] Token được hash trước khi lưu
- [ ] Bí mật trong biến môi trường (không bao giờ hardcode)
- [ ] HTTPS được bắt buộc (TLS 1.2+)
- [ ] CORS được cấu hình đúng
- [ ] Header bảo mật được đặt (helmet)
- [ ] Ghi log kiểm toán được bật
- [ ] SQL injection được ngăn chặn (sử dụng Prisma)
- [ ] Ngăn chặn XSS (làm sạch đầu vào)
- [ ] Xác thực tải lên tệp
- [ ] Kiểm tra bảo mật đã vượt qua
## Related Skills / Skills Liên Quan
- **[Project Rules](./project-rules.md)** - Coding standards and architecture
- **[API Design](./api-design.md)** - Secure API design patterns
- **[Testing Patterns](./testing-patterns.md)** - Security testing
## Resources / Tài Nguyên
**EN**:
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [OWASP API Security Top 10](https://owasp.org/www-project-api-security/)
- [Node.js Security Best Practices](https://nodejs.org/en/docs/guides/security/)
- [Express Security Best Practices](https://expressjs.com/en/advanced/best-practice-security.html)
**VI**:
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [OWASP API Security Top 10](https://owasp.org/www-project-api-security/)
- [Thực Hành Bảo Mật Node.js](https://nodejs.org/en/docs/guides/security/)
- [Thực Hành Bảo Mật Express](https://expressjs.com/en/advanced/best-practice-security.html)

View File

@@ -0,0 +1,738 @@
# Testing Patterns / Các Pattern Testing
> **EN**: Comprehensive testing best practices for GoodGo microservices including unit tests, integration tests, E2E tests, Jest configuration, mocking strategies, and debugging techniques.
> **VI**: Các thực hành tốt nhất về testing cho microservices GoodGo bao gồm unit tests, integration tests, E2E tests, cấu hình Jest, strategies mocking, và kỹ thuật debugging.
## Overview / Tổng Quan
**EN**: Testing is a critical component of the GoodGo microservices platform. This guide provides comprehensive patterns and best practices for writing maintainable, reliable tests across all services. It covers test types, Jest configuration, mocking strategies, test utilities, and debugging techniques that ensure code quality and reliability.
**VI**: Testing là thành phần quan trọng của nền tảng microservices GoodGo. Hướng dẫn này cung cấp các patterns và best practices toàn diện để viết các test có thể bảo trì và đáng tin cậy trên tất cả các services. Nó bao gồm các loại test, cấu hình Jest, strategies mocking, test utilities, và kỹ thuật debugging để đảm bảo chất lượng và độ tin cậy của code.
## When to Use / Khi Nào Sử Dụng
**EN**: Use these testing patterns when:
- Writing unit tests for services, controllers, or repositories
- Creating integration tests for middleware chains
- Building E2E tests for API endpoints
- Setting up Jest configuration for a new service
- Mocking external dependencies (Prisma, Redis, Auth SDK)
- Debugging test failures
- Improving test coverage
- Creating test utilities and factories
**VI**: Sử dụng các testing patterns này khi:
- Viết unit tests cho services, controllers, hoặc repositories
- Tạo integration tests cho middleware chains
- Xây dựng E2E tests cho API endpoints
- Thiết lập cấu hình Jest cho service mới
- Mocking các dependencies bên ngoài (Prisma, Redis, Auth SDK)
- Debugging test failures
- Cải thiện test coverage
- Tạo test utilities và factories
## Key Concepts / Khái Niệm Chính
### Test Types / Các Loại Test
#### 1. Unit Tests / Unit Tests
**EN**: Test individual functions or classes in isolation with all dependencies mocked.
**VI**: Test các functions hoặc classes riêng lẻ một cách cô lập với tất cả dependencies được mock.
**Characteristics / Đặc điểm**:
- **Location / Vị trí**: Next to source files (`*.test.ts`) or in `__tests__/` directory
- **Scope / Phạm vi**: Single function, method, or class
- **Dependencies / Dependencies**: All external dependencies mocked
- **Speed / Tốc độ**: Fast (<1s per test)
- **Purpose / Mục đích**: Verify logic correctness
**Example / Ví dụ**: [`services/iam-service/src/modules/feature/__tests__/feature.service.test.ts`](../../../services/iam-service/src/modules/feature/__tests__/feature.service.test.ts)
#### 2. Integration Tests / Integration Tests
**EN**: Test multiple components working together with some real dependencies.
**VI**: Test nhiều components làm việc cùng nhau với một số dependencies thật.
**Characteristics / Đặc điểm**:
- **Location / Vị trí**: `__tests__/` directory (`*.test.ts`)
- **Scope / Phạm vi**: Multiple components interacting
- **Dependencies / Dependencies**: Mix of real and mocked dependencies
- **Speed / Tốc độ**: Medium (1-5s per test)
- **Purpose / Mục đích**: Verify component integration
**Example / Ví dụ**: [`services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts`](../../../services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts)
#### 3. E2E Tests / E2E Tests
**EN**: Test complete request/response cycles through the entire application stack.
**VI**: Test các chu kỳ request/response hoàn chỉnh qua toàn bộ application stack.
**Characteristics / Đặc điểm**:
- **Location / Vị trí**: `__tests__/*.e2e.ts`
- **Scope / Phạm vi**: Full API workflow from HTTP request to response
- **Dependencies / Dependencies**: Test database, mocked external services
- **Speed / Tốc độ**: Slow (5-10s per test)
- **Purpose / Mục đích**: Verify end-to-end functionality
**Example / Ví dụ**: [`services/iam-service/src/__tests__/feature.e2e.ts`](../../../services/iam-service/src/__tests__/feature.e2e.ts)
## Jest Configuration / Cấu Hình Jest
### Standard Configuration / Cấu Hình Chuẩn
The standard Jest configuration for GoodGo services includes TypeScript support, coverage thresholds, and proper test environment setup.
**Location / Vị trí**: [`services/iam-service/jest.config.ts`](../../../services/iam-service/jest.config.ts)
```typescript
import type { Config } from 'jest';
const config: Config = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: [
'**/__tests__/**/*.test.ts',
'**/__tests__/**/*.spec.ts',
'**/__tests__/**/*.e2e.ts',
'**/?(*.)+(spec|test).ts'
],
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.d.ts',
'!src/main.ts',
'!src/config/**/*.ts',
'!src/**/*.config.ts'
],
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov', 'html'],
coverageThreshold: {
global: {
branches: 70,
functions: 70,
lines: 70,
statements: 70
}
},
setupFilesAfterEnv: ['<rootDir>/src/__tests__/setupTests.ts'],
testTimeout: 10000,
clearMocks: true,
resetModules: true
};
export default config;
```
### Key Configuration Points / Điểm Cấu Hình Quan Trọng
- **preset: 'ts-jest'**: Enables TypeScript support / Bật hỗ trợ TypeScript
- **testEnvironment: 'node'**: Sets Node.js environment (not browser) / Thiết lập môi trường Node.js (không phải browser)
- **coverageThreshold**: Enforces minimum 70% coverage across all metrics / Yêu cầu tối thiểu 70% coverage trên tất cả các metrics
- **setupFilesAfterEnv**: Loads test setup file before each test suite / Tải file setup test trước mỗi test suite
- **clearMocks**: Automatically clears mock calls between tests / Tự động xóa mock calls giữa các test
- **resetModules**: Resets module cache for test isolation / Reset module cache để cô lập test
## Setup Files / Files Thiết Lập
### Test Setup File / File Thiết Lập Test
The setup file (`setupTests.ts`) configures global mocks and test utilities that are available across all tests.
**Location / Vị trí**: [`services/iam-service/src/__tests__/setupTests.ts`](../../../services/iam-service/src/__tests__/setupTests.ts)
**Key Features / Tính Năng Chính**:
- Mock external services (logger, tracing, database, Redis) / Mock các services bên ngoài
- Configure test environment variables / Cấu hình biến môi trường test
- Set up global test utilities / Thiết lập test utilities toàn cục
- Initialize Prometheus mocks / Khởi tạo Prometheus mocks
**Example / Ví dụ**:
```typescript
import { jest } from '@jest/globals';
// EN: Mock environment variables for tests
// VI: Mock biến môi trường cho tests
process.env.NODE_ENV = 'test';
process.env.DATABASE_URL = 'postgresql://test:test@localhost:5432/test_db';
process.env.REDIS_URL = 'redis://localhost:6379/1';
// EN: Mock external services to avoid real network calls
// VI: Mock các service bên ngoài để tránh gọi mạng thật
jest.mock('@goodgo/logger', () => ({
logger: {
info: jest.fn(),
error: jest.fn(),
warn: jest.fn(),
debug: jest.fn(),
},
}));
// EN: Global test utilities
// VI: Utilities test toàn cục
global.testUtils = {
createMockReq: (overrides = {}) => ({
body: {},
params: {},
query: {},
headers: {},
...overrides,
}),
createMockRes: () => {
const res: any = {};
res.status = jest.fn().mockReturnValue(res);
res.json = jest.fn().mockReturnValue(res);
res.send = jest.fn().mockReturnValue(res);
return res;
},
createMockNext: () => jest.fn(),
};
```
## Common Patterns / Các Pattern Thường Dùng
### Unit Test Pattern / Pattern Unit Test
**Structure / Cấu trúc**: Follow the AAA (Arrange-Act-Assert) pattern for clarity / Tuân theo pattern AAA để rõ ràng.
```typescript
describe('FeatureService', () => {
let service: FeatureService;
let mockRepository: any;
beforeEach(() => {
// EN: Clear all mocks before each test
// VI: Xóa tất cả mocks trước mỗi test
jest.clearAllMocks();
mockRepository = {
findById: jest.fn(),
create: jest.fn(),
};
service = new FeatureService(mockRepository);
});
describe('create', () => {
it('should create a feature successfully', async () => {
// EN: Arrange
// VI: Chuẩn bị
const testData = { name: 'test-feature', title: 'Test Feature' };
const mockFeature = {
id: 'test-id',
name: testData.name,
// ... other fields
};
mockRepository.create.mockResolvedValue(mockFeature);
// EN: Act
// VI: Thực hiện
const result = await service.create(testData);
// EN: Assert
// VI: Kiểm tra
expect(mockRepository.create).toHaveBeenCalledWith(testData);
expect(result).toEqual(mockFeature);
});
});
});
```
**Real Example / Ví dụ Thực tế**: [`services/iam-service/src/modules/feature/__tests__/feature.service.test.ts`](../../../services/iam-service/src/modules/feature/__tests__/feature.service.test.ts)
### Integration Test Pattern / Pattern Integration Test
Integration tests verify that multiple components work together correctly / Integration tests xác minh nhiều components làm việc cùng nhau đúng cách.
```typescript
describe('Auth Middleware', () => {
const mockNext = jest.fn();
beforeEach(() => {
jest.clearAllMocks();
});
it('should authenticate valid token and attach user to request', () => {
// EN: Arrange
// VI: Chuẩn bị
const mockReq = createMockReq({
headers: { authorization: 'Bearer valid-token' },
});
const mockRes = createMockRes();
// EN: Act
// VI: Thực hiện
const middleware = authenticate({ secret: jwtSecret });
middleware(mockReq as Request, mockRes as Response, mockNext);
// EN: Assert
// VI: Kiểm tra
expect(mockNext).toHaveBeenCalled();
expect(mockReq.user).toBeDefined();
});
});
```
**Real Example / Ví dụ Thực tế**: [`services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts`](../../../services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts)
### E2E Test Pattern / Pattern E2E Test
E2E tests use supertest to test complete HTTP request/response cycles / E2E tests sử dụng supertest để test các chu kỳ HTTP request/response hoàn chỉnh.
```typescript
import request from 'supertest';
import express from 'express';
import { createRouter } from '../routes';
describe('Feature Endpoints E2E', () => {
let app: express.Application;
beforeAll(() => {
// EN: Set up test environment
// VI: Thiết lập môi trường test
process.env.NODE_ENV = 'test';
app = express();
app.use(express.json());
app.use(createRouter());
});
describe('POST /api/v1/features', () => {
it('should create a feature successfully', async () => {
// EN: Arrange
// VI: Chuẩn bị
const featureData = {
name: 'test-feature',
title: 'Test Feature',
description: 'A test feature for E2E testing'
};
// EN: Act
// VI: Thực hiện
const response = await request(app)
.post('/api/v1/features')
.send(featureData)
.expect(201);
// EN: Assert
// VI: Kiểm tra
expect(response.body).toMatchObject({
success: true,
message: 'Feature created successfully / Feature đã được tạo thành công',
});
});
});
});
```
**Real Example / Ví dụ Thực tế**: [`services/iam-service/src/__tests__/feature.e2e.ts`](../../../services/iam-service/src/__tests__/feature.e2e.ts)
## Mocking Strategies / Chiến Lược Mocking
### Mock Prisma Database / Mock Database Prisma
Mock Prisma client to avoid real database connections in unit tests / Mock Prisma client để tránh kết nối database thật trong unit tests.
```typescript
// In setupTests.ts or individual test files
jest.mock('../config/database.config', () => ({
connectDatabase: jest.fn(),
prisma: {
$queryRaw: jest.fn(),
$disconnect: jest.fn(),
feature: {
create: jest.fn(),
findMany: jest.fn(),
findUnique: jest.fn(),
update: jest.fn(),
delete: jest.fn(),
},
},
}));
// Usage in tests
const { prisma } = require('../config/database.config');
test('should create user', async () => {
prisma.feature.create.mockResolvedValue({
id: 'test-id',
name: 'test-feature',
// ... other fields
});
const result = await createFeature({ name: 'test-feature' });
expect(result).toBeDefined();
});
```
### Mock Redis / Mock Redis
Mock Redis client for caching and session management tests / Mock Redis client cho các test caching và quản lý session.
```typescript
jest.mock('../config/redis.config', () => ({
getRedisClient: jest.fn().mockReturnValue({
call: jest.fn(),
connect: jest.fn(),
disconnect: jest.fn(),
}),
}));
```
### Mock External APIs / Mock External APIs
Mock external HTTP calls using Jest mocks / Mock các HTTP calls bên ngoài sử dụng Jest mocks.
```typescript
jest.mock('axios');
import axios from 'axios';
const mockedAxios = axios as jest.Mocked<typeof axios>;
test('should fetch external data', async () => {
mockedAxios.get.mockResolvedValue({
data: { result: 'success' }
});
const result = await fetchExternalData();
expect(result).toEqual({ result: 'success' });
});
```
### Mock Auth SDK / Mock Auth SDK
Mock authentication SDK functions for middleware and service tests / Mock các functions của authentication SDK cho middleware và service tests.
```typescript
jest.mock('@goodgo/auth-sdk', () => ({
createToken: jest.fn(),
verifyToken: jest.fn(),
extractTokenFromHeader: jest.fn(),
}));
// Setup mock implementations
(verifyToken as jest.Mock).mockImplementation((token) => {
if (token === 'valid-token') {
return { userId: '123', role: 'user' };
}
throw new Error('Invalid token');
});
```
## Testing Utilities / Utilities Test
### Test Factory Pattern / Pattern Test Factory
Create reusable test data factories for consistent test data / Tạo các factories dữ liệu test có thể tái sử dụng để có dữ liệu test nhất quán.
```typescript
export class TestFactory {
static createUser(overrides = {}) {
return {
id: 'test-user-1',
email: 'test@example.com',
name: 'Test User',
createdAt: new Date(),
...overrides
};
}
static createAuthToken(userId: string) {
return jwt.sign({ userId }, 'test-secret');
}
static async cleanDatabase() {
await prisma.user.deleteMany();
await prisma.feature.deleteMany();
}
}
// Usage
const user = TestFactory.createUser({ name: 'Custom Name' });
const token = TestFactory.createAuthToken(user.id);
```
### Mock Request/Response Helpers / Helpers Mock Request/Response
Use global test utilities for creating mock Express request/response objects / Sử dụng test utilities toàn cục để tạo các objects mock Express request/response.
```typescript
// Available via global.testUtils (from setupTests.ts)
const mockReq = global.testUtils.createMockReq({
headers: { authorization: 'Bearer token' },
params: { id: '123' },
});
const mockRes = global.testUtils.createMockRes();
const mockNext = global.testUtils.createMockNext();
```
## Common Test Scenarios / Các Tình Huống Test Thường Gặp
### Testing Error Handling / Test Xử Lý Lỗi
```typescript
it('should handle database errors gracefully', async () => {
// EN: Arrange - Mock database error
// VI: Chuẩn bị - Mock lỗi database
prismaMock.user.findUnique.mockRejectedValue(
new Error('Database connection failed')
);
// EN: Act & Assert
// VI: Thực hiện & Kiểm tra
await expect(userService.findById('123')).rejects.toThrow();
// Or for HTTP endpoints
const response = await request(app)
.get('/api/users/123')
.expect(500);
expect(response.body).toEqual({
success: false,
error: {
code: 'INTERNAL_ERROR',
message: 'Internal server error / Lỗi máy chủ nội bộ',
},
});
});
```
### Testing Validation / Test Validation
```typescript
describe('Validation', () => {
it('should reject invalid email', async () => {
const response = await request(app)
.post('/api/auth/register')
.send({ email: 'invalid-email', password: '123456' })
.expect(400);
expect(response.body.error.code).toBe('VALIDATION_ERROR');
});
});
```
### Testing Authorization / Test Authorization
```typescript
it('should deny access for user with incorrect role', () => {
const mockReq = createMockReq({
user: { userId: 'user-123', role: 'user' },
});
const middleware = authorize('admin');
middleware(mockReq as Request, mockRes as Response, mockNext);
expect(mockNext).not.toHaveBeenCalled();
expect(mockStatus).toHaveBeenCalledWith(403);
});
```
## Test Commands / Lệnh Test
Add these scripts to `package.json` / Thêm các scripts này vào `package.json`:
```json
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:unit": "jest --testPathPattern=\\.test\\.ts$",
"test:e2e": "jest --testPathPattern=\\.e2e\\.ts$",
"test:ci": "jest --coverage --silent --maxWorkers=2"
}
}
```
**Usage / Sử dụng**:
- `pnpm test`: Run all tests / Chạy tất cả tests
- `pnpm test:watch`: Run tests in watch mode / Chạy tests ở chế độ watch
- `pnpm test:coverage`: Generate coverage report / Tạo báo cáo coverage
- `pnpm test:unit`: Run only unit tests / Chỉ chạy unit tests
- `pnpm test:e2e`: Run only E2E tests / Chỉ chạy E2E tests
- `pnpm test:ci`: Run tests optimized for CI/CD / Chạy tests tối ưu cho CI/CD
## Debugging Tests / Debugging Tests
### VS Code Debug Configuration / Cấu Hình Debug VS Code
Create `.vscode/launch.json` for debugging tests / Tạo `.vscode/launch.json` để debug tests:
```json
{
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Debug Jest Tests",
"runtimeExecutable": "npm",
"runtimeArgs": ["test", "--", "--runInBand"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen"
}
]
}
```
### Debug Tips / Mẹo Debug
1. **Use `test.only()`** to run a single test / Sử dụng `test.only()` để chạy một test duy nhất:
```typescript
it.only('should test specific behavior', () => {
// Only this test will run
});
```
2. **Use `--detectOpenHandles`** for async issues / Sử dụng `--detectOpenHandles` cho các vấn đề async:
```bash
pnpm test --detectOpenHandles
```
3. **Use `--runInBand`** for sequential execution / Sử dụng `--runInBand` cho thực thi tuần tự:
```bash
pnpm test --runInBand
```
4. **Add temporary console.log** / Thêm console.log tạm thời:
```typescript
console.log('Debug value:', someValue);
```
5. **Use debugger breakpoints** in VS Code / Sử dụng breakpoints debugger trong VS Code
## Best Practices / Thực Hành Tốt Nhất
### Test Organization / Tổ Chức Test
- ✅ Each test is independent and isolated / Mỗi test độc lập và cô lập
- ✅ Tests follow AAA pattern (Arrange-Act-Assert) / Tests tuân theo pattern AAA
- ✅ Use descriptive test names that explain what is being tested / Sử dụng tên test mô tả giải thích điều đang được test
- ✅ Group related tests using `describe` blocks / Nhóm các test liên quan sử dụng `describe` blocks
- ✅ Use `beforeEach`/`afterEach` for setup/cleanup / Sử dụng `beforeEach`/`afterEach` cho setup/cleanup
### Mocking / Mocking
- ✅ Mock external dependencies (database, APIs, services) / Mock các dependencies bên ngoài
- ✅ Use `jest.clearAllMocks()` in `beforeEach` to reset mocks / Sử dụng `jest.clearAllMocks()` trong `beforeEach` để reset mocks
- ✅ Verify mock calls to ensure correct behavior / Xác minh mock calls để đảm bảo hành vi đúng
- ✅ Keep mocks simple and focused / Giữ mocks đơn giản và tập trung
### Coverage / Coverage
- ✅ Maintain >70% code coverage (as per Jest config) / Duy trì >70% code coverage (theo cấu hình Jest)
- ✅ Focus on covering critical business logic / Tập trung vào bao phủ logic nghiệp vụ quan trọng
- ✅ Don't sacrifice test quality for coverage percentage / Không hy sinh chất lượng test cho phần trăm coverage
- ✅ Review coverage reports regularly / Xem xét báo cáo coverage thường xuyên
### Test Data / Dữ Liệu Test
- ✅ Use factories for creating test data / Sử dụng factories để tạo dữ liệu test
- ✅ Keep test data realistic and representative / Giữ dữ liệu test thực tế và đại diện
- ✅ Clean up test data after tests (if using real database) / Dọn dẹp dữ liệu test sau tests (nếu dùng database thật)
- ✅ Use meaningful test values, not just `'test'` or `123` / Sử dụng giá trị test có ý nghĩa, không chỉ `'test'` hoặc `123`
### Error Testing / Test Lỗi
- ✅ Test both success and error scenarios / Test cả kịch bản thành công và lỗi
- ✅ Test edge cases and boundary conditions / Test edge cases và điều kiện biên
- ✅ Test validation errors / Test lỗi validation
- ✅ Test error messages and error codes / Test thông báo lỗi và mã lỗi
### Performance / Hiệu Suất
- ✅ Keep unit tests fast (<1s each) / Giữ unit tests nhanh (<1s mỗi test)
- ✅ Avoid unnecessary async operations in unit tests / Tránh các thao tác async không cần thiết trong unit tests
- ✅ Use `--maxWorkers` in CI for parallel execution / Sử dụng `--maxWorkers` trong CI cho thực thi song song
- ✅ Don't test implementation details, test behavior / Không test chi tiết implementation, test hành vi
## Examples from Project / Ví Dụ Từ Dự Án
### Real Test Examples / Ví Dụ Test Thực Tế
1. **Unit Test**: [`services/iam-service/src/modules/feature/__tests__/feature.service.test.ts`](../../../services/iam-service/src/modules/feature/__tests__/feature.service.test.ts)
2. **Integration Test**: [`services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts`](../../../services/iam-service/src/middlewares/__tests__/auth.middleware.test.ts)
3. **E2E Test**: [`services/iam-service/src/__tests__/feature.e2e.ts`](../../../services/iam-service/src/__tests__/feature.e2e.ts)
4. **Setup File**: [`services/iam-service/src/__tests__/setupTests.ts`](../../../services/iam-service/src/__tests__/setupTests.ts)
5. **Jest Config**: [`services/iam-service/jest.config.ts`](../../../services/iam-service/jest.config.ts)
### Test Structure Examples / Ví Dụ Cấu Trúc Test
- **Repository Tests**: [`services/iam-service/src/modules/feature/__tests__/feature.repository.test.ts`](../../../services/iam-service/src/modules/feature/__tests__/feature.repository.test.ts)
- **Controller Tests**: [`services/iam-service/src/modules/health/__tests__/health.controller.test.ts`](../../../services/iam-service/src/modules/health/__tests__/health.controller.test.ts)
- **Middleware Tests**: [`services/iam-service/src/middlewares/__tests__/correlation.middleware.test.ts`](../../../services/iam-service/src/middlewares/__tests__/correlation.middleware.test.ts)
## Quick Reference / Tham Khảo Nhanh
### Test Type Decision Tree / Cây Quyết Định Loại Test
```
Need to test complete HTTP flow?
├─ Yes → E2E Test (*.e2e.ts)
└─ No → Multiple components interacting?
├─ Yes → Integration Test (*.test.ts)
└─ No → Unit Test (*.test.ts)
```
### Common Jest Matchers / Các Matcher Jest Thường Dùng
| Matcher | Purpose / Mục đích | Example / Ví dụ |
|---------|-------------------|-----------------|
| `toBe()` | Exact equality / So sánh chính xác | `expect(value).toBe(5)` |
| `toEqual()` | Deep equality / So sánh sâu | `expect(obj).toEqual({a: 1})` |
| `toMatchObject()` | Partial match / So sánh một phần | `expect(obj).toMatchObject({a: 1})` |
| `toHaveBeenCalled()` | Function called / Function đã được gọi | `expect(mockFn).toHaveBeenCalled()` |
| `toHaveBeenCalledWith()` | Called with args / Gọi với args | `expect(mockFn).toHaveBeenCalledWith('arg')` |
| `toThrow()` | Throws error / Ném lỗi | `expect(() => fn()).toThrow()` |
| `toBeDefined()` | Not undefined / Không undefined | `expect(value).toBeDefined()` |
| `toBeNull()` | Is null / Là null | `expect(value).toBeNull()` |
| `toContain()` | Array/string contains / Chứa trong array/string | `expect(array).toContain('item')` |
### Mock Function Helpers / Helpers Mock Function
```typescript
// Create mock
const mockFn = jest.fn();
// Set return value
mockFn.mockReturnValue('value');
mockFn.mockResolvedValue('async value');
mockFn.mockRejectedValue(new Error('error'));
// Set implementation
mockFn.mockImplementation((arg) => arg * 2);
// Clear/reset
mockFn.mockClear(); // Clear call history
mockFn.mockReset(); // Reset to initial state
jest.clearAllMocks(); // Clear all mocks
```
## Related Skills / Skills Liên Quan
- **[Comment Code](./comment-code.md)**: Writing bilingual comments in tests / Viết comments song ngữ trong tests
- **[Security](./security.md)**: Testing security-critical code / Test code bảo mật quan trọng
- **[API Design](./api-design.md)**: Testing API endpoints and responses / Test API endpoints và responses
- **[Project Rules](./project-rules.md)**: Code organization for tests / Tổ chức code cho tests
## Resources / Tài Nguyên
### Official Documentation / Tài Liệu Chính Thức
- [Jest Documentation](https://jestjs.io/docs/getting-started)
- [Supertest Documentation](https://github.com/visionmedia/supertest)
- [jest-mock-extended](https://github.com/marchaos/jest-mock-extended)
### Internal Documentation / Tài Liệu Nội Bộ
- [Service Development Guide](../guides/development.md)
- [Local Development Setup](../guides/local-development.md)
- [Troubleshooting Guide](../guides/troubleshooting.md)
### Tools / Công Cụ
- **Jest**: JavaScript testing framework / Framework testing JavaScript
- **Supertest**: HTTP assertion library / Thư viện assertion HTTP
- **jest-mock-extended**: Enhanced mocking for TypeScript / Mock nâng cao cho TypeScript
- **ioredis-mock**: Redis mock for testing / Mock Redis cho testing