Files
pos-system/docs/en/guides/development.md
Ho Ngoc Hai 9ba4a478ee feat(docs): Enhance deployment and development guides with improved clarity and structure
- Updated Mermaid diagrams in the deployment and development guides for better visual representation and consistency.
- Improved formatting and clarity in the Kubernetes local deployment and IAM migration guides, including detailed workflows and troubleshooting sections.
- Enhanced the Vietnamese documentation to align with the English version, ensuring consistency across guides.
- Added quick tips and common issues sections to facilitate user navigation and understanding.
2026-01-08 17:10:06 +07:00

331 lines
8.7 KiB
Markdown

# Development Guide
Comprehensive standards and workflows for contributing to the GoodGo Microservices Platform.
## Table of Contents
1. [Project Structure](#project-structure)
2. [Code Standards](#code-standards)
3. [Git Workflow](#git-workflow)
4. [Backend Development](#backend-development)
5. [Testing Strategy](#testing-strategy)
6. [Database Workflow](#database-workflow)
7. [Kubernetes Deployment](#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.
```typescript
/**
* 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`).
```mermaid
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](https://www.conventionalcommits.org/):
```
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
```mermaid
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`):
```typescript
export const CreateUserDto = z.object({
email: z.string().email(),
name: z.string().min(2),
});
export type CreateUserDto = z.infer<typeof CreateUserDto>;
```
2. **Create Service Method** (`modules/user/user.service.ts`):
* Implement business logic.
* Use `BaseRepository`.
* Throw `HttpError` (e.g., `NotFound`, `BadRequest`).
3. **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 })`.
4. **Register Route** (`modules/user/index.ts`):
* Add to Express router with middlewares.
### Error Handling
Always use the custom error classes from `core/errors`:
```typescript
import { NotFoundError, ConflictError } from '../../core/errors';
if (!user) {
throw new NotFoundError('User not found');
}
```
---
## Testing Strategy
```mermaid
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):
```bash
./scripts/db/migrate.sh iam-service dev --name add_user_profile
```
3. Apply to Production (CI/CD):
```bash
./scripts/db/migrate.sh iam-service deploy
```
### Seed Data
Populate database with initial data:
```bash
./scripts/db/seed.sh iam-service
```
### Visualizing Data
Use Prisma Studio:
```bash
pnpm --filter @goodgo/iam-service prisma studio
```
---
## Kubernetes Deployment
For local Kubernetes testing (Docker Desktop / Minikube):
```bash
# 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](./kubernetes-local.md) for detailed setup.