Files
pos-system/docs/vi/guides/local-development.md
Ho Ngoc Hai 4da46b5b8e Sure! Pl
2025-12-27 01:31:10 +07:00

18 KiB

Hướng Dẫn Development Local

Hướng dẫn chi tiết cách chạy và phát triển dự án trên máy local với hot reload real-time.

Yêu Cầu Hệ Thống

  • Node.js: >= 20.0.0
  • PNPM: >= 8.0.0
  • Docker & Docker Compose: Phiên bản mới nhất
  • Git: Để clone repository
  • Tài khoản Neon: https://neon.tech (cho database)

Thiết Lập Ban Đầu

1. Clone Repository

git clone <repository-url>
cd Base

2. Cài Đặt Dependencies

pnpm install

3. Thiết Lập Environment Variables

Dự án sử dụng Hybrid Environment Configuration:

  • Shared configs (JWT secrets, Redis): deployments/local/.env.local
  • Service-specific configs (DATABASE_URL, PORT): services/<service>/.env.local

3.1. Tạo Shared Environment File

cp deployments/local/env.local.example deployments/local/.env.local

File này chứa configs dùng chung cho tất cả services:

# JWT Secrets - MUST be same across all services
JWT_SECRET=dev-jwt-secret-change-in-production-min-32-chars
JWT_REFRESH_SECRET=dev-refresh-secret-change-in-production-min-32-chars

# Redis (Docker)
REDIS_HOST=redis
REDIS_PORT=6379

# Common configs
NODE_ENV=development
LOG_LEVEL=debug
CORS_ORIGIN=http://localhost:3000,http://localhost:3001

3.2. Tạo Service-Specific Environment File

Mỗi service cần file .env.local riêng cho DATABASE_URL và configs cụ thể:

# Ví dụ: Auth Service
cp services/auth-service/env.local.example services/auth-service/.env.local

Chỉnh sửa services/auth-service/.env.local:

# Database riêng cho auth-service
DATABASE_URL=postgresql://user:password@ep-xxx.region.neon.tech/goodgo_auth_dev?sslmode=require&pgbouncer=true

# Service configs
PORT=5001
SERVICE_NAME=auth-service

# Redis override (native dev - Redis in Docker)
REDIS_HOST=localhost

Lưu ý:

  • Mỗi service có database riêng (microservices pattern)
  • JWT secrets phải giống nhau để services verify tokens của nhau
  • Xem Hướng Dẫn Neon Database để tạo databases

4. Chạy Database Migrations

./scripts/db/migrate.sh auth-service dev

5. Seed Database (Tùy chọn)

./scripts/db/seed.sh auth-service

Các Cách Chạy Dự Án

Cách 1: Chạy Tất Cả Services (Khuyến nghị)

Cách này phù hợp khi bạn làm full-stack hoặc cần test toàn bộ hệ thống:

./scripts/dev/start-all.sh

Script này sẽ:

  1. Kiểm tra Docker đang chạy
  2. Kiểm tra DATABASE_URL đã được cấu hình
  3. Khởi động infrastructure (Redis, Traefik)
  4. Khởi động tất cả services với hot reload

Hoặc chạy thủ công:

# Bước 1: Khởi động infrastructure
cd deployments/local
docker-compose up -d
cd ../..

# Bước 2: Khởi động tất cả services
pnpm dev

Cách 2: Chạy Service Cụ Thể

Cách này phù hợp khi bạn chỉ làm việc với 1 service:

# Sử dụng script
./scripts/dev/start-service.sh auth-service

# Hoặc chạy trực tiếp
cd services/auth-service
pnpm dev

Cách 3: Hybrid - Native + Docker (Linh hoạt nhất)

Cách này kết hợp tốt nhất của cả hai thế giới: Infrastructure chạy Docker, services đang dev chạy native với hot reload nhanh.

Phù hợp khi:

  • Làm việc với 1-2 services cụ thể
  • Cần services khác chạy background
  • Muốn hot reload nhanh cho service đang dev
  • Tiết kiệm tài nguyên máy

Setup:

# Bước 1: Khởi động infrastructure (Redis, Traefik)
cd deployments/local
docker-compose up -d redis traefik
cd ../..

# Bước 2: Chạy service đang dev với native (hot reload nhanh)
pnpm --filter @goodgo/auth-service dev

# Bước 3: (Tùy chọn) Chạy services khác trong Docker nếu cần
docker-compose -f deployments/local/docker-compose.yml up -d user-service payment-service

Ví dụ workflow thực tế:

# Scenario 1: Chỉ dev auth-service
cd deployments/local && docker-compose up -d redis traefik && cd ../..
pnpm --filter @goodgo/auth-service dev

# Scenario 2: Dev auth-service + cần web-admin để test
cd deployments/local && docker-compose up -d redis traefik && cd ../..
pnpm --filter @goodgo/auth-service dev &
pnpm --filter @goodgo/web-admin dev

