Files
Ho Ngoc Hai 76d75c753b Migrate
2026-05-23 18:37:02 +07:00

963 lines
31 KiB
Markdown

# Service Template / Template Dịch Vụ
> **EN**: Standard template for creating new microservices in the @goodgo ecosystem.
> **VI**: Template chuẩn để tạo các microservice mới trong hệ sinh thái @goodgo.
## Features / Tính Năng
- **Framework**: Express.js with TypeScript / Express.js với TypeScript.
- **Database**: Prisma ORM with PostgreSQL / Prisma ORM với PostgreSQL.
- **Validation**: Zod for environment & input validation / Zod cho validation biến môi trường và đầu vào.
- **Observability / Khả năng quan sát**:
- **Metrics**: Prometheus metrics at `/metrics` / Metrics Prometheus tại `/metrics`.
- **Logging**: Common logger with request tracking / Logger chung với theo dõi request.
- **Tracing**: OpenTelemetry/Jaeger integration / Tích hợp OpenTelemetry/Jaeger.
- **Resilience / Khả năng phục hồi**:
- Graceful shutdown / Đóng ứng dụng an toàn.
- Rate limiting (Distributed via Redis) / Giới hạn tốc độ request (Phân tán qua Redis).
- Circuit Breaker / Ngắt mạch.
- Health checks (liveness/readiness) / Kiểm tra sức khỏe hệ thống.
- **Caching**: Redis caching strategy / Chiến lược caching với Redis.
- **Security / Bảo mật**: Helmet & CORS configured / Đã cấu hình Helmet & CORS.
## Project Structure / Cấu trúc Dự án
```
src/
├── config/ # Configuration & Env validation / Cấu hình & Validate biến môi trường
├── middlewares/ # Express middlewares (error, logger, metrics)
├── modules/ # Feature modules (controller, service, repository)
├── routes/ # API route definitions
└── main.ts # Entry point & App bootstrapping
```
## Getting Started / Bắt đầu
### Prerequisites / Yêu cầu tiên quyết
- Node.js >= 20
- pnpm
- Docker (Redis required)
### Installation / Cài đặt
#### Option 1: Local Development / Phát triển Cục bộ
1. **Clone & Install dependencies**:
```bash
pnpm install
```
2. **Start infrastructure with Docker**:
For local development, start the platform infrastructure from `deployments/local/`:
Để phát triển local, khởi động hạ tầng nền tảng từ `deployments/local/`:
```bash
# Navigate to deployments directory
cd deployments/local
# Start platform services (PostgreSQL, Redis, Traefik, etc.)
docker-compose up -d redis
# Return to service directory
cd ../../services/_template
```
**Note**: For full platform deployment with all services, see "Adding This Service to the Platform" section below.
**Lưu ý**: Để triển khai nền tảng đầy đủ với tất cả services, xem phần "Thêm Service Vào Nền Tảng" bên dưới.
3. **Setup database**:
```bash
pnpm prisma migrate dev
pnpm prisma db seed
```
4. **Start development server**:
```bash
pnpm dev
```
2. **Environment Setup / Thiết lập môi trường**:
Environment variables are managed at the **platform level**, not per-service:
Biến môi trường được quản lý ở **cấp độ nền tảng**, không phải mỗi service:
```bash
# EN: Setup shared environment variables (from deployments/local/)
# VI: Thiết lập biến môi trường chung (từ deployments/local/)
cd deployments/local
cp env.local.example .env.local
# Edit .env.local with your values (JWT_SECRET, DATABASE_URL, etc.)
```
**Environment Variables / Biến Môi trường**:
**Shared Variables** (in `deployments/local/.env.local`):
- `JWT_SECRET`, `JWT_REFRESH_SECRET` - Must be same across all services
- `REDIS_HOST`, `REDIS_PORT` - Shared Redis instance
- `CORS_ORIGIN` - Allowed origins for all services
- `NODE_ENV`, `LOG_LEVEL` - Common configuration
**Service-Specific Variables** (in `docker-compose.yml`):
- `PORT` - Unique port for each service
- `DATABASE_URL` - Service's database connection
- `SERVICE_NAME` - Service identifier
**Key Environment Variables / Biến Môi Trường Chính**:
| Variable / Biến | Description / Mô tả | Default / Mặc định | Required / Bắt buộc |
|-----------------|---------------------|-------------------|---------------------|
| `PORT` | Server port / Cổng server | `5000` | No / Không |
| `NODE_ENV` | Environment mode / Chế độ môi trường | `development` | No / Không |
| `API_VERSION` | API version prefix / Tiền tố phiên bản API | `v1` | No / Không |
| `CORS_ORIGIN` | Allowed CORS origins (comma-separated) / Origins CORS được phép | `http://localhost:3000` | No / Không |
| `SERVICE_NAME` | Service identifier / Mã định danh service | `microservice-template` | No / Không |
| `DATABASE_URL` | PostgreSQL connection string / Chuỗi kết nối PostgreSQL | - | **Yes / Có** |
| `REDIS_URL` | Redis connection URL / URL kết nối Redis | `redis://localhost:6379` | No / Không |
| `JWT_SECRET` | JWT secret key for token signing and verification / Khóa bí mật JWT để ký và xác minh token | - | **Yes / Có** |
| `TRACING_ENABLED` | Enable Jaeger tracing / Bật tracing Jaeger | `false` | No / Không |
| `JAEGER_ENDPOINT` | Jaeger collector endpoint / Endpoint collector Jaeger | - | No / Không |
**Environment Configuration Priority / Ưu tiên Cấu hình Môi trường**:
1. **Docker Compose environment** (in `deployments/local/docker-compose.yml`) - Highest priority
2. **Shared `.env.local`** (in `deployments/local/.env.local`) - Platform-level shared configs
3. **System environment variables** - OS-level environment
3. **Database Setup / Thiết lập Database**:
**Prerequisites / Yêu cầu tiên quyết**:
- PostgreSQL database running / Database PostgreSQL đang chạy
- `DATABASE_URL` configured in `.env` / `DATABASE_URL` đã được cấu hình trong `.env`
**Database Workflow / Quy trình Database**:
```bash
# EN: Generate Prisma client / Tạo Prisma client
pnpm prisma:generate
# EN: Create and run initial migration / Tạo và chạy migration ban đầu
pnpm prisma:migrate
# EN: (Optional) Seed database with initial data / (Tùy chọn) Seed database với dữ liệu ban đầu
pnpm prisma:seed
```
**Development Workflow / Quy trình Phát triển**:
```bash
# EN: After schema changes, regenerate client / Sau khi thay đổi schema, tạo lại client
pnpm prisma:generate
# EN: Create new migration for schema changes / Tạo migration mới cho thay đổi schema
pnpm prisma:migrate dev --name your-migration-name
# EN: View database in Prisma Studio / Xem database trong Prisma Studio
pnpm prisma:studio
```
**Production Deployment / Triển khai Production**:
```bash
# EN: Deploy migrations to production / Triển khai migrations lên production
pnpm prisma:migrate deploy
# EN: Reset database (CAUTION: destroys all data) / Reset database (CẨN THẬN: xóa tất cả dữ liệu)
pnpm prisma:migrate reset
```
4. **Run Development / Chạy môi trường phát triển**:
```bash
pnpm dev
```
5. **Build & Start Production / Build và Chạy Production**:
```bash
pnpm build
pnpm start
```
## Adding This Service to the Platform / Thêm Service Vào Nền Tảng
This template represents a **single microservice**. To deploy it as part of the GoodGo microservices platform:
Template này đại diện cho **một microservice đơn lẻ**. Để triển khai nó như một phần của nền tảng microservices GoodGo:
### 1. Register in Platform Compose File / Đăng Ký Trong Platform Compose File
Add your service to `deployments/local/docker-compose.yml`:
Thêm service của bạn vào `deployments/local/docker-compose.yml`:
```yaml
services:
your-service:
build:
context: ../..
dockerfile: services/your-service/Dockerfile
container_name: your-service-local
environment:
- NODE_ENV=development
- PORT=5002
- DATABASE_URL=${DATABASE_URL}
- REDIS_HOST=redis
- REDIS_PORT=6379
- JWT_SECRET=${JWT_SECRET}
- SERVICE_NAME=your-service
- API_VERSION=v1
- CORS_ORIGIN=http://localhost:3000,http://localhost:3001
depends_on:
redis:
condition: service_healthy
networks:
- microservices-network
labels:
# Enable Traefik service discovery
- "traefik.enable=true"
# Define routing rule (path-based routing)
- "traefik.http.routers.your-service.rule=PathPrefix(`/api/v1/your-service`)"
# Specify the service port
- "traefik.http.services.your-service.loadbalancer.server.port=5002"
# Health check configuration
- "traefik.http.services.your-service.loadbalancer.healthcheck.path=/health/live"
- "traefik.http.services.your-service.loadbalancer.healthcheck.interval=10s"
```
### 2. Start the Platform / Khởi Động Nền Tảng
```bash
# Navigate to deployments directory
cd deployments/local
# Start all services including your new service
docker-compose up -d
# View logs for your service
docker-compose logs -f your-service
```
### 3. Access Your Service / Truy Cập Service Của Bạn
Once deployed, your service is accessible through Traefik:
Sau khi triển khai, service của bạn có thể truy cập qua Traefik:
- **API**: http://localhost/api/v1/your-service
- **Health Check**: http://localhost/api/v1/your-service/health
- **API Documentation**: http://localhost/api/v1/your-service/api-docs
- **Traefik Dashboard**: http://localhost:8080 (view all registered services)
### 4. Traefik Configuration / Cấu Hình Traefik
Traefik is configured at the platform level in `infra/traefik/`:
Traefik được cấu hình ở cấp độ nền tảng trong `infra/traefik/`:
- **Static Config**: `infra/traefik/traefik.yml` - Entry points, providers, dashboard
- **Dynamic Config**: `infra/traefik/dynamic/` - Middlewares, routes, services
- **Service Discovery**: Automatic via Docker labels (no manual route configuration needed)
For advanced routing or middleware, add to `infra/traefik/dynamic/routes.yml`:
Để định tuyến nâng cao hoặc middleware, thêm vào `infra/traefik/dynamic/routes.yml`:
```yaml
http:
routers:
your-service:
rule: "PathPrefix(`/api/v1/your-service`)"
service: your-service
middlewares:
- secure-headers
- cors
- compress
```
## Observability / Khả năng quan sát
When deployed via the platform (`deployments/local/docker-compose.yml`), your service exposes:
Khi triển khai qua nền tảng (`deployments/local/docker-compose.yml`), service của bạn expose:
- **Metrics**: `http://localhost/api/v1/your-service/metrics` (Prometheus format via Traefik)
- **Health Checks**:
- Liveness: `http://localhost/api/v1/your-service/health/live`
- Readiness: `http://localhost/api/v1/your-service/health/ready`
- **API Documentation**: `http://localhost/api/v1/your-service/api-docs` (Swagger UI via Traefik)
- **Tracing**: Jaeger integration (when `TRACING_ENABLED=true`)
- **Correlation IDs**: Automatic request tracing with `x-correlation-id` headers
- **Structured Logging**: Request/response logging with correlation context
**Note**: For local development (without platform), replace `/api/v1/your-service` with `http://localhost:5000`.
**Lưu ý**: Để phát triển local (không dùng platform), thay `/api/v1/your-service` bằng `http://localhost:5000`.
### Metrics / Metrics
The service exposes comprehensive Prometheus metrics:
- **Request Duration**: `http_request_duration_seconds` (histogram)
- **Request Count**: `http_requests_total` (counter)
- **Active Requests**: `http_active_requests` (gauge)
- **Request Errors**: `http_request_errors_total` (counter)
- **Payload Sizes**: Request/response payload size histograms
- **Default Metrics**: Memory, CPU, event loop lag
### Correlation IDs / Correlation IDs
Every request gets a correlation ID for tracing across services:
- **Header**: `x-correlation-id` (propagated from upstream or auto-generated)
- **Request ID**: `x-request-id` (unique per request)
- **Logging**: All logs include correlation context
- **Metrics**: Request metrics tagged with correlation ID
### Health Checks / Health Checks
- **Liveness** (`/health/live`): Basic service availability
- **Readiness** (`/health/ready`): Service ready to handle requests (includes DB connectivity)
- **Metrics**: Health check results are tracked in Prometheus metrics
### Logging / Logging
Structured logging with multiple levels:
- **Request/Response**: Automatic logging with correlation IDs
- **Errors**: Detailed error logging with stack traces
- **Business Logic**: Custom logging with context
- **Performance**: Request duration and resource usage
### API Documentation / Tài liệu API
- **Swagger UI**: Interactive API documentation at `/api-docs`
- **OpenAPI 3.0**: Complete API specification
- **Request/Response Examples**: Real examples for all endpoints
- **Authentication**: JWT Bearer token examples
## Authentication / Xác thực
The service uses JWT (JSON Web Tokens) for authentication. Include the token in the `Authorization` header as `Bearer <token>`.
### API Documentation / Tài liệu API
#### Authentication Endpoints / Endpoints Xác thực
**Get Current User Info / Lấy Thông tin Người dùng Hiện tại**
```http
GET /auth/me
Authorization: Bearer <your-jwt-token>
```
#### Feature Management / Quản lý Feature
**Base URL**: `http://localhost/api/v1/features`
#### Create Feature / Tạo Feature
```http
POST /api/v1/features
Authorization: Bearer <admin-jwt-token>
Content-Type: application/json
{
"name": "example-feature",
"title": "Example Feature",
"description": "An example feature for demonstration",
"config": {
"enabled": true,
"priority": 1
},
"tags": ["example", "demo"]
}
```
**Required Role:** `admin`
#### Get All Features / Lấy Tất cả Features
```http
GET /api/v1/features
```
#### Get Feature by ID / Lấy Feature theo ID
```http
GET /api/v1/features/{id}
```
#### Update Feature / Cập nhật Feature
```http
PUT /api/v1/features/{id}
Content-Type: application/json
{
"title": "Updated Title",
"enabled": false
}
```
#### Delete Feature / Xóa Feature
```http
DELETE /api/v1/features/{id}
```
#### Toggle Feature Status / Chuyển đổi Trạng thái Feature
```http
PATCH /api/v1/features/{id}/toggle
```
### Response Format / Định dạng Response
All API responses follow this structure / Tất cả responses API tuân theo cấu trúc này:
```json
{
"success": true,
"data": { ... },
"message": "Operation completed / Hoạt động hoàn thành",
"timestamp": "2024-01-01T00:00:00.000Z"
}
```
Error responses / Responses lỗi:
```json
{
"success": false,
"error": {
"code": "FEATURE_001",
"message": "Error description / Mô tả lỗi"
},
"timestamp": "2024-01-01T00:00:00.000Z"
}
```
## Troubleshooting / Khắc phục sự cố
### Common Issues / Vấn đề thường gặp
#### Database Connection Issues / Vấn đề kết nối Database
**Problem**: `Error: P1001: Can't reach database server`
```bash
# EN: Check if PostgreSQL is running (from deployments/local/)
# VI: Kiểm tra PostgreSQL có đang chạy (từ deployments/local/)
cd deployments/local
docker-compose ps
# EN: Check database logs
# VI: Kiểm tra logs database
docker-compose logs postgres
# EN: Restart database service
# VI: Khởi động lại database service
docker-compose restart postgres
```
**Problem**: `Error: P2002: Unique constraint failed`
```typescript
// EN: This usually means you're trying to create a duplicate record
// VI: Điều này thường có nghĩa là bạn đang cố tạo record trùng lặp
// EN: Check your seed data or migration scripts
// VI: Kiểm tra seed data hoặc migration scripts
```
#### Authentication Issues / Vấn đề Authentication
**Problem**: `401 Unauthorized`
```bash
# EN: Check JWT token format
# VI: Kiểm tra định dạng JWT token
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost/auth/me
# EN: Verify JWT secret in environment
# VI: Xác minh JWT secret trong environment
echo $JWT_SECRET
# EN: Check token expiration
# VI: Kiểm tra token hết hạn
# EN: Use https://jwt.io to decode your token
```
#### Port Already in Use / Port đã được sử dụng
**Problem**: `Error: listen EADDRINUSE: address already in use`
```bash
# EN: Find process using the port
# VI: Tìm process đang sử dụng port
lsof -i :5000
# EN: Kill the process
# VI: Kill process
kill -9 <PID>
# EN: Or change port in .env
# VI: Hoặc thay đổi port trong .env
PORT=5001
```
#### Docker Issues / Vấn đề Docker
**Problem**: `ERROR: Couldn't connect to Docker daemon`
```bash
# EN: Start Docker service
# VI: Khởi động Docker service
sudo systemctl start docker
# EN: Add user to docker group (Linux)
# VI: Thêm user vào docker group (Linux)
sudo usermod -aG docker $USER
```
**Problem**: Container won't start
```bash
# EN: Check container logs (from deployments/local/)
# VI: Kiểm tra logs container (từ deployments/local/)
cd deployments/local
docker-compose logs your-service
# EN: Check container health
# VI: Kiểm tra health container
docker-compose ps
# EN: Rebuild without cache
# VI: Rebuild không dùng cache
docker-compose build --no-cache your-service
docker-compose up -d your-service
```
#### Test Failures / Test thất bại
**Problem**: Tests fail with database connection
```bash
# EN: Ensure test database is running
# VI: Đảm bảo test database đang chạy
docker-compose -f docker-compose.test.yml up -d
# EN: Run tests with verbose output
# VI: Chạy tests với output verbose
pnpm test -- --verbose
# EN: Reset test database
# VI: Reset test database
docker-compose -f docker-compose.test.yml down -v
```
### Debug Mode / Chế độ Debug
```bash
# EN: Enable debug logging (local development)
# VI: Bật debug logging (phát triển local)
DEBUG=* pnpm dev
# EN: Check application health (via platform)
# VI: Kiểm tra health ứng dụng (qua platform)
curl http://localhost/api/v1/your-service/health/ready
# EN: View application logs (from deployments/local/)
# VI: Xem logs ứng dụng (từ deployments/local/)
cd deployments/local
docker-compose logs -f your-service
# EN: Monitor metrics (via platform)
# VI: Monitor metrics (qua platform)
curl http://localhost/api/v1/your-service/metrics
```
### Performance Issues / Vấn đề Performance
**Slow Requests**:
- Check database query performance
- Review middleware chain efficiency
- Monitor Redis cache hit rates
- Check for memory leaks
**High Memory Usage**:
```bash
# EN: Check memory usage
# VI: Kiểm tra memory usage
docker stats
# EN: Monitor with Prometheus metrics
# VI: Monitor với Prometheus metrics
curl http://localhost/metrics | grep heap
```
## Docker / Docker
### Docker Image / Docker Image
This template includes a production-ready Dockerfile with:
Template này bao gồm Dockerfile production-ready với:
```dockerfile
# Multi-stage build for optimized image size
FROM node:20-alpine AS base
# ... dependency installation
FROM base AS builder
# ... build stage
FROM node:20-alpine AS runner
# ... production runtime
```
**Build the image:**
```bash
docker build -t your-service:latest .
```
### Docker Compose for Testing / Docker Compose Cho Testing
- **`docker-compose.test.yml`**: Isolated test environment with test database and Redis
**Run tests in Docker:**
```bash
docker-compose -f docker-compose.test.yml up -d
DATABASE_URL=postgresql://postgres:test_password@localhost:5433/microservice_test pnpm test
docker-compose -f docker-compose.test.yml down -v
```
### Production Deployment / Triển khai Production
For production deployment, services are orchestrated via:
Để triển khai production, các service được điều phối qua:
- **Local/Dev**: `deployments/local/docker-compose.yml`
- **Staging**: `deployments/staging/kubernetes/` (Kubernetes manifests)
- **Production**: `deployments/production/kubernetes/` (Kubernetes manifests)
**Build production image:**
```bash
docker build -t your-service:v1.0.0 .
docker tag your-service:v1.0.0 registry.example.com/your-service:v1.0.0
docker push registry.example.com/your-service:v1.0.0
```
### Docker Image Features / Tính năng Docker Image
- **Multi-stage Build**: Optimized for small production images
- **Security**: Non-root user, minimal attack surface
- **Health Checks**: Built-in health check endpoints
- **Signal Handling**: Proper signal handling with dumb-init
- **Layer Caching**: Efficient Docker layer caching
### Environment Variables for Docker / Biến môi trường cho Docker
When running in Docker, ensure these environment variables are set:
```bash
# EN: Database connection
# VI: Kết nối database
DATABASE_URL=postgresql://postgres:password@postgres:5432/microservice_template
# EN: Redis connection
# VI: Kết nối Redis
REDIS_URL=redis://redis:6379
# EN: JWT secret (change in production!)
# VI: JWT secret (thay đổi trong production!)
JWT_SECRET=your-production-jwt-secret
```
## Testing / Kiểm thử
```bash
# EN: Run all tests / Chạy tất cả tests
pnpm test
# EN: Run unit tests only / Chạy chỉ unit tests
pnpm test:unit
# EN: Run E2E tests only / Chạy chỉ E2E tests
pnpm test:e2e
# EN: Run tests with coverage / Chạy tests với coverage
pnpm test:coverage
# EN: Run tests in watch mode / Chạy tests ở chế độ watch
pnpm test:watch
# EN: Run tests in specific file / Chạy tests trong file cụ thể
pnpm test src/modules/feature/__tests__/feature.service.test.ts
# EN: Run tests matching pattern / Chạy tests khớp pattern
pnpm test -- --testNamePattern="authentication"
```
### Test Structure / Cấu trúc Test
```
src/
├── middlewares/__tests__/ # Middleware unit tests
├── modules/
│ ├── feature/__tests__/ # Feature module tests
│ └── health/__tests__/ # Health module tests
├── __tests__/ # E2E tests
│ ├── health.e2e.ts # Health endpoint E2E
│ └── feature.e2e.ts # Feature endpoint E2E
└── config/__tests__/ # Configuration tests
```
### Writing Tests / Viết Tests
#### Unit Test Example / Ví dụ Unit Test
```typescript
import { FeatureService } from '../feature.service';
import { featureRepository } from '../feature.repository';
jest.mock('../feature.repository');
describe('FeatureService', () => {
let service: FeatureService;
beforeEach(() => {
service = new FeatureService();
});
it('should create feature successfully', async () => {
const mockFeature = { id: '1', name: 'test', enabled: true };
(featureRepository.create as jest.Mock).mockResolvedValue(mockFeature);
const result = await service.create({ name: 'test' });
expect(result).toEqual(mockFeature);
});
});
```
#### E2E Test Example / Ví dụ E2E Test
```typescript
import request from 'supertest';
import express from 'express';
import { createRouter } from '../routes';
describe('Feature Endpoints E2E', () => {
let app: express.Application;
beforeAll(() => {
app = express();
app.use(express.json());
app.use(createRouter());
});
it('should create feature successfully', async () => {
const response = await request(app)
.post('/api/v1/features')
.send({ name: 'test-feature' })
.expect(201);
expect(response.body.success).toBe(true);
});
});
```
## Creating a New Service / Tạo Service Mới
To create a new microservice from this template / Để tạo microservice mới từ template này:
1. **Copy Template / Sao chép Template**:
```bash
# EN: Copy template to new service directory / Sao chép template vào thư mục service mới
cp -r services/_template services/your-service-name
cd services/your-service-name
```
2. **Update Package Configuration / Cập nhật Cấu hình Package**:
```bash
# EN: Update package.json name and description / Cập nhật tên và mô tả trong package.json
# VI: Thay đổi "name", "description", và các thông tin khác
```
3. **Configure Environment / Cấu hình Môi trường**:
```bash
# EN: Set up shared environment variables at platform level
# VI: Thiết lập biến môi trường chung ở cấp độ nền tảng
cd ../../deployments/local
cp env.local.example .env.local
# EN: Edit .env.local with shared values (JWT_SECRET, DATABASE_URL, etc.)
# VI: Chỉnh sửa .env.local với các giá trị chung (JWT_SECRET, DATABASE_URL, etc.)
nano .env.local
```
4. **Database Setup / Thiết lập Database**:
```bash
# EN: Update Prisma schema with your models / Cập nhật schema Prisma với models của bạn
# VI: Chỉnh sửa prisma/schema.prisma
# EN: Generate and run migrations / Tạo và chạy migrations
pnpm prisma:generate
pnpm prisma:migrate
```
5. **Implement Business Logic / Triển khai Logic Kinh doanh**:
- Add your modules in `src/modules/`
- Update routes in `src/routes/index.ts`
- Add validation schemas and DTOs
6. **Testing / Kiểm thử**:
```bash
# EN: Add tests for your new functionality / Thêm tests cho chức năng mới
pnpm test
```
7. **Documentation / Tài liệu**:
- Update `README.md` with service-specific information
- Update `ARCHITECTURE.md` if needed
- Update OpenAPI documentation in route files
## Extending the Template / Mở rộng Template
### Adding a New Module / Thêm Module Mới
1. **Create Module Structure / Tạo cấu trúc Module**:
```bash
mkdir -p src/modules/your-module/{__tests__}
touch src/modules/your-module/your-module.{controller,service,repository,dto,module}.ts
touch src/modules/your-module/__tests__/your-module.{service,controller}.test.ts
```
2. **Implement Repository / Triển khai Repository**:
```typescript
// src/modules/your-module/your-module.repository.ts
import { BaseRepository } from '../common/repository';
import { prisma } from '../../config/database.config';
export class YourModuleRepository extends BaseRepository<YourEntity, CreateInput, UpdateInput> {
constructor() {
super(prisma, 'yourEntity');
}
async findByCustomField(value: string): Promise<YourEntity[]> {
return this.prisma.yourEntity.findMany({
where: { customField: value },
});
}
}
export const yourModuleRepository = new YourModuleRepository();
```
3. **Implement Service / Triển khai Service**:
```typescript
// src/modules/your-module/your-module.service.ts
import { yourModuleRepository } from './your-module.repository';
import { CreateYourEntityDto, UpdateYourEntityDto } from './your-module.dto';
export class YourModuleService {
async create(data: CreateYourEntityDto) {
// Business logic
return yourModuleRepository.create(data);
}
async findAll() {
return yourModuleRepository.findAll();
}
}
```
4. **Implement Controller / Triển khai Controller**:
```typescript
// src/modules/your-module/your-module.controller.ts
import { Request, Response } from 'express';
import { asyncHandler } from '../../middlewares/error.middleware';
import { YourModuleService } from './your-module.service';
export class YourModuleController {
private service = new YourModuleService();
create = asyncHandler(async (req: Request, res: Response) => {
const result = await this.service.create(req.body);
res.status(201).json({
success: true,
data: result,
message: 'Created successfully',
timestamp: new Date().toISOString(),
});
});
findAll = asyncHandler(async (req: Request, res: Response) => {
const result = await this.service.findAll();
res.json({
success: true,
data: result,
message: 'Retrieved successfully',
timestamp: new Date().toISOString(),
});
});
}
```
5. **Create Routes / Tạo Routes**:
```typescript
// src/modules/your-module/your-module.module.ts
import { Router } from 'express';
import { YourModuleController } from './your-module.controller';
import { validateDto } from '../../middlewares/validation.middleware';
export const createYourModuleRouter = (): Router => {
const router = Router();
const controller = new YourModuleController();
router.post('/', validateDto(createYourEntitySchema), controller.create);
router.get('/', controller.findAll);
return router;
};
```
6. **Register Routes / Đăng ký Routes**:
```typescript
// src/routes/index.ts
import { createYourModuleRouter } from '../modules/your-module/your-module.module';
router.use('/api/v1/your-entities', createYourModuleRouter());
```
### Adding Environment Variables / Thêm Biến Môi trường
1. **Update config schema / Cập nhật config schema**:
```typescript
// src/config/app.config.ts
const envSchema = z.object({
// ... existing fields
YOUR_NEW_VARIABLE: z.string().default('default-value'),
});
export const appConfig = {
// ... existing config
yourNewVariable: config.YOUR_NEW_VARIABLE,
};
```
2. **Update .env files / Cập nhật file .env**:
```bash
# .env.example
YOUR_NEW_VARIABLE=your-default-value
# .env.local.example
YOUR_NEW_VARIABLE=your-local-value
```
### Security Best Practices / Thực tiễn Bảo mật
- **Input Validation**: Always validate and sanitize user inputs using Zod
- **Authentication**: Use JWT tokens with reasonable expiration times
- **Authorization**: Implement proper RBAC for your endpoints
- **Rate Limiting**: Protect against abuse with distributed rate limiting
- **HTTPS**: Always use HTTPS in production
- **Secrets**: Never commit secrets to version control
- **Dependencies**: Keep dependencies updated and audit regularly
### Performance Considerations / Lưu ý Performance
- **Database Queries**: Use indexes for frequently queried fields
- **Caching**: Implement Redis caching for expensive operations
- **Connection Pooling**: Configure appropriate connection pool sizes
- **Async Operations**: Use proper async/await patterns
- **Memory Management**: Monitor memory usage and implement cleanup
- **Metrics**: Monitor performance with built-in Prometheus metrics
## Development Guidelines / Hướng dẫn Phát triển
### Comments / Comment Code
- Use bilingual comments for all public APIs and complex logic.
- Format: `EN` first, then `VI`.
- See `.cursor/skills/comment-code/SKILL.md` for details.
### Adding a Module / Thêm Module
1. Create `src/modules/<name>/`.
2. Implement `Controller`, `Service`.
3. Register routes in `src/routes/index.ts`.
### Code Style / Phong cách Code
- Follow the established patterns in existing modules
- Use TypeScript strictly with proper type annotations
- Implement proper error handling with custom error classes
- Add comprehensive tests for all new functionality