Files
pos-system/docs/en/skills/project-rules.md
Ho Ngoc Hai 2640b351c3 Enhance documentation with detailed diagrams and structured flows
- Added request/response flow diagrams to api-design and api-gateway-advanced skills for better visualization of processes.
- Introduced configuration loading flow in configuration-management skill to clarify the configuration process.
- Included error propagation flow in error-handling-patterns skill to illustrate error handling across layers.
- Enhanced various skills with additional diagrams to improve understanding of complex concepts.

These updates aim to provide clearer guidance and improve the overall documentation experience for developers.
2026-01-01 23:22:54 +07:00

13 KiB

name, description
name description
project-rules GoodGo Microservices Platform coding standards and architecture patterns. Use when working with services, apps, packages, or infrastructure.

GoodGo Project Rules

Architecture

Monorepo Structure:

  • Apps: Next.js (web) + Flutter (mobile)
  • Services: Node.js/TypeScript microservices (Express)
  • Packages: Shared libraries (logger, types, http-client, auth-sdk, tracing)
  • Infrastructure: Traefik (API Gateway), Redis, Neon PostgreSQL, Observability
  • Deployments: Local (Docker Compose), Staging/Production (Kubernetes)

Template Location: services/_template/ - Use as starting point for new services

Monorepo Architecture

graph TB
    subgraph apps[Apps Layer]
        webAdmin[web-admin<br/>Next.js Admin]
        webClient[web-client<br/>Next.js Client]
        appAdmin[app-admin<br/>Flutter Admin]
        appClient[app-client<br/>Flutter Client]
    end

    subgraph gateway[API Gateway]
        traefik[Traefik<br/>Path-based Routing]
    end

    subgraph services[Services Layer]
        iamService[iam-service<br/>IAM Service]
        templateService[_template<br/>Service Template]
        otherServices[Other Services<br/>Node.js/TypeScript]
    end

    subgraph packages[Shared Packages]
        loggerPackage[@goodgo/logger<br/>Centralized Logging]
        typesPackage[@goodgo/types<br/>TypeScript Types]
        httpClientPackage[@goodgo/http-client<br/>API Client]
        authSdkPackage[@goodgo/auth-sdk<br/>Auth Utilities]
        tracingPackage[@goodgo/tracing<br/>OpenTelemetry]
        configPackage[@goodgo/config<br/>Shared Configs]
    end

    subgraph infrastructure[Infrastructure]
        postgres[Neon PostgreSQL<br/>Database]
        redis[Redis<br/>Cache]
        prometheus[Prometheus<br/>Metrics]
        grafana[Grafana<br/>Dashboards]
        loki[Loki<br/>Log Aggregation]
    end

    subgraph deployments[Deployments]
        dockerCompose[Docker Compose<br/>Local Development]
        kubernetes[Kubernetes<br/>Staging/Production]
    end

    webAdmin --> traefik
    webClient --> traefik
    appAdmin --> traefik
    appClient --> traefik
    traefik --> iamService
    traefik --> otherServices
    iamService --> packages
    otherServices --> packages
    iamService --> postgres
    otherServices --> postgres
    iamService --> redis
    otherServices --> redis
    services --> prometheus
    services --> loki
    prometheus --> grafana
    loki --> grafana
    services --> deployments

Tech Stack

Frontend:

  • Next.js 14+ (App Router), TypeScript, Tailwind CSS, Zustand
  • Flutter 3.x with Provider pattern
  • Use @goodgo/types and @goodgo/http-client

Backend:

  • Node.js 20+, TypeScript 5+, Express
  • Prisma ORM + Neon PostgreSQL
  • Zod validation, @goodgo/logger, @goodgo/tracing, @goodgo/auth-sdk

Infrastructure:

  • Traefik (path-based routing), Redis (cache), Prometheus + Grafana + Loki

Project Structure

Service: src/{config,modules,middlewares,routes,main.ts} + prisma/ + Dockerfile Package: src/index.ts + package.json + tsconfig.json + README.md App: src/{app,services/api,stores} + Dockerfile

Detailed Structure Diagram

