Codebase Summary
Project: PTX Channel Manager (ptx-cm)
Version: 2.6.0
Last Updated: 2026-03-30
1. Monorepo Dependency Graph
2. Directory Structure & Metrics
| Directory | Purpose | Est. LOC | Files |
|---|---|---|---|
| apps/api | NestJS Backend | ~13,300 | 205 TS |
| apps/web | Next.js Frontend | ~30,800 | 188 TSX/TS |
| packages/database | Prisma + migrations | ~1,800 | 15 |
| packages/types | Shared types/enums | ~600 | 6 |
| packages/config | ESLint/TS configs | ~100 | 3 |
| docs | Documentation | ~11,300 | 22 MD |
| Total | All source | ~49,000 | 440+ |
3. Backend Module Map
31 Feature Modules (apps/api/src/modules)
Auth & Users:
auth— JWT, login, refresh, password reset, rate limitingusers— User CRUD, account settings (locale, country, dateFormat)roles— Role definitions, permission bitmasks (15 modules × 4 actions)activity-logs— HTTP request logging, audit trail via middleware
Inventory & Operations:
properties— Property CRUD, timezone/currency, city/buildingName, manager assignmentroom-types— Room inventory, base rates per propertyroom-mappings— OTA ↔ local room type mappingsuppliers— Supplier/room-owner managementsupplier-room-allocations— M:N supplier ↔ room allocation
OTA Integration:
ota-accounts— Encrypted credentials (AES-256-GCM)ota-connections— Property ↔ OTA account linksota-adapters— Factory + 4 adapters (Booking, Agoda, Traveloka, Expedia)ota-rate-configs— Per-OTA rate formula configuration + formula engineota-status— OTA-specific status definitions (per-OTA status mapping)
Bookings & CRM:
bookings— Booking CRUD, upsertFromOta dedup, manual creation, 4-axis status, CS/Source owner assignment, health computationbooking-status— Configurable BookingStatusDef definitions with department tracks (cs, payment, source, accounting), health weights, hard-deletecustomers— Guest profiles, booking consolidation, link/unlink/merge operations
Availability & Rates:
availability— Calendar-based availability matrix, block/unblock date ranges, multi-room selectionrates— Base rate management per room typerate-rules— Markup/discount/seasonal rule definitionsrate-plans— Rate plan configurations with adjustmentsbulk-rates— Batch rate updates across properties/room types
Sync Engine:
sync-engine— Polling scheduler, job tracking, OTA polling/availability sync processorssync-jobs— Async job tracking with status
Support & System:
alerts— Overbooking detection & notifications (6 alert types)dashboard— KPI metrics (occupancy, revenue, alerts, sync status)settings— App config (sync intervals, notification toggles, health flag rules)notifications— Email service (Resend API + Mailpit in dev)countries— Reference data for filteringhealth— Liveness probesprisma— Prisma client provider module
Common Patterns (apps/api/src/common)
Guards (applied globally, opt-out via @Public):
JwtAuthGuard— JWT signature & expiry validationPermissionsGuard— Module:action bitmask verificationCountryScopeGuard— Country filter injection from user contextThrottlerGuard— Rate limiting (5/min login, 10/min refresh)
Decorators:
@Public()— Skip JwtAuthGuard@RequirePermission(module, action)— Bitwise permission check@CountryScope()— Inject countryScope from user.country
4. Frontend Route Map
| Route | Layer | Auth | Purpose |
|---|---|---|---|
/login, /forgot-password, /reset-password, /change-password | (auth) | Public | Auth flows |
/dashboard | (dashboard) | Required | KPI overview |
/bookings, /bookings/[id], /bookings/new | (dashboard) | Required | Booking list, detail & manual creation |
/properties, /properties/[id] | (dashboard) | Required | Property list & detail |
/customers, /customers/[id] | (dashboard) | Required | Guest CRM profiles |
/ota-accounts, /ota-accounts/connect | (dashboard) | Required | OTA account management |
/availability | (dashboard) | Required | Availability calendar & blocking |
/rates, /rates/base-rates | (dashboard) | Required | Rate management (OTA formulas) |
/rates/bulk-ops, /rates/bulk-apply | (dashboard) | Required | Bulk rate operations |
/team, /team/[id] | (dashboard) | Required | Team workload & user booking assignments |
/workflows | (dashboard) | Required | Workflow hub (status CRUD, health flags) |
/workflows/designer | (dashboard) | Required | Visual workflow diagram |
/workflows/instances, /workflows/process-types | (dashboard) | Required | Process tracking |
/workflows/trigger-rules, /workflows/visibility | (dashboard) | Required | Lifecycle rules & UI visibility matrix |
/process-instances | (dashboard) | Required | BPM workflow instances |
/suppliers, /suppliers/[id] | (dashboard) | Required | Supplier management |
/alerts, /sync-jobs, /logs | (dashboard) | Required | Monitoring & audit |
/master-data, /settings, /profile | (dashboard) | Required | Configuration |
Context Provider Chain
AuthProvider → CountryProvider → ReferenceDataProvider → ThemeProvider → I18nProvider → ActivityTrackerProviderKey Components (by directory)
availability/— Availability grid, calendar picker, block-range popover, multi-room drag selectionrates/— Formula overview matrix, bulk rate operations, bulk apply formula, price calendarcustomers/— Customer table, detail view, booking history mergebookings/— Booking detail (health badge, department status bar, 4-axis status track panel, owner assignment, cost/margin), history timeline, status transition dialogproperties/— Property detail tabs, OTA connections, grouped sidebar list, pricing matrixworkflows/— Health flags manager, transition editor panelsettings/— Workflow status CRUD, visual diagram, transition table, UI visibilitylayout/— Sidebar navigation, topbar, country switcher, language switcherui/— Reusable primitives (data-table, dialog, tabs, status-badge, icon-picker, etc.)
5. Database Schema (30 Models, 9 Enums)
Auth/Users (6): users, roles, refresh_tokens, password_reset_tokens, countries, activity_logs
Inventory (4): properties, room_types, suppliers, supplier_room_allocations
OTA Integration (4): ota_accounts, ota_connections, ota_room_mappings, sync_jobs
Bookings & CRM (5): bookings, booking_status_def, availability, customers, ota_status_def
Rates (7): rates, rate_rules, rate_plans, rate_plan_adjustments, ota_formula_templates, ota_rate_configs, ota_rate_lines
Operations (4): alerts, audit_logs, settings, property_formula_configs
Key Relationships:
- Property → [RoomTypes, OtaConnections, Availability, Manager(User)]
- OtaAccount → OtaConnections → Bookings
- RoomType → [Rates, RateRules, OtaRateConfigs, SupplierRoomAllocations]
- Booking → BookingStatusDef (4-axis: status, paymentStatus, sourceStatus, accountingStatus)
- Booking → User (csOwner, sourceOwner)
- OtaFormulaTemplate → OtaRateConfig → OtaRateLines (rate formulas)
6. Tech Stack
| Layer | Stack |
|---|---|
| Frontend | Next.js 16, React 18, Tailwind CSS, TanStack Table, SWR, react-hook-form, zod |
| Backend | NestJS 10, Passport JWT, class-validator, BullMQ, Redis |
| Database | PostgreSQL 16, Prisma 7 ORM |
| Auth | JWT + refresh tokens, HttpOnly cookies, bcrypt |
| Encryption | AES-256-GCM (OTA credentials) |
| Build | Turborepo, pnpm workspaces, TypeScript 5.7 |
| Testing | Jest, @nestjs/testing |
7. Key Design Patterns
Authentication: JWT payload (sub, email, roleId, permissions, country, locale) extracted from HttpOnly access_token cookie with Bearer fallback.
Authorization: Bitmask permissions per module (VIEW=1, CREATE=2, EDIT=4, DELETE=8), 6 role presets (super_admin, admin, manager, ota, cs, fin).
OTA Adapters: Factory pattern returning strategy-based adapters for Booking, Agoda, Traveloka, Expedia.
Sync Pipeline: BullMQ repeating jobs (150s) → BookingPull → AvailabilityCalc → OTA push, with SyncJob tracking for audit/retry.
Rate Engine: OTA-formula-based rate calculation. OtaFormulaTemplates define per-OTA price derivation logic. OtaRateConfigs link templates to properties. OtaRateLines store computed daily rates.
4-Axis Booking Workflow: Each booking tracks 4 department statuses (CS, Payment, Source, Accounting) via BookingStatusDef. Status transitions are role-gated with JSON-based transition rules. Health weights (ok/warning/risk) and flag rules drive bookingHealth computation.
Data Fetching: SWR for frontend caching, Context providers for global state, TanStack Table for CRUD tables.
8. Critical Files
| File | Purpose |
|---|---|
packages/database/prisma/schema.prisma | Source of truth for DB schema |
packages/types/src/enums.ts | OTA types, role enums, status constants |
docs/API_SPEC.md | Backend endpoint contracts |
docs/DB_DESIGN.md | Database design rationale & ER |
docs/BPM_SPEC.md | Business process management spec |
9. Sync Engine Flow (Core Feature)
PollingScheduler (startup) → Creates BullMQ repeating jobs every 150s
↓
OtaPollingProcessor (concurrency: 3) → BookingPullService.pullBookings()
↓
OTA Adapters (factory) → fetchBookings() from each OTA
↓
BookingsService.upsertFromOta() → Dedup & upsert bookings
↓
BookingHooks → Post-upsert side effects (notifications, status checks)
↓
AvailabilitySyncProcessor (concurrency: 2) → AvailabilityCalcService.recalculate()
↓
Count bookings per date, detect isOverbooked
↓
AlertsService (if overbooking) + OTA Adapters.pushAvailability() (always)Last Updated: 2026-03-30 | Status: Active