# Scenario 3: Dev frontend, backend chạy Docker
cd deployments/local && docker-compose up -d redis traefik auth-service && cd ../..
pnpm --filter @goodgo/web-admin dev

Lợi ích:

  • Hot reload cực nhanh (1-2s) cho service đang dev
  • 💻 Tiết kiệm RAM - chỉ chạy Docker cho services cần thiết
  • 🐛 Debug dễ dàng - attach debugger trực tiếp
  • 🎯 Linh hoạt - chọn service nào chạy native, service nào chạy Docker

Cách 4: Chạy Nhóm Services

# Chỉ chạy backend services
pnpm --filter "./services/*" dev

# Chỉ chạy frontend apps
pnpm --filter "./apps/*" dev

# Chạy service cụ thể với dependencies
pnpm --filter @goodgo/auth-service... dev

Cách 5: Chạy Với Docker Compose (Full Stack)

cd deployments/local
docker-compose up -d

# Xem logs
docker-compose logs -f

# Dừng services
docker-compose down

Lưu ý: Dockerfile hiện tại là production build, không có hot reload. Phù hợp để test môi trường giống production.

So Sánh Các Phương Án

Tiêu chí Cách 1: All Native Cách 3: Hybrid Cách 5: Full Docker
Hot Reload Cực nhanh (1-2s) Nhanh cho service native Không có (production build)
RAM Usage 💚 Thấp (~1-2GB) 💛 Trung bình (~2-3GB) 🔴 Cao (~3-5GB)
Debug Dễ nhất Dễ (native services) ⚠️ Khó hơn (qua container)
Setup 🟢 Đơn giản 🟡 Trung bình 🟢 Đơn giản
Giống Production ⚠️ Khác biệt 🟡 Một phần Gần giống nhất
Khi nào dùng Dev hàng ngày Dev 1-2 services Test integration/deployment

Khuyến nghị:

  • 🎯 90% thời gian: Dùng Cách 1 (All Native) - nhanh nhất, tiện nhất
  • 🔧 Khi cần linh hoạt: Dùng Cách 3 (Hybrid) - chọn service nào chạy native
  • 🐳 Test production-like: Dùng Cách 5 (Full Docker) - test networking, deployment

Điểm Truy Cập

Khi các services đang chạy, bạn có thể truy cập:

Service URL Mô tả
API Gateway http://localhost/api/v1 Điểm truy cập chính qua Traefik
Auth Service http://localhost:5001 Truy cập trực tiếp auth service
Auth API http://localhost/api/v1/auth Auth API qua gateway
Web Admin http://admin.localhost hoặc http://localhost:3000 Admin dashboard
Web Client http://localhost hoặc http://localhost:3001 Client web app
Traefik Dashboard http://localhost:8080 Xem routing và services

Hot Reload & Live Development

Backend Services (TypeScript)

Backend services sử dụng tsx watch hoặc nodemon để tự động restart khi code thay đổi:

# Trong services/auth-service/package.json
"scripts": {
  "dev": "tsx watch src/index.ts"
}

Khi bạn thay đổi:

  • .ts files → Service tự động restart (1-2 giây)
  • .env files → Cần restart thủ công
  • prisma/schema.prisma → Cần chạy migration

Frontend Apps (Next.js)

Frontend apps sử dụng Next.js Fast Refresh:

# Trong apps/web-admin/package.json
"scripts": {
  "dev": "next dev"
}

Khi bạn thay đổi:

  • React components → Cập nhật ngay lập tức (không reload page)
  • CSS/Tailwind → Cập nhật ngay lập tức
  • next.config.js → Cần restart

Shared Packages

Khi thay đổi shared packages (trong packages/):

# Packages tự động rebuild với Turbo watch mode
pnpm --filter @goodgo/logger dev

Workflow Development Thực Tế

Setup 3 Terminals (Khuyến nghị)

Option A: Development Hàng Ngày (All Native)

Terminal 1: Chạy Services

./scripts/dev/start-all.sh
# Hoặc: pnpm dev

Terminal 2: Watch Tests

# Auto-run tests khi code thay đổi
pnpm --filter @goodgo/auth-service test --watch

Terminal 3: Development Tasks

# Prisma Studio
pnpm --filter @goodgo/auth-service prisma studio

# Xem logs
./scripts/dev/logs.sh auth-service

# Migrations
./scripts/db/migrate.sh auth-service dev

Option B: Hybrid Development (Selective Services)

Terminal 1: Infrastructure + Service đang dev

# Start infrastructure
cd deployments/local && docker-compose up -d redis traefik && cd ../..

# Dev service cụ thể với hot reload
pnpm --filter @goodgo/auth-service dev

Terminal 2: Frontend (nếu cần)