graph TB
    subgraph service[Service Structure]
        serviceRoot[service-name/]
        serviceSrc[src/]
        serviceConfig[config/<br/>Configuration]
        serviceModules[modules/<br/>Feature Modules]
        serviceMiddlewares[middlewares/<br/>Express Middlewares]
        serviceRoutes[routes/<br/>Route Definitions]
        serviceMain[main.ts<br/>Entry Point]
        servicePrisma[prisma/<br/>Schema & Migrations]
        serviceDockerfile[Dockerfile<br/>Container Definition]
        servicePackageJson[package.json<br/>Dependencies]
        
        serviceRoot --> serviceSrc
        serviceRoot --> servicePrisma
        serviceRoot --> serviceDockerfile
        serviceRoot --> servicePackageJson
        serviceSrc --> serviceConfig
        serviceSrc --> serviceModules
        serviceSrc --> serviceMiddlewares
        serviceSrc --> serviceRoutes
        serviceSrc --> serviceMain
    end

    subgraph package[Package Structure]
        packageRoot[package-name/]
        packageSrc[src/]
        packageIndex[index.ts<br/>Main Export]
        packagePackageJson[package.json<br/>Package Metadata]
        packageTsconfig[tsconfig.json<br/>TypeScript Config]
        packageReadme[README.md<br/>Documentation]
        
        packageRoot --> packageSrc
        packageRoot --> packagePackageJson
        packageRoot --> packageTsconfig
        packageRoot --> packageReadme
        packageSrc --> packageIndex
    end

    subgraph app[App Structure - Next.js]
        appRoot[app-name/]
        appSrc[src/]
        appApp[app/<br/>Next.js App Router]
        appServicesApi[services/api/<br/>API Clients]
        appStores[stores/<br/>State Management]
        appDockerfile[Dockerfile<br/>Container Definition]
        appPackageJson[package.json<br/>Dependencies]
        
        appRoot --> appSrc
        appRoot --> appDockerfile
        appRoot --> appPackageJson
        appSrc --> appApp
        appSrc --> appServicesApi
        appSrc --> appStores
    end

    subgraph module[Module Structure inside modules/]
        moduleRoot[modules/feature-name/]
        moduleController[feature.controller.ts<br/>HTTP Handlers]
        moduleService[feature.service.ts<br/>Business Logic]
        moduleRepository[feature.repository.ts<br/>Data Access]
        moduleDto[feature.dto.ts<br/>Zod Schemas]
        moduleTypes[feature.types.ts<br/>TypeScript Types]
        moduleTest[feature.controller.test.ts<br/>Unit Tests]
        
        moduleRoot --> moduleController
        moduleRoot --> moduleService
        moduleRoot --> moduleRepository
        moduleRoot --> moduleDto
        moduleRoot --> moduleTypes
        moduleRoot --> moduleTest
        moduleController --> moduleService
        moduleService --> moduleRepository
    end

    serviceModules --> moduleRoot

Naming Conventions

  • Services/Packages: kebab-case (e.g., auth-service, http-client)
  • Files: kebab-case.type.ts (e.g., user.controller.ts)
  • Components: PascalCase.tsx (React), snake_case.dart (Flutter)
  • Classes: PascalCase, Functions: camelCase, Constants: UPPER_SNAKE_CASE
  • Package Names: @goodgo/package-name

Workflows

New Service:

  1. Copy services/_template/
  2. Update package.json name to @goodgo/service-name
  3. Add to deployments/local/docker-compose.yml with Traefik labels
  4. Configure Prisma schema if needed
  5. Add health check endpoint

New Package:

  1. Create in packages/, export from src/index.ts
  2. Add to pnpm-workspace.yaml
  3. Use TypeScript strict mode

Dependencies:

pnpm --filter @goodgo/service-name add package-name
pnpm --filter @goodgo/service-name add @goodgo/logger  # workspace
pnpm --filter @goodgo/service-name add -D @types/pkg   # dev

Database:

pnpm --filter @goodgo/service-name prisma migrate dev
pnpm --filter @goodgo/service-name prisma generate

Code Standards

TypeScript:

  • Strict mode, no any (use unknown)
  • Zod for runtime validation
  • Export shared types from @goodgo/types

API Responses:

// Success: { success: true, data: any }
// Error: { success: false, error: { code, message, details? } }

Logging:

import { logger } from '@goodgo/logger';
logger.info('Message', { context });
logger.error('Error', { error, context });

Environment:

  • Use .env.example template, never commit .env
  • Validate with Zod at startup
  • Document all vars in README

