Skip to content

System Architecture

ProjectPTX Channel Manager (ptx-cm)
Version2.0.0
Last Updated2026-02-20

Overview

PTX Channel Manager is a unified OTA channel management platform that auto-syncs room availability across Booking.com, Agoda, Traveloka, and Expedia to prevent overbookings. The system uses a monorepo structure with a Next.js frontend, NestJS backend, PostgreSQL database, and Redis queue system.


1. High-Level Architecture Diagram


2. Sync Engine Flow (Polling → Booking → Availability)


3. Authentication & Authorization Flow


4. Database Entity Relationship Diagram

20 tables — Auth (5), Inventory (4), OTA (3), Bookings (4), Operations (4)


2. Monorepo Structure

ptx-cm/
├── apps/
│   ├── api/                          # NestJS 10 Backend
│   │   ├── src/
│   │   │   ├── modules/              # 15 feature modules
│   │   │   ├── common/               # Guards, filters, decorators
│   │   │   ├── utils/                # Helpers, crypto, pagination
│   │   │   └── main.ts               # Bootstrap
│   │   └── package.json
│   │
│   └── web/                          # Next.js 16 Frontend
│       ├── app/                      # App Router
│       │   ├── (auth)/               # Public routes
│       │   ├── (main)/               # Protected routes
│       │   └── api/[...proxy]/       # Backend proxy
│       ├── components/               # React components
│       ├── hooks/                    # Custom hooks
│       ├── contexts/                 # Provider contexts
│       ├── lib/                      # Utilities
│       └── package.json

├── packages/
│   ├── database/                     # Prisma
│   │   ├── prisma/                   # Schema + migrations
│   │   ├── src/
│   │   │   └── client.ts
│   │   └── package.json
│   │
│   ├── types/                        # Shared TypeScript
│   │   ├── src/
│   │   │   ├── api.types.ts          # Request/response DTOs
│   │   │   └── enums.ts              # OtaType, AlertSeverity, etc.
│   │   └── package.json
│   │
│   └── config/                       # ESLint/TypeScript
│       ├── eslint-config/
│       ├── typescript-config/
│       └── package.json

├── docs/                             # Documentation
│   ├── system-architecture.md        # This file
│   ├── codebase-summary.md           # File counts & module map
│   ├── code-standards.md             # Naming, patterns, error handling
│   ├── project-overview-pdr.md       # Requirements & PDR
│   ├── development-roadmap.md        # Feature status & milestones
│   ├── SRD.md                        # System Requirements
│   ├── API_SPEC.md                   # REST API spec
│   ├── DB_DESIGN.md                  # Database design
│   └── UI_SPEC.md                    # Design system & screens

├── docker-compose.yml                # PostgreSQL 16 + Redis 7
├── turbo.json                        # Turborepo config
├── pnpm-workspace.yaml               # pnpm workspaces
└── package.json                      # Root config

3. Backend Module Architecture

Core Modules (15 total)

ModulePurposeKey Files
authJWT authentication, login, refresh, password resetauth.service.ts, jwt.strategy.ts
usersUser CRUD, account settingsusers.service.ts, users.controller.ts
rolesRole definitions, permission bitmasksroles.service.ts
activity-logsHTTP request logging, audit trailactivity-log.middleware.ts
notificationsEmail service (Resend API)notifications.service.ts
propertiesProperty CRUD, timezone/currency assignmentproperties.service.ts
room-typesRoom inventory, base ratesroom-types.service.ts
room-mappingsOTA ↔ local room type mappingroom-mappings.service.ts
suppliersSupplier/room-owner managementsuppliers.service.ts
ota-accountsEncrypted OTA credentials (AES-256-GCM)ota-accounts.service.ts, crypto.service.ts
ota-connectionsProperty ↔ OTA account linksota-connections.service.ts
ota-adaptersFactory pattern + 4 adapter stubsota-adapter.factory.ts, booking.adapter.ts
bookingsBooking CRUD, upsertFromOta dedupbookings.service.ts
booking-statusStatus definitions, state machinebooking-status.service.ts
sync-engineOrchestration of polling, pulling, syncingsync-engine.service.ts, ota-polling.processor.ts
sync-jobsJob tracking with statussync-jobs.service.ts
alertsOverbooking detection, notificationsalerts.service.ts
dashboardAggregated KPI metricsdashboard.service.ts
settingsApp config (booking_pull_minutes, etc)settings.service.ts
healthLiveness probeshealth.controller.ts
countriesReference data for country filteringcountries.service.ts

