Kiến trúc hệ thống
Cấu trúc Monorepo
SmartCK Hub sử dụng pnpm workspace kết hợp Turborepo để quản lý monorepo:
smartck-hub/
├── apps/
│ ├── backend/ # NestJS 10 - REST API
│ ├── frontend/ # React 19 + Vite 7
│ └── docs/ # Docusaurus - tài liệu
├── packages/
│ ├── api-client/ # Orval auto-generated API hooks
│ ├── shared-types/ # TypeScript types dùng chung
│ ├── eslint-config/ # ESLint shared config
│ └── tsconfig/ # TypeScript shared config
├── scripts/ # Dev scripts, Playwright helpers
├── turbo.json # Turborepo pipeline config
└── pnpm-workspace.yaml # Workspace definition
Backend - Modular Monolith
Backend được thiết kế theo pattern Modular Monolith -- không phải microservices, nhưng code được tổ chức thành các module độc lập với ranh giới rõ ràng.
Tầng kiến trúc
src/
├── main.ts # Entry point
├── app.module.ts # Root module
├── modules/ # Business modules
│ ├── iam/ # Identity & Access Management
│ ├── commercial/ # Kinh doanh
│ ├── delivery/ # Vận hành
│ ├── finance-ops/ # Tài chính
│ └── organization/ # Tổ chức
├── infrastructure/ # Hạ tầng kỹ thuật
│ ├── cache/ # Redis service
│ ├── config/ # App configuration
│ ├── database/ # Prisma service
│ ├── logger/ # Winston logger
│ ├── monitoring/ # Health check
│ └── websocket/ # Socket.IO + Redis adapter
└── shared/ # Code dùng chung
├── common/ # Utils, decorators, interceptors
├── constants/ # Permissions, enums
├── filters/ # Exception filters
├── middleware/ # HTTP middleware
├── storage/ # S3 storage service
└── validation/ # Validation service
Cấu trúc một module
Mỗi domain trong module tuân theo pattern nhất quán:
modules/commercial/
├── commercial.module.ts # Module gốc
├── customers/
│ ├── controllers/ # HTTP endpoints
│ ├── services/ # Business logic
│ ├── repositories/ # Data access (Prisma)
│ ├── dto/ # Request/Response DTOs
│ └── customers.module.ts # Sub-module
├── contracts/
│ └── ...
└── service-packages/
└── ...
Nguyên tắc
- Controller: Chỉ xử lý HTTP request/response, validate input
- Service: Chứa business logic, gọi repository
- Repository: Truy vấn database qua Prisma, không chứa logic
- DTO: Định nghĩa shape dữ liệu vào/ra với class-validator