Skip to content

Monorepo Architecture & 5 PM2 Runtime Processes ​

1. Cấu trúc Thư mục Monorepo (Gotrace-portal) ​

Dự án sử dụng Yarn Workspaces (1.22.22) kết hợp Turborepo (turbo.json) để quản lý 4 applications độc lập trong apps/ và 6 shared packages trong packages/:

text
Gotrace-portal/
├── apps/
│   ├── frontend/              # Next.js 16.1.1 (App Router, Standalone) — Multi-brand Web Portal (:3000)
│   ├── backend/               # NestJS 11 — Core API (:3001) + VC Worker (main.ts & vc-worker.main.ts)
│   ├── zalo-be/               # NestJS 11 — Dedicated Backend cho Zalo MiniApp (:3002)
│   └── integration-gateway/   # NestJS 11 — Gateway đồng bộ 12 cổng Quốc gia (:3003 public / 127.0.0.1:3013 internal)
├── packages/
│   ├── shared-types/          # Shared TypeScript interfaces/enums/contracts (@gotrace/shared-types)
│   ├── integration-client/    # HMAC-SHA256 signed HTTP Client gọi sang integration-gateway (@gotrace/integration-client)
│   ├── integration-crypto/    # AES-256-GCM Envelope Encryption cho integration credentials (@gotrace/integration-crypto)
│   ├── integration-outbox/    # Helper enqueueInTx() ghi event vào bảng integration_outbox trong cùng DB transaction
│   ├── eslint-config/         # Shared ESLint configuration
│   └── typescript-config/     # Base tsconfig profiles
├── docs/                      # Tài liệu SRS (docs/srs/), 5-Layer Architecture (docs/technical/), User Guides (docs/hdsd-modules/)
├── docker-compose.dev.yml     # Local infra: PostgreSQL 16, Redis 7, MinIO, Backend, Frontend
├── ecosystem.config.js        # PM2 configuration điều phối 5 processes trên Production
└── turbo.json                 # Turborepo pipeline (build / dev / lint / check-types)

2. Năm PM2 Runtime Processes trong ecosystem.config.js ​

Mặc dù có 4 thư mục trong apps/, hệ thống chạy 5 PM2 processes độc lập trên môi trường Production (do apps/backend được build ra 2 entrypoints khác nhau là dist/src/main.js và dist/src/vc-worker.main.js):

