Case study · restaurantsoftware · businesskritische logica

Hoe ik een reserveringssysteem heb gefixt dat tafels soms dubbel “vrij” zag

Dit was geen klein UI-probleem, maar een fout in de kern van de beschikbaarheidslogica. In productie leek een tafel soms vrij terwijl ze in werkelijkheid al bezet was. Mijn ingreep zat daarom waar die moest zitten: in overlapdetectie, legacy fallback en de definitie van effectieve bezetting.

Kernprobleem

Dubbele boekingen

Een tafel die bezet was, verscheen soms als vrij — met als gevolg meerdere gasten op dezelfde tafel.

Impact op service

Verlies van vertrouwen

Het personeel kon tijdens drukke diensten niet meer vertrouwen op de beschikbaarheidsweergave.

Resultaat

Betrouwbare planning

Tafels worden alleen als vrij getoond wanneer ze dat werkelijk zijn — ook bij oudere reservaties.

Probleem

In productie loog het systeem soms over tafelbeschikbaarheid

We zagen een hardnekkig probleem: een tafel leek soms beschikbaar terwijl ze in werkelijkheid al bezet was. Niet bij elke reservatie, maar vooral bij oudere records en bij boekingen die niet netjes met een eindtijd waren opgeslagen.

Dat maakt zo'n bug gevaarlijk. Ze is niet luid, maar ondermijnt wel precies het vertrouwen dat een restaurant nodig heeft tijdens drukke service-uren.

Business impact

Het risico zat niet alleen in een fout scherm, maar in dubbele boekingen op momenten waarop het systeem juist zekerheid moest bieden.

Analyse

De fout zat in de manier waarop beschikbaarheid gemodelleerd werd

Beschikbaarheid werd te simplistisch geëvalueerd op tijdslotniveau.

Oudere reservaties zonder Tot-tijd vielen buiten de check en creëerden blind spots.

De UI toonde een symptoom, maar de fout zat in datamodel en servicelogica.

Een tafel moest worden beoordeeld op overlap en effectieve bezetting, niet op nette records alleen.

Mijn conclusie was snel duidelijk: dit moest niet worden weggewerkt met extra UI-condities. Dit was een businesslogica- en datamodelprobleem dat centraal opgelost moest worden.

Oplossing

Van simplistische slotcheck naar echte overlapcontrole

De kern van de fix was eenvoudig in formule, maar belangrijk in betekenis: niet vergelijken op gelijke tijdstippen, wel controleren of twee reservaties elkaar werkelijk overlappen.

Overlaplogica

bool hasOverlap = startNode < reservationEnd && reservationStart < endNode;

Fallback voor legacy data

if (reservation.Tot.HasValue)
{
    reservationEnd = reservation.Tot.Value;
}
else
{
    var duurMinuten = await _tijdslotService.GetTijdslotDuurAsync(
        restaurantId,
        reservation.Van);

    reservationEnd = duurMinuten.HasValue
        ? reservation.Van.AddMinutes(duurMinuten.Value)
        : reservation.Van.AddHours(3);
}

Overlapdetectie in beeld

Waarom exacte tijdstippen niet volstaan

Vóór: enkel tijdslot vergelijken

Reservatie A : [18:00 ──────── 20:00]

Aanvraag B : [19:00 ──── 21:00]

→ Zelfde slot? Nee → foutief vrij gemeld

Na: overlap controleren

Reservatie A : [18:00 ──────── 20:00]

Aanvraag B : [19:00 ──── 21:00]

→ startA < eindB && startB < eindA → ✓ conflict

Legacy fallback (geen eindtijd)

Reservatie zonder Tot:

→ Tot = Van + tijdslotduur uit config

→ Fallback: Van + 3 uur (conservatief)

Trade-off

Bewuste keuze in de servicelaag

Pro

Correcte beschikbaarheidscontrole voor zowel actuele als historische reservaties.

Con

