This commit is contained in:
Ho Ngoc Hai
2026-05-23 18:37:02 +07:00
parent f15d91ee29
commit 76d75c753b
3993 changed files with 403 additions and 0 deletions

View File

@@ -0,0 +1,246 @@
# Deployment Guide
>Deployment strategies for GoodGo Microservices Platform across Local, Staging, and Production environments using Kubernetes and Neon PostgreSQL
## Table of Contents
1. [Deployment Architecture](#deployment-architecture)
2. [Prerequisites](#prerequisites)
3. [Database Setup (Neon)](#database-setup-neon)
4. [Local Deployment](#local-deployment)
5. [CI/CD Pipeline](#cicd-pipeline)
6. [Staging Deployment](#staging-deployment)
7. [Production Deployment](#production-deployment)
8. [Scaling & Resilience](#scaling--resilience)
9. [Rollback Procedures](#rollback-procedures)
---
## Deployment Architecture
```mermaid
graph TD
subgraph "CI/CD Pipeline - GitHub Actions"
Code[Code Push] --> Test[Run Tests]
Test --> Build[Build Docker Image]
Build --> Registry[Push to Registry]
Registry --> Deploy[Deploy to K8s]
end
subgraph "Infrastructure - Kubernetes"
Ingress[Traefik Ingress] --> Service[K8s Service]
Service --> Pods[Application Pods]
Pods --> Secrets[K8s Secrets]
end
subgraph "External Services"
Pods --> Neon[(Neon PostgreSQL)]
Pods --> Redis[(Redis Cloud)]
end
Deploy --> Ingress
style Code fill:#1e3a5f,color:#e0e7ff
style Test fill:#065f46,color:#d1fae5
style Build fill:#1e40af,color:#dbeafe
style Registry fill:#581c87,color:#f3e8ff
style Deploy fill:#9a3412,color:#fed7aa
style Ingress fill:#312e81,color:#e0e7ff
style Service fill:#1e40af,color:#dbeafe
style Pods fill:#14532d,color:#d1fae5
style Secrets fill:#78350f,color:#fef3c7
style Neon fill:#4c1d95,color:#f3e8ff
style Redis fill:#854d0e,color:#fef3c7
```
---
## Prerequisites
Before deploying, ensure you have:
* **Tools**: `kubectl`, `helm`, `docker` installed.
* **Access**:
* Kubernetes Cluster (EKS/GKE/DigitalOcean).
* Container Registry (GHCR/DockerHub).
* Neon Console Account.
* **Configuration**:
* `KUBECONFIG` file set up.
* GitHub Secrets configured for CI/CD.
---
## Database Setup (Neon)
We use **Neon Serverless PostgreSQL** for all environments to leverage branching and auto-scaling.
1. **Create Project**: Log in to [neon.tech](https://neon.tech) and create a project `goodgo-platform`.
2. **Create Branches**:
* `main` -> For Development/Local.
* `staging` -> For Staging environment.
* `production` -> For Production environment (Protected).
3. **Get Connection Strings**:
* Note the connection string for each branch (Pooler mode recommended).
---
## Local Deployment
For local development, we use Docker Compose.
```bash
# 1. Setup Environment
cp deployments/local/env.local.example deployments/local/.env.local
# Edit .env.local with Neon `main` branch connection string
# 2. Start Infrastructure (Redis, Traefik, etc.)
cd deployments/local
docker-compose up -d
# 3. Start Services (Hot-reload)
pnpm dev
```
---
## CI/CD Pipeline
We use GitHub Actions for automated deployments.
| Workflow | Trigger | Description |
| :--- | :--- | :--- |
| `ci-check.yml` | Pull Request | Runs unit tests, linting, and build check. |
| `deploy-staging.yml` | Push to `develop` | Build image -> Deploy to Staging Namespace. |
| `deploy-prod.yml` | Release / Tag | Build image -> Deploy to Production Namespace. |
### Secrets Configuration (GitHub)
Set these secrets in your repository settings:
* `NEON_DATABASE_URL_STAGING`: Connection string for staging branch.
* `NEON_DATABASE_URL_PRODUCTION`: Connection string for production branch.
* `KUBECONFIG_STAGING`: Base64 encoded kubeconfig for staging.
* `KUBECONFIG_PRODUCTION`: Base64 encoded kubeconfig for production.
* `DOCKER_REGISTRY_TOKEN`: For pushing images.
---
## Staging Deployment
Staging mirrors production but uses cost-effective resources.
### Manual Deployment
```bash
# 1. Create Secrets
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='<STAGING_NEON_URL>' \
--from-literal=jwt-secret='<RANDOM_SECRET>' \
-n staging
# 2. Apply Manifests
kubectl apply -f deployments/staging/kubernetes/ -n staging
# 3. Verify
kubectl get pods -n staging
```
### via CI/CD
Push code to `develop` branch. The action will:
1. Run tests.
2. Run `prisma migrate deploy` against Staging DB.
3. Update Kubernetes deployment image.
---
## Production Deployment
Production uses high-availability configurations.
### 1. Database Preparation
* Ensure Production branch in Neon is **protected**.
* Configure **Point-in-Time Recovery (PITR)** window (e.g., 7 days).
### 2. Manual Deployment Steps
```bash
# 1. Create Namespace
kubectl create namespace production
# 2. Create Sealed Secrets (Recommended) or Standard Secrets
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='<PROD_NEON_URL>' \
--from-literal=jwt-secret='<SECURE_RANDOM_SECRET>' \
--from-literal=jwt-refresh-secret='<SECURE_RANDOM_SECRET>' \
-n production
# 3. Deploy
kubectl apply -f deployments/production/kubernetes/ -n production
```
### 3. Verification
```bash
# Check Rollout Status
kubectl rollout status deployment/iam-service -n production
# Check Logs
kubectl logs -l app=iam-service -n production
```
---
## Scaling & Resilience
### Horizontal Pod Autoscaler (HPA)
We use HPA to automatically scale pods based on CPU/Memory.
```yaml
# Example HPA Config
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: iam-service-hpa
spec:
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
```
### Zero-Downtime Deployment
Kubernetes handles this via Rolling Updates.
* **MaxSurge**: 25% (Add new pods before removing old ones).
* **MaxUnavailable**: 0 (Ensure no downtime during update).
---
## Rollback Procedures
If a deployment fails or introduces a critical bug:
### Kubernetes Rollback
```bash
# Undo last deployment
kubectl rollout undo deployment/iam-service -n production
# Undo to specific revision
kubectl rollout undo deployment/iam-service -n production --to-revision=2
```
### Database Rollback
Since Neon supports branching and PITR:
1. Go to Neon Console.
2. Restore the `production` branch to a timestamp before the bad migration.
3. **Warning**: This may result in data loss for new transactions. Use with caution.

View File

@@ -0,0 +1,330 @@
# 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.

View File

@@ -0,0 +1,259 @@
# Getting Started
> **Note**: This guide assumes you are setting up the project on macOS or Linux. Windows users should use WSL2.
## Table of Contents
1. [Prerequisites](#prerequisites)
2. [Architecture Overview](#architecture-overview)
3. [Project Structure](#project-structure)
4. [Installation & Setup](#installation--setup)
5. [Development Workflow](#development-workflow)
6. [Common Commands](#common-commands)
7. [Troubleshooting](#troubleshooting)
## Prerequisites
Before starting, ensure you have the following installed:
* **Node.js**: v20.0.0 or higher (recommended v22+ or v25+)
```bash
node -v
# v25.2.1
```
* **PNPM**: v8.15.0 or higher (we use pnpm workspaces)
```bash
pnpm -v
# 8.15.0
```
* **Docker & Docker Compose**: v24.0.0 or higher for local infrastructure
```bash
docker -v
# Docker version 29.1.3, build f52814d
```
* **Git**: For version control
* **Neon Account**: Serverless PostgreSQL (https://neon.tech)
## Architecture Overview
GoodGo Platform uses a microservices architecture with a shared infrastructure layer.
```mermaid
graph TD
Client[Client Apps] --> Traefik[Traefik Gateway]
Traefik --> IAM[IAM Service]
Traefik --> Template[Template Service]
IAM --> DB[(Neon PostgreSQL)]
IAM --> Redis[(Redis Cache)]
IAM --> Kafka[Kafka Events]
style Client fill:#34495E,stroke:#2C3E50,color:#ECF0F1
style Traefik fill:#1A5490,stroke:#154360,color:#ECF0F1
style IAM fill:#1E8449,stroke:#186A3B,color:#ECF0F1
style Template fill:#BA6610,stroke:#935116,color:#ECF0F1
style DB fill:#6C3483,stroke:#512E5F,color:#ECF0F1
style Redis fill:#CA6F1E,stroke:#A04000,color:#ECF0F1
style Kafka fill:#21618C,stroke:#1B4F72,color:#ECF0F1
```
### Color Palette
```mermaid
graph LR
A[" Primary<br/>#1A5490"] --> B[" Data/Cache<br/>#CA6F1E"]
B --> C[" Success<br/>#1E8449"]
C --> D[" Warning<br/>#BA6610"]
D --> E[" Error<br/>#922B21"]
E --> F[" Processing<br/>#6C3483"]
F --> G[" Info<br/>#21618C"]
G --> H[" Neutral<br/>#34495E"]
style A fill:#1A5490,stroke:#154360,color:#ECF0F1
style B fill:#CA6F1E,stroke:#A04000,color:#ECF0F1
style C fill:#1E8449,stroke:#186A3B,color:#ECF0F1
style D fill:#BA6610,stroke:#935116,color:#ECF0F1
style E fill:#922B21,stroke:#78281F,color:#ECF0F1
style F fill:#6C3483,stroke:#512E5F,color:#ECF0F1
style G fill:#21618C,stroke:#1B4F72,color:#ECF0F1
style H fill:#34495E,stroke:#2C3E50,color:#ECF0F1
```
## Project Structure
The repository follows a monorepo structure:
```
Base/
apps/ # Frontend applications
app-admin/ # Admin dashboard application
app-client/ # Client mobile application (Flutter)
web-client/ # Next.js web application
web-docs/ # Documentation website (Next.js)
services/ # Backend microservices
iam-service/ # Authentication & Authorization service
_template/ # Template for new services
packages/ # Shared libraries
auth-sdk/ # Authentication SDK
config/ # Shared configuration utilities
http-client/ # Internal HTTP client
logger/ # Structured logging (@goodgo/logger)
tracing/ # OpenTelemetry tracing
types/ # Shared TypeScript types
infra/ # Infrastructure configuration
databases/ # Database setup scripts
docker/ # Docker configurations
observability/ # Prometheus, Grafana, Loki configs
secrets/ # Secrets management templates
traefik/ # API Gateway configuration
deployments/ # Deployment configurations
local/ # Docker Compose for development
staging/ # Staging environment configs
production/ # Production Kubernetes manifests
scripts/ # Automation scripts
build/ # Build scripts
db/ # Database utilities
deploy/ # Deployment scripts
dev/ # Development helpers
observability/ # Monitoring setup scripts
setup/ # Initial setup scripts
utils/ # Utility scripts
docs/ # Documentation
en/ # English documentation
vi/ # Vietnamese documentation
```
## Installation & Setup
### 1. Clone the Repository
```bash
git clone <repository-url>
cd Base
```
### 2. Configure Environment
Each service and the local infrastructure needs environment variables. We provide templates for these.
```bash
# Initialize project setup (copies .env.example to .env)
./scripts/setup/init-project.sh
```
### 3. Setup Neon Database
We use Neon (Serverless PostgreSQL) for all environments (Dev, Staging, Prod).
1. Create a project at [neon.tech](https://neon.tech).
2. Create a branch named `dev` (or use `main`).
3. Get the Connection String from the Neon dashboard.
4. Update `deployments/local/.env.local`:
```env
DATABASE_URL="postgres://user:pass@ep-xyz.region.neon.tech/neondb"
```
### 4. Start Infrastructure
Start the supporting infrastructure (Redis, Traefik, Observability) using Docker Compose.
```bash
cd deployments/local
docker-compose up -d
# Expected output: Containers for traefik, redis, kafka created
```
### 5. Install Dependencies
```bash
pnpm install
```
### 6. Setup Database Schema
Push the Prisma schema to your Neon database.
```bash
# Run migrations for IAM service
pnpm --filter @goodgo/iam-service prisma migrate dev
```
### 7. Start Services
Start all backend services in development mode.
```bash
pnpm dev
# or start specific service
pnpm --filter @goodgo/iam-service dev
```
## Development Workflow
### Creating a New Service
1. Copy the template:
```bash
cp -r services/_template services/my-new-service
```
2. Update `package.json` name.
3. Add logic in `src/modules/`.
4. Register in `deployments/local/docker-compose.yml`.
### Making Changes
1. Create a new branch: `feature/my-feature`.
2. Implement changes.
3. Run tests: `pnpm test`.
4. Commit with conventional commits: `feat(iam): add login endpoint`.
## Common Commands
| Command | Description |
| :--- | :--- |
| `pnpm install` | Install all dependencies |
| `pnpm dev` | Start all services in dev mode |
| `pnpm build` | Build all packages and services |
| `pnpm test` | Run unit tests |
| `pnpm lint` | Lint code |
| `docker-compose up -d` | Start local infra |
| `docker-compose down` | Stop local infra |
## Troubleshooting
### Port Conflicts
**Error**: `Bind for 0.0.0.0:80 failed: port is already allocated`
**Solution**: Check what's using port 80 (likely another web server) and stop it, or change Traefik ports in `docker-compose.yml`.
```bash
lsof -i :80
kill -9 <PID>
```
### Database Connection Failed
**Error**: `P1001: Can't reach database server`
**Solution**:
1. Check your internet connection (Neon is cloud-based).
2. Verify `DATABASE_URL` in `deployments/local/.env.local`.
3. Ensure your IP is allowed in Neon dashboard settings.
### Service Not Found in Gateway
**Error**: `404 Not Found` from api.localhost
**Solution**:
1. Check if service is running.
2. Check Traefik dashboard at http://localhost:8080.
3. Verify `PathPrefix` labels in `docker-compose.yml`.
## Next Steps
* [Development Guide](development.md) - Deep dive into coding standards
* [API Documentation](../api/openapi/) - Explore the APIs
* [Architecture](../architecture/system-design.md) - Understand the system design

View File

@@ -0,0 +1,351 @@
# IAM Service Authentication Guide
> Complete guide for authentication using GoodGo IAM Service with OAuth2/OpenID Connect.
## Overview
The IAM Service provides OAuth2/OIDC authentication using Duende IdentityServer:
- **Password Grant** - User login with email/password
- **Refresh Token** - Token renewal without re-authentication
- **Client Credentials** - Service-to-service authentication
- **Email Verification** - SMTP-based email confirmation
- **Two-Factor Authentication (2FA)** - TOTP with QR code and recovery codes
- **Social Login** - Google and Facebook OAuth integration
## Quick Start
### 1. Register a User
```bash
curl -X POST http://localhost:5001/api/v1/auth/register \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com",
"password": "Password123!",
"firstName": "John",
"lastName": "Doe"
}'
```
### 2. Login (Get Tokens)
```bash
curl -X POST http://localhost:5001/connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "username=user@example.com" \
-d "password=Password123!" \
-d "scope=openid profile email offline_access"
```
**Response:**
```json
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 900,
"refresh_token": "eyJhbGciOiJSUzI1NiIs...",
"scope": "openid profile email offline_access"
}
```
### 3. Use Access Token
```bash
curl http://localhost:5001/api/v1/users/me \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..."
```
## OAuth2 Grant Types
### Password Grant (User Login)
For trusted first-party applications where users enter credentials directly.
```bash
curl -X POST http://localhost:5001/connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "username=user@example.com" \
-d "password=Password123!" \
-d "scope=openid profile email offline_access"
```
| Parameter | Required | Description |
|-----------|----------|-------------|
| `grant_type` | Yes | Must be `password` |
| `username` | Yes | User's email |
| `password` | Yes | User's password |
| `scope` | No | Space-separated scopes |
### Refresh Token
Renew access token without re-entering credentials.
```bash
curl -X POST http://localhost:5001/connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=eyJhbGciOiJSUzI1NiIs..."
```
| Parameter | Required | Description |
|-----------|----------|-------------|
| `grant_type` | Yes | Must be `refresh_token` |
| `refresh_token` | Yes | Valid refresh token |
### Client Credentials (Service-to-Service)
For backend services authenticating without user context.
```bash
curl -X POST http://localhost:5001/connect/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=goodgo-service" \
-d "client_secret=service-secret" \
-d "scope=api"
```
| Parameter | Required | Description |
|-----------|----------|-------------|
| `grant_type` | Yes | Must be `client_credentials` |
| `client_id` | Yes | Registered client ID |
| `client_secret` | Yes | Client secret |
| `scope` | No | Requested scopes |
> **Note:** Client applications must be registered in the database before use.
## Token Lifetimes
| Token Type | Lifetime | Use |
|------------|----------|-----|
| Access Token | 15 minutes | API authorization |
| Refresh Token | 7 days | Token renewal |
## Available Scopes
| Scope | Description |
|-------|-------------|
| `openid` | Required for OIDC |
| `profile` | User profile (name) |
| `email` | User email |
| `roles` | User roles |
| `offline_access` | Get refresh token |
| `api` | API access |
## API Endpoints
### Authentication
| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | `/api/v1/auth/register` | Register new user |
| `POST` | `/connect/token` | OAuth2 token endpoint |
| `POST` | `/api/v1/auth/change-password` | Change password (auth required) |
| `POST` | `/api/v1/auth/logout` | Revoke tokens (auth required) |
### Email Verification
| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | `/api/v1/auth/send-verification-email` | Send email verification link (auth required) |
| `POST` | `/api/v1/auth/confirm-email` | Confirm email with token |
### Two-Factor Authentication (2FA)
| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | `/api/v1/auth/2fa/enable` | Enable 2FA (get QR code) (auth required) |
| `POST` | `/api/v1/auth/2fa/verify` | Verify TOTP code & activate (auth required) |
| `POST` | `/api/v1/auth/2fa/disable` | Disable 2FA (auth required) |
### Social Login
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/v1/auth/external-login/{provider}` | Initiate OAuth flow (Google/Facebook) |
| `GET` | `/api/v1/auth/external-callback` | Handle OAuth callback |
| `GET` | `/api/v1/auth/linked-accounts` | Get linked OAuth providers (auth required) |
### User Management
| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/api/v1/users` | List users (paginated) |
| `GET` | `/api/v1/users/me` | Current user info |
| `GET` | `/api/v1/users/{id}` | Get user by ID |
| `PUT` | `/api/v1/users/{id}` | Update user |
| `DELETE` | `/api/v1/users/{id}` | Delete user (soft) |
## Integration Examples
### JavaScript/TypeScript
```typescript
// Login
const response = await fetch('http://localhost:5001/connect/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'password',
username: 'user@example.com',
password: 'Password123!',
scope: 'openid profile email offline_access'
})
});
const { access_token, refresh_token } = await response.json();
// Use token
const user = await fetch('http://localhost:5001/api/v1/users/me', {
headers: { 'Authorization': `Bearer ${access_token}` }
}).then(r => r.json());
```
### C# / .NET
```csharp
// Login
var client = new HttpClient();
var content = new FormUrlEncodedContent(new Dictionary<string, string>
{
["grant_type"] = "password",
["username"] = "user@example.com",
["password"] = "Password123!",
["scope"] = "openid profile email offline_access"
});
var response = await client.PostAsync("http://localhost:5001/connect/token", content);
var tokens = await response.Content.ReadFromJsonAsync<TokenResponse>();
// Use token
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
var user = await client.GetFromJsonAsync<UserDto>("/api/v1/users/me");
```
## Email Verification
### Send Verification Email
```bash
curl -X POST http://localhost:5001/api/v1/auth/send-verification-email \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com"}'
```
### Confirm Email
```bash
curl -X POST http://localhost:5001/api/v1/auth/confirm-email \
-H "Content-Type: application/json" \
-d '{"userId": "user-guid", "token": "confirmation-token"}'
```
## Two-Factor Authentication (2FA)
### Enable 2FA
```bash
curl -X POST http://localhost:5001/api/v1/auth/2fa/enable \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
**Response:**
```json
{
"success": true,
"data": {
"secretKey": "JBSWY3DPEHPK3PXP",
"qrCodeBase64": "data:image/png;base64,...",
"recoveryCodes": ["code1", "code2", "code3"]
}
}
```
### Verify 2FA Code
```bash
curl -X POST http://localhost:5001/api/v1/auth/2fa/verify \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"code": "123456"}'
```
### Disable 2FA
```bash
curl -X POST http://localhost:5001/api/v1/auth/2fa/disable \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"code": "123456"}'
```
## Social Login
### Initiate OAuth Flow
Redirect user to:
```
GET http://localhost:5001/api/v1/auth/external-login/Google?returnUrl=http://your-app/callback
GET http://localhost:5001/api/v1/auth/external-login/Facebook?returnUrl=http://your-app/callback
```
### Get Linked Accounts
```bash
curl http://localhost:5001/api/v1/auth/linked-accounts \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
**Response:**
```json
{
"success": true,
"data": {
"linkedProviders": [
{"provider": "Google", "providerDisplayName": "Google"},
{"provider": "Facebook", "providerDisplayName": "Facebook"}
]
}
}
```
## Error Responses
### Common Errors
| Error | HTTP Code | Description |
|-------|-----------|-------------|
| `invalid_grant` | 400 | Invalid credentials |
| `invalid_client` | 400 | Unknown client_id |
| `invalid_scope` | 400 | Invalid scope requested |
| `unauthorized` | 401 | Invalid/expired token |
### Error Response Format
```json
{
"error": "invalid_grant",
"error_description": "The username or password is incorrect."
}
```
## Security Best Practices
1. **Store tokens securely** - Use httpOnly cookies or secure storage
2. **Refresh tokens proactively** - Before access token expires
3. **Use HTTPS in production** - Never send credentials over HTTP
4. **Logout properly** - Call logout endpoint to revoke tokens
5. **Validate tokens server-side** - Don't trust client-side validation
## Swagger UI
Access interactive API documentation:
- **Local**: http://localhost:5001/swagger
## Related Documentation
- [IAM Migration Guide](./iam-migration.md)
- [Local Development](./local-development.md)
- [Security Architecture](../architecture/security-architecture.md)

View File

@@ -0,0 +1,391 @@
# Migration Guide: Auth Service → IAM Service
This document guides you through migrating from `auth-service` to `iam-service`.
## Overview
IAM Service is an extended version of Auth Service with additional features for Identity Management, Access Management, and Governance & Compliance. All Auth Service API endpoints remain unchanged to ensure backward compatibility.
## Migration Workflow
```mermaid
graph LR
Start([Start Migration]) --> Backup[ Backup]
Backup --> DBMigrate[ Database Migration]
DBMigrate --> UpdateDeps[ Update Dependencies]
UpdateDeps --> Deploy[ Deploy]
Deploy --> Verify[ Verify]
Verify --> Decision{All Tests Pass?}
Decision -->|Yes| Rollout[ Gradual Rollout]
Decision -->|No| Rollback[⏮ Rollback]
Rollback --> Debug[ Debug Issues]
Debug --> DBMigrate
Rollout --> Monitor[ Monitor]
Monitor --> Complete([ Complete])
style Start fill:#2d4263,stroke:#c69b7b,stroke-width:2px,color:#f5f5f5
style Backup fill:#191e29,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style DBMigrate fill:#191e29,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style UpdateDeps fill:#191e29,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style Deploy fill:#2d4263,stroke:#87a2a7,stroke-width:2px,color:#f5f5f5
style Verify fill:#2d4263,stroke:#87a2a7,stroke-width:2px,color:#f5f5f5
style Decision fill:#4a5568,stroke:#c69b7b,stroke-width:2px,color:#f5f5f5
style Rollout fill:#1a472a,stroke:#48bb78,stroke-width:2px,color:#f5f5f5
style Rollback fill:#742a2a,stroke:#f56565,stroke-width:2px,color:#f5f5f5
style Debug fill:#742a2a,stroke:#f56565,stroke-width:2px,color:#f5f5f5
style Monitor fill:#2d4263,stroke:#87a2a7,stroke-width:2px,color:#f5f5f5
style Complete fill:#1a472a,stroke:#48bb78,stroke-width:2px,color:#f5f5f5
```
## Backward Compatibility
**All existing endpoints continue to work normally:**
- `/api/v1/auth/*` - Authentication endpoints
- `/api/v1/rbac/*` - RBAC endpoints
- `/api/v1/mfa/*` - MFA endpoints
- `/api/v1/sessions/*` - Session management endpoints
- `/api/v1/oidc/*` - OIDC endpoints
No breaking changes. Existing clients can continue using these endpoints without any modifications.
## Architecture Comparison
```mermaid
graph TB
subgraph "Auth Service (Old)"
A1[Authentication]
A2[RBAC]
A3[MFA]
A4[Sessions]
A5[OIDC]
end
subgraph "IAM Service (New)"
B1[Authentication]
B2[RBAC]
B3[MFA]
B4[Sessions]
B5[OIDC]
B6[Identity Management]
B7[Access Management]
B8[Governance]
end
A1 -.->|Unchanged| B1
A2 -.->|Unchanged| B2
A3 -.->|Unchanged| B3
A4 -.->|Unchanged| B4
A5 -.->|Unchanged| B5
style A1 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style A2 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style A3 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style A4 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style A5 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style B1 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style B2 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style B3 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style B4 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style B5 fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style B6 fill:#1a472a,stroke:#48bb78,stroke-width:2px,color:#f5f5f5
style B7 fill:#1a472a,stroke:#48bb78,stroke-width:2px,color:#f5f5f5
style B8 fill:#1a472a,stroke:#48bb78,stroke-width:2px,color:#f5f5f5
```
## Changes
### 1. Service Name
- **Old**: `auth-service`
- **New**: `iam-service`
### 2. Package Name
- **Old**: `@goodgo/auth-service`
- **New**: `@goodgo/iam-service`
### 3. Database Schema
Database schema is extended with new models but **does not delete or modify** existing models:
**New models added:**
- `Organization` - Organization management
- `Group` - Group management
- `GroupMember` - Group members
- `GroupPermission` - Group permissions
- `UserProfile` - Extended profile
- `IdentityVerification` - Identity verification
- `AccessRequest` - Access requests
- `AccessReview` - Access reviews
- `ComplianceReport` - Compliance reports
- `PolicyTemplate` - Policy templates
- `RiskScore` - Risk scores
**User model extended:**
- Added `organizationId` field (optional)
- Added new relations (optional)
```mermaid
erDiagram
User ||--o{ UserProfile : has
User ||--o{ AccessRequest : creates
User }o--|| Organization : "belongs to"
User ||--o{ GroupMember : "member of"
Organization ||--o{ Group : contains
Group ||--o{ GroupMember : has
Group ||--o{ GroupPermission : has
AccessRequest ||--|| AccessReview : "reviewed by"
Organization ||--o{ ComplianceReport : generates
User {
string id PK
string email
string organizationId FK
}
Organization {
string id PK
string name
}
Group {
string id PK
string organizationId FK
}
UserProfile {
string userId FK
json metadata
}
AccessRequest {
string id PK
string userId FK
}
```
### 4. New API Endpoints
#### Identity Management
- `/api/v1/identity/users/*` - User lifecycle management
- `/api/v1/identity/users/:id/profile` - Profile management
- `/api/v1/identity/verification/*` - Identity verification
- `/api/v1/identity/organizations/*` - Organization management
- `/api/v1/identity/groups/*` - Group management
#### Access Management
- `/api/v1/access/requests/*` - Access requests
- `/api/v1/access/reviews/*` - Access reviews
- `/api/v1/access/analytics/*` - Access analytics
#### Governance
- `/api/v1/governance/compliance/*` - Compliance reports
- `/api/v1/governance/policies/*` - Policy governance
- `/api/v1/governance/risk/*` - Risk management
- `/api/v1/governance/reports/*` - Reporting dashboard
### 5. Environment Variables
Some new environment variables may be added in the future for advanced IAM features (email service, SMS service, file storage), but they will not affect existing variables.
### 6. Deployment Configuration
**Docker Compose:**
- Service name: `auth-service``iam-service`
- Container name: `auth-service-local``iam-service-local`
- Traefik labels: Add new routes for `/api/v1/identity/*`, `/api/v1/access/*`, `/api/v1/governance/*`
**Kubernetes:**
- Deployment name: `auth-service``iam-service`
- Service name: `auth-service``iam-service`
- ConfigMap: `auth-service-config``iam-service-config`
- Secrets: `auth-service-secrets``iam-service-secrets`
## Migration Steps
### Step 1: Backup
```bash
# Backup database
pg_dump $DATABASE_URL > auth-service-backup.sql
# Backup code
cp -r services/auth-service services/auth-service.backup
```
### Step 2: Database Migration
```bash
cd services/iam-service
# Generate Prisma client with new schema
pnpm prisma generate
# Create migration
pnpm prisma migrate dev --name add_iam_models
# Verify migration
pnpm prisma studio # Check database structure
```
### Step 3: Update Dependencies
```bash
# Install dependencies (if new packages exist)
pnpm install
# Verify types compile
pnpm typecheck
```
### Step 4: Update Deployment
**Local Development:**
```bash
cd deployments/local
# Update docker-compose.yml (already updated)
docker-compose up -d iam-service
```
**Staging/Production:**
- Update Kubernetes manifests
- Update ingress routes
- Update ConfigMaps and Secrets
### Step 5: Verify Backward Compatibility
Test that all old endpoints still work:
```bash
# Test auth endpoints
curl http://localhost/api/v1/auth/me
# Test RBAC endpoints
curl http://localhost/api/v1/rbac/permissions
# Test MFA endpoints
curl http://localhost/api/v1/mfa/devices
```
### Step 6: Gradual Rollout
1. **Dual Deployment** (Optional):
- Deploy both `auth-service` and `iam-service` simultaneously
- Gradually route traffic to `iam-service`
- Monitor errors and performance
2. **Update Clients**:
- Update clients to use new endpoints if needed
- Clients don't need updates if only using old endpoints
3. **Deprecate Old Service**:
- After verifying everything works well, deprecate `auth-service`
- Ensure all clients have migrated to `iam-service`
## Deployment Strategy
```mermaid
graph TB
Current[Current: auth-service] --> Phase1[Phase 1: Dual Deploy]
Phase1 --> Split{Traffic Split}
Split -->|10%| IAM1[iam-service]
Split -->|90%| Auth1[auth-service]
Split --> Phase2[Phase 2: Increase]
Phase2 --> Split2{Traffic Split}
Split2 -->|50%| IAM2[iam-service]
Split2 -->|50%| Auth2[auth-service]
Split2 --> Phase3[Phase 3: Majority]
Phase3 --> Split3{Traffic Split}
Split3 -->|90%| IAM3[iam-service]
Split3 -->|10%| Auth3[auth-service]
Split3 --> Phase4[Phase 4: Complete]
Phase4 --> Final[iam-service only]
style Current fill:#2d4263,stroke:#76b6c4,stroke-width:2px,color:#f5f5f5
style Phase1 fill:#2d4263,stroke:#87a2a7,stroke-width:2px,color:#f5f5f5
style Phase2 fill:#2d4263,stroke:#87a2a7,stroke-width:2px,color:#f5f5f5
style Phase3 fill:#2d4263,stroke:#87a2a7,stroke-width:2px,color:#f5f5f5
style Phase4 fill:#2d4263,stroke:#87a2a7,stroke-width:2px,color:#f5f5f5
style Final fill:#1a472a,stroke:#48bb78,stroke-width:2px,color:#f5f5f5
style Split fill:#4a5568,stroke:#c69b7b,stroke-width:2px,color:#f5f5f5
style Split2 fill:#4a5568,stroke:#c69b7b,stroke-width:2px,color:#f5f5f5
style Split3 fill:#4a5568,stroke:#c69b7b,stroke-width:2px,color:#f5f5f5
style IAM1 fill:#1a472a,stroke:#48bb78,stroke-width:1px,color:#f5f5f5
style IAM2 fill:#1a472a,stroke:#48bb78,stroke-width:1px,color:#f5f5f5
style IAM3 fill:#1a472a,stroke:#48bb78,stroke-width:1px,color:#f5f5f5
style Auth1 fill:#742a2a,stroke:#f56565,stroke-width:1px,color:#f5f5f5
style Auth2 fill:#742a2a,stroke:#f56565,stroke-width:1px,color:#f5f5f5
style Auth3 fill:#742a2a,stroke:#f56565,stroke-width:1px,color:#f5f5f5
```
## Rollback Plan
If rollback is needed:
1. **Database Rollback**:
```bash
# Revert Prisma migration
cd services/iam-service
pnpm prisma migrate resolve --rolled-back <migration_name>
# Or restore from backup
psql $DATABASE_URL < auth-service-backup.sql
```
2. **Service Rollback**:
```bash
# Switch back to auth-service in docker-compose
# Or revert Kubernetes deployment
kubectl rollout undo deployment/auth-service
```
## Breaking Changes
**No breaking changes** in this migration. All existing API endpoints and database models are preserved.
## Notes
- This migration is **additive** - only adds new features, does not remove or change existing ones
- Database migrations are **non-destructive** - do not delete or modify existing data
- Clients can continue using old endpoints without any changes
## Support
If you encounter issues during migration:
1. Check logs: `docker-compose logs iam-service`
2. Verify database connection
3. Check environment variables
4. Review error messages and stack traces
## Quick Tips
**Migration Checklist:**
- Backup database and code
- Run database migrations
- Update deployment configuration
- Test backward compatibility
- Monitor gradual rollout
- Prepare rollback plan
### Common Issues & Solutions
| Issue | Cause | Solution |
|-------|-------|----------|
| Migration failed | Database connection | Check `DATABASE_URL` in `.env` |
| Service won't start | Missing env vars | Verify all env vars are set |
| Slow performance | Database indexes | Run Prisma migrations completely |
| Connection timeout | Network issues | Check firewall & security groups |
| New endpoints 404 | Routing config | Update Traefik/Ingress config |
**Visual Indicators:**
- Old Components (Unchanged)
- New Components (Added)
- Components to Deprecate
- Requires Attention

View File

@@ -0,0 +1,312 @@
# Local Kubernetes Deployment Guide
**Last Updated**: 2026-01-05
**Difficulty**: Intermediate
**Duration**: 30-45 minutes
## Workflow
```mermaid
graph TD
Start([ Start]) --> EnvPrep[1⃣ Environment Prep<br/>Enable K8s in Docker Desktop]
EnvPrep --> BuildImg[2⃣ Build Docker Image<br/>docker build -t service:local]
BuildImg --> LoadImg[3⃣ Load Image to Cluster<br/>kind load docker-image]
LoadImg --> Secrets[4⃣ Configure Secrets<br/>kubectl create secret]
Secrets --> Deploy[5⃣ Deploy Service<br/>kubectl apply -f manifests]
Deploy --> Verify[6⃣ Verify Deployment<br/>kubectl get pods]
Verify --> Test[7⃣ Test Service<br/>Port Forward & Curl]
Test --> End([ Complete])
subgraph Deployment[" Deployment Resources"]
Deploy --> |Apply| ConfigMap[ConfigMap<br/>Environment Config]
Deploy --> |Apply| K8sDeployment[Deployment<br/>Pod Template]
Deploy --> |Apply| Service[Service<br/>LoadBalancer/NodePort]
end
%% Start/End nodes - Success Green
style Start fill:#004d40,stroke:#00bfa5,stroke-width:3px,color:#e0f2f1
style End fill:#1b5e20,stroke:#66bb6a,stroke-width:3px,color:#e8f5e9
%% Workflow steps - Dark theme with distinct colors
style EnvPrep fill:#263238,stroke:#546e7a,stroke-width:2px,color:#eceff1
style BuildImg fill:#3e2723,stroke:#8d6e63,stroke-width:2px,color:#efebe9
style LoadImg fill:#1a237e,stroke:#5c6bc0,stroke-width:2px,color:#e8eaf6
style Secrets fill:#b71c1c,stroke:#ef5350,stroke-width:2px,color:#ffebee
style Deploy fill:#004d40,stroke:#26a69a,stroke-width:2px,color:#e0f2f1
style Verify fill:#1565c0,stroke:#42a5f5,stroke-width:2px,color:#e3f2fd
style Test fill:#4a148c,stroke:#ab47bc,stroke-width:2px,color:#f3e5f5
%% Deployment resources subgraph
style Deployment fill:#1a1a1a,stroke:#424242,stroke-width:2px,color:#e0e0e0
style ConfigMap fill:#263238,stroke:#78909c,stroke-width:1px,color:#cfd8dc
style K8sDeployment fill:#263238,stroke:#78909c,stroke-width:1px,color:#cfd8dc
style Service fill:#263238,stroke:#78909c,stroke-width:1px,color:#cfd8dc
```
## Overview
This guide details how to deploy the IAM Service (or any microservice in the GoodGo ecosystem) to a local Kubernetes cluster using Docker Desktop on macOS.
**Important:** This guide assumes you are using **Docker Desktop** with **Kubernetes enabled**. If you are using Minikube or plain Kind, the steps might differ slightly (especially the image loading part).
## 1. Prerequisites
### Software
- **Docker Desktop 4.0+**: [Download Link](https://www.docker.com/products/docker-desktop/)
- Kubernetes must be enabled in settings.
- **kubectl CLI**: Command-line tool for interacting with K8s.
```bash
brew install kubectl
```
- **kind CLI**: Required to load images into the cluster if using Kind backend explicitely.
```bash
brew install kind
```
- **pnpm 8+**: Project package manager.
```bash
npm install -g pnpm
```
### Knowledge
- Basic understanding of Kubernetes concepts: **Pod**, **Deployment**, **Service**, **Secret**, **ConfigMap**.
- Familiarity with basic Docker commands (`docker build`, `docker images`).
- Ability to navigate and run commands in the Terminal.
## 2. Environment Preparation
### 2.1 Enable Kubernetes in Docker Desktop
1. Open **Docker Desktop**.
2. Click the **Settings ()** icon.
3. Select the **Kubernetes** tab.
4. Check **Enable Kubernetes**.
5. Select **Show system containers (advanced)** for easier debugging (optional).
6. Click **Apply & Restart**.
7. Wait 2-3 minutes until the Kubernetes icon in the bottom corner turns green.
### 2.2 Verify Kubernetes Connection
Check if `kubectl` is connected to the correct context:
```bash
# Check current context
kubectl config current-context
# Expected Output: docker-desktop
# List all nodes in the cluster
kubectl get nodes
# Expected Output:
# NAME STATUS ROLES AGE VERSION
# docker-desktop Ready control-plane 10m v1.29.1
```
## 3. Build Docker Image
We need to build the service image before deploying. Taking `iam-service` as an example.
```bash
# Navigate to the kubernetes deployment directory
cd deployments/local/kubernetes
# Build the Docker image from the root context
# Note: -f points to service Dockerfile, context is root (../../..)
docker build -t iam-service:local -f ../../../services/iam-service/Dockerfile ../../..
# Verify the image was built successfully
docker images | grep iam-service
# Expected Output:
# iam-service local [IMAGE_ID] [SIZE] [CREATED]
```
## 4. Load Image into Cluster
** IMPORTANT**: Docker Desktop can use different backends. If you are running Kubernetes inside Docker Desktop, sometimes it doesn't immediately see local images if using a `kind` node underneath.
If you are using **Kind** (Kubernetes in Docker) separately or a specific Docker Desktop config, you need to load the image:
```bash
# Load image into kind cluster (if using kind explicitly)
kind load docker-image iam-service:local --name desktop
# Validating image presence (optional, hard with Docker Desktop K8s directly)
```
**Tip:** With default Docker Desktop, building the local image (`docker build ...`) is usually automatically available to Docker Desktop's K8s cluster. This loading step is mainly for those using `kind` CLI to create separate clusters.
## 5. Configure Secrets & ConfigMap
Kubernetes environments need sensitive environment variables (Secrets) and general configuration (ConfigMap).
### 5.1 Create Secrets (Manually)
You can run a script or the following commands to create secrets securely.
```bash
# Create a dedicated namespace for local testing
kubectl create namespace iam-local
# Generate random secrets and store in Kubernetes
kubectl create secret generic iam-service-secrets \
--from-literal=DATABASE_URL="postgresql://user:password@host.docker.internal:5432/iam_db?schema=public" \
--from-literal=JWT_SECRET="$(openssl rand -base64 32)" \
--from-literal=JWT_REFRESH_SECRET="$(openssl rand -base64 32)" \
--from-literal=ENCRYPTION_KEY="$(openssl rand -base64 32)" \
-n iam-local
# Verify secrets creation
kubectl get secrets -n iam-local
```
**Note on `host.docker.internal`:** On macOS, for a K8s pod to connect to PostgreSQL running on the host machine (or another container via port mapping), we use `host.docker.internal`.
### 5.2 ConfigMap
The `iam-service-configmap.yaml` file typically contains non-sensitive variables like `NODE_ENV`, `LOG_LEVEL`.
```bash
# Apply ConfigMap
kubectl apply -f iam-service-configmap.yaml -n iam-local
```
## 6. Deploy Service
Now we will deploy the main resources.
```bash
# Apply Deployment manifest
kubectl apply -f iam-service-deployment.yaml -n iam-local
# Apply Service manifest (LoadBalancer/NodePort)
kubectl apply -f iam-service-service.yaml -n iam-local
```
## 7. Verify & Debug
After deployment, ensure the Pod is stable (Running).
### 7.1 Check Pods
```bash
# Get all pods in the namespace
kubectl get pods -n iam-local
# Expected Output:
# NAME READY STATUS RESTARTS AGE
# iam-service-68994fdc79-gh2mj 1/1 Running 0 30s
```
### 7.2 View Detailed Logs
If Status is not `Running` (e.g., `CrashLoopBackOff` or `ImagePullBackOff`), check logs:
```bash
# Stream logs from the pod
kubectl logs -f -n iam-local -l app=iam-service
# Describe pod to see events (pull error, mounts, scheduling)
kubectl describe pod -n iam-local -l app=iam-service
```
### 7.3 Common Errors
1. **ImagePullBackOff**:
- **Reason**: K8s cannot find `iam-service:local` image.
- **Fix**: Ensure `imagePullPolicy: IfNotPresent` or `Never` in local deployment yaml. If using Kind, remember to run `kind load`.
2. **CrashLoopBackOff**:
- **Reason**: Runtime error, usually unable to connect to Database.
- **Fix**: Check `DATABASE_URL` in Secret. Ensure Postgres is running and accessible from K8s (use `host.docker.internal`).
3. **Pending Service**:
- **Reason**: `LoadBalancer` type on local sometimes hangs pending IP.
- **Fix**: Not a problem, we can use `port-forward` or access via `localhost`.
## 8. Test Service Access
To access the service from your local machine, the safest way is `port-forward`.
```bash
# Port forward from local port 5002 to service port 80
kubectl port-forward svc/iam-service 5002:80 -n iam-local
# Terminal will hang and show: Forwarding from 127.0.0.1:5002 -> 8000
```
Open another terminal and test:
```bash
# Test Health Check
curl http://localhost:5002/health/live
# Response: {"status":"ok", ...}
# View Swagger/OpenAPI docs (if enabled)
open http://localhost:5002/api-docs
```
## 9. Cleanup
When done, delete resources to free up capacity.
```bash
# Delete the namespace (removes all resources within)
kubectl delete namespace iam-local
```
## Quick Tips
### Common Issues & Solutions
| Issue | Symptoms | Solution |
|-------|----------|----------|
| **ImagePullBackOff** | Pod stuck in `ImagePullBackOff` | Set `imagePullPolicy: Never` in deployment YAML<br/>Run `kind load docker-image` if using Kind |
| **CrashLoopBackOff** | Pod keeps restarting | Check logs with `kubectl logs`<br/>Verify `DATABASE_URL` in secrets<br/>Ensure DB is accessible via `host.docker.internal` |
| **Pending LoadBalancer** | Service External-IP shows `<pending>` | Normal on local—use `kubectl port-forward` instead |
| **Connection Refused** | Can't connect after port-forward | Check pod is `Running` (not `CrashLoopBackOff`)<br/>Verify correct port mapping |
### Essential Commands Reference
```bash
# Debugging
kubectl get pods -n iam-local -w # Watch pods in real-time
kubectl describe pod <POD_NAME> -n iam-local # Detailed pod info + events
kubectl logs -f <POD_NAME> -n iam-local # Stream logs
kubectl exec -it <POD_NAME> -n iam-local -- /bin/sh # Shell into container
# Image Management
docker build -t service:local -f Dockerfile . # Build image
kind load docker-image service:local --name desktop # Load to Kind cluster
docker images | grep service # List local images
# Quick Deployment
kubectl apply -f deployment.yaml -n iam-local # Deploy single manifest
kubectl apply -f . -n iam-local # Deploy all files in directory
kubectl rollout restart deployment/iam-service -n iam-local # Force pod restart
# Cleanup
kubectl delete pod <POD_NAME> -n iam-local --force # Force delete stuck pod
kubectl delete namespace iam-local --force --grace-period=0 # Force delete namespace
```
### Visual Status Indicators
- **Running** - Service is healthy
- **Pending** - Waiting for resources
- **CrashLoopBackOff** - Service keeps failing (check logs!)
- **ContainerCreating** - Pod starting up
- **Terminating** - Pod shutting down
### Pro Tips
1. ** Fast Rebuild**: For quick iteration, use `kubectl rollout restart deployment/iam-service -n iam-local` after rebuilding image
2. ** Watch Mode**: Use `-w` flag to watch resources update in real-time
3. ** YAML Validation**: Run `kubectl apply --dry-run=client -f file.yaml` to validate before applying
4. ** Label Filtering**: Use `-l app=iam-service` to filter resources by label instead of typing pod names
## References
- [Kubernetes Documentation](https://kubernetes.io/docs/)
- [Docker Desktop for Mac](https://docs.docker.com/desktop/mac/networking/)
- [Prisma Deployment Guide](https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-kubernetes)

View File

@@ -0,0 +1,317 @@
# Local Development Deployment
This directory contains Docker Compose configuration for running the entire GoodGo platform locally.
## Quick Start
```bash
# 1. Setup environment variables
cp env.local.example .env
cp env.local.example .env.local
# Edit both files with your values (JWT_SECRET, service DB URLs, Redis, etc.)
# 2. Start all services
docker-compose up -d
# 3. Check service status
docker-compose ps
# 4. View logs
docker-compose logs -f
```
## Access Points
| Service | URL | Description |
|---------|-----|-------------|
| **Traefik Dashboard** | http://localhost:8080 | API Gateway dashboard |
| **Auth Service** | http://localhost/api/v1/auth | Authentication API |
| **Web Admin** | http://admin.localhost | Admin dashboard |
| **Web Client** | http://localhost | Client application |
| **Redis** | localhost:6379 | Cache (direct access) |
## Services
### Infrastructure
- **Traefik** (Port 80, 8080): API Gateway with automatic service discovery
- **Redis** (Port 6379): Shared cache and session store
### Backend Services
- **iam-service** (Port 5001): Authentication and user management
- Routes: `/api/v1/auth`, `/api/v1/users`
- Health: http://localhost/api/v1/auth/health
### Frontend Applications
- **web-admin** (Port 3000): Admin dashboard (Next.js)
- **web-client** (Port 3001): Client application (Next.js)
## Environment Configuration
Environment variables are managed in `.env` and `.env.local`:
### Required Variables
```bash
# Authentication (MUST be same across all services)
JWT_SECRET=your-super-secret-jwt-key-min-32-characters
JWT_REFRESH_SECRET=your-super-secret-refresh-key-min-32-characters
JWT_ID_SECRET=your-super-secret-id-key-min-32-characters
# IAM + service databases (Neon PostgreSQL)
IAM_DATABASE_URL=Host=...;Port=5432;Database=iam_service;Username=...;Password=...;SSL Mode=Require
STORAGE_DATABASE_URL=Host=...;Port=5432;Database=storage_service;Username=...;Password=...;SSL Mode=Require
ORDER_DATABASE_URL=Host=...;Port=5432;Database=order_service;Username=...;Password=...;SSL Mode=Require
```
### Optional Variables
```bash
# Redis
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=replace-with-redis-password
# Observability
TRACING_ENABLED=false
JAEGER_ENDPOINT=http://jaeger:14268/api/traces
# CORS
CORS_ORIGIN=http://localhost:3000,http://localhost:3001
# Object storage and messaging
MINIO_ENDPOINT=minio:9000
MINIO_ACCESS_KEY=...
MINIO_SECRET_KEY=...
RABBITMQ_PASSWORD=...
```
## Common Commands
```bash
# Start all services
docker-compose up -d
# Start specific service
docker-compose up -d iam-service
# Stop all services
docker-compose down
# Stop and remove volumes
docker-compose down -v
# View logs (all services)
docker-compose logs -f
# View logs (specific service)
docker-compose logs -f iam-service
# Restart service
docker-compose restart iam-service
# Rebuild service
docker-compose up -d --build iam-service
# Check service status
docker-compose ps
# Execute command in container
docker-compose exec iam-service sh
```
## Adding New Service
1. **Add service to docker-compose.yml**:
```yaml
services:
my-new-service:
build:
context: ../..
dockerfile: services/my-new-service/Dockerfile
container_name: my-new-service-local
env_file:
- .env.local
environment:
- PORT=5002
- SERVICE_NAME=my-new-service
- DATABASE_URL=${DATABASE_URL}
- REDIS_HOST=${REDIS_HOST}
- JWT_SECRET=${JWT_SECRET}
ports:
- "5002:5002"
depends_on:
redis:
condition: service_healthy
traefik:
condition: service_started
networks:
- microservices-network
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.my-new-service.rule=PathPrefix(`/api/v1/my-new-service`)"
- "traefik.http.services.my-new-service.loadbalancer.server.port=5002"
```
2. **Start the service**:
```bash
docker-compose up -d my-new-service
```
3. **Access the service**:
- Via Traefik: http://localhost/api/v1/my-new-service
- Direct: http://localhost:5002
## Traefik Configuration
Traefik is configured via:
- **Static config**: `infra/traefik/traefik.yml`
- **Dynamic config**: `infra/traefik/dynamic/`
- **Service discovery**: Docker labels in this file
Services are automatically discovered by Traefik using Docker labels. No manual route configuration needed.
## Troubleshooting
### Port Already in Use
```bash
# Find process using port
lsof -i :80
lsof -i :5001
# Kill process
kill -9 <PID>
```
### Service Won't Start
```bash
# Check logs
docker-compose logs service-name
# Rebuild without cache
docker-compose build --no-cache service-name
docker-compose up -d service-name
```
### Database Connection Issues
```bash
# Verify IAM_DATABASE_URL in .env/.env.local
cat .env | grep IAM_DATABASE_URL
# Test connection from service
docker-compose exec iam-service sh
# Inside container:
# curl $DATABASE_URL (won't work, but shows if var is set)
```
### Redis Connection Issues
```bash
# Check Redis is running
docker-compose ps redis
# Test Redis connection
docker-compose exec redis redis-cli ping
# Should return: PONG
```
### Traefik Not Routing
```bash
# Check Traefik dashboard
open http://localhost:8080
# Verify service has correct labels
docker-compose config | grep -A 5 "labels:"
# Check Traefik logs
docker-compose logs traefik
```
## Network Architecture
```mermaid
graph TB
Client[ Client<br/>Browser] --> Traefik
Traefik[ Traefik<br/>API Gateway<br/>:80, :8080]
Traefik --> IAM[ IAM Service<br/>Authentication<br/>:5001]
Traefik --> Admin[ Web Admin<br/>Dashboard<br/>:3000]
Traefik --> WebClient[ Web Client<br/>Application<br/>:3001]
IAM --> Redis[( Redis<br/>Cache<br/>:6379)]
IAM --> DB[( PostgreSQL<br/>Neon Database)]
classDef client fill:#1a1a2e,stroke:#16213e,stroke-width:2px,color:#eee
classDef gateway fill:#0f3460,stroke:#16213e,stroke-width:3px,color:#eee
classDef service fill:#16213e,stroke:#533483,stroke-width:2px,color:#eee
classDef frontend fill:#1a1a40,stroke:#6c5ce7,stroke-width:2px,color:#eee
classDef data fill:#2d132c,stroke:#801336,stroke-width:2px,color:#eee
class Client client
class Traefik gateway
class IAM service
class Admin,WebClient frontend
class Redis,DB data
```
**Legend:**
- **Client**: External users via browser
- **Gateway**: Traefik API Gateway (auto-routing)
- **Backend**: IAM Service (authentication)
- **Frontend**: Web Admin & Client applications
- **Storage**: Redis cache & PostgreSQL database
## Quick Tips
### Common Issues
| Problem | Solution |
|---------|----------|
| **Port conflict** | Check if port 80/5001/6379 is already in use: `lsof -i :<port>` |
| **Service won't start** | Check logs: `docker-compose logs <service-name>` |
| **Database connection** | Verify `DATABASE_URL` in `.env.local` is correct |
| **Redis connection** | Ensure Redis is healthy: `docker-compose exec redis redis-cli ping` |
| **Traefik routing** | Check dashboard at http://localhost:8080 for route status |
### Development Workflow
```bash
# Quick restart (code changes)
docker-compose restart iam-service
# Full rebuild (dependency changes)
docker-compose up -d --build iam-service
# Clean restart (database issues)
docker-compose down -v && docker-compose up -d
```
### Security Checklist
- Change default `JWT_SECRET` (min 32 characters)
- Use environment-specific `.env` / `.env.local` with real secrets (never commit real values)
- Verify CORS origins match your frontend URLs
- Enable HTTPS in production (not needed for local)
### Monitoring
- **Traefik Dashboard**: http://localhost:8080 - View all routes and services
- **Service Health**: http://localhost/api/v1/auth/health - Check service status
- **Redis CLI**: `docker-compose exec redis redis-cli` - Query cache directly
## Resources
- [Traefik Configuration](../../infra/traefik/)
- [Service Template](../../services/_template/)
- [Development Guide](../../docs/en/guides/development.md)
- [Neon Database Guide](../../docs/en/guides/neon-database.md)

View File

@@ -0,0 +1,257 @@
# Local Development Guide
> **EN**: Local Development Guide
>
> **VI**: Hướng dẫn phát triển cục bộ
**Last Updated**: 2026-01-05
**Difficulty**: Intermediate
**Setup Time**: 15-30 minutes
## Workflow
```mermaid
graph TD
Start([Start]) --> Prerequisites[1. System Prerequisites]
Prerequisites --> Clone["2. Clone and Install"]
Clone --> Env["3. Configure Environment - Shared and Service-Specific"]
Env --> DB["4. Setup Database - Migrate and Seed"]
DB --> Run["5. Run Project - Native/Docker/Hybrid"]
Run --> Dev["6. Development Loop - Watch Mode"]
Dev --> Test["7. Testing and Verify"]
Test --> End([Complete])
subgraph "Run Modes"
Run --> Mode1[Mode 1: Native - Fastest]
Run --> Mode2[Mode 2: Hybrid - Flexible]
Run --> Mode3[Mode 3: Full Docker - Production-like]
end
style Start fill:#27AE60,color:#fff,stroke:#27AE60,stroke-width:2px
style End fill:#27AE60,color:#fff,stroke:#27AE60,stroke-width:2px
style Prerequisites fill:#7F8C8D,color:#fff
style Clone fill:#7F8C8D,color:#fff
style Env fill:#E67E22,color:#fff
style DB fill:#E67E22,color:#fff
style Run fill:#2980B9,color:#fff
style Dev fill:#2980B9,color:#fff
style Test fill:#3498DB,color:#fff
style Mode1 fill:#8E44AD,color:#fff
style Mode2 fill:#8E44AD,color:#fff
style Mode3 fill:#8E44AD,color:#fff
```
## Overview
This guide provides a detailed process for setting up a development environment for the GoodGo Microservices ecosystem. You will learn how to run services, set up databases, and establish an efficient workflow with hot-reload.
## 1. Prerequisites
Before starting, ensure your machine has the following tools installed:
- **Node.js**: Latest LTS version (v20+).
- **PNPM**: Main project package manager (`npm install -g pnpm`).
- **Docker Desktop**: Required for running infrastructure services (Redis, Local Database).
- **Git**: For source code management.
- **Neon Account** (Optional): If using Neon Database on cloud (recommended for dev).
## 2. Initial Setup
### 2.1 Clone and Install Dependencies
```bash
# EN: Clone the repository
# VI: Clone repository về máy
git clone <repository-url>
cd Base
# EN: Install dependencies using pnpm
# VI: Cài đặt các thư viện phụ thuộc bằng pnpm
pnpm install
```
### 2.2 Quick Init Script (Recommended)
The project includes an automation script for basic initialization:
```bash
# EN: Run initialization script
# VI: Chạy script khởi tạo
./scripts/setup/init-project.sh
```
> This script will:
> - Install dependencies.
> - Copy example environment files (`.env.example` -> `.env`).
> - Generate Prisma client.
## 3. Environment Configuration
The project uses a **Hybrid Environment** strategy to optimize configuration management:
### 3.1 Shared Configuration
File: `deployments/local/.env.local`
Contains variables shared across the entire system (JWT, Redis, Logging).
```bash
# EN: Create shared env file from example
# VI: Tạo file môi trường chung từ file mẫu
cp deployments/local/env.local.example deployments/local/.env.local
```
### 3.2 Service-Specific Configuration
Each service (e.g., `iam-service`) needs its own `.env.local` file containing specific details like Database URL and Port.
```bash
# EN: Create service-specific env file
# VI: Tạo file môi trường riêng cho service
cp services/iam-service/env.local.example services/iam-service/.env.local
```
**Key contents to check in `services/iam-service/.env.local`**:
```properties
# Database URL (Use Neon Tech or Local Postgres)
DATABASE_URL=postgresql://user:password@host:5432/db_name?sslmode=require
# Service Port (Must be unique per service)
PORT=5001
# Service Name
SERVICE_NAME=iam-service
# Redis Host (localhost for Native Dev, redis for Docker Dev)
REDIS_HOST=localhost
```
## 4. Setup Database
After configuring `DATABASE_URL`, you need to sync the schema and seed initial data.
```bash
# EN: Run migrations for iam-service
# VI: Chạy migration cho iam-service
./scripts/db/migrate.sh iam-service dev
# EN: Seed initial data (optional)
# VI: Tạo dữ liệu mẫu (tùy chọn)
./scripts/db/seed.sh iam-service
```
## 5. Run Modes
You can run the project in 3 ways depending on your needs:
### Mode 1: Native Development (Recommended for Backend Dev)
Run directly on the host machine. Fastest speed, fastest hot-reload.
1. **Start Infrastructure**:
```bash
# EN: Start Redis and Traefik in Docker background
# VI: Khởi động Redis và Traefik chạy ngầm bằng Docker
cd deployments/local
docker-compose up -d redis traefik
cd ../..
```
2. **Run Service**:
```bash
# EN: Start iam-service in watch mode
# VI: Chạy iam-service ở chế độ watch
pnpm --filter @goodgo/iam-service dev
```
### Mode 2: Hybrid Development (Flexible)
Use when you need to run multiple auxiliary services in Docker but want to dev the main service directly.
```bash
# EN: Start dependent services in Docker
# VI: Chạy các service phụ thuộc trong Docker
docker-compose -f deployments/local/docker-compose.yml up -d user-service payment-service
# EN: Run the service you are working on natively
# VI: Chạy service bạn đang làm việc trực tiếp trên máy
pnpm --filter @goodgo/iam-service dev
```
### Mode 3: Full Docker (Production Simulation)
Run the entire system in Docker. Good for Integration Testing but no hot-reload.
```bash
# EN: Start everything with Docker Compose
# VI: Chạy tất cả bằng Docker Compose
cd deployments/local
docker-compose up -d
```
## 6. Access & Verification
After startup, you can access the following endpoints:
| Service | URL | Description |
|---------|-----|-------------|
| **API Gateway** | `http://localhost/api/v1` | Main entry point via Traefik |
| **IAM Service** | `http://localhost:5001` | Direct service access |
| **Health Check** | `http://localhost:5001/health` | Service status check |
| **Metrics** | `http://localhost:5001/metrics` | Prometheus metrics |
| **API Docs** | `http://localhost:5001/api-docs` | Swagger UI |
### Health Check Validation
```bash
# EN: Check liveness
# VI: Kiểm tra liveness
curl http://localhost:5001/health/live
# EN: Check readiness
# VI: Kiểm tra readiness
curl http://localhost:5001/health/ready
```
## 7. Troubleshooting
### Port Already In Use
**Error**: `Error: listen EADDRINUSE: address already in use :::5001`
**Solution**:
```bash
# EN: Find process using port 5001
# VI: Tìm process đang chiếm port 5001
lsof -i :5001
# EN: Kill the process
# VI: Tắt process đó
kill -9 <PID>
```
### Database Connection Error
**Error**: `P1001: Can't reach database server`
**Solution**:
- Re-check `DATABASE_URL` variable.
- If using local Postgres Docker, ensure container is running (`docker ps`).
- If using Neon, check internet connection.
### Module Not Found
**Error**: Cannot find internal packages (e.g., `@goodgo/logger`).
**Solution**:
```bash
# EN: Re-install dependencies and build packages
# VI: Cài lại dependencies và build lại packages
pnpm install
pnpm build
```
## References
- [Kubernetes Guide](kubernetes-local.md) - Deploy to Local K8s.
- [Project Architecture](../../docs/en/ARCHITECTURE.en.md) - System architecture overview.

View File

@@ -0,0 +1,661 @@
# Mermaid Diagram Guide
## Overview
This guide helps you choose the right Mermaid diagram type for your documentation and provides examples for common use cases.
## Quick Reference
| Diagram Type | Use For | Complexity |
|----------------------|------------------------|---------------------------|
| **Flowchart** | Workflows, decision trees | |
| **Sequence Diagram** | API interactions, request flows | |
| **Class Diagram** | Code structure, patterns | |
| **Graph** | System architecture, dependencies | |
| **ER Diagram** | Database schema | |
| **Gantt** | Timeline, project schedule | |
| **C4 Diagram** | System context, containers | |
---
## 1. Flowcharts
### When to Use
Use flowcharts for:
- Step-by-step guides and workflows (e.g., **"Onboarding process"**)
- Decision trees and conditional logic (e.g., **"Discount calculation"**)
- Process flows with multiple branches (e.g., **"Order fulfillment"**)
- Troubleshooting procedures (e.g., **"Login issue diagnosis"**)
### Basic Flowchart
```mermaid
flowchart TD
Start([Start]) --> Input[Get Input]
Input --> Check{Valid?}
Check -->|Yes| Process[Process Data]
Check -->|No| Error[Show Error]
Process --> Output[Return Result]
Output --> End([End])
Error --> End
style Start fill:#2C3E50,stroke:#34495E,stroke-width:2px,color:#ECF0F1
style End fill:#27AE60,stroke:#229954,stroke-width:2px,color:#ECF0F1
style Check fill:#F39C12,stroke:#D68910,stroke-width:2px,color:#ECF0F1
style Error fill:#C0392B,stroke:#A93226,stroke-width:2px,color:#ECF0F1
style Process fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style Input fill:#34495E,stroke:#2C3E50,stroke-width:2px,color:#ECF0F1
style Output fill:#34495E,stroke:#2C3E50,stroke-width:2px,color:#ECF0F1
```
**Explanation**: A basic flowchart starting with an input, followed by a validation check. If valid, it proceeds to processing and returns a result; otherwise, it shows an error and ends.
**Code**:
````markdown
```mermaid
flowchart TD
Start([Start]) --> Input[Get Input]
Input --> Check{Valid?}
Check -->|Yes| Process[Process Data]
Check -->|No| Error[Show Error]
Process --> Output[Return Result]
Output --> End([End])
Error --> End
style Start fill:#2C3E50,stroke:#34495E,stroke-width:2px,color:#ECF0F1
style End fill:#27AE60,stroke:#229954,stroke-width:2px,color:#ECF0F1
style Check fill:#F39C12,stroke:#D68910,stroke-width:2px,color:#ECF0F1
style Error fill:#C0392B,stroke:#A93226,stroke-width:2px,color:#ECF0F1
```
````
### Advanced Flowchart with Subgraphs
```mermaid
flowchart LR
A[Client Request] --> B{Auth?}
B -->|No| C[401 Unauthorized]
B -->|Yes| D[Process]
subgraph Processing["Request Processing"]
D --> E[Validate Input]
E --> F[Execute Logic]
F --> G[Format Response]
end
G --> H[Return 200 OK]
C --> I[End]
H --> I
style Processing fill:#34495E,stroke:#2C3E50,stroke-width:2px,color:#ECF0F1
style A fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style B fill:#F39C12,stroke:#D68910,stroke-width:2px,color:#ECF0F1
style C fill:#C0392B,stroke:#A93226,stroke-width:2px,color:#ECF0F1
style D fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style E fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style F fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style G fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style H fill:#27AE60,stroke:#229954,stroke-width:2px,color:#ECF0F1
style I fill:#2C3E50,stroke:#34495E,stroke-width:2px,color:#ECF0F1
```
**Explanation**: A flowchart featuring an authorization check and a dedicated **Subgraph** for detailed request processing steps.
---
## 2. Sequence Diagrams
### When to Use
Use sequence diagrams for:
- API communication flows (e.g., **"New order creation API"**)
- Authentication/authorization flows (e.g., **"OAuth2 login flow"**)
- Service-to-service interactions (e.g., **"Microservices sync/async calls"**)
- Request/response cycles (e.g., **"Checkout process"**)
### Basic Sequence Diagram
```mermaid
sequenceDiagram
participant Client
participant API
participant Service
participant DB
Client->>API: POST /login
API->>Service: authenticate(credentials)
Service->>DB: findUser(email)
DB-->>Service: user
Service->>Service: verifyPassword()
Service-->>API: JWT token
API-->>Client: 200 OK {token}
```
**Explanation**: A login sequence illustrating the interaction between the Client, API, Service Layer, and Database, including password verification.
**Code**:
````markdown
```mermaid
sequenceDiagram
participant Client
participant API
participant Service
participant DB
Client->>API: POST /login
API->>Service: authenticate(credentials)
Service->>DB: findUser(email)
DB-->>Service: user
Service->>Service: verifyPassword()
Service-->>API: JWT token
API-->>Client: 200 OK {token}
```
````
### Advanced with Alt/Opt/Loop
```mermaid
sequenceDiagram
participant Client
participant API
participant Cache
participant DB
Client->>API: GET /users/:id
API->>Cache: get(key)
alt Cache Hit
Cache-->>API: cached data
API-->>Client: 200 OK (from cache)
else Cache Miss
Cache-->>API: null
API->>DB: SELECT * FROM users
DB-->>API: user data
API->>Cache: set(key, data, ttl)
API-->>Client: 200 OK (from DB)
end
```
**Explanation**: A data retrieval sequence using **Alt/Else** blocks to handle both Cache Hit and Cache Miss scenarios.
---
## 3. Class Diagrams
### When to Use
Use class diagrams for:
- Design patterns and code structure (e.g., **"Singleton Pattern for Logger"**)
- Object-oriented architecture (e.g., **"Domain-Driven Design (DDD) models"**)
- Inheritance and relationships (e.g., **"Repository base and concrete classes"**)
- Module dependencies (e.g., **"Service layer dependencies"**)
### Basic Class Diagram
```mermaid
classDiagram
class BaseRepository {
#prisma: PrismaClient
#modelName: string
+findById(id: string) T
+findAll(options: QueryOptions) T[]
+create(data: CreateDto) T
+update(id: string, data: UpdateDto) T
+delete(id: string) void
}
class UserRepository {
+findByEmail(email: string) User
+findByUsername(username: string) User
}
class FeatureRepository {
+findByName(name: string) Feature
+toggleStatus(id: string) Feature
}
BaseRepository <|-- UserRepository
BaseRepository <|-- FeatureRepository
```
**Explanation**: A class diagram showing inheritance relationships between a generic `BaseRepository` and specific repository implementations.
---
## 4. Graph Diagrams
### When to Use
Use graph diagrams for:
- System architecture overview (e.g., **"Microservices Architecture"**)
- Component relationships (e.g., **"Service-to-database mapping"**)
- Data flow diagrams (e.g., **"Request processing pipeline"**)
- Dependency graphs (e.g., **"Package to package dependencies"**)
### System Architecture
```mermaid
graph TD
Client[Web Client] --> Gateway[Traefik Gateway]
Gateway --> Auth[Auth Service]
Gateway --> IAM[IAM Service]
Gateway --> User[User Service]
Auth --> DB[(PostgreSQL)]
IAM --> DB
User --> DB
User --> Cache[(Redis Cache)]
style Client fill:#34495E,stroke:#2C3E50,stroke-width:2px,color:#ECF0F1
style Gateway fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style Auth fill:#8E44AD,stroke:#7D3C98,stroke-width:2px,color:#ECF0F1
style IAM fill:#8E44AD,stroke:#7D3C98,stroke-width:2px,color:#ECF0F1
style User fill:#8E44AD,stroke:#7D3C98,stroke-width:2px,color:#ECF0F1
style DB fill:#F39C12,stroke:#D68910,stroke-width:2px,color:#ECF0F1
style Cache fill:#E67E22,stroke:#CA6F1E,stroke-width:2px,color:#ECF0F1
```
**Explanation**: A high-level view of the system architecture showing how the Gateway routes requests to different services, all connected to a shared Database and Cache.
### Data Flow
```mermaid
graph LR
Input[User Input] --> Validation[Zod Validation]
Validation --> Controller[Controller]
Controller --> Service[Service Layer]
Service --> Repository[Repository]
Repository --> Prisma[Prisma ORM]
Prisma --> DB[(Database)]
Service --> Cache[(Redis Cache)]
style Input fill:#34495E,stroke:#2C3E50,stroke-width:2px,color:#ECF0F1
style Validation fill:#27AE60,stroke:#229954,stroke-width:2px,color:#ECF0F1
style Controller fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style Service fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style Repository fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style Prisma fill:#8E44AD,stroke:#7D3C98,stroke-width:2px,color:#ECF0F1
style DB fill:#F39C12,stroke:#D68910,stroke-width:2px,color:#ECF0F1
style Cache fill:#E67E22,stroke:#CA6F1E,stroke-width:2px,color:#ECF0F1
```
**Explanation**: A detailed data flow showing Input going through Validation -> Controller -> Service -> Repository -> ORM -> DB, while also interacting with the Cache.
---
## 5. ER Diagrams
### When to Use
Use ER diagrams for:
- Database schema documentation (e.g., **"User and IAM tables"**)
- Entity relationships (e.g., **"One-to-many between User and Sessions"**)
- Data modeling (e.g., **"Designing new feature entities"**)
- Prisma schema visualization (e.g., **"Mapping code entities to DB tables"**)
### Database Schema
```mermaid
erDiagram
User ||--o{ Session : has
User ||--o{ RefreshToken : has
User ||--o{ UserRole : has
Role ||--o{ UserRole : has
Role ||--o{ RolePermission : has
Permission ||--o{ RolePermission : has
User {
string id PK
string email UK
string passwordHash
boolean mfaEnabled
datetime createdAt
datetime updatedAt
}
Session {
string id PK
string userId FK
string token UK
string deviceId
string ipAddress
datetime expiresAt
}
Role {
string id PK
string name UK
string description
datetime createdAt
}
Permission {
string id PK
string code UK
string resource
string action
string scope
}
```
**Explanation**: An Entity-Relationship diagram illustrating a typical IAM schema with Users, Sessions, Roles, and Permissions.
---
## 6. Gantt Charts
### When to Use
Use Gantt charts for:
- Project timelines
- Implementation phases
- Migration schedules
- Deployment plans
### Project Timeline
```mermaid
gantt
title Documentation Update Project Timeline
dateFormat YYYY-MM-DD
section Phase 1
Analysis & Research :done, p1, 2024-01-01, 1d
section Phase 2
Templates & Strategy :active, p2, 2024-01-02, 0.5d
section Phase 3
High Priority Docs :p3, 2024-01-03, 2d
section Phase 4
Remaining Docs :p4, 2024-01-05, 3d
section Phase 5
QA & Verification :p5, 2024-01-08, 1d
```
---
## 7. C4 Diagrams
### When to Use
Use C4 diagrams for:
- System context (highest level)
- Container diagrams (services, databases)
- Component diagrams (modules within services)
- Code diagrams (classes, functions)
### System Context
```mermaid
C4Context
title System Context Diagram for IAM System
Person(user, "User", "System user needing authentication")
Person(admin, "Admin", "System administrator")
System(iam, "IAM System", "Identity and Access Management")
System_Ext(email, "Email Service", "SendGrid/AWS SES")
System_Ext(oauth, "OAuth Providers", "Google, Facebook, GitHub")
Rel(user, iam, "Authenticates with", "HTTPS")
Rel(admin, iam, "Manages users and permissions", "HTTPS")
Rel(iam, email, "Sends emails", "SMTP/API")
Rel(iam, oauth, "OAuth login", "OAuth 2.0")
```
---
## Color Palette Reference
### Dark Theme Color System
Our diagrams use a consistent dark color palette based on professional design principles:
```mermaid
graph LR
subgraph Primary[" Primary Colors"]
A1["Dark Blue<br/>#2980B9"]
A2["Purple<br/>#8E44AD"]
A3["Green<br/>#27AE60"]
end
subgraph Secondary[" Secondary Colors"]
B1["Orange<br/>#E67E22"]
B2["Yellow<br/>#F39C12"]
B3["Red<br/>#C0392B"]
end
subgraph Neutrals[" Neutral Colors"]
C1["Dark Gray<br/>#2C3E50"]
C2["Medium Gray<br/>#34495E"]
C3["Light Text<br/>#ECF0F1"]
end
style A1 fill:#2980B9,stroke:#1F618D,stroke-width:3px,color:#ECF0F1
style A2 fill:#8E44AD,stroke:#7D3C98,stroke-width:3px,color:#ECF0F1
style A3 fill:#27AE60,stroke:#229954,stroke-width:3px,color:#ECF0F1
style B1 fill:#E67E22,stroke:#CA6F1E,stroke-width:3px,color:#ECF0F1
style B2 fill:#F39C12,stroke:#D68910,stroke-width:3px,color:#ECF0F1
style B3 fill:#C0392B,stroke:#A93226,stroke-width:3px,color:#ECF0F1
style C1 fill:#2C3E50,stroke:#1C2833,stroke-width:3px,color:#ECF0F1
style C2 fill:#34495E,stroke:#2C3E50,stroke-width:3px,color:#ECF0F1
style C3 fill:#ECF0F1,stroke:#BDC3C7,stroke-width:3px,color:#2C3E50
```
### Color Usage Guidelines
| Color | Hex Code | Use For | Example |
|-------|----------|---------|---------|
| **Dark Blue** | `#2980B9` | Services, Processing, APIs | User Service, API Gateway |
| **Purple** | `#8E44AD` | Core Components, ORM | Prisma, IAM Service |
| **Green** | `#27AE60` | Success, Validation, End States | Success Flow, Validated Data |
| **Orange** | `#E67E22` | Cache, Warning States | Redis Cache, Warnings |
| **Yellow** | `#F39C12` | Database, Important Decisions | PostgreSQL, Decision Nodes |
| **Red** | `#C0392B` | Errors, Failures, Alerts | Error States, Failed Operations |
| **Dark Gray** | `#2C3E50` | Start/End, Neutral Elements | Start Node, End Node |
| **Medium Gray** | `#34495E` | Subgraphs, Background | Processing Groups, Containers |
| **Light Text** | `#ECF0F1` | Text Color (always use) | All node text |
### Standard Style Pattern
Always include these three properties for professional appearance:
```markdown
style NodeName fill:#HexColor,stroke:#DarkerShade,stroke-width:2px,color:#ECF0F1
```
**Components:**
- `fill`: Main background color
- `stroke`: Border color (typically darker shade of fill)
- `stroke-width`: Border thickness (use `2px` for standard, `3px` for emphasis)
- `color`: Text color (always use `#ECF0F1` for dark backgrounds)
### Node Type Color Patterns
| Node Type | Fill Color | Stroke Color | Use Case |
|-----------|------------|--------------|----------|
| **Services** | `#2980B9` | `#1F618D` | Auth Service, User Service |
| **API/Gateway** | `#2980B9` | `#1F618D` | Traefik, API Gateway |
| **Database** | `#F39C12` | `#D68910` | PostgreSQL, MySQL |
| **Cache** | `#E67E22` | `#CA6F1E` | Redis, Memcached |
| **ORM/Framework** | `#8E44AD` | `#7D3C98` | Prisma, TypeORM |
| **Success/End** | `#27AE60` | `#229954` | Success Flow, Completion |
| **Error/Failure** | `#C0392B` | `#A93226` | Error States, Failures |
| **Decision** | `#F39C12` | `#D68910` | Validation, Conditionals |
| **Start** | `#2C3E50` | `#1C2833` | Entry Point |
| **Process** | `#34495E` | `#2C3E50` | General Processing |
### Quick Color Selection Guide
**Choose colors based on node function:**
**Blue (`#2980B9`)** → Services, APIs, Controllers
**Purple (`#8E44AD`)** → Core Systems, ORM, Frameworks
**Green (`#27AE60`)** → Success, Validation, Completion
**Orange (`#E67E22`)** → Cache, Memory, Storage
**Yellow (`#F39C12`)** → Databases, Decisions, Important Actions
**Red (`#C0392B`)** → Errors, Failures, Critical Issues
**Dark Gray (`#2C3E50`)** → Start/End, Neutral States
**Medium Gray (`#34495E`)** → Containers, Subgraphs, Groups
---
## Best Practices
### Guidelines
1. **Keep it Simple**: Don't overcomplicate diagrams
2. **Use Consistent Styling**: Apply color scheme consistently
3. **Add Legends**: Explain symbols and colors when needed
4. **Limit Complexity**: Break into multiple diagrams if too complex
5. **Test Rendering**: Always test diagrams render correctly
6. **Dark Theme**: Always use dark color palette for professional appearance
7. **Text Contrast**: Always use `color:#ECF0F1` for text on dark backgrounds
---
## Common Pitfalls
### Too Complex
```mermaid
graph TD
A --> B
A --> C
B --> D
B --> E
C --> F
C --> G
D --> H
E --> H
F --> I
G --> I
H --> J
I --> J
```
### Simplified with Subgraphs
```mermaid
graph TD
A[Start] --> B[Process A]
B --> C[Process B]
subgraph Detailed["Detailed Processing"]
C --> D[Step 1]
D --> E[Step 2]
end
E --> F[End]
style Detailed fill:#34495E,stroke:#2C3E50,stroke-width:2px,color:#ECF0F1
style A fill:#2C3E50,stroke:#1C2833,stroke-width:2px,color:#ECF0F1
style F fill:#27AE60,stroke:#229954,stroke-width:2px,color:#ECF0F1
style B fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style C fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style D fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
style E fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
```
---
## Testing Diagrams
Always test your diagrams before committing:
```bash
# Install mermaid-cli
npm install -g @mermaid-js/mermaid-cli
# Test render (SVG)
mmdc -i your-doc.md -o test-output.svg
# Render high-quality PNG with dark theme
mmdc -i your-doc.md -o test-output.png -b black -t dark -s 3
# Render ALL diagrams in a markdown file
mmdc -i your-doc.md
# Parameter Explanations:
# -i: Input file (.md or .mmd)
# -o: Output file (format based on extension .svg, .png, .pdf)
# -b: Background color (hex code or color names like black, white, transparent)
# -t: Theme (default, forest, dark, neutral)
# -s: Scale (increase resolution, e.g., 3 for sharper images)
```
---
## Quick Tips
### Mermaid Common Issues
**Issue**: Diagram not rendering
- Check for syntax errors (missing arrows, brackets)
- Ensure proper indentation in subgraphs
- Validate special characters are escaped
**Issue**: Colors not applying
- Place style commands after all node definitions
- Use exact node IDs in style statements
- Ensure hex colors include `#` prefix
**Issue**: Text overlapping
- Use shorter labels or `<br/>` for line breaks
- Adjust diagram direction (TD, LR, RL, BT)
- Increase spacing between nodes
### Color Pattern Quick Reference
```markdown
// Services & APIs
style Node fill:#2980B9,stroke:#1F618D,stroke-width:2px,color:#ECF0F1
// Database
style Node fill:#F39C12,stroke:#D68910,stroke-width:2px,color:#ECF0F1
// Cache
style Node fill:#E67E22,stroke:#CA6F1E,stroke-width:2px,color:#ECF0F1
// Success/End
style Node fill:#27AE60,stroke:#229954,stroke-width:2px,color:#ECF0F1
// Error/Failure
style Node fill:#C0392B,stroke:#A93226,stroke-width:2px,color:#ECF0F1
// Decision Points
style Node fill:#F39C12,stroke:#D68910,stroke-width:2px,color:#ECF0F1
// Start/Neutral
style Node fill:#2C3E50,stroke:#1C2833,stroke-width:2px,color:#ECF0F1
```
### Visual Indicators
Use emojis to enhance diagram readability:
- Services & APIs
- Core Systems
- Success Paths
- Databases
- Cache/Storage
- Errors
- Neutral/Start/End
- Warnings
- Validated
- Failed
---
## Resources
- [Mermaid Official Documentation](https://mermaid.js.org/) - Complete reference
- [Mermaid Live Editor](https://mermaid.live/) - Test diagrams online
- [Mermaid CheatSheet](https://jojozhuang.github.io/tutorial/mermaid-cheat-sheet/) - Quick reference
---
**Last Updated**: 2026-01-08

View File

@@ -0,0 +1,351 @@
# Neon Database Guide
This project uses [Neon PostgreSQL](https://neon.tech) for all environments.
## Why Neon?
- **Serverless**: No infrastructure management
- **Branching**: Separate databases for dev/staging/prod
- **Auto-scaling**: Handles traffic spikes automatically
- **Point-in-time restore**: Easy recovery from mistakes
- **Free tier**: Perfect for development
- **Connection pooling**: Built-in PgBouncer support
## Architecture Overview
```mermaid
graph TD
Project[" Neon Project<br/>goodgo-platform"]
Dev[" Development Branch<br/>main"]
Staging[" Staging Branch<br/>staging"]
Prod[" Production Branch<br/>production"]
LocalDev[" Local Dev<br/>.env.local"]
K8sStaging[" Kubernetes<br/>staging namespace"]
K8sProd[" Kubernetes<br/>production namespace"]
Project --> Dev
Project --> Staging
Project --> Prod
Dev -.->|DATABASE_URL| LocalDev
Staging -.->|Secret| K8sStaging
Prod -.->|Secret| K8sProd
style Project fill:#1e293b,stroke:#3b82f6,stroke-width:3px,color:#fff
style Dev fill:#0f172a,stroke:#10b981,stroke-width:2px,color:#fff
style Staging fill:#0f172a,stroke:#f59e0b,stroke-width:2px,color:#fff
style Prod fill:#0f172a,stroke:#ef4444,stroke-width:2px,color:#fff
style LocalDev fill:#475569,stroke:#94a3b8,stroke-width:2px,color:#fff
style K8sStaging fill:#475569,stroke:#94a3b8,stroke-width:2px,color:#fff
style K8sProd fill:#475569,stroke:#94a3b8,stroke-width:2px,color:#fff
```
## Quick Start
### 1. Create Neon Account
1. Sign up at https://neon.tech
2. Create a new project: `goodgo-platform`
### 2. Create Branches
In Neon Console, create branches:
- `main` (development) - already exists
- `staging` - create from main
- `production` - create from main
### 3. Get Connection Strings
For each branch, copy the connection string:
- Format: `postgresql://user:password@ep-xxx.region.neon.tech/dbname?sslmode=require`
- Add `?pgbouncer=true` for connection pooling (recommended)
### 4. Configure Local Development
```bash
# Create .env.local
cp deployments/local/env.local.example deployments/local/.env.local
# Edit .env.local and add:
DATABASE_URL=postgresql://user:pass@ep-xxx.region.neon.tech/dbname?sslmode=require&pgbouncer=true
```
### 5. Run Migrations
```bash
./scripts/db/migrate.sh iam-service dev
```
## Connection String Format
```
postgresql://[user]:[password]@[endpoint]/[dbname]?sslmode=require&pgbouncer=true
```
**Parameters**:
- `sslmode=require` - Required for Neon
- `pgbouncer=true` - Enable connection pooling (recommended)
## Environment Configuration
### Local Development
File: `deployments/local/.env.local`
```bash
DATABASE_URL=postgresql://user:pass@ep-xxx.region.neon.tech/dbname?sslmode=require&pgbouncer=true
```
### Staging
Store in GitHub Secrets: `NEON_DATABASE_URL_STAGING`
Or in Kubernetes:
```bash
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://...' \
-n staging
```
### Production
Store in GitHub Secrets: `NEON_DATABASE_URL_PRODUCTION`
Or in Kubernetes:
```bash
kubectl create secret generic iam-service-secrets \
--from-literal=database-url='postgresql://...' \
-n production
```
## Migrations
### Migration Workflow
```mermaid
graph LR
subgraph Local[" Local Development"]
Schema[" Update Schema<br/>prisma/schema.prisma"]
CreateMig[" Create Migration<br/>migrate dev"]
TestLocal[" Test Locally"]
end
subgraph CI[" CI/CD Pipeline"]
Push[" Git Push"]
Build[" Build"]
TestCI[" Run Tests"]
end
subgraph Staging[" Staging"]
MigStaging[" Run Migrations<br/>migrate deploy"]
TestStaging[" Verify Schema"]
end
subgraph Prod[" Production"]
Approval[" Manual Approval"]
MigProd[" Run Migrations<br/>migrate deploy"]
Rollback[" Rollback Plan"]
end
Schema --> CreateMig
CreateMig --> TestLocal
TestLocal --> Push
Push --> Build
Build --> TestCI
TestCI --> MigStaging
MigStaging --> TestStaging
TestStaging --> Approval
Approval --> MigProd
MigProd -.->|If Failed| Rollback
style Local fill:#1e293b,stroke:#3b82f6,stroke-width:2px,color:#fff
style CI fill:#1e293b,stroke:#8b5cf6,stroke-width:2px,color:#fff
style Staging fill:#1e293b,stroke:#f59e0b,stroke-width:2px,color:#fff
style Prod fill:#1e293b,stroke:#ef4444,stroke-width:2px,color:#fff
style Schema fill:#0f172a,stroke:#10b981,color:#fff
style CreateMig fill:#0f172a,stroke:#10b981,color:#fff
style TestLocal fill:#0f172a,stroke:#10b981,color:#fff
style Push fill:#475569,stroke:#94a3b8,color:#fff
style Build fill:#475569,stroke:#94a3b8,color:#fff
style TestCI fill:#475569,stroke:#94a3b8,color:#fff
style MigStaging fill:#0f172a,stroke:#f59e0b,color:#fff
style TestStaging fill:#0f172a,stroke:#f59e0b,color:#fff
style Approval fill:#475569,stroke:#94a3b8,color:#fff
style MigProd fill:#0f172a,stroke:#ef4444,color:#fff
style Rollback fill:#7f1d1d,stroke:#ef4444,color:#fff
```
### Development
```bash
# Create new migration
./scripts/db/migrate.sh iam-service dev
# This will:
# 1. Create migration file
# 2. Apply to database
# 3. Update Prisma Client
```
### Staging/Production
Migrations run automatically in CI/CD:
- Before deployment to staging
- Before deployment to production (with approval)
Manual migration:
```bash
./scripts/db/migrate.sh iam-service deploy
```
## Backup & Restore
### Automatic Backups
Neon provides automatic backups. Access via Neon Console:
- Point-in-time restore
- Branch restore
- Export data
### Manual Backup
```bash
./scripts/db/backup.sh iam-service
```
This creates a SQL dump file in `backups/` directory.
### Restore
```bash
# From Neon Console (recommended)
# Or using psql:
psql $DATABASE_URL < backup.sql
```
## Monitoring
Monitor your databases via Neon Console:
- Connection metrics
- Query performance
- Storage usage
- Branch status
## Troubleshooting
### Connection Issues
1. **Check connection string format**
- Must include `?sslmode=require`
- Verify credentials
2. **Check IP allowlist**
- Neon may restrict IPs
- Add your IP in Neon Console
3. **Check branch status**
- Ensure branch is active
- Check for maintenance
### Migration Issues
1. **DATABASE_URL not set**
```bash
export DATABASE_URL="your-neon-url"
```
2. **Schema mismatch**
```bash
# Reset and re-migrate (dev only!)
pnpm prisma migrate reset
```
3. **Connection timeout**
- Add `?pgbouncer=true` for pooling
- Check Neon console for limits
### Performance Issues
1. **Enable connection pooling**
- Add `?pgbouncer=true` to connection string
2. **Check query performance**
- Use Neon Console query analyzer
- Review slow queries
3. **Optimize indexes**
- Review Prisma schema
- Add indexes for frequent queries
## Cost Optimization
- **Free tier**: 0.5 GB storage, sufficient for dev
- **Staging**: Use free tier or minimal paid plan
- **Production**: Scale based on usage
- **Branching**: Free branches for testing
## Best Practices
1. **Always use connection pooling**: `?pgbouncer=true`
2. **Use SSL**: `?sslmode=require`
3. **Separate branches**: One per environment
4. **Regular backups**: Use Neon's automatic backups
5. **Monitor usage**: Check Neon Console regularly
## Quick Tips
### Mermaid Diagram Color Palette
| Element | Color | Usage |
|---------|-------|-------|
| **Project/Main** | `#1e293b` + `#3b82f6` | Primary containers |
| **Development** | `#0f172a` + `#10b981` | Dev environment (green) |
| **Staging** | `#0f172a` + `#f59e0b` | Staging environment (orange) |
| **Production** | `#0f172a` + `#ef4444` | Prod environment (red) |
| **Infrastructure** | `#475569` + `#94a3b8` | K8s, CI/CD (gray) |
| **Error/Rollback** | `#7f1d1d` + `#ef4444` | Critical actions (dark red) |
### Common Mermaid Issues
**Syntax Errors:**
- Use quotes for labels with special chars: `["Label<br/>text"]`
- Escape HTML entities: `&amp;` not `&`
- Use `<br/>` for line breaks inside labels
- Avoid `<br>` without closing slash
**Rendering Issues:**
- If diagram doesn't render, check for matching brackets `[]` or `{}`
- Verify all style declarations use valid CSS colors
- Ensure subgraph names are unique
### Visual Indicators
| Icon | Meaning |
|------|---------|
| | Project/Package |
| | Development/Tools |
| | Testing/Staging |
| | Production/Deploy |
| | Local Environment |
| | Kubernetes |
| | CI/CD Pipeline |
| | Configuration/Schema |
| | Database/Data |
| | Success/Validation |
| | Error/Failed |
| | Rollback/Retry |
| | Manual Action |
| | Push/Upload |
| | Build Process |
## Resources
- [Neon Documentation](https://neon.tech/docs)
- [Neon Console](https://console.neon.tech)
- [Prisma + Neon Guide](https://neon.tech/docs/guides/prisma)

View File

@@ -0,0 +1,301 @@
# Observability Stack Guide
This guide explains how to use the observability stack (Grafana, Prometheus, Loki, Promtail) included in the infrastructure.
## Architecture Overview
### Components
The stack consists of the following components:
- **Prometheus**: Metrics collection and storage
- **Loki**: Log aggregation system
- **Promtail**: Log collector agent
- **Grafana**: Unified visualization dashboard
### Architecture Diagram
```mermaid
flowchart LR
subgraph Services["Microservices"]
IAM[IAM Service]
USER[User Service]
TRAEFIK[Traefik Gateway]
end
subgraph Collection["Data Collection"]
PROM[Prometheus]
PROMTAIL[Promtail]
end
subgraph Storage["Data Storage"]
PROM_DB[(Prometheus DB)]
LOKI_DB[(Loki DB)]
end
subgraph Visualization["Visualization"]
GRAFANA[Grafana Dashboard]
end
IAM -->|Metrics| PROM
USER -->|Metrics| PROM
TRAEFIK -->|Metrics| PROM
IAM -.->|Logs| PROMTAIL
USER -.->|Logs| PROMTAIL
TRAEFIK -.->|Logs| PROMTAIL
PROM -->|Store| PROM_DB
PROMTAIL -->|Push| LOKI_DB
PROM_DB -->|Query| GRAFANA
LOKI_DB -->|Query| GRAFANA
style Services fill:#2d3748
style Collection fill:#2c5282
style Storage fill:#2f855a
style Visualization fill:#744210
style IAM fill:#4a5568
style USER fill:#4a5568
style TRAEFIK fill:#4a5568
style PROM fill:#3182ce
style PROMTAIL fill:#3182ce
style PROM_DB fill:#38a169
style LOKI_DB fill:#38a169
style GRAFANA fill:#d69e2e
```
### Data Flow
```mermaid
sequenceDiagram
participant S as Service
participant PT as Promtail
participant P as Prometheus
participant L as Loki
participant G as Grafana
Note over S,G: Metrics Flow
S->>P: Expose /metrics endpoint
P->>P: Scrape metrics (15s interval)
G->>P: Query PromQL
P-->>G: Return metrics data
Note over S,G: Logs Flow
S->>PT: Write logs to stdout
PT->>PT: Parse & Label logs
PT->>L: Push logs via HTTP
G->>L: Query LogQL
L-->>G: Return log data
```
## Getting Started
### Prerequisites
- Docker and Docker Compose installed
- Existing `microservices-network` (created by the main application stack or manually)
### Starting the Stack
You can easily start the stack using the provided script:
```bash
./scripts/observability/start.sh
```
Or manually:
```bash
docker network create microservices-network || true
cd infra/observability
docker-compose -f docker-compose.observability.yml up -d
```
Check if all containers are running:
```bash
docker ps
```
You should see `grafana`, `prometheus`, `loki`, and `promtail`.
## Accessing Services
| Service | URL | Credentials | Description |
| :--- | :--- | :--- | :--- |
| **Grafana** | [http://localhost:3001](http://localhost:3001) | `admin` / `admin` | Main dashboard for visualization |
| **Prometheus** | [http://localhost:9090](http://localhost:9090) | N/A | Raw metrics and target status |
| **Loki** | [http://localhost:3100](http://localhost:3100) | N/A | Log aggregation API (no UI) |
## Using Grafana
### Initial Setup
1. **Login**: Access [http://localhost:3001](http://localhost:3001) and login with `admin`/`admin`
2. **Change Password**: You'll be prompted to change the default password (recommended)
3. **Verify Datasources**:
- Navigate to **Configuration****Data Sources**
- Ensure both **Prometheus** and **Loki** are connected
### Exploring Data
Go to **Explore** (compass icon) in the sidebar:
- Select **Loki** from the datasource dropdown to search logs
- Select **Prometheus** from the datasource dropdown to query metrics
### Viewing Logs (Loki)
In the **Explore** view with **Loki** selected:
1. Click **Label browser**
2. Select a label, e.g., `container`
3. Choose a specific container (e.g., `iam-service` or `traefik`)
4. Click **Show logs**
**LogQL Query Examples:**
```logql
{container="iam-service"}
{container="iam-service"} |= "error"
{container="iam-service"} |= "error" | json
```
### Viewing Metrics (Prometheus)
In the **Explore** view with **Prometheus** selected:
1. Type a metric name in the query field (e.g., `up`, `container_memory_usage_bytes`)
2. Click **Run query**
**PromQL Query Examples:**
```promql
up
rate(http_requests_total[5m])
container_memory_usage_bytes{container="iam-service"}
```
## Configuration
### File Locations
- **Prometheus**: `infra/observability/prometheus/prometheus.yml`
- **Promtail**: `infra/observability/promtail/promtail-config.yml`
- **Grafana**: `infra/observability/grafana/`
### Custom Metrics
To expose custom metrics from your service:
```typescript
import { Counter, Histogram } from 'prom-client';
const requestCounter = new Counter({
name: 'http_requests_total',
help: 'Total HTTP requests',
labelNames: ['method', 'route', 'status']
});
const requestDuration = new Histogram({
name: 'http_request_duration_seconds',
help: 'HTTP request duration',
labelNames: ['method', 'route']
});
```
### Custom Dashboards
Create custom dashboards in Grafana:
1. Click **+** → **Dashboard**
2. Add **Panel**
3. Configure query (Prometheus or Loki)
4. Save dashboard
## Color Palette Reference
Diagrams use a dark color palette for better readability:
| Component Type | Fill Color | Stroke Color | Purpose |
|----------------|------------|--------------|----------|
| Services | `#e94560` | `#c81e3b` | Microservices (red) |
| Collectors | `#f39c12` | `#d68910` | Data collection (orange) |
| Storage | `#3498db` | `#2874a6` | Storage (blue) |
| Visualization | `#9b59b6` | `#7d3c98` | Visualization (purple) |
| Subgraphs | `#1a1a2e` - `#533483` | `#16213e` - `#0f3460` | Logical groups |
**All text uses `color:#ffffff` (white) for readability on dark backgrounds**
## Quick Tips
### Mermaid Common Issues
**DO:**
- Use `flowchart LR` for left-to-right flow
- Use `sequenceDiagram` for time-based interactions
- Apply dark colors for better contrast
- Use descriptive node IDs
**DON'T:**
- Mix `graph` and `flowchart` syntax
- Use special characters in node IDs without quotes
- Forget closing brackets for subgraphs
### LogQL Quick Reference
```logql
{label="value"}
{label="value"} |= "search"
{label="value"} |= "error" | json
{label="value"} | logfmt
```
### PromQL Quick Reference
```promql
metric_name
metric_name{label="value"}
rate(metric_name[5m])
sum(metric_name) by (label)
```
### Visual Indicators
- **Metrics**: Numerical time-series data
- **Logs**: Text-based event records
- **Query**: Search/filter operations
- **Explore**: Investigation interface
- **Dashboard**: Pre-configured visualizations
## Troubleshooting
### Common Issues
| Issue | Symptoms | Solution |
|-------|----------|----------|
| No logs visible | Grafana Explore shows no logs | Check Promtail is running: `docker ps \| grep promtail` |
| Missing metrics | Services don't appear in Prometheus targets | Check service `/metrics` endpoint |
| Container won't start | `docker ps` doesn't show container | View logs: `docker-compose logs <service-name>` |
| Network issue | Services can't connect | Create network: `docker network create microservices-network` |
### Logs Not Appearing in Loki
1. Check Promtail logs: `docker logs promtail`
2. Verify container labels are correct
3. Ensure services are on `microservices-network`
### Metrics Not Appearing in Prometheus
1. Check Prometheus targets: [http://localhost:9090/targets](http://localhost:9090/targets)
2. Verify service exposes `/metrics` endpoint
3. Check Prometheus scrape config
### Grafana Shows "No Data"
1. Verify datasource connection (Configuration → Data Sources)
2. Check time range in query
3. Ensure data exists in Prometheus/Loki

View File

@@ -0,0 +1,423 @@
# Troubleshooting Guide
> **Note**: This guide focuses on debugging the GoodGo Microservices Platform in a local development environment (Docker Compose).
## Table of Contents
1. [General Diagnosis](#general-diagnosis)
2. [Infrastructure Issues](#infrastructure-issues)
- [Database (Neon/PostgreSQL)](#database-neonpostgresql)
- [Redis](#redis)
- [Traefik Gateway](#traefik-gateway)
3. [Service Issues](#service-issues)
- [Service Fails to Start](#service-fails-to-start)
- [Prisma/Database Errors](#prismadatabase-errors)
- [Authentication Errors](#authentication-errors)
4. [Debugging Tools](#debugging-tools)
5. [FAQ](#faq)
---
## General Diagnosis
When something goes wrong, follow this checklist:
1. **Check Service Status**:
```bash
cd deployments/local
docker-compose ps
```
*All services should be `Up` or `Running`.*
2. **Check Logs**:
```bash
# View logs for a specific service
docker-compose logs -f <service-name>
# View last 100 lines for all
docker-compose logs --tail=100
```
3. **Check Connectivity**:
* Can you reach the Gateway? `curl http://localhost/health`
* Can you reach the Dashboard? http://localhost:8080
### Troubleshooting Flowchart
```mermaid
flowchart TD
Start([ Issue Detected]) --> CheckStatus{Check Service<br/>Status}
CheckStatus -->|All Running| CheckLogs[ Check Logs]
CheckStatus -->|Some Down| IdentifyService[ Identify Failed<br/>Service]
IdentifyService --> ServiceType{Service Type?}
ServiceType -->|Infrastructure| InfraCheck[ Infrastructure<br/>Check]
ServiceType -->|Application| AppCheck[ Application<br/>Check]
InfraCheck --> DBCheck{Database?}
InfraCheck --> RedisCheck{Redis?}
InfraCheck --> TraefikCheck{Traefik?}
DBCheck -->|Yes| DBSolution[ Check DATABASE_URL<br/> Verify Neon connection<br/> Check IP whitelist]
RedisCheck -->|Yes| RedisSolution[ Restart Redis<br/> Check port mapping<br/> Verify connection string]
TraefikCheck -->|Yes| TraefikSolution[ Check labels<br/> Verify PathPrefix<br/> Check health status]
AppCheck --> ErrorType{Error Type?}
ErrorType -->|Config| ConfigFix[ Check .env variables<br/> Run init-project.sh]
ErrorType -->|Prisma| PrismaFix[ Check migrations<br/> Regenerate client<br/> Reset database]
ErrorType -->|Auth| AuthFix[ Check token expiry<br/> Verify keys<br/> Sync Docker time]
CheckLogs --> LogAnalysis{Log Shows<br/>Error?}
LogAnalysis -->|Yes| ErrorType
LogAnalysis -->|No| ConnCheck[ Check Connectivity]
ConnCheck --> GatewayTest{Gateway<br/>Reachable?}
GatewayTest -->|No| TraefikCheck
GatewayTest -->|Yes| ServiceTest{Service<br/>Reachable?}
ServiceTest -->|No| AppCheck
ServiceTest -->|Yes| Resolved([ Issue Resolved])
DBSolution --> Restart[ Restart Services]
RedisSolution --> Restart
TraefikSolution --> Restart
ConfigFix --> Restart
PrismaFix --> Restart
AuthFix --> Restart
Restart --> Verify{Issue<br/>Fixed?}
Verify -->|Yes| Resolved
Verify -->|No| DeepDebug[ Deep Debugging<br/>Required]
DeepDebug --> ContainerShell[Access Container Shell]
DeepDebug --> PrismaStudio[Use Prisma Studio]
DeepDebug --> RedisInspect[Inspect Redis]
DeepDebug --> APITest[Direct API Testing]
style Start fill:#1a1a2e,color:#fff
style Resolved fill:#0f3460,color:#fff
style CheckStatus fill:#16213e,color:#fff
style ServiceType fill:#16213e,color:#fff
style ErrorType fill:#16213e,color:#fff
style DBCheck fill:#16213e,color:#fff
style RedisCheck fill:#16213e,color:#fff
style TraefikCheck fill:#16213e,color:#fff
style GatewayTest fill:#16213e,color:#fff
style ServiceTest fill:#16213e,color:#fff
style Verify fill:#16213e,color:#fff
style LogAnalysis fill:#16213e,color:#fff
style InfraCheck fill:#1a1a40,color:#fff
style AppCheck fill:#1a1a40,color:#fff
style DBSolution fill:#0f4c75,color:#fff
style RedisSolution fill:#0f4c75,color:#fff
style TraefikSolution fill:#0f4c75,color:#fff
style ConfigFix fill:#0f4c75,color:#fff
style PrismaFix fill:#0f4c75,color:#fff
style AuthFix fill:#0f4c75,color:#fff
style Restart fill:#3282b8,color:#fff
style DeepDebug fill:#1b262c,color:#fff
style IdentifyService fill:#1a1a40,color:#fff
style CheckLogs fill:#1a1a40,color:#fff
style ConnCheck fill:#1a1a40,color:#fff
style ContainerShell fill:#0f3460,color:#fff
style PrismaStudio fill:#0f3460,color:#fff
style RedisInspect fill:#0f3460,color:#fff
style APITest fill:#0f3460,color:#fff
```
---
## Infrastructure Issues
### Database (Neon/PostgreSQL)
**Problem**: `P1001: Can't reach database server` or `Connection timed out`
* **Cause 1**: Internet connectivity issues (Neon is cloud-based).
* **Cause 2**: Incorrect `DATABASE_URL` in `.env`.
* **Cause 3**: IP address blocked by Neon.
**Solution**:
1. Verify internet connection: `ping neon.tech`.
2. Check `deployments/local/.env.local`. The URL should look like:
`postgres://user:pass@ep-xyz.aws.neon.tech/neondb`
3. Go to Neon Dashboard -> Settings, ensure "Allow all IPs" or add your current IP.
**Problem**: `P1003: Database does not exist`
* **Reason**: You are connecting to the wrong database name.
* **Fix**: Check the end of your connection string (e.g., `/neondb` usually). If you are using a custom DB name, ensure it exists in Neon.
### Redis
**Problem**: `Redis connection refused` or `ECONNREFUSED`
* **Cause**: Redis container is not running or port mapping is wrong.
**Solution**:
1. Check Redis status: `docker-compose ps redis`.
2. Restart Redis: `docker-compose restart redis`.
3. Check logs: `docker-compose logs redis`.
4. Connection string from services:
* **Inside Docker**: `redis:6379`
* **From Host**: `localhost:6379`
### Traefik Gateway
**Problem**: `404 Not Found` when accessing APIs (e.g., `http://localhost/api/v1/auth`)
* **Cause**: Service is down or Labels are misconfigured.
**Solution**:
1. Check Traefik Dashboard at http://localhost:8080.
* Look for "HTTP Routers" and "Services".
* If your service is missing, check `docker-compose.yml` labels.
2. Verify `PathPrefix` in labels matches your request.
```yaml
- "traefik.http.routers.iam.rule=PathPrefix(`/api/v1/auth`)"
```
3. Check if the service passed health checks (Health status in dashboard).
**Problem**: `Bad Gateway` or `Gateway Timeout`
* **Cause**: Service is crashing or taking too long to respond.
* **Fix**: Check the specific service logs (`docker-compose logs iam-service`).
---
## Service Issues
### Service Fails to Start
**Symptom**: Container status is `Exited (1)` or `Restarting`.
**Debugging**:
1. Check logs immediately:
```bash
docker-compose logs iam-service
```
2. **Common Error**: `Config validation error`
* **Fix**: Check environment variables. Using `./scripts/setup/init-project.sh` ensures `.env` exists.
3. **Common Error**: `PrismaClientInitializationError`
* **Fix**: Database connectivity issue (see Infrastructure section).
### Prisma/Database Errors
**Error**: `P2025: Record to update not found`
* **Fix**: Logic error. Ensure the ID exists before updating.
**Error**: `P2002: Unique constraint failed`
* **Fix**: You are trying to insert duplicate data (e.g., same email).
**Error**: `Migration failed`
* **Fix**:
1. Delete `prisma/migrations` folder (only in dev!).
2. Reset database: `pnpm prisma migrate reset`.
3. Regenerate client: `pnpm prisma generate`.
### Authentication Errors
**Problem**: `401 Unauthorized` despite valid token
* **Cause 1**: Token expired.
* **Cause 2**: Public key mismatch (Service can't verify token signed by IAM).
* **Cause 3**: Clock skew (Docker time vs Host time).
**Solution**:
1. Check server logs for JWT verification errors.
2. Restart services to refresh keys.
3. Sync Docker time: restart Docker Desktop.
---
## Debugging Tools
### 1. Accessing Container Shell
To inspect files or run commands inside a running container:
```bash
docker-compose exec iam-service sh
# or /bin/bash
```
### 2. Inspecting Database (via Prisma Studio)
Use Prisma Studio to view/edit data visually:
```bash
pnpm --filter @goodgo/iam-service prisma studio
# Opens http://localhost:5555
```
### 3. Inspecting Redis
```bash
docker-compose exec redis redis-cli
> PING
PONG
> KEYS *
1) "user:123:session"
```
### 4. Direct API Testing
Use `curl` or Postman.
```bash
# Health Check
curl -v http://localhost/api/v1/auth/health/live
# Login (example)
curl -X POST http://localhost/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.com", "password":"password"}'
```
---
## FAQ
**Q: Why is my change not reflecting?**
A: If you changed `.env` or `docker-compose.yml`, you must restart:
```bash
docker-compose down && docker-compose up -d
```
If you changed code, hot-reloading (nodemon) should pick it up. If not, restart container.
**Q: How do I reset everything?**
A: Be careful, this deletes all data!
```bash
docker-compose down -v
# -v removes volumes (Redis data, etc.)
```
**Q: My computer is slow when running everything.**
A: Docker consumes RAM.
1. Stop unused services (e.g., `future-service`).
2. Increase Docker resource limits in Docker Desktop settings.
---
## Quick Tips
### Debugging Shortcuts
```bash
# Quick health check all services
docker-compose ps | grep -v "Up"
# Tail logs for all services
docker-compose logs -f --tail=50
# Restart specific service without rebuilding
docker-compose restart iam-service
# Rebuild and restart service
docker-compose up -d --build iam-service
# Check resource usage
docker stats --no-stream
# Clean up unused resources
docker system prune -a --volumes
```
### Common Error Patterns
| Error Pattern | Likely Cause | Quick Fix |
|--------------|--------------|-----------|
| `ECONNREFUSED` | Service not running | `docker-compose restart <service>` |
| `P1001` | Database unreachable | Check `DATABASE_URL` and internet |
| `P2002` | Duplicate entry | Check unique constraints |
| `401 Unauthorized` | Token expired/invalid | Refresh token or re-login |
| `404 Not Found` | Wrong route/service down | Check Traefik dashboard |
| `502 Bad Gateway` | Service crashed | Check service logs |
| `Config validation error` | Missing env vars | Run `init-project.sh` |
### Log Analysis Tips
**What to look for in logs:**
- `Server listening on port XXXX` = Service started successfully
- `Warning:` = Non-critical issues
- `Error:` = Critical issues requiring attention
- `Trace:` = Detailed execution flow
**Useful grep patterns:**
```bash
# Find all errors
docker-compose logs | grep -i error
# Find specific service errors
docker-compose logs iam-service | grep -i "error\|failed"
# Find database connection issues
docker-compose logs | grep -i "prisma\|database\|p1001\|p1003"
# Find auth issues
docker-compose logs | grep -i "unauthorized\|401\|jwt\|token"
```
### Resource Management
**Recommended Docker Resources:**
- **RAM**: Minimum 4GB, Recommended 8GB
- **CPU**: Minimum 2 cores, Recommended 4 cores
- **Disk**: Minimum 10GB free space
**Check resource usage:**
```bash
# Overall system
docker system df
# Per container
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
```
**Cleanup commands:**
```bash
# Remove stopped containers
docker container prune
# Remove unused images
docker image prune -a
# Remove unused volumes ( deletes data!)
docker volume prune
# Nuclear option ( removes everything!)
docker system prune -a --volumes
```
### Best Practices
1. **Always check logs first** before making changes
2. **Use Traefik Dashboard** (http://localhost:8080) to verify routing
3. **Keep `.env.local` updated** with correct credentials
4. **Don't delete volumes** unless you want to lose data
5. **Restart Docker Desktop** if experiencing weird networking issues
6. **Use `docker-compose down && up`** after `.env` changes
7. **Keep services running** you're actively developing
8. **Stop services** you're not using to save resources
### Visual Indicators
When reading logs, look for these patterns:
- `[INFO]` = Normal operation
- `[WARN]` = Something to watch
- `[ERROR]` = Needs immediate attention
- `[DEBUG]` = Detailed information
- `[TRACE]` = Very detailed execution flow
### Related Resources
- [Local Deployment Guide](./local-deployment.md) - Setup instructions
- [Development Guide](./development.md) - Development workflow
- [Kubernetes Local Guide](./kubernetes-local.md) - K8s troubleshooting
- [Neon Database Guide](./neon-database.md) - Database management