STTPM2 Process NameSource App & EntrypointExec ModePortVai trò & Lý do Tách Process
1gotrace-backendapps/backend (dist/src/main.js)cluster (API_INSTANCES hoặc max):3001Phục vụ toàn bộ HTTP REST API /api/v1/* cho Web Portal, Public QR Trace, Cronjobs nội bộ và Bull Board (/api/v1/admin/queues/vc). Đặt VC_ISSUANCE_WORKER_ENABLED=false để không làm nghẽn Event Loop khi ký số.
2gotrace-vc-workerapps/backend (dist/src/vc-worker.main.js)fork (1 instance + Piscina thread pool)Headless Worker (ApplicationContext)Background worker chuyên biệt (VcWorkerModule) lắng nghe BullMQ queue vc-issuance và vc-status, điều phối Piscina Worker Threads để ký Ed25519 W3C Verifiable Credentials cho hàng vạn SGTIN mà không ảnh hưởng latency của API chính.
3gotrace-zalo-beapps/zalo-be (dist/main.js)fork (1 instance):3002Phục vụ API /api/v1/zalo/* cho Zalo MiniApp (Driver, Enterprise, Consumer) và nhận Webhook Zalo OA (/api/v1/zalo/webhook). Tích hợp sẵn VC worker cho các sự kiện phát sinh từ Zalo (SHIP, RECEIVE, SOLD).
4gotrace-integration-gatewayapps/integration-gateway (dist/main.js)fork (1 instance):3003 (Public) & 127.0.0.1:3013 (Internal)Poll bảng integration_outbox, quản lý state của 12 National Connectors, thực thi push/pull dữ liệu qua BullMQ (integration-delivery, integration-archive, integration-callback) với Circuit Breaker và Rate Limiter riêng.
5gotrace-frontendapps/frontend (.next/standalone/apps/frontend/server.js)fork (1 instance):3000Next.js 16 Standalone SSR server phục vụ giao diện Multi-brand (gotrace / hanoitrace).

IMPORTANT

CPU Isolation Principle: Phép ký mật mã học Ed25519 trên tập lớn SGTIN (ví dụ một batch 50.000 tem) là tác vụ CPU-bound. Việc tách gotrace-vc-worker khỏi gotrace-backend (qua cờ VC_ISSUANCE_WORKER_ENABLED=false trên tiến trình API) đảm bảo response time của HTTP API luôn ổn định ngay cả khi hệ thống đang batch-sign hàng vạn W3C VC.


3. Dependency Graph giữa 6 Internal Packages (packages/*) ​

Rendering diagram...
  1. @gotrace/shared-types: Chứa các contract types (IntegrationEventType, IntegrationEntityType, IntegrationErrorCode, IntegrationResultMessage...) giúp backend, integration-gateway và frontend đồng bộ tuyệt đối về kiểu dữ liệu tại compile-time.
  2. @gotrace/integration-outbox: Cung cấp hàm enqueueInTx(tx, event) được gọi ngay bên trong prisma.$transaction(...) của apps/backend. Khi doanh nghiệp tạo/cập nhật Product (gtin), Batch (batch), Input Source (input_source)..., bản ghi nghiệp vụ và bản ghi integration_outbox được atomic commit trong cùng một PostgreSQL transaction.
  3. @gotrace/integration-crypto: Cung cấp cơ chế AES-256-GCM Envelope Encryption (hỗ trợ key rotation masterKeys theo keyVersion) để bảo vệ credentials nhạy cảm trong bảng integration_company_credentials.
  4. @gotrace/integration-client: Cung cấp internal HTTP client để apps/backend gọi sang cổng nội bộ 127.0.0.1:3013 của apps/integration-gateway kèm header xác thực x-internal-key.

4. BullMQ Queues & Dual Object Storage (MinIO / S3) ​

4.1. BullMQ Queues trên Redis ​

  • vc-issuance & vc-status (apps/backend & apps/zalo-be): Xử lý phát hành (issuance) và thu hồi/cập nhật trạng thái W3C Verifiable Credentials từ bảng vc_outbox.
  • vc-anchor (apps/backend/src/modules/vc-anchor): Gom các VC leaves đã phát hành thành Merkle Batch và gửi giao dịch neo lên Spores Blockchain.
  • recall-cascade (apps/backend/src/modules/batchs): Khi một batch nguyên liệu hoặc bán thành phẩm bị recall, worker tự động trace ngược/xuôi để Cascading Recall các bộ Combo (ComboAssembly) có chứa SGTIN thuộc batch đó trong SLA ≤ 60 giây (TXNG-F32).
  • integration-delivery, integration-archive, integration-callback (apps/integration-gateway): Điều phối gửi dữ liệu ra 12 cổng quốc gia, archive HTTP request/response payload vào MinIO/S3 (integration-archive), và xử lý async webhook callback trả về.

4.2. Dual Storage Driver Architecture (STORAGE_DRIVER=minio | s3) ​

Hệ thống hỗ trợ 2 storage drivers qua interface IStorageService (apps/backend/src/common/interfaces/storage.interface.ts):

  • minio (MinioStorageService): Tự động khởi tạo bucket và gắn bucket policy PublicReadForUploads trên prefix public/*. URL trả về trỏ trực tiếp tới MinIO endpoint.
  • s3 (S3StorageService + PublicFilesController): Giữ bucket ở chế độ 100% Private (tương thích AWS S3 Directory Buckets hoặc S3 chuẩn chặn public bucket). Mọi file dưới public/* được phục vụ qua proxy route của Backend GET /api/v1/files/public/*path với header Cache-Control: public, max-age=31536000, immutable để CDN/Cloudflare cache phía trước.

Technical Documentation & Security Audit Report — kl-audit v3.0