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

@@ -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