Meer logica in de servicelaag en een extra afhankelijkheid van tijdslotconfiguratie. Dat is verantwoord, omdat correctheid hier zwaarder weegt dan abstracte eenvoud.

Wat mee in scope moest

Beschikbaarheid is meer dan reservaties vergelijken

Ik heb het hele tafelsysteem mee opgenomen in de evaluatie, inclusief walk-ins en gekoppelde tafels. Daardoor beoordeelt het platform niet alleen boekingen, maar de effectieve bezetting van de zaal.

Architectuurstandpunt

Beschikbaarheid is geen presentatielogica. Het is businesskritische infrastructuur die consistent moet zijn voor elke flow die reservaties leest, schrijft of wijzigt.

Resultaat

Het systeem stopte met liegen over beschikbaarheid

Oude reservaties breken de berekening niet langer.

Tafels worden niet meer onterecht als beschikbaar gepresenteerd.

De logica sluit aan op restaurantrealiteit in plaats van op ideale invoer.

Het team kan opnieuw vertrouwen op de beschikbaarheidsweergave tijdens piekmomenten.

Voor het team woog dat zwaarder dan een perfect abstracte implementatie. In restaurantsoftware is betrouwbaarheid de feature, niet alleen de interface errond.

Lessons learned

Wat ik hieruit meeneem voor elk reserveringssysteem

Reservaties zijn nooit alleen een tijdslotprobleem. Zodra data groeit en historische uitzonderingen zich opstapelen, wordt een simpele check op “zelfde dag en zelfde uur” een bron van fouten.

Controleer overlap, niet enkel exacte tijdstippen.

Voorzie expliciete fallback voor oude of onvolledige data.

Modelleer gekoppelde tafels en walk-ins als deel van bezetting.

Plaats deze logica in services, niet in views of componenten.

Testmatrix

Wat ik minimaal zou testen voor livegang

Reservaties zonder eindtijd die terugvallen op tijdslotconfiguratie.

Deels overlappende boekingen die niet exact op hetzelfde uur starten.

Walk-ins die een tafel innemen zonder klassieke reservatieflow.

Reservaties die meerdere gekoppelde tafels blokkeren.

Takeaway

Als je een reserveringssysteem bouwt, dan is beschikbaarheid geen presentatielogica maar bedrijfskritische infrastructuur.

Zodra legacy data, reële overlap en zaalbezetting samenkomen, moet je systeem daar expliciet op ontworpen zijn. Alles daaronder is tijdelijk geluk, geen betrouwbare software.

Veelgestelde vragen

Waarom is een overlapcontrole beter dan een check op hetzelfde tijdslot?
Omdat restaurants niet in perfecte blokken werken. Een reservatie van 18:30 tot 20:45 kan perfect overlappen met een aanvraag om 20:00. Wie alleen dezelfde start- of eindtijd vergelijkt, mist dat soort conflicten.
Waarom is legacy data zo gevaarlijk voor beschikbaarheidslogica?
Omdat historische records vaak afwijken van de huidige datastandaard. Zodra eindtijden ontbreken of vroeger anders werden opgeslagen, krijg je foutieve vrijmeldingen tenzij je expliciet een fallback voorziet.
Hoort deze logica in de UI thuis?
Nee. De UI mag beschikbaarheid tonen, maar niet bepalen. Dit soort regels hoort in de servicelaag zodat elke consumer van dezelfde, correcte businesslogica gebruikmaakt.
Is een vaste fallback van drie uur niet te simplistisch?
Dat is bewust de laatste veiligheidsnet-optie. Eerst wordt de duur uit de tijdslotconfiguratie gehaald. Alleen wanneer die ontbreekt, wordt een conservatieve standaard gebruikt om het risico op dubbele boekingen te minimaliseren.
Mitch

Werk jij met software die in productie nét te vaak uitzonderingen verkeerd interpreteert?

Plan een vrijblijvende digitale kennismaking met Mitch en ontdek wat wij voor jouw organisatie kunnen betekenen.