pnpm --filter @goodgo/web-admin dev

Terminal 3: Tools & Logs

# Watch tests
pnpm --filter @goodgo/auth-service test --watch

# Xem Docker logs
docker logs -f redis-cache-local

# Quick commands
pnpm format

Workflow Theo Use Case

Use Case 1: Dev Backend Service

# Terminal 1
cd deployments/local && docker-compose up -d redis traefik && cd ../..
pnpm --filter @goodgo/auth-service dev

# Terminal 2
pnpm --filter @goodgo/auth-service test --watch

# Terminal 3
pnpm --filter @goodgo/auth-service prisma studio

Use Case 2: Dev Frontend + Backend

# Terminal 1: Backend
pnpm --filter @goodgo/auth-service dev

# Terminal 2: Frontend
pnpm --filter @goodgo/web-admin dev

# Terminal 3: Infrastructure
cd deployments/local && docker-compose up -d redis traefik

Use Case 3: Full Stack Development

# Terminal 1: All services
./scripts/dev/start-all.sh

# Terminal 2: Watch tests
pnpm test --watch

# Terminal 3: Tools
# Prisma Studio, logs, migrations, etc.

Kiểm Tra Health

Health Endpoints

# Kiểm tra API Gateway
curl http://localhost/api/v1/health

# Kiểm tra Auth Service trực tiếp
curl http://localhost:5001/health

# Kiểm tra Redis
docker exec redis-cache-local redis-cli ping

Traefik Dashboard

Truy cập http://localhost:8080 để xem:

  • Tất cả routes đang hoạt động
  • Services đã đăng ký
  • Health status của services

Database Development

Thay Đổi Schema

# 1. Chỉnh sửa prisma/schema.prisma
# 2. Tạo và áp dụng migration
cd services/auth-service
pnpm prisma migrate dev --name add_new_field

# 3. Prisma Client sẽ tự động regenerate

Reset Database (Development Only!)

cd services/auth-service
pnpm prisma migrate reset

Xem Database

# Mở Prisma Studio
cd services/auth-service
pnpm prisma studio
# Truy cập: http://localhost:5555

Debugging

VS Code Debugging

Tạo file .vscode/launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Debug Auth Service",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "pnpm",
      "runtimeArgs": ["--filter", "@goodgo/auth-service", "dev"],
      "skipFiles": ["<node_internals>/**"],
      "console": "integratedTerminal"
    }
  ]
}

Xem Logs Chi Tiết

# Service logs
./scripts/dev/logs.sh auth-service

# Docker logs
docker logs -f auth-service-local
docker logs -f redis-cache-local
docker logs -f traefik-local

# Tất cả logs
docker-compose -f deployments/local/docker-compose.yml logs -f

Troubleshooting

Port Đã Được Sử Dụng

# Tìm process đang dùng port
lsof -i :5001  # Auth service
lsof -i :3000  # Web admin
lsof -i :6379  # Redis
lsof -i :80    # Traefik

# Kill process
kill -9 <PID>

Docker Không Chạy

# Kiểm tra Docker
docker info

# Khởi động Docker Desktop (macOS)
open -a Docker

# Restart Docker services
docker-compose -f deployments/local/docker-compose.yml restart

Database Connection Failed

# Kiểm tra DATABASE_URL trong service-specific env
cat services/auth-service/.env.local | grep DATABASE_URL

# Nếu chưa có file .env.local, tạo từ example
cp services/auth-service/env.local.example services/auth-service/.env.local

# Chỉnh sửa DATABASE_URL với connection string từ Neon
# DATABASE_URL=postgresql://user:pass@ep-xxx.neon.tech/goodgo_auth_dev?sslmode=require&pgbouncer=true

# Test connection
cd services/auth-service
pnpm prisma db pull

Lưu ý: Mỗi service cần file .env.local riêng với DATABASE_URL của service đó.

Module Not Found

# Cleanup và reinstall
./scripts/utils/cleanup.sh
pnpm install

