analysis/04-functional-spec/bookings-module.md
Bookings Management
Bookings Module – Functional Specification
1. Purpose
The Bookings Module defines the full functional behavior of how bookings (الحجوزات) are created, validated, displayed, updated, and managed across:
- B2C Web Platform
- Mobile App (Flutter)
- Provider Portal
- Admin Panel
- Backend REST API & Database
The module covers:
- Booking creation flow
- Booking passengers
- Payment rules
- Status lifecycle
- Validation
- Edge cases
- Cross-module interactions
2. Involved Entities
| Entity | Description |
|---|---|
| Booking | Main record representing a customer reservation for a Trip. |
| BookingPassenger | Sub-record for each traveler included in the booking. |
| Trip | Parent entity; the booking references a Trip. |
| User | Customer who makes the booking. |
| PaymentTransaction | Transaction generated upon booking payment completion. |
| Provider | The company that owns the Trip. |
| Rating | Follow-up entity created only after Trip completion. |
4. Fields & Data Requirements
4.1 Booking
| Field | Type | Notes |
|---|---|---|
| id | UUID / Numeric | Primary Key |
| trip_id | FK | Required |
| user_id | FK | Required |
| booking_reference | String | Number shown in UI (e.g., 2952000) |
| total_passengers | Integer | ≥1 |
| total_amount | Decimal | Calculated = base_price × passengers |
| vat_amount | Decimal | Based on rules (15% for bookings) |
| grand_total | Decimal | total_amount + vat_amount |
| status | Enum | Booking status |
| payment_method | Enum | Credit Card / Mada / STC Pay / SADAD |
| payment_status | Enum | pending / success / failed |
| created_at | Timestamp | — |
| updated_at | Timestamp | — |
4.2 BookingPassenger
| Field | Type | Notes |
|---|---|---|
| id | PK | — |
| booking_id | FK | required |
| first_name | String | appears in mobile UI |
| last_name | String | appears in mobile UI |
| national_id | String | National ID / Residence ID |
| gender | Enum | male/female |
| phone | String | Phone number |
| birth_date | Date | Required |
| nationality | String | Only appears in Admin view |
| passport_number | String | Appears in Admin table |
5. Business Rules
EMAIL-01. Email collected ONCE (Slice 3)
Email is requested once in Contact section only — NOT repeated per traveler.
SSOT: analysis/04-functional-spec/bookings-module.md §5.2.1
TRAV-01. Account Holder ≠ Traveler (Slice 3)
The booking account holder may NOT be one of the travelers. Parent can book for children, etc.
Optional checkbox: 'أنا أحد المسافرين' pre-fills Traveler 1
SAVED-01. Saved Travelers Integration (Slice 4)
Users can select from saved travelers to auto-fill form. On passport expiry/modification, prompt to update saved record.
SSOT: users-management-module.md §15, bookings-module.md §5.2.5
DEC-S3-01. Traveler Phone Optional
Traveler phone is NOT required per traveler. Contact phone (collected once) is sufficient.
OFFICIAL DECISION
DEC-S3-02. Domestic ID Types
Domestic trips accept: National ID (هوية وطنية) | Iqama (إقامة) | Passport (جواز سفر). Not National ID only.
OFFICIAL DECISION
DEC-S3-03. Gender Options
Gender = Male (ذكر) | Female (أنثى) only.
OFFICIAL DECISION
BR-1. Mandatory Passenger Data
Domestic: الاسم الثلاثي, نوع الوثيقة, رقم الوثيقة, الجنس. Phone/DOB optional. International: اسم جواز, رقم جواز, انتهاء جواز, جنسية, ميلاد, جنس.
SSOT: analysis/04-functional-spec/bookings-module.md §5.2.4
BR-2. Booking is not created until payment succeeds
A Booking record is only committed when: payment_status = success
If payment fails or user closes screen → discard incomplete data.
BR-3. VAT for bookings is 15%
SSOT: See analysis/04-functional-spec/platform-settings-module.md. VAT = platformSettings.vatRateDefault (0.15). Derived from UI in Admin 'Payment Details'.
BR-5. A booking cannot be edited
From UI evidence: Admin has View only. Provider has View only. No 'Edit' exists.
BR-6. Booking cancellation
Cancellation is possible depending on: Admin action, Customer cancellation policy, Financial refund policy.
BR-7. Trip capacity validation
Before confirming booking: current_bookings < trip.capacity
If full → Show UI error: 'Booking not available'
BR-4. Booking status values
| UI Label | Meaning | Enum |
|---|---|---|
| Confirmed (مؤكدة) | Paid + active booking | CONFIRMED |
| Pending (قيد التنفيذ) | Initial state / still in process | PENDING |
| Cancelled (ملغاه) | Booking cancelled | CANCELLED |
6. Booking Lifecycle
Initial state when booking is created but payment is still in progress or awaiting confirmation.
Set automatically once payment transaction returns success. This is the stable 'active booking' state.
Set by admin, system, or customer cancellation (subject to refund policy).
Derived state when trip end_date < today. Used in B2C UI.
Derived state when trip start_date > today. Used in B2C UI.
Note: Pending (قيد التنفيذ) is the initial state, NOT an operational stage set by admin. See statuses-and-lifecycles.md for authoritative definitions.
7. State Transitions
PENDING → CONFIRMED (Successful payment) PENDING → CANCELLED (User/admin cancellation) CONFIRMED → COMPLETED (Automatic when trip ends) CONFIRMED → CANCELLED (Manual cancellation + refund rules)
8. Cancellation & Refund (Slice 10)
SSOT: analysis/04-functional-spec/bookings-module.md §8
8.1 Cancellation Eligibility
Booking can be cancelled if status is CONFIRMED/UPCOMING and departure date has not passed.
8.2 Refund Destination (DEC-S5-01 OFFICIAL)
Credit (رصيدي) is the DEFAULT refund destination. Card refund requires Admin approval.
8.3 Refund Tiers
| Days Before Departure | Refund % |
|---|---|
| ≥ 30 days | 90% |
| 15-29 days | 70% |
| 7-14 days | 50% |
| < 7 days | 0% |
8.4 Booking Status + Refund Status (DEC-S10-01)
| Field | Values | Description |
|---|---|---|
| booking.status | CANCELLED | Direct cancellation, no intermediate state (DEC-S10-01 OFFICIAL) |
| refund_status | NONE / PENDING / PROCESSING / COMPLETED / FAILED | Separate field tracks refund lifecycle (DEC-S10-01 OFFICIAL) |
| refund_percentage | 0 / 50 / 70 / 90 / 100 | Per tier; 100% for trip cancellation (DEC-S10-02/03 OFFICIAL) |
✅ DEC-S10-01: CANCELLED direct + refund_status separate. DEC-S10-02: No block, tier applies. DEC-S10-03: Trip cancellation cascades 100%. 📢 Notification wording (Slice 11): SSOT §13 — In-App [OFFICIAL], Email/SMS [PROPOSED].
This module reflects the real behavior extracted solely from UI/UX analysis (Web + Mobile + Admin + Provider), without inventing any features.