# Development Guide > **Note**: This guide provides 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 { ... } ``` ### 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`). ### 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 ### 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; ``` 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 ### 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.