Files
pos-system/microservices/docs/en/guides/development.md
Ho Ngoc Hai 76d75c753b Migrate
2026-05-23 18:37:02 +07:00

8.7 KiB

Development Guide

Comprehensive standards and workflows for contributing to the GoodGo Microservices Platform.

Table of Contents

  1. Project Structure
  2. Code Standards
  3. Git Workflow
  4. Backend Development
  5. Testing Strategy
  6. Database Workflow
  7. Kubernetes Deployment

Project Structure

We follow a strict monorepo structure managed by PNPM Workspaces.

Base/
 apps/ # Frontend applications
 web-client/ # Next.js 14+ (App Router)
 mobile-client/ # Flutter
 services/ # Backend microservices
 _template/ # Template for new services
 iam-service/ # Identity & Access Management
 ...
 packages/ # Shared libraries
 logger/ # Structured logging (Winston)
 types/ # Shared DTOs & Interfaces
 http-client/ # Internal Service Client
 tracing/ # OpenTelemetry configuration
 infra/ # Infrastructure-as-Code
 traefik/ # API Gateway
 databases/ # Database setup scripts
 docs/ # Documentation (EN & VI)

Code Standards

Naming Conventions

  • Files: kebab-case.ts (e.g., user.controller.ts, app.config.ts)
  • Classes: PascalCase (e.g., UserController, AuthService)
  • Functions/Variables: camelCase (e.g., getUserById, isValid)
  • Constants: UPPER_SNAKE_CASE (e.g., MAX_RETRIES, DEFAULT_TIMEOUT)
  • Interfaces: PascalCase (e.g., User, CreateUserDto) - No 'I' prefix

Bilingual Comments

For core logic and public APIs, assume both international and Vietnamese developers reading the code.

/**
 * EN: Validates user credentials and returns a token
 * VI: Xác thực thông tin người dùng và trả về token
 */
async login(dto: LoginDto): Promise<TokenResponse> { ... }

TypeScript Usage

  • Strict Mode: Enabled in tsconfig.json. No any allowed (use unknown if needed).
  • DTOs: Use Zod for runtime validation and type inference.
  • Return Types: Explicitly declare return types for all public methods.

Git Workflow

Branching Strategy

  • main: Production-ready code.
  • develop: Integration branch for next release.
  • feature/xyz: New features (branch off develop).
  • fix/xyz: Bug fixes (branch off develop).
  • hotfix/xyz: Critical fixes (branch off main).
gitGraph
 commit id: "Initial"
 branch develop
 checkout develop
 commit id: "Setup"

 branch feature/login
 checkout feature/login
 commit id: "Add login form"
 commit id: "Add validation"
 checkout develop
 merge feature/login

 branch feature/dashboard
 checkout feature/dashboard
 commit id: "Create dashboard"
 checkout develop

 checkout main
 merge develop tag: "v1.0.0"

 checkout develop
 merge feature/dashboard

 checkout main
 branch hotfix/security
 commit id: "Fix security issue"
 checkout main
 merge hotfix/security tag: "v1.0.1"
 checkout develop
 merge hotfix/security

Commit Messages

We follow Conventional Commits:

feat(iam): add multi-factor authentication
fix(db): correct unique constraint on email
docs(guide): update development setup
style: format code with prettier
refactor: simplify auth middleware
test: add unit tests for user service
chore: update dependencies

Backend Development

graph TD
 Start([Start Creating New API]) --> DTO[1. Define DTO - Zod Schema]
 DTO --> Repo[2. Create Repository Method]
 Repo --> Service[3. Create Service Method - Business Logic]
 Service --> Controller[4. Create Controller - HTTP Handler]
 Controller --> Route[5. Register Route - Express Router]
 Route --> Middleware[6. Add Middlewares]
 Middleware --> Test[7. Write Tests]
 Test --> Done([API Complete])

 Service --> ErrorCheck{Has Error?}
 ErrorCheck -->|Yes| ThrowError[Throw HttpError]
 ThrowError --> ErrorHandler[Global Error Handler]
 ErrorHandler --> Response[Error Response]
 ErrorCheck -->|No| Success[Success Response]

 style Start fill:#1e3a2e,color:#4ade80,stroke:#4ade80,stroke-width:3px
 style Done fill:#1e3a2e,color:#4ade80,stroke:#4ade80,stroke-width:3px
 style DTO fill:#1e293b,color:#60a5fa
 style Repo fill:#1e293b,color:#3b82f6
 style Service fill:#2e1a47,color:#a78bfa
 style Controller fill:#2d1b0e,color:#fb923c
 style Route fill:#1e293b,color:#3b82f6
 style Middleware fill:#1e293b,color:#60a5fa
 style Test fill:#1e3a2e,color:#4ade80
 style ErrorCheck fill:#2d1b0e,color:#fb923c
 style ThrowError fill:#3f1a1a,color:#f87171
 style ErrorHandler fill:#3f1a1a,color:#f87171
 style Response fill:#27272a,color:#a1a1aa
 style Success fill:#1e3a2e,color:#4ade80

