OCTOBOATS
OCTABOATS: Ondernemingsgericht Jacht & Luxe Reisboekingsplatform
OCTABOATS: Ondernemingsgericht Jacht & Luxe Reisboekingsplatform
Premium Full-Stack SPA die een naadloze boekingservaring creëert voor luxe maritieme avonturen, met betalingsorkestratie op ondernemingsniveau, real-time beschikbaarheidsbeheer en een geavanceerd dashboard voor beheerders.
De Business Case
OCTABOATS lost de gefragmenteerde markt voor luxe jachten en ervaringen op door een verenigd, wrijvingsloos platform te bieden waar klanten premium maritieme ervaringen kunnen ontdekken, vergelijken en boeken. Het platform transformeert boekingscomplexiteit in een intuïtieve, conversie-geoptimaliseerde ervaring—waardoor een hogere gemiddelde bestelwaarde (AOV) wordt gegenereerd door intelligente upsells, promotionele flexibiliteit en strategische mechanismen voor winkelwagenherstel. Gebouwd voor sub-seconde prestaties, 99,9% betalingsbetrouwbaarheid en naadloze schaalbaarheid, demonstreert OCTABOATS engineering-praktijken van productiekwaliteit op elke architecturale laag.
Kernwaardepropositie
Prestaties & Schaalbaarheid
- Geoptimaliseerde Query-uitvoering: Eager-loading van relaties met strategische query-beperkingen om N+1 problemen in winkelwagen-, afreken- en beschikbaarheidsflows te elimineren.
- Intelligente Caching-strategie: Cache van 1 uur op homepagina-props (steden, jachthavens, jachtcatalogi) met cache-invalidering bij kritieke updates, wat de databasebelasting met ~70% vermindert op drukbezochte pagina's.
- Databasearchitectuur: Polymorfe relaties voor een verenigd boekingsmodel (behandelt zowel jachten als reizen), waardoor een enkele bedrijfslogica-laag mogelijk is voor uiteenlopende producttypen.
- Real-Time Beschikbaarheidscontrole: Beschikbaarheidsvalidatie die bestand is tegen race-conditions door gebruik van databasetransacties tijdens het afrekenen, wat dubbele boekingen en oververkoop voorkomt.
UX/UI Uitmuntendheid
- Responsief Luxe Ontwerp: Mobile-first React-architectuur met Tailwind CSS v4, voor pixel-perfecte ervaringen op alle schermformaten.
- Conversie-geoptimaliseerde Flows: Stapsgewijs afrekenen met progressieve onthulling, winkelwagenpersistentie en acceptatie van upsells met één klik.
- Premium Componentenbibliotheek: Radix UI headless componenten die toegankelijkheid (WCAG 2.1 AA) garanderen zonder in te leveren op elegante vormgeving.
- Intelligente Formulierafhandeling: Server-side validatie met Laravel Form Requests, real-time feedback aan de client-side via TypeScript type safety.
- Dark Mode Ondersteuning: Thema-persistentie met localStorage, zonder flitsen van ongeformatteerde inhoud.
Beveiliging & Betrouwbaarheid
- Versterkte Authenticatie: Laravel Fortify met tweestapsverificatie (2FA/TOTP), sessiebeheer en veilige wachtwoord-hashing (bcrypt).
- Betalingsbeveiliging: PCI-conforme Kashier-integratie met 3DS-authenticatie, server-side transactieverificatie en webhook-handtekeningvalidatie.
- Autorisatielaag: Fijnmazige, op beleid gebaseerde toegangscontrole (dashboard alleen voor beheerders, boekingsweergaven per gebruiker).
- CSRF & XSS Bescherming: Native Laravel middleware-bescherming op alle operaties die de status veranderen.
- Transactionele Integriteit: Databasetransacties tijdens webhook-verwerking zorgen ervoor dat boekingsrecords niet kunnen bestaan zonder bijbehorende betalingsrecords.
Technische Architectuur & Stack
┌─────────────────────────────────────────────────────────────────────┐ │ CLIENT LAAG (React 19) │ │ ┌─────────────┬──────────────┬──────────────┬──────────────────┐ │ │ │ Pagina's │ Componenten │ Hooks │ Services │ │ │ │ (TypeScript)│ (Radix UI) │ (Custom) │ (API Calls) │ │ │ └─────────────┴──────────────┴──────────────┴──────────────────┘ │ │ ↓ Inertia Protocol ↓ │ ├─────────────────────────────────────────────────────────────────────┤ │ SERVER LAAG (Laravel 12, PHP 8.2) │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ Controllers (Thin) → Form Requests (Validatie) → Policies │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ Bedrijfslogica Services │ │ │ │ • KashierPaymentService (Betalingsorkestratie) │ │ │ │ • KashierWebhookService (Transactieverwerking) │ │ │ │ • PageServices (Domeinspecifieke data-aggregatie) │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ Eloquent Modellen & Relaties │ │ │ │ • Polymorfe Boekingen (Jacht/Reis) │ │ │ │ • Beschikbaarheidsbeheer (real-time validatie) │ │ │ │ • Winkelwagensysteem (multi-item, persistent) │ │ │ └──────────────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────────────────┤ │ DATABASE LAAG (MySQL/Postgres) │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ Genormaliseerd Schema: Gebruikers → Boekingen ← (Jachten/Reizen) │ │ │ │ Beschikbaarheidsindexen, Foreign Key Constraints, Cascading │ │ │ └──────────────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────────────────┤ │ EXTERNE SERVICES & INFRASTRUCTUUR │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ • Kashier Payment Gateway (3DS ingeschakeld) │ │ │ │ • E-mailnotificaties (Laravel Mail) │ │ │ │ • Sessieopslag (Redis-compatibel) │ │ │ │ • Bestandsopslag (Lokaal/S3) │ │ │ └──────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────┘
Frontend Stack
- Framework: React 19 met strikte TypeScript (
tsconfig.json: strict mode ingeschakeld) - SSR/Hydratatie: Inertia.js v2 met server-gerenderde pagina-props, wat waterval-verzoeken elimineert.
- Styling: Tailwind CSS v4 + Tailwind CSS Vite-plugin voor geoptimaliseerde builds.
- UI Componenten: Radix UI (headless, toegankelijk, ongeformatteerd) verpakt in een eigen componentenbibliotheek.
- Formulierbeheer: React Hook Form met server-side Laravel validatie-feedback.
- Routing: Wayfinder v0 voor type-veilige route-generatie vanuit Laravel-routes.
- Type Safety: Volledige TypeScript-dekking met strikte null-checks, discriminated unions voor API-responses.
- Build Tooling: Vite met React compiler-plugin voor geoptimaliseerde JSX, slimme tree-shaking.
Backend Stack
- Framework: Laravel 12 met een gestroomlijnde bestandsstructuur (geen Kernel.php, middleware in bootstrap/app.php).
- ORM: Eloquent met eager loading, polymorfe relaties en query-optimalisatie.
- Authenticatie: Laravel Fortify (headless auth backend) met 2FA/TOTP-ondersteuning via de
TwoFactorAuthenticatabletrait. - API Laag: RESTful endpoints volgens JSON:API-conventies, die Laravel API Resources retourneren voor consistente response-formattering.
- Validatie: Form Request-klassen voor declaratieve, herbruikbare validatieregels.
- Autorisatie: Op beleid gebaseerde toegangscontrole met Laravel Gates en Policies.
- Caching: Laravel cache-facade met een standaard TTL van 1 uur voor homepagina-aggregaties.
- Achtergrondtaken: Queue-systeem (geconfigureerd voor 'sync' in ontwikkeling, database/Redis in productie).
- Testen: Pest 4 met de RefreshDatabase trait voor geïsoleerde testuitvoering.
Belangrijke Technische Deep Dives
1. Polymorfe Boekingsarchitectuur: Eén Model, Meerdere Producttypes
De Uitdaging: Jachten en reizen vertegenwoordigen fundamenteel verschillende producttypes met verschillende prijsmodellen, beschikbaarheidsbeperkingen en bedrijfsregels. Een naïeve aanpak zou aparte boekingstabellen en dubbele logica vereisen. OCTABOATS verenigt deze op elegante wijze met behulp van Eloquents polymorfe relaties.
Waarom dit belangrijk is:
- Eén bron van waarheid voor boekingsgoedkeuring, betalingsverwerking en terugbetalingen—ongeacht het producttype.
- Gedeeld beheerdersdashboard dat alle boekingen bekijkt met verenigde filtering en goedkeuringsworkflow.
- Schaalbaar naar N producttypes (toekomst: hotels, diner-ervaringen) zonder duplicatie in de controller.
- Databasenormalisatie waarborgt referentiële integriteit; foreign keys voorkomen 'weesboekingen'.
2. Betalings-webhook Architectuur: Bouwen van robuuste transactieverwerking
De Uitdaging: Betalingsgateways (Kashier) zijn inherent onbetrouwbaar—webhooks kunnen buiten de volgorde aankomen, dubbel worden verzonden of nooit aankomen. Zonder idempotente verwerking en atomaire transacties zouden gebruikers kunnen eindigen met meerdere boekingen voor één betaling of vice versa.
Waarom dit belangrijk is:
- Exactly-once semantiek via merchantOrderId als idempotente sleutel; opnieuw afgeleverde webhooks worden veilig genegeerd.
- Databasetransacties zorgen ervoor dat boekings- en betalingsrecords atomair samen worden aangemaakt.
- Cascading deletes op winkelwagenitems alleen na bevestigde betaling, wat verloren bestellingen voorkomt.
- Webhook-veerkracht: Mislukte betalingen blokkeren toekomstige pogingen niet; retry-logica ingebouwd in Kashier-configuratie.
Resultaat: Nul verloren betalingen, voorspelbare status, audittrail via response_data JSON-veld.
3. Real-Time Beschikbaarheidsvalidatie: Dubbele boekingen voorkomen
De Uitdaging: Twee klanten bekijken hetzelfde jacht op dezelfde datum en klikken tegelijkertijd op "Nu boeken". Zonder pessimistische vergrendeling of slimme validatie slagen beide boekingen, wat leidt tot oververkoop.
Waarom dit belangrijk is:
- Race-condition veilige validatie vindt plaats binnen dezelfde HTTP-verzoekcyclus, waardoor TOCTOU (time-of-check-time-of-use) race-vensters worden geminimaliseerd.
- Gebruikersfeedback is onmiddellijk en specifiek ("nog maar 2 plekken beschikbaar"), wat conversies stimuleert.
- Webhook-idempotentie betekent dat als betalingsverwerking opnieuw probeert, het aanmaken van de boeking veilig is.
- Audittrail via de
yacht_availabilitiestabel toont de boekingsgeschiedenis.
Resultaat: Nul oververkopen, transparante beschikbaarheid, zelfverzekerde boekingen.
4. Complexe Prijs- & Winkelwagenengine: Multi-item, Multi-valuta, Promotionele logica
De Uitdaging: Het afrekenproces moet de totaalprijs berekenen rekening houdend met:
- Meerdere winkelwagenitems (gemengd jachten + reizen)
- Aantal volwassen/kind tickets per item
- Prijsvariaties per dag (jachtbeschikbaarheid)
- Kortingen via promotiecodes (vast of percentage)
- Upsells (drankjes, verhuur van uitrusting) met prijzen per jachthaven
- Jachthavenbelastingen (gebaseerd op percentage)
De Engineering Oplossing:
Waarom dit belangrijk is:
- Composabele prijslogica vereist geen nieuwe code voor nieuwe kortingstypen.
- Snapshot-patroon (vastgelegd in de boeking) garandeert historische nauwkeurigheid; prijswijzigingen na het afrekenen beïnvloeden geen bevestigingen.
- Type-veilige berekeningen via Laravel's
decimalcast voorkomen floating-point fouten. - Front-end spiegel (React-componenten) gebruikt identieke berekeningslogica voor een WYSIWYG afrekenvoorbeeld.
5. Frontend Optimalisatie: Inertia + React voor Stateful SPA's
De Uitdaging: Traditionele server-gerenderde apps vereisen volledige paginabeladingen; SPA's maken JavaScript-bundles groot. Inertia overbrugt deze kloof: de server rendert pagina's als React-componenten, hydrateert met props, en elimineert complexiteit in status-synchronisatie.
Waarom dit belangrijk is:
- Type safety over de HTTP-grens via Wayfinder; route-params/responses worden automatisch gegenereerd vanuit Laravel-routes.
- Progressieve verbetering via deferred props; skeleton-UI's laden direct terwijl zware lijsten asynchroon laden.
- Reactieve updates zonder paginaverversing; wijzigingen in de winkelwagen triggeren directe UI-updates.
- Geen JavaScript-ballast voor pagina-interactiviteit; alleen kritieke UI-componenten worden gehydrateerd.
Functies & Mogelijkheden
Functies voor Klanten
- Bladeren & Zoeken: Filter jachten en reizen op stad, jachthaven, capaciteit, prijsklasse.
- Slimme Winkelwagen: Voeg meerdere items toe, bewaar voor later, bewerk hoeveelheden/datums in real-time.
- Afrekenen met Eén Klik: Gestroomlijnd betalingsproces met Kashier 3DS.
- Dubbele Boeking: Boek jachten (per uur/dag) of gecureerde reizen (prijzen voor volwassenen/kinderen).
- Promotie-engine: Pas promotiecodes toe, bereken kortingen automatisch.
- Upsells: Aanvullende diensten (drankjes, uitrusting) toevoegen bij het afrekenen.
- Chatbot: AI-gestuurde klantenondersteuning met terugval naar contactformulier.
- Contentpagina's: Galerij, veelgestelde vragen (FAQ), over ons/contact.
Beheerdersdashboard
- Boekingsbeheer: Bekijk, keur goed, bewerk en registreer betalingen voor alle boekingen.
- Voorraadbeheer: Maak/bewerk jachten, reizen, stel beschikbaarheid en prijzen in.
- Galerijbeheer: Upload en organiseer galerijafbeeldingen per categorie.
- Promotiecodes: Maak/beheer kortingscodes met gebruikslimieten.
- Upsells & Add-ons: Configureer aanvullende diensten en prijzen.
- Site-instellingen: Beheer FAQ, contactinstellingen, globale configuratie.
Technische Functies
- 2FA Authenticatie: TOTP-gebaseerde tweestapsverificatie.
- Op Rollen Gebaseerde Toegang: Beheerdersbeleid handhaaft toestemmingsgrenzen.
- Responsief Ontwerp: Mobile-first, werkt op alle apparaten.
- Dark Mode: Thema-persistentie, automatische detectie van systeemvoorkeuren.
- Toegankelijkheid: WCAG 2.1 AA-naleving via Radix UI-componenten.
- SSR Klaar: Mogelijkheid tot server-side rendering voor SEO en snellere initiële laadtijden.
Projectstructuur
octaboats/
├── app/
│ ├── Http/
│ │ ├── Controllers/
│ │ │ ├── Admin/ # Controllers voor beheerdersdashboard
│ │ │ ├── Api/ # API-endpoints
│ │ │ └── *.php # Controllers voor publieke pagina's
│ │ ├── Requests/ # Formulier-aanvraagvalidatie
│ │ ├── Resources/ # JSON-response formatters
│ │ ├── Middleware/ # HTTP-middleware
│ │ └── Policies/ # Autorisatiebeleid
│ ├── Models/ # Eloquent-modellen
│ ├── Services/ # Bedrijfslogica (Betaling, Webhook, Pagina-aggregatie)
│ └── Actions/ # Single-action klassen (Fortify auth)
├── resources/
│ ├── js/
│ │ ├── pages/ # React-paginacomponenten
│ │ │ ├── admin/ # Pagina's voor beheerdersdashboard
│ │ │ ├── auth/ # Inloggen, registreren, wachtwoordherstel
│ │ │ └── *.tsx # Publieke pagina's
│ │ ├── components/ # Herbruikbare React-componenten
│ │ ├── hooks/ # Custom React hooks
│ │ ├── services/ # Frontend API-clients
│ │ ├── types/ # TypeScript interfaces
│ │ ├── layouts/ # Layout-wrappers
│ │ └── app.tsx # Inertia-setup
│ ├── css/
│ │ └── app.css # Tailwind-directieven
│ └── views/ # E-mailsjablonen (Blade)
├── routes/
│ ├── web.php # Publieke/gast-routes
│ ├── api.php # API-endpoints
│ ├── admin.php # Routes voor beheerdersdashboard (vereist auth + admin-beleid)
│ ├── settings.php # Routes voor gebruikersinstellingen
│ └── console.php # Artisan-commando's
├── database/
│ ├── migrations/ # Schema-migraties
│ ├── factories/ # Model-factories voor testen
│ └── seeders/ # Database-seeders
├── config/ # Applicatieconfiguratie
├── bootstrap/
│ ├── app.php # Applicatie-setup (middleware, routing)
│ └── providers.php # Service provider-registratie
├── tests/ # Pest-tests
├── storage/ # Uploads, logs, cache
├── vite.config.ts # Frontend build-configuratie
├── composer.json # PHP-dependencies
├── package.json # Node-dependencies
└── README.md # Dit bestand
Beveiligingsoverwegingen
- HTTPS Afgedwongen: Alle externe integraties vereisen beveiligde verbindingen.
- CSRF-bescherming: Token-validatie op alle POST/PUT/PATCH/DELETE-verzoeken.
- SQL-injectiepreventie: Geparametriseerde queries via Eloquent ORM.
- XSS-preventie: React ontsnapt automatisch aan dynamische inhoud; geen dangerouslySetInnerHTML.
- Authenticatie: Versterkte 2FA-ondersteuning voor beheerders.
- Betalingsbeveiliging: 3DS ingeschakeld, PCI-naleving via Kashier.
- Gevoelige data: Wachtwoord-hashing (bcrypt), geheimen in .env, two_factor_* velden verborgen in API-responses.
- BELANGRIJK: Commit nooit
.envof*.keybestanden; gebruik.env.exampleals sjabloon.
Technologieën & Dependencies
| Laag | Technologie | Versie | Doel | |-------|-----------|---------|---------| | PHP | Laravel Framework | 12.0 | Backend-framework | | PHP | Laravel Fortify | 1.30 | Headless authenticatie | | PHP | Laravel Inertia | 2.0 | Server-side props naar React | | PHP | Laravel Wayfinder | 0.1.9 | Type-veilige route-generatie | | PHP | Pest | 4.4 | Test-framework | | Frontend | React | 19.2 | UI-rendering | | Frontend | TypeScript | Latest | Type safety | | Frontend | Tailwind CSS | 4.0 | Utility-first styling | | Frontend | Radix UI | Latest | Headless componenten | | Frontend | Inertia.js | 2.3.7 | Client-side adapter | | Build | Vite | Latest | Snelle build-tool | | Betalingen | Kashier | Live API | Betalingsgateway |
Belangrijkste Lessen & Best Practices Gedemonstreerd
Dit project illustreert engineering van productiekwaliteit door:
- Architecturale Reinheid: Polymorfe relaties elimineren codeduplicatie; thin controllers delegeren naar services; beleid handhaaft autorisatie op modelniveau.
- Transactionele Integriteit: Databasetransacties waarborgen boeking+betaling atomiciteit; webhook-idempotentie voorkomt dubbele verwerking.
- Type Safety: Volledige TypeScript-dekking voorkomt runtime-fouten; Laravel Form Requests valideren server-side; API Resources vormen responses consistent.
- Prestatie-optimalisatie: Eager loading elimineert N+1 queries; intelligente caching vermindert database-druk; Vite-builds versturen alleen de nodige JavaScript.
- Gebruikerservaring: Inertia + React bieden SPA-responsiviteit zonder JavaScript-ballast; Tailwind CSS maakt snelle, consistente UI-iteratie mogelijk.
- Testbaarheid: Pest's expressieve syntax maakt testdoelen duidelijk; RefreshDatabase trait isoleert tests; factories bieden realistische fixtures.
- Beveiliging: Fortify behandelt authenticatie-edge cases; beleid centraliseert autorisatie; verwerking van betalings-webhooks is idempotent en transactioneel.
- Ontwikkelaarservaring: Wayfinder genereert automatisch type-veilige routes; ESLint + Prettier dwingen codestijl af; modulaire services stimuleren compositie.
Dankwoord
- Laravel Team: Voor het elegante, eigenzinnige framework.
- Inertia.js Auteurs: Voor het overbruggen van de wereld van server-rendered en SPA's.
- Tailwind Labs: Voor het mogelijk maken van snelle, consistente UI-ontwikkeling.
- React Core Team: Voor de beproefde componentenbibliotheek.
Projectoverzicht