Testing

  • Unit: Place tests next to source (*.test.ts), use Jest, mock dependencies, >80% coverage
  • Integration: Test API endpoints, use test database, cleanup after
  • Commands: pnpm test, pnpm --filter @goodgo/service-name test, pnpm test:coverage

Docker

Multi-stage Build Pattern:

FROM node:20-alpine AS builder
# ... build stage
FROM node:20-alpine
# ... production stage with non-root user

Image Naming: goodgo/service-name:version (semantic versioning)

Git Workflow

Branches: feature/, fix/, hotfix/, release/

Commits: Conventional Commits format

type(scope): subject

Types: feat, fix, docs, style, refactor, test, chore

PRs: Use template, link issues, ensure CI passes, squash merge to main

CI/CD

GitHub Actions: PR (lint, test, build) → develop (staging) → main (production)

Deployment Checklist: Tests pass, no lint errors, env vars set, migrations applied, docs updated, monitoring configured

Security

Auth: JWT (15min access, 7d refresh), httpOnly cookies, use @goodgo/auth-sdk Authorization: RBAC, check permissions at service level, middleware for routes Data: bcrypt (cost 12), HTTPS, sanitize inputs, Zod validation Secrets: Environment variables, Kubernetes secrets, never hardcode, rotate regularly

Performance

Backend: Redis caching, connection pooling, pagination, database indexes, rate limiting Frontend: Next.js Image optimization, code splitting, lazy loading, React.memo, bundle optimization Database: Prisma optimization, indexes, transactions, soft deletes

Observability

Metrics: Prometheus (request count, duration, errors), set alerts Logging: @goodgo/logger with trace IDs, levels (error, warn, info, debug), Loki aggregation Tracing: OpenTelemetry via @goodgo/tracing, trace cross-service requests

Documentation

Code: JSDoc for public APIs, inline comments for complex logic, README per service/package API: OpenAPI/Swagger specs in docs/api/openapi/, document endpoints with examples Architecture: System design in docs/architecture/, service communication, data flows, ADRs

Architecture Patterns

Modular Structure: Controller → Service → Repository pattern DTO Validation: Zod schemas with type inference Error Handling: Custom error classes, global error middleware Dependency Injection: Constructor injection for testability

Example Module:

// DTO with Zod
export const CreateFeatureDto = z.object({
  name: z.string().min(1),
  email: z.string().email()
});
export type CreateFeatureDto = z.infer<typeof CreateFeatureDto>;

// Controller
export class FeatureController {
  constructor(private service: FeatureService) {}
  async create(req: Request, res: Response, next: NextFunction) {
    try {
      const dto = CreateFeatureDto.parse(req.body);
      const result = await this.service.create(dto);
      res.json({ success: true, data: result });
    } catch (error) { next(error); }
  }
}

// Service
export class FeatureService {
  constructor(private repository: FeatureRepository) {}
  async create(dto: CreateFeatureDto) {
    return this.repository.create(dto);
  }
}

// Repository
export class FeatureRepository extends BaseRepository<Feature> {
  async create(data: CreateFeatureDto) {
    return this.prisma.feature.create({ data });
  }
}

Deployment & Traefik

Service Registration: Services are deployed via deployments/local/docker-compose.yml and auto-discovered by Traefik:

services:
  my-service:
    build:
      context: ../..
      dockerfile: services/my-service/Dockerfile
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.my-service.rule=PathPrefix(`/api/v1/my-service`)"
      - "traefik.http.services.my-service.loadbalancer.server.port=5002"
      - "traefik.http.services.my-service.loadbalancer.healthcheck.path=/health/live"

Traefik Configuration:

  • Location: infra/traefik/ (platform-level, not per-service)
  • Static Config: traefik.yml - Entry points, providers, dashboard
  • Dynamic Config: dynamic/middlewares.yml, dynamic/routes.yml
  • Dashboard: http://localhost:8080

Access Points:

  • API: http://localhost/api/v1/service-name
  • Health: http://localhost/api/v1/service-name/health
  • Docs: http://localhost/api/v1/service-name/api-docs

Troubleshooting

Common Issues:

  • Port conflicts: Check deployments/local/docker-compose.yml
  • Database: Verify DATABASE_URL in .env.local
  • Module not found: Run pnpm install
  • Type errors: Run pnpm --filter @goodgo/service-name prisma generate

Debug:

cd deployments/local
docker-compose logs -f service-name
docker-compose ps
docker-compose up -d --build

Resources