Owner: Dev Team | Last Updated: 2026-02-21 | Status: Current
Overview of the Booking platform architecture -- from the server side to the frontend and external integrations.
┌────────────────────────────────────────┐
│ External Services │
│ ┌─────────┐ ┌────────┐ ┌───────────┐ │
│ │ Stripe │ │ Bokun │ │ Mail │ │
│ │ Payment │ │ CM API │ │ (Postmark)│ │
│ └────┬────┘ └───┬────┘ └─────┬─────┘ │
└───────┼──────────┼────────────┼───────┘
│ │ │
┌───────────────┐ ┌──────▼──────────▼────────────▼──────┐
│ Customers │ │ Booking │
│ (Browser) │ │ Laravel 12 + Vue 3 │
│ │ │ │
│ ┌──────────┐ │ │ ┌────────────────────────────────┐ │
│ │Dashboard │─┼────┼─>│ Inertia.js (SPA Bridge) │ │
│ │(Vue SPA) │ │ │ │ Session Auth + CSRF │ │
│ └──────────┘ │ │ └────────────────────────────────┘ │
│ │ │ │
│ ┌──────────┐ │ │ ┌────────────────────────────────┐ │
│ │Embed │─┼────┼─>│ Public API (Sanctum Token) │ │
│ │Widget │ │ │ │ /api/v1/* │ │
│ └──────────┘ │ │ └────────────────────────────────┘ │
└───────────────┘ │ │
│ ┌────────────────────────────────┐ │
┌───────────────┐ │ │ REST API (Session Auth) │ │
│ OTA / CM │ │ │ /rest/* │ │
│ (Bokun) │────┼─>│ ──────────────────────────── │ │
│ │ │ │ Channel Manager API │ │
└───────────────┘ │ │ /api/v1/cm/* (Basic Auth) │ │
│ └────────────────────────────────┘ │
│ │
│ ┌─────────┐ ┌─────────┐ ┌────────┐ │
│ │ MySQL │ │ Redis │ │ Queue │ │
│ │ 8.0 │ │ Cache │ │ Worker │ │
│ └─────────┘ └─────────┘ └────────┘ │
└──────────────────────────────────────┘
| Component | Technology | Purpose |
|---|---|---|
| Dashboard SPA | Vue 3 + Inertia.js | Admin interface for management |
| Embed Widget | Vue 3 (standalone SPA) | Booking widget for third-party websites |
| Blade Templates | Laravel Blade | Base HTML layout, entry point |
| Component | Location | Purpose |
|---|---|---|
| Controllers | app/Http/Controllers/ |
HTTP request handling |
| Form Requests | app/Http/Requests/ |
Input validation |
| Resources | app/Http/Resources/ |
Response formatting |
| Middleware | app/Http/Middleware/ |
Request filtering (auth, roles) |
| Component | Location | Purpose |
|---|---|---|
| Services | app/Services/ |
Business logic (62 files) |
| Actions | app/Actions/ |
Single-purpose operations (31 files) |
| DTOs | app/DTOs/ |
Data transfer between layers (82 files) |
| Jobs | app/Jobs/ |
Async operations via queue |
| Component | Location | Purpose |
|---|---|---|
| Repositories | app/Repositories/ |
Database queries (56 files) |
| Models | app/Models/ |
Eloquent ORM (67 models) |
| Observers | app/Observers/ |
Model lifecycle hooks |
| Component | Technology | Purpose |
|---|---|---|
| Database | MySQL 8.0 | Primary data store |
| Cache | Redis | Performance and session storage |
| Queue | Database / Redis | Background job processing |
| File Storage | Local / S3 | Media and documents |
Controller → Service → Repository → Model (Eloquent) → Database
Each entity has its own Repository to encapsulate database queries.
Single-purpose classes for specific operations:
// Example: app/Actions/Notifications/OrderPaidAction.php
class OrderPaidAction {
public function execute(Order $order): void {
// Send confirmation email
// Update lead status
// Log activity
}
}
Data Transfer Objects for typed data transfer between layers:
Request → DTO → Service → Repository → Model
All business logic is concentrated in Services. Controllers remain thin:
// Controller (thin)
public function store(CreateBookingRequest $request) {
return $this->bookingService->createBooking($request->toDTO());
}
Booking supports multi-tenancy at the Company level:
User → CompanyUser → Company → [Experiences, Orders, Customers, ...]
EnsureCompanyIdsInSessionMiddleware)┌────────────────────────────────────────────┐
│ Vue 3 Application │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Pages (Inertia) │ │
│ │ ├── Dashboard │ │
│ │ ├── Experiences │ │
│ │ ├── Bookings │ │
│ │ └── ... (22 page groups) │ │
│ └──────────────────────────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ Components │ │ Composables │ │
│ │ (273 files) │ │ (reusable logic) │ │
│ └──────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ REST Clients │ │ Pinia Stores │ │
│ │ (30 modules) │ │ (state mgmt) │ │
│ └──────────────┘ └──────────────────┘ │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ UI Library (shadcn + radix-vue) │ │
│ └──────────────────────────────────────┘ │
└────────────────────────────────────────────┘
app.ts (dashboard), embed-app.ts (widget), embed-api.ts (API)node_modules extracted into a separate chunk| Service | Protocol | Purpose |
|---|---|---|
| Stripe | HTTPS REST | Payments, customers, refunds |
| Bokun | HTTPS REST (Basic Auth) | Channel Manager OTA |
| Proxy API | HTTPS REST (Bearer) | External tours/bikes system |
| Postmark / SES | SMTP / API | Transactional email |
| AWS S3 | HTTPS | File storage (optional) |
| Strategy | Implementation |
|---|---|
| Redis Caching | Experiences, availability, customer types |
| Queue Workers | Email, notifications, sync jobs |
| Code Splitting | Vite chunks by directory |
| Lazy Loading | Inertia page-level code splitting |
| Database Indexing | Foreign keys, composite indexes |
| Date | Author | Change |
|---|---|---|
| 2026-02-21 | Documentation Team | Initial creation |
Next: Data Flow | Up: Architecture