Booklane
Booklane geeft klanten van een dienstverlener een zelfbedieningsflow: de juiste dienst, een prijsindicatie vooraf en een moment dat past — direct boekbaar of op aanvraag. Gebouwd voor Vancoillie IT Hulp.

01Het probleem
Vroeger
De klant belt of mailt. “Wanneer kan je?” Een paar keer heen en weer. De afspraak belandt handmatig in de agenda. De prijs wordt pas achteraf duidelijk.
Met Booklane
De klant vindt de juiste dienst, ziet meteen een prijsindicatie, kiest enkel uit momenten die echt kunnen en bevestigt in één scherm. De technieker krijgt een volledige aanvraag met context.
02De klantreis
De klant kiest een categorie en beschrijft in eigen woorden het probleem. Booklane leidt daaruit de juiste dienst af.

Per categorie kunnen extra vragen verschijnen. De antwoorden reizen mee met de aanvraag, zodat er meteen context is.

Ter plaatse of op afstand. Bij een adres wordt de rijafstand vanaf de basis berekend, gecheckt of het binnen 20 km valt, en direct een prijsindicatie getoond: duur × uurtarief + verplaatsing, als schatting.

Sommige momenten zijn direct boekbaar en meteen bevestigd, andere gaan op aanvraag. Wie verder woont dan de directe straal, kan enkel aanvragen.

Contactgegevens, akkoord en overzicht op één scherm, met één knop. Daarna volgt automatisch een bevestigingsmail. Betalen gebeurt na de interventie.

03De drie onderdelen
Voor de klant · publiek
Een server-rendered wizard: categorie, intake, dienst, locatie, moment, bevestigen. Geen account. Beschermd met honeypot, rate-limiting per IP en e-mailvalidatie.

Voor de technieker · aan de laptop
Single-user login met bcrypt en CSRF op elk formulier. Dashboard, aanvragen-inbox, afspraken, agenda, beschikbaarheid, diensten, prijzen en instellingen.


Voor de technieker · onderweg · iOS
Een native SwiftUI-app op een dunne JSON-API die exact dezelfde serverfuncties hergebruikt — geen logica verdubbeld. Dashboard, afspraken en aanvragen afhandelen, met pushmeldingen bij elke nieuwe boeking en deeplinks naar het juiste scherm.

04Onder de motorkap
Eén businesslaag, hergebruikt door de publieke site, de web-admin en de JSON-API voor de app. Geen logica gedupliceerd.
PHP 8 met MySQL/MariaDB via vanilla PDO, volledig server-rendered. Geen framework, geen Composer. Draait op shared hosting; elke push naar main deployt via een GitHub Action over FTPS. Alle bedrijfswaarden — tarieven, teksten, werkgebied — staan in een settings-tabel, niet in de code.
Terugkerende weekregels (weekdag, tijdvak, modus: direct / op aanvraag / gesloten) plus eenmalige uitzonderingen per datum. Eén functie legt beide samen tot de tijdssegmenten van een dag; uitzonderingen overrulen de weekregels.
OAuth2 in de admin. Google zegt enkel wanneer je bezet bent — de agenda-inhoud blijft dicht. Vrij/bezet wordt elke 15 minuten opgehaald en gecachet. Een bevestigde afspraak verschijnt als event in de doelagenda; bij annuleren verdwijnt het weer.
Berekent de concrete boekbare startmomenten. Instellingen die meespelen: opzegtermijn, boekingshorizon, slot-granulariteit en per dienst de duur, buffer en modus. Woont de klant buiten de directe straal, dan zakken direct-slots automatisch naar “op aanvraag”.
beschikbaarheid (weekregels + uitzonderingen) − Google-bezet (gecachte vrij/bezet) − bestaande afspraken + hun buffer binnen [nu + opzegtermijn, nu + horizon] in stappen van de slot-granulariteit = boekbare slots, elk met hun modus
Postcode en gemeente worden gegeocodeerd (met cache, ook voor mislukkingen). Rijafstand via OpenRouteService, met terugval op hemelsbreed. Buiten het werkgebied is niet boekbaar; in de basisgemeente geldt een vast tarief, elders tarief per km, heen en terug.
Eén centrale functie schrijft de statusovergang weg en voert daarna de neveneffecten uit — Google, mails, facturatie — in een try/catch, zodat een mislukte mail de statuswijziging nooit breekt. Een tegenvoorstel krijgt een geheime token die na één klik in de mail opbrandt; dat is de enige uitzondering op “geen klant-login”.
aangevraagd ──▶ bevestigd ──▶ uitgevoerd
│ │
▼ ▼
geweigerd geannuleerdMail via PHPMailer en SMTP, elke poging gelogd. Alle klantmails gaan automatisch — ontvangst, bevestiging, voorstel, weigering, annulatie — met een blinde kopie voor de technieker. Push naar iPhone via APNs, met een wachtrij die mislukte meldingen opnieuw probeert.
Drie taken: de vrij/bezet-cache warm houden (elk kwartier), de GDPR-bewaartermijn toepassen (dagelijks) en de push-wachtrij leegmaken (elke minuut).
05Uitgangspunten
De privé-agenda blijft dicht — alleen vrij of bezet telt mee. GDPR-tekst, toestemming en een bewaartermijn zitten ingebouwd.
De enige uitzondering is de éénklik-bevestiglink bij een tegenvoorstel: een geheime token die opbrandt na gebruik.
Tarieven, teksten, werkgebied en taal staan in de beheeromgeving. Niets hardgecodeerd — alles blijft aanpasbaar zonder de code aan te raken.
Nederlandstalig, met Engels, Frans en Duits voorzien in de structuur.