Creating a New API Endpoint

  1. Define DTO (modules/user/user.dto.ts):
export const CreateUserDto = z.object({
email: z.string().email(),
name: z.string().min(2),
});
export type CreateUserDto = z.infer<typeof CreateUserDto>;
  1. Create Service Method (modules/user/user.service.ts):
  • Implement business logic.
  • Use BaseRepository.
  • Throw HttpError (e.g., NotFound, BadRequest).
  1. Create Controller (modules/user/user.controller.ts):
  • Parse body with DTO: const dto = CreateUserDto.parse(req.body).
  • Call service.
  • Return success response: res.json({ success: true, data: result }).
  1. Register Route (modules/user/index.ts):
  • Add to Express router with middlewares.

Error Handling

Always use the custom error classes from core/errors:

import { NotFoundError, ConflictError } from '../../core/errors';

if (!user) {
 throw new NotFoundError('User not found');
}

Testing Strategy

graph TB
 subgraph "Testing Pyramid - Bottom to Top"
 Unit[Unit Tests - Most, Fastest]
 Integration[Integration Tests - Medium]
 E2E[E2E Tests - Least, Slowest]
 end

 Code[Code Changes] --> CheckLint{Lint Pass?}
 CheckLint -->|No| FixLint[Fix Linting Errors]
 FixLint --> CheckLint
 CheckLint -->|Yes| RunUnit[Run Unit Tests]

 RunUnit --> UnitPass{Unit Tests Pass?}
 UnitPass -->|No| FixUnit[Fix Unit Tests]
 FixUnit --> RunUnit
 UnitPass -->|Yes| RunIntegration[Run Integration Tests]

 RunIntegration --> IntPass{Integration Pass?}
 IntPass -->|No| FixIntegration[Fix Integration]
 FixIntegration --> RunIntegration
 IntPass -->|Yes| RunE2E[Run E2E Tests]

 RunE2E --> E2EPass{E2E Pass?}
 E2EPass -->|No| FixE2E[Fix E2E]
 FixE2E --> RunE2E
 E2EPass -->|Yes| Coverage{Coverage > 70%?}

 Coverage -->|No| AddTests[Add More Tests]
 AddTests --> RunUnit
 Coverage -->|Yes| ReadyMerge[Ready to Merge]

 style Unit fill:#1e3a2e,color:#4ade80
 style Integration fill:#1e293b,color:#60a5fa
 style E2E fill:#2e1a47,color:#a78bfa
 style Code fill:#1e293b,color:#3b82f6
 style CheckLint fill:#2d1b0e,color:#fb923c
 style UnitPass fill:#1e3a2e,color:#4ade80
 style IntPass fill:#1e293b,color:#60a5fa
 style E2EPass fill:#2e1a47,color:#a78bfa
 style Coverage fill:#2d1b0e,color:#fbbf24
 style RunUnit fill:#1e3a2e,color:#4ade80
 style RunIntegration fill:#1e293b,color:#60a5fa
 style RunE2E fill:#2e1a47,color:#a78bfa
 style ReadyMerge fill:#1e3a2e,color:#4ade80,stroke:#4ade80,stroke-width:3px
 style FixLint fill:#3f1a1a,color:#f87171
 style FixUnit fill:#3f1a1a,color:#f87171
 style FixIntegration fill:#3f1a1a,color:#f87171
 style FixE2E fill:#3f1a1a,color:#f87171
 style AddTests fill:#2d1b0e,color:#fbbf24

Unit Tests (*.test.ts)

  • Scope: Individual classes/functions.
  • Mocking: Mock all external dependencies (DB, other services) using jest-mock-extended.
  • Location: Co-located with source files.
  • Run: pnpm test

E2E Tests (tests/**/*.e2e.ts)

  • Scope: Full API flows (Controller -> Service -> DB).
  • Database: Use a separate test database (Dockerized).
  • Run: pnpm test:e2e

Linting & Formatting

  • Lint: pnpm lint (ESLint)
  • Format: pnpm format (Prettier)
  • Typecheck: pnpm typecheck (TSC)

Database Workflow

We use Prisma with Neon PostgreSQL.

Migrations

  1. Modify prisma/schema.prisma.
  2. Create migration (Dev):
./scripts/db/migrate.sh iam-service dev --name add_user_profile
  1. Apply to Production (CI/CD):
./scripts/db/migrate.sh iam-service deploy

Seed Data

Populate database with initial data:

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

Visualizing Data

Use Prisma Studio:

pnpm --filter @goodgo/iam-service prisma studio

Kubernetes Deployment

For local Kubernetes testing (Docker Desktop / Minikube):

# 1. Build images
docker build -t goodgo/iam-service:latest -f services/iam-service/Dockerfile .

# 2. Deploy
cd deployments/local/kubernetes
./deploy.sh

# 3. Verify
kubectl get pods -n iam-local
kubectl logs -f -l app=iam-service -n iam-local

See Kubernetes Guide for detailed setup.