Business Process Management Specification (BPM_SPEC)
Project: PTX Channel Manager (ptx-cm)
Version: 1.0.0
Date: 2026-03-02
Standard: ISO 19510:2013 (BPMN 2.0) — Practical Modeling
Related: SRD.md | UI_SPEC.md | system-architecture.md
1. Scope & ISO 19510 Reference
1.1 Purpose
This document models all PTX-CM operational processes using Business Process Model and Notation (BPMN 2.0) concepts as defined in ISO 19510:2013. Processes are visualized as Mermaid diagrams for inline rendering.
1.2 Compliance Level
Practical modeling — not strict XML compliance. We use BPMN concepts (tasks, gateways, events, lanes) for documentation and visualization. The runtime engine is a custom TypeScript state machine (NestJS), not a BPMN XML executor.
1.3 Diagram Notation Convention
| Shape | Mermaid Syntax | BPMN Element | Description |
|---|---|---|---|
| Rounded rect | ([text]) | User Task | Manual action requiring human input |
| Rectangle | [text] | Service Task | Automated system action |
| Diamond | {text} | Exclusive Gateway (XOR) | Decision point, one path taken |
| Circle | ((text)) | Start/End Event | Process boundary |
| Subgraph | subgraph Name | Pool/Lane | Actor or system grouping |
| Dashed arrow | -.-> | Message/Signal | Cross-process trigger |
| Bold arrow | ==> | Critical path | Primary happy path |
2. ISO 19510 Concept Mapping
| BPMN Element | ISO 19510 Type | PTX-CM Implementation | Component |
|---|---|---|---|
| Pool | Participant | System boundary (PTX-CM) | NestJS application |
| Lane | Participant | Actor role (U-01–U-07) | RBAC PermissionsGuard |
| User Task | Activity | UI action: button click, form submit | React component + API call |
| Service Task | Activity | BullMQ job or hook execution | BookingHooksService, SyncEngine |
| Script Task | Activity | Internal computation | AvailabilityCalc, DeduplicationLogic |
| Exclusive Gateway | Gateway | Transition validation + role check | BookingStatusTransition.allowedRoles |
| Parallel Gateway | Gateway | Concurrent hook execution | Promise.all(hooks) in BookingHooksService |
| Timer Start Event | Event | BullMQ repeatable job schedule | PollingScheduler (every 2-3 min) |
| Error Boundary Event | Event | Try/catch → Alert creation | SyncJob.status=failed → E-11 Alert |
| Message Intermediate Event | Event | Notification dispatch | send_notification hook (email/LINE) |
| Signal Event | Event | System-wide broadcast | Overbooking detection → Alert + Dashboard |
| Start Event | Event | Process trigger | API request, BullMQ job trigger, user action |
| End Event (terminate) | Event | Terminal status | BookingStatusDef.isTerminal=true |
| Data Object | Data | Entity (E-xx) | Prisma model |
| Data Store | Data | PostgreSQL table / Redis cache | Database layer |
3. Process Catalog
| ID | Process | Complexity | Trigger | Actors | Related FR |
|---|---|---|---|---|---|
| P-01 | Booking Lifecycle | High | OTA sync / manual action | System, U-04, U-05, U-01/02 | FR-03, FR-25–FR-30, FR-41 |
| P-02 | OTA Sync Pipeline | Medium | Timer (BullMQ) | System | FR-03, FR-04 |
| P-03 | Alert Resolution | Low | System alert creation | U-04, U-05, U-01/02 | FR-07 |
| P-04 | Customer Management | Low | CS manual action | U-05, U-01/02 | FR-36–FR-38 |
| P-05 | OTA Onboarding | Medium | Admin action | U-01/02 | FR-01, FR-02 |
| P-06 | Property Setup | Medium | Admin/import action | U-01/02, U-04 | FR-05, FR-31–FR-32 |
4. Process Definitions
P-01: Booking Lifecycle
Trigger: New booking detected via OTA sync OR manual status change
Entities: E-08 (Booking), E-07 (Availability), E-12 (AuditLog), E-15 (Transition), E-20 (OtaStatusDef), E-22 (ProcessInstance), E-27 (LifecycleTriggerRule)
Tracks: 5 parallel tracks — booking_lifecycle (master, owns Booking.status) + 4 department tracks
Steps:
| # | BPMN Type | Actor | Step | Component |
|---|---|---|---|---|
| 1 | Start Event | System | OTA sync detects new/updated booking | SyncEngine.pullBookings |
| 2 | Service Task | System | Upsert booking with dedup (ota_booking_id) | BookingsService.upsertFromOta |
| 3 | Service Task | System | Init 5 ProcessInstances (lifecycle + 4 dept) | BookingsService.initProcessInstances |
| 4 | Service Task | System | Store raw OTA status string (view-only) | Booking.otaStatus field |
| 5 | User Task | U-04/05 | Request dept track status transition via UI | PATCH /bookings/:id/status |
| 6 | XOR Gateway | System | Validate transition exists + role allowed | BookingStatusTransition check |
| 7 | Service Task | System | Query LifecycleTriggerRule from DB | evaluateLifecycleTrigger |
| 8 | XOR Gateway | System | Evaluate conditions (check other tracks) | evaluateConditions |
| 9 | Service Task | System | Auto-transition lifecycle + update Booking.status | transitionLifecycle |
| 10 | Parallel Gateway | System | Execute hooks concurrently | Promise.all([audit, avail, notify]) |
| 11 | End Event | — | Terminal lifecycle status reached | lc_closed or lc_cancelled |
Exceptions: Invalid transition → 400. Role denied → 403. Hook failure → logged, doesn't block transition. Trigger rule not matched → no lifecycle change (dept track still transitions).
P-02: OTA Sync Pipeline
Trigger: BullMQ timer every 2-3 minutes
Entities: E-04 (OtaAccount), E-05 (OtaConnection), E-08 (Booking), E-07 (Availability), E-09 (SyncJob)
Steps:
| # | BPMN Type | Actor | Step | Component |
|---|---|---|---|---|
| 1 | Timer Start | System | BullMQ repeatable job fires | PollingScheduler |
| 2 | Service Task | System | Create SyncJob record (pending) | SyncJobsService |
| 3 | Service Task | System | Fetch active OtaConnections | OtaConnectionsService |
| 4 | XOR Gateway | System | Check OtaAccount session validity | OtaAccount.status check |
| 5 | Service Task | System | Pull bookings via OTA adapter | OtaAdapter.fetchBookings |
| 6 | Service Task | System | Upsert + dedup bookings | BookingsService.upsertFromOta |
| 7 | Script Task | System | Recalculate room availability | AvailabilityCalc |
| 8 | XOR Gateway | System | Check if booked >= total | Overbooking detection |
| 9 | Service Task | System | Push availability to other OTAs | OtaAdapter.pushAvailability |
| 10 | End Event | System | Mark SyncJob completed/failed | SyncJob.status update |
Exceptions: Session expired → Alert + skip. Fetch error → SyncJob failed + retry (3x backoff). Push error → partial sync logged.
P-03: Alert Resolution
Trigger: System creates alert (overbooking, sync failure, session expired)
Entities: E-11 (Alert)
Steps:
| # | BPMN Type | Actor | Step |
|---|---|---|---|
| 1 | Signal Start | System | Alert created (E-11) by sync engine or availability check |
| 2 | Service Task | System | Dispatch notification (email/LINE) |
| 3 | User Task | U-04/05 | Review alert on dashboard |
| 4 | XOR Gateway | U-04/05 | Decide: resolve or escalate |
| 5 | User Task | U-04/05 | Add resolution notes |
| 6 | End Event | — | Alert marked resolved |
P-04: Customer Management
Trigger: CS creates customer profile or links booking
Entities: E-19 (Customer), E-08 (Booking)
Steps:
| # | BPMN Type | Actor | Step |
|---|---|---|---|
| 1 | User Task | U-05 | Create customer profile |
| 2 | User Task | U-05 | Search/select unlinked bookings |
| 3 | Service Task | System | Suggestion engine (fuzzy name/email match) |
| 4 | User Task | U-05 | Link selected bookings |
| 5 | XOR Gateway | U-05 | Detect duplicate customer |
| 6 | User Task | U-05 | Confirm merge |
| 7 | Service Task | System | Atomic merge transaction |
P-05: OTA Onboarding
Trigger: Admin connects new OTA account
Entities: E-04 (OtaAccount), E-02 (Property), E-03 (RoomType), E-05 (OtaConnection), E-06 (OtaRoomMapping)
Steps:
| # | BPMN Type | Actor | Step |
|---|---|---|---|
| 1 | User Task | U-01/02 | Select OTA, enter credentials |
| 2 | XOR Gateway | U-01/02 | Choose 2FA method |
| 3 | Service Task | System | Test connection via Playwright |
| 4 | XOR Gateway | System | Connection success/fail |
| 5 | Service Task | System | Discover properties from OTA |
| 6 | Script Task | System | Cross-OTA property matching |
| 7 | User Task | U-01/02 | Select properties to import |
| 8 | Service Task | System | Batch create entities |
P-06: Property Setup
Trigger: Admin creates property manually or imports from OTA
Entities: E-02 (Property), E-03 (RoomType), E-05 (OtaConnection), E-17 (SupplierRoomAllocation)
Steps:
| # | BPMN Type | Actor | Step |
|---|---|---|---|
| 1 | User Task | U-01/02 | Enter property details |
| 2 | User Task | U-01/02 | Add room types |
| 3 | XOR Gateway | U-01/02 | Connect to OTA? |
| 4 | User Task | U-04 | Map room types to OTA |
| 5 | XOR Gateway | U-01/02 | Assign suppliers? |
| 6 | User Task | U-01/02 | Set supplier allocations |
| 7 | XOR Gateway | System | Validate allocation totals (soft) |
5. Process Interaction Matrix
| Source | Target | Trigger Mechanism | Data Flow |
|---|---|---|---|
| P-05 → P-06 | OTA Onboarding → Property Setup | Property import creates entities | E-02, E-03, E-05, E-06 |
| P-05 → P-02 | OTA Onboarding → OTA Sync | New OtaConnection activates polling | E-05 isActive=true |
| P-02 → P-01 | OTA Sync → Booking Lifecycle | Booking upsert creates/updates E-08 | E-08 with status=lc_new |
| P-02 → P-03 | OTA Sync → Alert Resolution | Sync failure or overbooking detected | E-11 Alert created |
| P-01 → P-04 | Booking Lifecycle → Customer Mgmt | CS links booking to customer profile | E-08.customerId set |
6. Process Maturity & Automation Level
| Process | Current State | Automation Level | Engine |
|---|---|---|---|
| P-01 Booking Lifecycle | ✅ Implemented (4-axis dept tracks) | State machine + hooks + lifecycle triggers | BookingStatusTransition table + LifecycleTriggerRule table |
| P-02 OTA Sync Pipeline | ⚠️ Partial (adapters stubbed) | BullMQ job queue | PollingScheduler + SyncEngine |
| P-03 Alert Resolution | ✅ Implemented | Manual (UI-driven) | AlertsService.resolve |
| P-04 Customer Management | ✅ Implemented | Manual (UI-driven) | CustomersService CRUD |
| P-05 OTA Onboarding | ⚠️ Partial (connection stubbed) | Wizard-guided | OtaAccountsService + S-06 |
| P-06 Property Setup | ✅ Implemented | Manual (UI-driven) | PropertiesService CRUD |
7. Phase B: Generalized Workflow Engine — IMPLEMENTED
Phase B generalized the booking state machine to support multiple process types:
7.1 Entities Added (Phase B)
| Entity | Code | Purpose |
|---|---|---|
| ProcessType | E-21 | Registry of process definitions (6 seeded types: booking, ota_sync, alert_resolution, customer_mgmt, ota_onboarding, property_setup) |
| ProcessInstance | E-22 | Execution tracking per process (polymorphic: any entity_type) |
7.2 Existing Entities Enhanced (Phase B)
- BookingStatusDef — added
processTypeKeyFK, default='booking' for backward compatibility - BookingStatusTransition — added
processTypeKeyFK, default='booking' for backward compatibility
7.3 Phase B Completion Status
| Component | Status |
|---|---|
| Database schema (E-21, E-22) | ✅ Implemented |
| API endpoints (/process-types, /process-status, /process-transitions, /process-instances) | ✅ Implemented |
| Workflow tab in Settings (S-16) | ✅ Implemented |
| Process Management tab (S-28) | ✅ Implemented |
| Process Instances page (S-29) | ✅ Implemented |
| NestJS modules registration | ✅ Implemented |
| BookingHooksService generalized with entityType support | ✅ Implemented |
7.4 Backward Compatibility
Existing booking workflow preserved via processTypeKey = 'booking' default on all status/transition records. No breaking changes to P-01 Booking Lifecycle process.
See SRD.md FR-44 to FR-47 for detailed requirements.
8. Phase C: Unified Booking Lifecycle — IMPLEMENTED
Reference:
plans/reports/brainstorm-lean-260324-1607-unified-booking-workflow.md
Phase C decouples Booking.status from the CS department track and introduces a unified lifecycle track:
8.1 New Entity (Phase C)
| Entity | Code | Purpose |
|---|---|---|
| LifecycleTriggerRule | E-27 | Data-driven rules that auto-transition booking_lifecycle when department tracks change status |
8.2 Architecture
Booking.status ← booking_lifecycle (master, 10 statuses)
↑ auto-triggered by
booking_cs (14) + booking_source (4) + booking_payment (7) + booking_accounting (12)- User interaction: Users change statuses on department tracks (CS, Source, Payment, Accounting)
- Engine: After each dept track transition → query
LifecycleTriggerRulefrom DB → evaluate conditions → auto-transitionbooking_lifecycle→ syncBooking.status - ~17 seeded rules define the mapping from department events to lifecycle transitions
8.3 Phase C Completion Status
| Component | Status |
|---|---|
| Brainstorm + architecture (FR-56, FR-57) | ✅ Designed |
Prisma model LifecycleTriggerRule (E-27) | ✅ Implemented |
| Seed lifecycle statuses + trigger rules | ✅ Implemented |
| Trigger evaluation engine | ✅ Implemented |
| Remove CS→Booking.status sync | ✅ Implemented |
| Data migration existing bookings | ✅ Implemented |
| Frontend lifecycle display | ✅ Implemented |
See SRD.md FR-56, FR-57 for requirements.