Files
pos-system/docs/vi/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

16 KiB

Quy Tắc Dự Án

GoodGo Microservices Platform coding standards and architecture patterns. Use when working with services, apps, packages, or infrastructure.

Tiêu chuẩn mã hóa và mẫu kiến trúc của GoodGo Microservices Platform. Sử dụng khi làm việc với services, apps, packages, hoặc infrastructure.

Tổng Quan

The Project Rules skill provides comprehensive guidelines for the GoodGo Microservices Platform architecture, coding standards, naming conventions, workflows, and best practices. This skill ensures consistency across all services, packages, and applications in the monorepo.

Skill Project Rules cung cấp hướng dẫn toàn diện về kiến trúc GoodGo Microservices Platform, tiêu chuẩn mã hóa, quy ước đặt tên, quy trình làm việc và thực hành tốt nhất. Skill này đảm bảo tính nhất quán trên tất cả services, packages và applications trong monorepo.

Khi Nào Sử Dụng

Use this skill when:

  • Creating a new service or package
  • Setting up project structure
  • Following naming conventions
  • Understanding deployment patterns
  • Working with dependencies
  • Configuring Docker containers
  • Setting up CI/CD workflows
  • Understanding the monorepo structure

Sử dụng skill này khi:

  • Tạo service hoặc package mới
  • Thiết lập cấu trúc dự án
  • Tuân theo quy ước đặt tên
  • Hiểu các mẫu triển khai
  • Làm việc với dependencies
  • Cấu hình Docker containers
  • Thiết lập CI/CD workflows
  • Hiểu cấu trúc monorepo

Khái Niệm Chính

Kiến Trúc

The platform follows a microservices architecture with:

  • 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)

Nền tảng tuân theo kiến trúc microservices với:

  • Apps: Next.js (web) + Flutter (mobile)
  • Services: Node.js/TypeScript microservices (Express)
  • Packages: Thư viện dùng chung (logger, types, http-client, auth-sdk, tracing)
  • Infrastructure: Traefik (API Gateway), Redis, Neon PostgreSQL, Observability
  • Deployments: Local (Docker Compose), Staging/Production (Kubernetes)

Kiến Trúc Monorepo

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

Công Nghệ

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

Các Pattern Thường Dùng

Cấu Trúc Service

Standard service structure:

services/[service-name]/
├── src/
│   ├── config/          # Configuration files
│   ├── modules/         # Feature modules
│   ├── middlewares/     # Express middlewares
│   ├── repositories/    # Data access layer
│   ├── routes/          # Route definitions
│   └── main.ts         # Entry point
├── prisma/             # Database schema
├── Dockerfile          # Container definition
└── package.json        # Dependencies

Cấu trúc service chuẩn:

services/[service-name]/
├── src/
│   ├── config/          # File cấu hình
│   ├── modules/         # Module tính năng
│   ├── middlewares/     # Express middlewares
│   ├── repositories/    # Lớp truy cập dữ liệu
│   ├── routes/          # Định nghĩa routes
│   └── main.ts         # Điểm vào
├── prisma/             # Database schema
├── Dockerfile          # Định nghĩa container
└── package.json        # Dependencies

Biểu Đồ Cấu Trúc Chi Tiết

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

Pattern Module

Controller → Service → Repository pattern:

// 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 });
  }
}

Pattern Controller → Service → Repository:

// DTO với 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 });
  }
}

Pattern Phản Hồi API

Standardized API responses:

// Success response
{
  success: true,
  data: any,
  timestamp: string
}

// Error response
{
  success: false,
  error: {
    code: string,
    message: string,
    details?: any
  },
  timestamp: string
}

Phản hồi API chuẩn hóa:

// Phản hồi thành công
{
  success: true,
  data: any,
  timestamp: string
}

// Phản hồi lỗi
{
  success: false,
  error: {
    code: string,
    message: string,
    details?: any
  },
  timestamp: string
}

Thực Hành Tốt Nhất

Quy Ước Đặt Tên

  • Services/Packages: kebab-case (e.g., iam-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

VI:

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

Tiêu Chuẩn TypeScript

  • Strict mode enabled
  • No any type (use unknown instead)
  • Zod for runtime validation
  • Export shared types from @goodgo/types

VI:

  • Bật strict mode
  • Không dùng type any (dùng unknown thay thế)
  • Zod cho runtime validation
  • Export shared types từ @goodgo/types

Ghi Log

Use @goodgo/logger:

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

Sử dụng @goodgo/logger:

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

Biến Môi Trường

  • Use .env.example template
  • Never commit .env files
  • Validate with Zod at startup
  • Document all variables in README

VI:

  • Sử dụng template .env.example
  • Không bao giờ commit file .env
  • Validate với Zod khi khởi động
  • Tài liệu hóa tất cả biến trong README

Ví Dụ Từ Dự Án

Template Service

See services/_template/ for a complete service template with:

  • Standard structure
  • Middleware setup
  • Error handling
  • Health checks
  • Swagger documentation

Xem services/_template/ để có template service hoàn chỉnh với:

  • Cấu trúc chuẩn
  • Thiết lập middleware
  • Xử lý lỗi
  • Health checks
  • Tài liệu Swagger

Cấu Hình Traefik

Services are registered in deployments/local/docker-compose.yml:

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"

Services được đăng ký trong deployments/local/docker-compose.yml:

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"

Ví Dụ Service Thực Tế

  • services/iam-service/ - Identity and Access Management service (RBAC, OIDC, MFA, Identity, Access, Governance)
  • packages/logger/ - Shared logging package
  • packages/types/ - Shared TypeScript types

VI:

  • services/iam-service/ - Service quản lý danh tính và quyền truy cập (RBAC, OIDC, MFA, Identity, Access, Governance)
  • packages/logger/ - Package logging dùng chung
  • packages/types/ - TypeScript types dùng chung

Tham Khảo Nhanh

Tạo Service Mới

# 1. Copy template
cp -r services/_template services/my-service

# 2. Update package.json name
# Change to: "@goodgo/my-service"

# 3. Add to docker-compose.yml
# Add service configuration with Traefik labels

# 4. Configure Prisma schema
cd services/my-service
pnpm prisma migrate dev

# 5. Add health check endpoint
# Already included in template

Làm Việc Với Dependencies

# Add external package
pnpm --filter @goodgo/service-name add package-name

# Add workspace package
pnpm --filter @goodgo/service-name add @goodgo/logger

# Add dev dependency
pnpm --filter @goodgo/service-name add -D @types/pkg

Lệnh Database

# Run migrations
pnpm --filter @goodgo/service-name prisma migrate dev

# Generate Prisma client
pnpm --filter @goodgo/service-name prisma generate

# Seed database
pnpm --filter @goodgo/service-name prisma db seed

Skills Liên Quan

Tài Nguyên

VI: