Kiến Trúc Hệ Thống
| Dự Án | PTX Channel Manager (ptx-cm) |
| Phiên Bản | 2.0.0 |
| Cập Nhật | 2026-02-20 |
Tổng Quan
PTX Channel Manager là nền tảng quản lý kênh OTA thống nhất, tự động đồng bộ phòng trống giữa Booking.com, Agoda, Traveloka và Expedia để ngăn chặn overbooking. Hệ thống sử dụng cấu trúc monorepo với frontend Next.js, backend NestJS, database PostgreSQL và hệ thống queue Redis.
1. Sơ Đồ Kiến Trúc Tổng Quan
2. Luồng Sync Engine (Polling → Booking → Phòng Trống)
3. Luồng Xác Thực & Phân Quyền
4. Sơ Đồ Quan Hệ Thực Thể Database
20 bảng — Xác Thực (5), Inventory (4), OTA (3), Booking (4), Vận Hành (4)
2. Cấu Trúc Monorepo
ptx-cm/
├── apps/
│ ├── api/ # NestJS 10 Backend
│ │ ├── src/
│ │ │ ├── modules/ # 15 feature module
│ │ │ ├── common/ # Guard, filter, decorator
│ │ │ ├── utils/ # Helper, crypto, phân trang
│ │ │ └── main.ts # Khởi động
│ │ └── package.json
│ │
│ └── web/ # Next.js 16 Frontend
│ ├── app/ # App Router
│ │ ├── (auth)/ # Route công khai
│ │ ├── (main)/ # Route bảo vệ
│ │ └── api/[...proxy]/ # Proxy backend
│ ├── components/ # Component React
│ ├── hooks/ # Hook tùy chỉnh
│ ├── contexts/ # Provider context
│ ├── lib/ # Tiện ích
│ └── package.json
│
├── packages/
│ ├── database/ # Prisma
│ │ ├── prisma/ # Schema + migration
│ │ ├── src/
│ │ │ └── client.ts
│ │ └── package.json
│ │
│ ├── types/ # TypeScript dùng chung
│ │ ├── src/
│ │ │ ├── api.types.ts # DTO request/response
│ │ │ └── enums.ts # OtaType, AlertSeverity, v.v.
│ │ └── package.json
│ │
│ └── config/ # ESLint/TypeScript
│ ├── eslint-config/
│ ├── typescript-config/
│ └── package.json
│
├── docs/ # Tài liệu
├── docker-compose.yml # PostgreSQL 16 + Redis 7
├── turbo.json # Cấu hình Turborepo
├── pnpm-workspace.yaml # pnpm workspace
└── package.json # Cấu hình gốc3. Kiến Trúc Module Backend
Module Chính (tổng 15)
| Module | Mục Đích | File Chính |
|---|---|---|
| auth | Xác thực JWT, đăng nhập, refresh, đặt lại mật khẩu | auth.service.ts, jwt.strategy.ts |
| users | CRUD user, cài đặt tài khoản | users.service.ts, users.controller.ts |
| roles | Định nghĩa vai trò, bitmask quyền hạn | roles.service.ts |
| activity-logs | Ghi log HTTP request, audit trail | activity-log.middleware.ts |
| notifications | Dịch vụ email (Resend API) | notifications.service.ts |
| properties | CRUD property, gán timezone/tiền tệ | properties.service.ts |
| room-types | Inventory phòng, giá cơ bản | room-types.service.ts |
| room-mappings | Mapping OTA ↔ room type nội bộ | room-mappings.service.ts |
| suppliers | Quản lý supplier/chủ phòng | suppliers.service.ts |
| ota-accounts | Credential OTA mã hóa (AES-256-GCM) | ota-accounts.service.ts, crypto.service.ts |
| ota-connections | Liên kết property ↔ tài khoản OTA | ota-connections.service.ts |
| ota-adapters | Factory pattern + 4 adapter stub | ota-adapter.factory.ts, booking.adapter.ts |
| bookings | CRUD booking, loại trùng upsertFromOta | bookings.service.ts |
| booking-status | Định nghĩa trạng thái, state machine | booking-status.service.ts |
| sync-engine | Điều phối polling, kéo dữ liệu, đồng bộ | sync-engine.service.ts, ota-polling.processor.ts |
| sync-jobs | Theo dõi job với trạng thái | sync-jobs.service.ts |
| alerts | Phát hiện overbooking, thông báo | alerts.service.ts |
| dashboard | KPI tổng hợp | dashboard.service.ts |
| settings | Cài đặt ứng dụng (booking_pull_minutes, v.v.) | settings.service.ts |
| health | Liveness probe | health.controller.ts |
| countries | Dữ liệu tham khảo lọc quốc gia | countries.service.ts |
Mẫu Guard & Decorator
typescript
// Guard toàn cục (áp dụng theo thứ tự):
1. JwtAuthGuard // Xác thực chữ ký JWT & hạn sử dụng
2. PermissionsGuard // Kiểm tra bitmask module:action
3. CountryScopeGuard // Áp dụng bộ lọc quốc gia vào truy vấn
// Decorator để tùy chỉnh:
@Public() // Bỏ qua JwtAuthGuard
@RequirePermission(MODULE.PROPERTIES, ACTIONS.CREATE)
@CountryScope() // Inject tham số countryScope4. Kiến Trúc Route Frontend
| Mẫu Route | Layer | Xác Thực |
|---|---|---|
/login, /forgot-password, /reset-password | (auth) | Công khai |
/dashboard, /bookings, /properties, /alerts, /sync-jobs, /ota-accounts, /suppliers, /master-data, /logs, /profile, /settings | (main) | Bảo vệ + JWT |
Chuỗi Context Provider
AuthProvider (JWT + trạng thái user)
↓
CountryProvider (bộ lọc VN/ID/MY)
↓
ReferenceDataProvider (cache quốc gia)
↓
ThemeProvider (chế độ sáng/tối)
↓
I18nProvider (ngôn ngữ en/vi)
↓
ActivityTrackerProvider (timeout phiên)5. Tổng Hợp Tech Stack
| Tầng | Công Nghệ | Phiên Bản |
|---|---|---|
| Frontend | Next.js + React + Tailwind CSS | 16 + 18 |
| Frontend State | SWR + Context API | - |
| Frontend Form | react-hook-form + zod | - |
| Frontend Tables | TanStack Table (react-table) | - |
| Backend | NestJS + Passport | 10 |
| Backend Validation | class-validator | - |
| Backend Queue | BullMQ + Redis | - |
| Database | PostgreSQL + Prisma ORM | 16 + 7 |
| Xác Thực | JWT + bcrypt | - |
| Mã Hóa | AES-256-GCM | - |
| Build Tool | Turborepo + pnpm | - |
| Ngôn Ngữ | TypeScript | 5.7 |
| Testing | Jest + @nestjs/testing | - |
6. Mẫu Thiết Kế Chính
Mẫu Xác Thực
- JWT payload bao gồm:
sub,email,roleId,permissions(PermissionMap),country,locale - Trích xuất token: Cookie HttpOnly
access_token→ fallback sang Bearer header - Guard áp dụng theo phương thức controller hoặc toàn cục
Mẫu Phân Quyền
- Quyền hạn dựa trên bitmask theo module (VIEW=1, CREATE=2, EDIT=4, DELETE=8)
- Vai trò mặc định: super_admin, admin, manager, ota, cs, fin
- Truy vấn phân quyền quốc gia: tất cả truy vấn user lọc theo middleware
countryScope
Mẫu OTA Adapter
- Factory pattern:
OtaAdapterFactory.create(otaType)trả về instance adapter - Strategy interface:
IOtaAdapter { fetchBookings(), pushAvailability() } - 4 triển khai: BookingAdapter, AgodaAdapter, TravelokaAdapter, ExpediaAdapter
Mẫu Pipeline Đồng Bộ
- Job lặp lại qua BullMQ scheduler (interval 150 giây)
- Xử lý đa giai đoạn: polling → kéo booking → tính phòng trống → đẩy OTA
- Theo dõi job: Bản ghi SyncJob cho audit + logic retry
Data Fetching (Frontend)
- SWR cho cache dữ liệu & revalidation
- Context provider cho state toàn cục (auth, quốc gia, dữ liệu tham khảo)
- TanStack Table cho sắp xếp, phân trang, lọc
7. Enum & Kiểu Dữ Liệu Chính
Enum OTA:
OtaType: Booking, Agoda, Traveloka, ExpediaConnectionStatus: Active, Inactive, ErrorSyncJobType: BookingPull, AvailabilitySyncSyncJobStatus: Pending, Running, Completed, Failed
Enum Booking:
BookingStatus: Pending, Confirmed, CheckedIn, CheckedOut, CancelledAlertType: Overbooking, SyncFailure, CredentialExpiredAlertSeverity: Info, Warning, Critical
Module Quyền Hạn (14): DASHBOARD, PROPERTIES, ROOM_TYPES, OTA_ACCOUNTS, BOOKINGS, AVAILABILITY, SYNC_JOBS, RATES, ALERTS, SETTINGS, USERS, SUPPLIERS, COUNTRIES, ROLES
8. Kiến Trúc Triển Khai
Phát Triển:
- Dev server monorepo:
pnpm devkhởi động cả hai app + BullMQ listener - PostgreSQL trong Docker: port 5433
- Redis trong Docker: port 6379
- Mailpit (bắt email): port 1025/8025
Production:
- Image container riêng biệt: API (port 3002), Web (port 3100)
- PostgreSQL managed service (Cloud SQL / RDS)
- Redis managed service (ElastiCache / Upstash)
- Email qua Resend API
- Sync job lưu trong BullMQ (Redis)
| Cập Nhật | 2026-02-20 |
| Trạng Thái | Đang hoạt động - Tất cả phần đã cập nhật theo review mã nguồn mới nhất |