Guard & Decorator Pattern

typescript
// Global guards (applied in order):
1. JwtAuthGuard          // Validates JWT signature & expiry
2. PermissionsGuard      // Checks module:action bitmask
3. CountryScopeGuard     // Applies country filter to query

// Decorators to opt out or customize:
@Public()                // Skip JwtAuthGuard
@RequirePermission(MODULE.PROPERTIES, ACTIONS.CREATE)
@CountryScope()          // Injects countryScope param

4. Frontend Route Architecture

Route PatternLayerAuthentication
/login, /forgot-password, /reset-password(auth)Public
/dashboard, /bookings, /properties, /alerts, /sync-jobs, /ota-accounts, /suppliers, /master-data, /logs, /profile, /settings(main)Protected + JWT

Context Provider Chain

AuthProvider (JWT + user state)

CountryProvider (VN/ID/MY filter)

ReferenceDataProvider (Countries cache)

ThemeProvider (Light/dark mode)

I18nProvider (en/vi locale)

ActivityTrackerProvider (Session timeout)

5. Tech Stack Summary

LayerTechnologyVersion
FrontendNext.js + React + Tailwind CSS16 + 18
Frontend StateSWR + Context API-
Frontend Formreact-hook-form + zod-
Frontend TablesTanStack Table (react-table)-
BackendNestJS + Passport10
Backend Validationclass-validator-
Backend QueueBullMQ + Redis-
DatabasePostgreSQL + Prisma ORM16 + 7
AuthenticationJWT + bcrypt-
EncryptionAES-256-GCM-
Build ToolTurborepo + pnpm-
LanguageTypeScript5.7
TestingJest + @nestjs/testing-

6. Key Design Patterns

Authentication Pattern

  • JWT payload includes: sub, email, roleId, permissions (PermissionMap), country, locale
  • Token extraction: HttpOnly cookie access_token → fallback to Bearer header
  • Guards applied per controller method or globally

Authorization Pattern

  • Bitmask-based permissions per module (VIEW=1, CREATE=2, EDIT=4, DELETE=8)
  • Role-based presets: super_admin, admin, manager, ota, cs, fin
  • Country-scoped queries: all user queries filtered by countryScope middleware

OTA Adapter Pattern

  • Factory pattern: OtaAdapterFactory.create(otaType) returns adapter instance
  • Strategy interface: IOtaAdapter { fetchBookings(), pushAvailability() }
  • 4 implementations: BookingAdapter, AgodaAdapter, TravelokaAdapter, ExpediaAdapter

Sync Pipeline Pattern

  • Repeating jobs via BullMQ scheduler (150s interval)
  • Multi-stage processing: polling → booking pull → availability calc → OTA push
  • Job tracking: SyncJob records created for audit + retry logic

Data Fetching (Frontend)

  • SWR for data caching & revalidation
  • Context providers for global state (auth, country, reference data)
  • TanStack Table for sorting, pagination, filtering

7. Key Enums & Types

OTA Enums:

  • OtaType: Booking, Agoda, Traveloka, Expedia
  • ConnectionStatus: Active, Inactive, Error
  • SyncJobType: BookingPull, AvailabilitySync
  • SyncJobStatus: Pending, Running, Completed, Failed

Booking Enums:

  • BookingStatus: Pending, Confirmed, CheckedIn, CheckedOut, Cancelled
  • AlertType: Overbooking, SyncFailure, CredentialExpired
  • AlertSeverity: Info, Warning, Critical

Permission Modules (14): DASHBOARD, PROPERTIES, ROOM_TYPES, OTA_ACCOUNTS, BOOKINGS, AVAILABILITY, SYNC_JOBS, RATES, ALERTS, SETTINGS, USERS, SUPPLIERS, COUNTRIES, ROLES


8. Deployment Architecture

Development:

  • Monorepo dev servers: pnpm dev starts both apps + BullMQ listeners
  • PostgreSQL in Docker: port 5433
  • Redis in Docker: port 6379
  • Mailpit (email catcher): ports 1025/8025

Production:

  • Separate container images: API (port 3002), Web (port 3100)
  • PostgreSQL managed service (Cloud SQL / RDS)
  • Redis managed service (ElastiCache / Upstash)
  • Email via Resend API
  • Sync jobs persist in BullMQ (Redis)

Last Updated2026-02-20
StatusActive - All sections current as of latest codebase review

PTX Channel Manager — Internal Documentation