# Hoặc chỉ cleanup node_modules
rm -rf node_modules
rm -rf services/*/node_modules
rm -rf apps/*/node_modules
rm -rf packages/*/node_modules
pnpm install

Hot Reload Không Hoạt Động

# Restart service
# Ctrl+C để dừng, sau đó:
pnpm dev

# Hoặc restart Docker container
docker-compose -f deployments/local/docker-compose.yml restart auth-service

Tips & Best Practices

1. Sử Dụng Turbo Cache

Turbo cache giúp build nhanh hơn:

# Lần đầu chạy sẽ chậm
pnpm dev

# Các lần sau sẽ nhanh hơn nhờ cache
# Cache được lưu trong node_modules/.cache/turbo

2. Dev Selective Services

Không cần chạy tất cả nếu chỉ làm 1 service:

# Chỉ chạy auth-service
pnpm --filter @goodgo/auth-service dev

# Chạy auth-service và dependencies
pnpm --filter @goodgo/auth-service... dev

3. Watch Tests

# Chạy tests tự động khi code thay đổi
pnpm --filter @goodgo/auth-service test --watch

4. Format Code Tự Động

Cài đặt Prettier extension trong VS Code và bật format on save.

5. Sử Dụng Git Hooks

# Pre-commit hook sẽ tự động format và lint
git commit -m "feat: add new feature"

6. Hybrid Development (Best of Both Worlds)

Kết hợp Docker và Native để tối ưu workflow:

# Infrastructure luôn chạy Docker
cd deployments/local && docker-compose up -d redis traefik

# Service đang dev chạy native (hot reload nhanh)
pnpm --filter @goodgo/auth-service dev

# Services khác có thể chạy Docker nếu cần
docker-compose up -d user-service payment-service

Lợi ích:

  • Hot reload nhanh nhất cho service đang làm
  • 💻 Tiết kiệm RAM - không chạy tất cả containers
  • 🐛 Debug dễ dàng - breakpoints, logs trực tiếp
  • 🎯 Linh hoạt - chọn service nào chạy native

7. Quản Lý Multiple Services

# Chạy selective services với pnpm workspace
pnpm --filter "@goodgo/auth-service" --filter "@goodgo/user-service" dev

# Hoặc dùng pattern
pnpm --filter "./services/{auth,user}-service" dev

Environment Variables

Dự án sử dụng Hybrid Environment Configuration với 2 levels:

Level 1: Shared Environment (deployments/local/.env.local)

Configs dùng chung cho tất cả services:

# JWT Secrets - MUST be same across all services
JWT_SECRET=dev-jwt-secret-change-in-production-min-32-chars
JWT_REFRESH_SECRET=dev-refresh-secret-change-in-production-min-32-chars
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d

# Redis (Docker hostname)
REDIS_HOST=redis
REDIS_PORT=6379

# Common configs
NODE_ENV=development
LOG_LEVEL=debug
CORS_ORIGIN=http://localhost:3000,http://localhost:3001

# Monitoring (optional)
TRACING_ENABLED=false

Tạo file:

cp deployments/local/env.local.example deployments/local/.env.local

Level 2: Service-Specific Environment (services/<service>/.env.local)

Configs riêng cho từng service:

# services/auth-service/.env.local

# Database riêng cho service này
DATABASE_URL=postgresql://user:pass@ep-xxx.neon.tech/goodgo_auth_dev?sslmode=require&pgbouncer=true

# Service configs
PORT=5001
SERVICE_NAME=auth-service
API_VERSION=v1

# Redis override (native dev - Redis in Docker)
REDIS_HOST=localhost

# Service-specific configs
EMAIL_SERVICE_URL=http://notification-service:5003
PROMETHEUS_PORT=9090

Tạo file:

cp services/auth-service/env.local.example services/auth-service/.env.local

Cách Hoạt Động

Services load env theo thứ tự:

  1. Shared env (deployments/local/.env.local) - JWT, Redis, common configs
  2. Service env (.env.local) - DATABASE_URL, PORT, overrides
# Trong package.json
"dev": "dotenv -e ../../deployments/local/.env.local -e .env.local -- tsx watch src/main.ts"

Lợi ích:

  • JWT secrets giống nhau → services verify tokens của nhau
  • Mỗi service có database riêng → microservices pattern
  • Override configs dễ dàng → REDIS_HOST=localhost cho native dev
  • Không duplicate configs → maintain dễ hơn

Important Notes

  1. JWT Secrets: MUST be identical across all services
  2. Database: Each service has its own database (e.g., goodgo_auth_dev, goodgo_user_dev)
  3. Redis Host:
    • redis (Docker hostname) in shared env
    • localhost (override) in service env for native dev
  4. Never commit: .env.local files are gitignored

Các Lệnh Hữu Ích

# Development
pnpm dev                    # Chạy tất cả services
pnpm build                  # Build tất cả
pnpm test                   # Test tất cả
pnpm lint                   # Lint tất cả
pnpm format                 # Format code

# Cleanup
pnpm clean                  # Xóa build artifacts
./scripts/utils/cleanup.sh  # Cleanup toàn bộ

# Database
./scripts/db/migrate.sh auth-service dev    # Migration
./scripts/db/seed.sh auth-service           # Seed data
./scripts/db/backup.sh auth-service         # Backup

# Docker
docker-compose -f deployments/local/docker-compose.yml up -d     # Start
docker-compose -f deployments/local/docker-compose.yml down      # Stop
docker-compose -f deployments/local/docker-compose.yml logs -f   # Logs
docker-compose -f deployments/local/docker-compose.yml restart   # Restart

Tài Nguyên Thêm