System Model (DocHub V3)
Mô hình 3 tầng của hệ thống FitZalo V2. Tham chiếu quyết định: DEC-001 (Auth/Tenant), DEC-003 (RBAC).
Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ PORTAL GOVERNOR (Web) │
│ React/Vite · apps/v2-portal · 60+ pages │
│ Roles: System Admin, Tenant Owner/Admin/Operator │
│ Auth: Email/Password + Zalo OAuth → select tenant → operate │
├─────────────────────────────────────────────────────────────────┤
│ UTILITY RUNTIME (API) │
│ NestJS · apps/api · 22 modules · 30 controllers │
│ Guard Stack: JwtAuth → Tenant → Permissions │
│ Data: MongoDB (Mongoose) · 57+ schemas │
│ Bus: EventEmitter2 (in-process events) │
├─────────────────────────────────────────────────────────────────┤
│ MINIAPP (Zalo Platform) │
│ Zalo Mini App · miniapp_v2 │
│ Auth: Zalo OAuth → tenant bind → end-user features │
│ Scope: Customer-facing (catalog browse, order, loyalty, ...) │
└─────────────────────────────────────────────────────────────────┘Layer 1: Portal Governor
Entry point: apps/v2-portal/ (React + Vite + TypeScript)
| Responsibility | Details |
|---|---|
| Authentication | Login → JWT (no tenant) → Workspace (select tenant) → Dashboard |
| Tenant Management | Create/switch/suspend tenants. Route: /workspace |
| Business Operations | Catalog, Orders, Inventory, CRM, CMS, Vouchers, ... |
| System Admin | MDM, Billing, Plugin Store, Global Settings |
| RBAC | UI guards based on PermissionString. Hide/show features per role |
Key Pages (60+)
Dashboard, Login, Workspace, ProductList/Form, OrderList/Detail, InventoryDashboard, TeamManagement, VoucherList/Form, CustomerList/Detail, PartnerList/Detail, CMS, EmailSettings, UnifiedInbox, InternalComms, ZaloCenter, PluginStore, Settings, Admin/*
Layer 2: Utility Runtime (Backend API)
Entry point: apps/api/ (NestJS + MongoDB)
Module Map (22 modules in libs/modules/)
| Domain | Module | Controllers | Key Entities |
|---|---|---|---|
| IAM | iam | auth, tenant, user, role, membership, invitation | User, Tenant, TenantSettings, Role, Permission, Membership, Identity, Invitation |
| Catalog | catalog | product, category | Product, Category |
| Commerce | ecommerce | order, cart, refund | Order, Cart, Refund |
| Voucher | voucher | voucher | Voucher |
| Inventory | inventory | inventory | Inventory, StockAdjustment, StockLocation, StockMove, StockPicking, StockQuant |
| Procurement | procurement | procurement | PurchaseOrder |
| Production | production | production | ProductionOrder |
| Shipping | shipping | shipping | ShippingOrder |
| CMS | cms | cms | Article |
| Comms (ESN) | comms | comms | CommsPost, CommsEvent, CommsKnowledge |
email | email-account, email-template, notification | EmailAccount, EmailTemplate, EmailOutbox, InAppNotification | |
| Partner/CRM | partner | partner | Partner |
| Inbox | inbox | inbox | Conversation, Message |
| AI | ai | ai | KnowledgeBase, AiDocument, AiProfile, DataSourceConfig |
| Loyalty | loyalty | loyalty | CommissionRule, Payout, PointTransaction, TierConfig |
| Customer Loyalty | customer-loyalty | customer-loyalty | MembershipCondition |
| Balance | balance | balance | Wallet, Transaction |
| Billing | billing | subscription, usage | Subscription, Usage, Plan, Feature |
| MDM | mdm | mdm | GlobalAttribute, GlobalCarrier, GlobalUom, Location, Registry |
| Plugin | plugin | plugin | PluginDef, InstalledPlugin |
| Zalo | zalo | zalo | ZaloConfig |
| Audit | audit | (interceptor) | AuditLog |
| Socket | socket | (gateway) | — |
Auth Flow (xem DEC-001)
POST /v2/iam/auth/login → JWT {sub: userId} (no tenant)
POST /v2/iam/auth/switch-tenant → JWT {sub, tenantId, role} (tenant set)
GET /v2/iam/auth/me → Current user info
POST /v2/iam/auth/zalo-login → Portal Zalo flow (DEC-002)
POST /v2/iam/auth/zalo-tenant-login → MiniApp Zalo flow (DEC-002)Guard Stack
Request → JwtAuthGuard → TenantGuard → PermissionsGuard → Controller
│ │ │
│ │ └─ Check @Permissions()
│ └─ Skip if @SkipTenantCheck()
└─ Skip if @Public()Layer 3: MiniApp (Zalo Platform)
Entry point: miniapp_v2/
| Responsibility | Details |
|---|---|
| Auth | Zalo OAuth → tenant bind → end-user JWT (DEC-002) |
| Catalog Browse | View products, categories, promotions |
| Ordering | Cart, checkout, order tracking |
| Loyalty | Points, tiers, rewards |
| Profile | User profile, order history |
Boundaries & Rules
- Portal ↔ API: Portal calls API via HTTP. Auth via JWT Bearer token.
- MiniApp ↔ API: MiniApp calls same API but with tenant-bound JWT.
- Tenant Isolation: All business data is tenant-scoped.
TenantGuardenforces. - Cross-Tenant: Only
SYSTEM_ADMINcan access cross-tenant data (with@SkipTenantCheck()). - Event Bus: Internal events (EventEmitter2) — not cross-service.
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite, TypeScript, Ant Design |
| Backend | NestJS 10, TypeScript, Mongoose/MongoDB |
| Auth | Passport JWT, bcrypt |
| Build | Nx Monorepo |
| MiniApp | Zalo Mini App SDK |