Maleku System’s booking engine is built around three design goals: guarantee that no two customers can book the same room or tour slot simultaneously, calculate accurate dynamic pricing at booking time rather than at display time, and immediately notify both the guest and the vendor with a confirmation email containing a unique reference code. The engine handles two fundamentally different booking types — property room stays and tour experiences — each with its own pricing logic and availability model.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/IvanchoDev89/maleku-system/llms.txt
Use this file to discover all available pages before exploring further.
Booking Types
Property Bookings
Created via
POST /api/v1/bookings/property. Requires a property_id and a room_id (the specific room within the property). Pricing is calculated per night using the room’s price_per_night and weekend_price fields. Check-in and check-out dates drive the night count. Minimum stay is 1 night; check-in cannot be in the past.Tour Bookings
Created via
POST /api/v1/bookings/tour. Requires a tour_id, a booking_date, and the number of participants. Pricing is flat per person: tour.price × participants. The booking_date must be a day the tour runs (validated against tour.schedule_days) and cannot exceed tour.max_group_size including existing bookings for that date.Availability Checking
The booking engine uses a two-phase availability check to eliminate race conditions without requiring application-level mutexes. Phase 1 — Advisory Lock Acquisition Before querying availability, the engine computes a deterministic 31-bit integer key from the resource ID and date range:check_room_availability() (from availability_service.py) executes two queries:
- It looks for any existing booking in
PENDING,CONFIRMED, orCOMPLETEDstatus whose date range overlaps the requested window. - It checks the
RoomAvailabilitytable for any vendor-blocked dates that fall within the range.
409 Conflict with a detail message: "Room is not available for the selected dates". The same pattern applies to tour bookings via check_tour_availability(), which additionally validates against the tour’s scheduled days of the week and counts booked participants for the requested date.
Pricing Calculation
Pricing is computed at booking time bypricing_service.py and is never inferred from the listing’s display price alone.
Property / Room Pricing
| Pricing Component | Rule |
|---|---|
| Weekday rate | room.price_per_night for Mon–Fri nights |
| Weekend rate | room.weekend_price for Sat–Sun nights; falls back to weekday rate if not set |
| Extra guest fee | room.extra_guest_price × (guests - room.max_guests) × nights; applied only when the guest count exceeds the room’s max occupancy |
| Weekly discount | If stay ≥ 7 nights and property.weekly_discount > 0, the percentage is subtracted from the subtotal after the nightly calculation |
Tour Pricing
Tour pricing is a flat per-person rate multiplied by the number of participants. The tour’sduration_hours is stored on the booking record for reference but does not affect the price.
Price Preview
Guests can preview the full price breakdown before confirming a booking by callingPOST /api/v1/bookings/preview. The response includes a detailed breakdown of weekday nights, weekend nights, extra-guest charges, any weekly discount, and the commission amount — all without creating a booking record.
Confirmation Codes
Every booking is assigned a unique confirmation code at creation time using Python’ssecrets module:
CRT-{8 hex chars uppercase}, for example:
confirmation_code column (unique, indexed) and is included in all confirmation emails to both the guest and the vendor.
Booking Statuses
TheBookingStatus enum (defined in app/models/base.py) governs the full booking lifecycle:
| Status | Description |
|---|---|
pending | Booking created; awaiting payment. Default state at creation. |
confirmed | Payment succeeded (set by Stripe webhook) or manually confirmed by vendor. |
cancelled | Cancelled by the guest (clients may only cancel their own bookings) or by the vendor. |
completed | Stay or tour has taken place; used for revenue reporting and review eligibility. |
refunded | Payment was refunded via Stripe; set automatically by the charge.refunded webhook handler. |
- Vendors can only move bookings to
confirmedorcancelled. - Clients can only move their own bookings to
cancelled. - Admins / Super Admins can set any status.
Email Notifications
TheEmailService sends confirmation emails asynchronously after a booking is committed to the database, so a mail delivery failure never blocks the booking response.
- Guest Email
- Vendor Email
- Payment Receipt
Sent to
booking.guest_email (or the authenticated user’s email) immediately after POST /api/v1/bookings/property or POST /api/v1/bookings/tour returns successfully. Includes the confirmation code, property/tour name, dates, participant count, total amount, and currency.8025. No real emails are delivered during development. Access the MailHog UI at http://localhost:8025.
Example: Create a Property Booking
BookingResponse with the generated confirmation_code, calculated subtotal, commission_amount, total_amount, and status: "pending".