Skip to content

Fase 1a: Platformkern

36 user stories, 13 scenario’s + 5 edge cases.

Een nieuwe klant doorloopt de complete 3-stappen onboarding na registratie.

Dekt: 1a.1.1, 1a.1.2, 1a.1.3, 1a.1.4, 1a.1.5, 1a.1.6, 1a.1.7, 1a.1.8, 1a.1.9

Voorwaarden: Klant net geregistreerd, redirect naar /onboarding

  1. Check voortgangsbalk bovenaan met 3 stappen.
  2. Stap 1 “Jouw gegevens”: vul voornaam, achternaam, telefoonnummer, WhatsApp nummer (optioneel), adres, stad, noodcontact naam, noodcontact telefoon en notities (optioneel) in.
  3. Probeer door te gaan met lege verplichte velden. Check inline foutmeldingen per veld (bijv. “Voornaam is verplicht”).
  4. Vul een ongeldig telefoonnummer in. Check foutmelding “Voer een geldig telefoonnummer in.”
  5. Vul een WhatsApp nummer in met geldig internationaal format.
  6. Vul alle velden correct in, klik “Volgende”.
  7. Check dat gegevens worden opgeslagen via PATCH /api/clients/:id.
  8. Stap 2 “Je hond(en)”: vul basisgegevens in: naam, ras, geboortedatum, geslacht (Reu/Teef), gewicht (kg), kleur. Optioneel: gesteriliseerd/gecastreerd, microchipnummer, hondenpaspoort nummer, foto.
  9. Vul dierenarts in: naam dierenarts (verplicht), naam kliniek (optioneel), telefoonnummer (verplicht).
  10. Vul voedingsschema in: voedingsmerk, hoeveelheid, tijden (alle verplicht), bijzonderheden (optioneel).
  11. Vul medische info in: medische aandoeningen, medicijnen, allergieen (alle optioneel), verzekerd checkbox.
  12. Beschrijf gedrag in vrij tekstveld (optioneel).
  13. Upload vaccinaties (DHLPP, Bordetella, Rabies): per vaccin datum toegediend, vervaldatum en document (alle verplicht per vaccin).
  14. Check dat verified_by_admin standaard false is bij elke vaccinatie.
  15. Check dat onderaan het formulier een knop “Nog een hond toevoegen” staat. Klik erop en controleer dat een leeg hondformulier verschijnt.
  16. Klik “Volgende” om naar stap 3 te gaan.
  17. Stap 3 “Voorwaarden”: check twee scrollbare tekstvakken (algemene voorwaarden/huisregels en aansprakelijkheidsverklaring).
  18. Probeer op “Afronden” te klikken zonder checkbox. Check foutmelding “Je moet akkoord gaan met de voorwaarden om verder te gaan.”
  19. Scroll naar beneden in beide tekstvakken. Vink checkbox aan: “Ik heb de algemene voorwaarden en huisregels gelezen en ga hiermee akkoord.”
  20. Klik “Afronden”. Check dat terms_accepted_at en onboarding_completed = true worden opgeslagen.
  21. Check dat een welkomstmail wordt verstuurd via Resend.
  22. Check redirect naar /dashboard.

Resultaat: Alle gegevens opgeslagen, vaccinaties wachten op admin verificatie, voorwaarden geaccepteerd, welkomstmail verstuurd, onboarding voltooid.

S-1a.2 Tweede hond toevoegen na onboarding

Section titled “S-1a.2 Tweede hond toevoegen na onboarding”

Een bestaande klant voegt een extra hond toe buiten de onboarding.

Dekt: 1a.1.10

Voorwaarden: Klant heeft onboarding voltooid

  1. Ga naar /dogs. Check knop “Hond toevoegen” bovenaan.
  2. Klik op “Hond toevoegen”, navigeert naar /dogs/new.
  3. Vul alle hondgegevens in (zelfde velden als onboarding stap 2).
  4. Upload vaccinaties.
  5. Klik opslaan. Check POST /api/dogs en POST /api/vaccinations.
  6. Check redirect naar /dogs met succesmelding “Hond toegevoegd.”
  7. Tweede hond verschijnt in de hondenlijst.

Resultaat: Tweede hond verschijnt in hondenlijst, vaccinaties wachten op verificatie.

S-1a.3 Hondprofielen en vaccinaties beheren

Section titled “S-1a.3 Hondprofielen en vaccinaties beheren”

Klant bekijkt en bewerkt hondprofielen en uploadt nieuwe vaccinaties.

Dekt: 1a.2.1, 1a.2.2, 1a.2.3, 1a.2.4

Voorwaarden: Klant heeft minstens 1 hond met vaccinaties

  1. Ga naar /dogs. Check overzicht met per hond een kaart: foto (of placeholder als geen foto geupload), naam, ras, leeftijd (berekend uit geboortedatum).
  2. Check vaccinatiestatus-indicator per hond: geldig (groen), bijna verlopen (oranje, binnen 30 dagen), verlopen (rood).
  3. Klik op een hond, navigeert naar /dogs/[id].
  4. Check profiel in readonly modus: alle gegevens gegroepeerd (basis, dierenarts, voeding, medisch, gedrag).
  5. Check vaccinatielijst per vaccin: status, datum, vervaldatum, geupload document.
  6. Check bezoekhistorie: de laatste 5 boekingen van deze hond.
  7. Klik “Vaccinatie uploaden” bij een vaccin. Check modal/inline formulier met datum, vervaldatum en document upload.
  8. Upload een vaccinatiebewijs. Check dat het verschijnt met status “In afwachting van goedkeuring” (verified_by_admin = false).
  9. Klik “Bewerken”, navigeert naar /dogs/[id]/edit.
  10. Bewerk een veld (bijv. gewicht), klik opslaan via PATCH /api/dogs/:id.
  11. Check redirect naar /dogs/[id] met succesmelding en gewijzigde waarde.

Resultaat: Hondenlijst toont correcte status en placeholder foto, profiel readonly met bewerkmogelijkheid, vaccinaties uploadbaar.

Klant bekijkt dashboard met boekingen, facturen en vaccinatiestatus.

Dekt: 1a.3.1, 1a.3.2

Voorwaarden: Klant heeft boekingen, facturen en honden

  1. Ga naar /dashboard.
  2. Check blok “Aankomende boekingen”: max 3 getoond met hond(en), dienst, datum, status.
  3. Als geen boekingen: check melding “Geen aankomende boekingen” met link naar “Nieuwe boeking” (/bookings/new).
  4. Check blok “Openstaande facturen”: per factuur factuurnummer, bedrag, status. Totaalbedrag bovenaan als er openstaande facturen zijn. Link “Alle facturen” naar /invoices.
  5. Check blok “Vaccinatiestatus”: honden met verlopen of bijna verlopen vaccinaties, per hond naam + welk vaccin aandacht nodig heeft, link naar hondprofiel.
  6. Check snelkoppeling “Nieuwe boeking” navigeert naar /bookings/new.
  7. Check snelkoppeling “Facturen betalen” navigeert naar /invoices (gefilterd op openstaand).

Resultaat: Dashboard toont relevante info in vier blokken, snelkoppelingen werken, vaccinatiestatus zichtbaar.

Systeem maakt een factuur aan met correcte berekeningen inclusief meerdere diensten.

Dekt: 1a.4.1, 1a.4.2, 1a.4.3, 1a.4.4, 1a.4.8

Voorwaarden: Boeking bevestigd

  1. Bevestig een boeking. Systeem maakt factuur aan.
  2. Check factuurnummer format: jaarXXXXXX (auto-increment).
  3. Check factuurregels: per hond per dienst een regel met beschrijving, eenheid, aantal, bedrag.
  4. Maak een boeking met meerdere diensten voor dezelfde hond. Check dat elke dienst een eigen factuurregel heeft.
  5. Check subtotaal.
  6. Check BBO (6%) en BAZV (1.5%) apart uitgesplitst onder het subtotaal.
  7. Check totaalbedrag (subtotaal + BBO + BAZV).
  8. Check bankgegevens Dog Hotel Aruba op de factuur.
  9. Check klantgegevens op de factuur.
  10. Wijzig de prijs van een dienst in instellingen.
  11. Controleer dat de bestaande factuur de oude prijs behoudt (snapshot). Nieuwe boekingen gebruiken de nieuwe prijs.

Resultaat: Factuurnummer correct, factuurregels per hond per dienst, BBO en BAZV apart getoond, bankgegevens aanwezig, prijssnapshot werkt.

Klant filtert en bekijkt eigen facturen.

Dekt: 1a.4.5

Voorwaarden: Klant heeft meerdere facturen (betaald + openstaand)

  1. Ga naar /invoices.
  2. Check filters (tabs of dropdown): Alle, Openstaand, Betaald, Verlopen.
  3. Bij filter “Openstaand”: check totaal openstaande bedrag bovenaan.
  4. Per factuur in de lijst: factuurnummer, datum, bedrag (incl. BBO en BAZV), status-badge (openstaand geel, betaald groen, verlopen rood).
  5. Filter op “Betaald”, alleen betaalde facturen zichtbaar.
  6. Filter op “Openstaand”, alleen openstaande zichtbaar.
  7. Filter op “Verlopen”, facturen voorbij betaaltermijn.
  8. Klik op een factuur, navigeert naar /invoices/[id].
  9. Check factuurdetail: factuurnummer, factuurdatum, vervaldatum, hotelgegevens, klantgegevens, factuurregels, subtotaal, BBO, BAZV, totaalbedrag, betaalstatus.
  10. Bij openstaande factuur: check knop “Betalen” en knop “PDF downloaden”.
  11. Bij betaalde factuur: alleen “PDF downloaden” zichtbaar.

Resultaat: Filters werken correct, juiste facturen getoond, detail toont volledige factuurinfo.

Admin bekijkt alle facturen en genereert een PDF.

Dekt: 1a.4.6, 1a.4.7

Voorwaarden: Facturen bestaan in het systeem

  1. Log in als admin.
  2. Ga naar /admin/invoices.
  3. Check filters: openstaand, betaald, verlopen.
  4. Check totaalbedragen per filtergroep bovenaan.
  5. Check tabel: factuurnummer, klant, datum, bedrag, status.
  6. Check knop “PDF genereren” per factuur.
  7. Check CSV export knop (voor de boekhouder).
  8. Klik “PDF genereren” op een factuur. Check dat PDF correct opent met alle factuurgegevens (via Forme PDF / Rust WASM op CF Workers).
  9. Open factuurdetail /admin/invoices/[id]. Check dezelfde info als klant ziet plus extra acties.
  10. Check knop “Herinnering sturen” bij openstaande/verlopen facturen. Stuurt herinneringsmail met betaallink.

Resultaat: Admin ziet alle facturen, filters werken, totaalbedragen per groep, PDF genereert correct, CSV export beschikbaar.

Klant betaalt een factuur online via Sentoo, webhook verwerkt betaling.

Dekt: 1a.5.1, 1a.5.2, 1a.5.3

Voorwaarden: Openstaande factuur

  1. Klant opent factuur op /invoices/[id], klikt op “Betalen”.
  2. Check dat POST /api/invoices/:id/pay wordt aangeroepen. API roept Sentoo aan en retourneert payment_url en QR code.
  3. Check tussenpagina: te betalen bedrag, QR code (voor mobiel bankieren), knop “Ga naar betalen”.
  4. Klik “Ga naar betalen”. Redirect naar Sentoo betaalpagina.
  5. Kies bank (Aruba Bank / CMB / Banco di Caribe).
  6. Voltooi betaling in bankapp.
  7. Sentoo stuurt webhook naar POST /api/payments/webhook.
  8. Check signature verificatie (x-sentoo-signature header met SENTOO_WEBHOOK_SECRET).
  9. Check dat factuur automatisch als “betaald” gemarkeerd wordt.
  10. Check dat bevestigingsmail naar klant wordt verstuurd.
  11. Stuur dezelfde webhook nogmaals. Check idempotentie (geen dubbele verwerking, factuur al betaald).
  12. Klant keert terug naar portaal en ziet factuur als “Betaald”.

Resultaat: Betaallink werkt, tussenpagina toont bedrag en QR, webhook verwerkt correct, idempotent, factuur gemarkeerd als betaald, bevestigingsmail verstuurd.

Admin markeert een factuur als betaald bij cash/pin betaling via een modal.

Dekt: 1a.5.4, 1a.5.5

Voorwaarden: Openstaande factuur, klant betaalt ter plekke

  1. Log in als admin, ga naar /admin/invoices.
  2. Open een openstaande factuur op /admin/invoices/[id].
  3. Klik “Markeer als betaald”.
  4. Check dat een modal verschijnt met: keuze betaalmethode (Cash / PIN) en het bedrag ter bevestiging.
  5. Selecteer “Cash” en bevestig.
  6. Check PATCH /api/admin/invoices/:id/mark-paid met methode, tijdstip en medewerker-ID.
  7. Check dat de factuur nu als “betaald” gemarkeerd is.
  8. Check dat de klant een bevestigingsmail ontvangt.
  9. Ga naar factuuroverzicht, filter op betaald. Check dat de factuur daar staat.

Resultaat: Handmatige betaling geregistreerd via modal met methode-keuze en bedragbevestiging, tijdstip en medewerker vastgelegd, bevestigingsmail verstuurd.

Systeem verstuurt emails op de juiste momenten in de juiste taal.

Dekt: 1a.6.1, 1a.6.2, 1a.6.3, 1a.6.4, 1a.6.5

Voorwaarden: Resend geconfigureerd, React Email templates aanwezig

  1. Registreer een nieuwe klant en rond onboarding af. Check welkomstmail met link naar het portaal.
  2. Check dat de link in de welkomstmail het juiste domein heeft (productie of staging).
  3. Maak een boeking. Check boekingsbevestigingsmail met boekingsdetails, datum, hond(en) en betaallink.
  4. Betaal de factuur. Check betaalbevestigingsmail met factuurnummer en bedrag.
  5. Controleer dat admin een notificatie ontvangt bij nieuwe boeking (met link naar de boeking).
  6. Wissel taal naar EN in klantprofiel. Trigger een nieuwe email. Check dat de email in het Engels is.
  7. Wissel terug naar NL, trigger email. Check dat de email in het Nederlands is.
  8. Controleer dat templates variabelen correct vullen (naam, bedrag, datum etc.).

Resultaat: Alle trigger-emails worden verstuurd in de juiste taal met correcte data en werkende links.

Admin zoekt klanten, bekijkt profielen en beheert hondgegevens.

Dekt: 1a.7.1, 1a.7.2, 1a.7.3, 1a.7.4, 1a.7.5

Voorwaarden: Meerdere klanten en honden in het systeem

  1. Ga naar /admin/clients. Check zoekbalk bovenaan.
  2. Zoek op naam, vind klant. Zoek op email, zelfde klant. Zoek op telefoon, zelfde klant.
  3. Check klanttabel: naam, aantal honden, laatste boeking, status (actief / onboarding niet voltooid).
  4. Open klantprofiel op /admin/clients/[id].
  5. Check secties: persoonsgegevens (bewerkbaar via “Bewerken” knop), honden met vaccinatiestatus, boekingshistorie (nieuwste eerst), factuuroverzicht met totaal openstaand.
  6. Bewerk een klantgegeven, klik “Opslaan”. Check PATCH /api/admin/clients/:id en succesmelding.
  7. Ga naar /admin/dogs. Check zoekbalk (hondnaam of eigenaar) en filter op vaccinatiestatus.
  8. Check hondentabel: naam, ras, eigenaar, vaccinatiestatus.
  9. Open een hondprofiel op /admin/dogs/[id].
  10. Bewerk gegevens, opslaan.
  11. Check veld “Bijzonderheden” (special_notes). Vul tekst in en sla op.
  12. Check dat special_notes NIET zichtbaar is voor de klant in het klantportaal.
  13. Check dat special_notes WEL getoond wordt bij de volgende check-in van die hond.
  14. Ga naar vaccinaties. Klik “Goedkeuren” bij een vaccinatie. Check PATCH /api/admin/vaccinations/:id met verified_by_admin = true.
  15. Check dat de vaccinatiestatus direct bijwerkt in de UI.
  16. Voeg handmatig een vaccinatie toe via “Vaccinatie toevoegen” (voor fysiek meegebrachte bewijzen).

Resultaat: Zoeken werkt op naam, email en telefoon, profiel toont volledige info, special_notes alleen admin-zichtbaar en beschikbaar bij check-in, vaccinaties verificeerbaar.

Admin beheert diensten, contactgegevens en medewerkers.

Dekt: 1a.8.1, 1a.8.2, 1a.8.3

Voorwaarden: Admin ingelogd

  1. Ga naar /admin/settings.
  2. Open tab/sectie “Diensten”. Check tabel: naam, type (single/bundle/subscription), prijs, eenheid, actief/inactief.
  3. Klik “Nieuwe dienst”. Vul naam, beschrijving, prijs, eenheid (per dag/nacht/les/maand), type in. Check POST /api/admin/services.
  4. Nieuwe dienst verschijnt in de lijst.
  5. Toggle een dienst naar “inactief”. Check dat die dienst niet meer zichtbaar is voor klanten.
  6. Bewerk een prijs via “Dienst bewerken”, opslaan. Check PATCH /api/admin/services/:id.
  7. Open tab “Contactgegevens”. Vul hotelnaam, upload logo, adres, telefoonnummer, email in. Check PATCH /api/admin/settings.
  8. Check dat deze gegevens op facturen en in emails verschijnen.
  9. Open tab “Medewerkers”. Check lijst met naam, email, rol.
  10. Klik “Medewerker toevoegen”. Vul naam, email en rol (admin / medewerker / trainer) in. Check POST /api/admin/users.
  11. Check dat de medewerker een uitnodigingsmail ontvangt met link om wachtwoord in te stellen.
  12. Log in als medewerker met rol “trainer”. Check dat trainer lessen kan inplannen en notities kan toevoegen bij trainingen.
  13. Check dat trainer GEEN toegang heeft tot /admin/settings (instellingen) en financieel overzicht.
  14. Deactiveer een medewerker. Check dat die niet meer kan inloggen.

Resultaat: Diensten beheerbaar met types en eenheden, deactivatie werkt, contactgegevens op facturen, medewerkerrollen correct: trainer kan lessen beheren maar geen instellingen wijzigen.

Klant bewerkt persoonlijke gegevens en instellingen.

Dekt: 1a.9.1, 1a.9.2, 1a.9.3

Voorwaarden: Klant ingelogd

  1. Ga naar /account.
  2. Check sectie “Persoonlijke gegevens”: dezelfde velden als stap 1 van de onboarding, voorgevuld.
  3. Bewerk naam, klik “Opslaan”. Check PATCH /api/clients/:id en succesmelding “Gegevens opgeslagen.”
  4. Bewerk adres en telefoon, opslaan.
  5. Check sectie “Wachtwoord wijzigen”: velden huidig wachtwoord, nieuw wachtwoord (min. 8 karakters), bevestig nieuw wachtwoord.
  6. Wijzig wachtwoord. Log uit. Log in met nieuw wachtwoord. Werkt.
  7. Probeer wachtwoord te wijzigen met fout huidig wachtwoord. Check foutmelding “Het huidige wachtwoord is onjuist.”
  8. Vul twee nieuwe wachtwoorden in die niet overeenkomen. Check foutmelding “Wachtwoorden komen niet overeen.”
  9. Vul nieuw wachtwoord in korter dan 8 tekens. Check foutmelding “Wachtwoord moet minimaal 8 karakters zijn.”
  10. Check sectie “Taalvoorkeur”: keuze NL/EN.
  11. Wijzig naar EN. Check dat de hele UI direct wisselt naar Engels en de voorkeur wordt opgeslagen.
  12. Wijzig terug naar NL.

Resultaat: Alle gegevens bewerkbaar, wachtwoord wijzigen werkt met correcte foutmeldingen, taalvoorkeur persistent en direct toegepast.

Klant stopt halverwege de onboarding en logt opnieuw in.

Versterkt: S-1a.1

  1. Start onboarding op /onboarding, vul stap 1 in, sluit browser zonder stap 2.
  2. Log opnieuw in. Check redirect naar /onboarding (niet naar /dashboard).
  3. Controleer dat stap 1 gegevens bewaard zijn (geen dubbele invoer).
  4. Rond stap 2 en 3 af. onboarding_completed = true.
  5. Log opnieuw in. Nu wel redirect naar /dashboard (niet meer naar onboarding).
  6. Probeer handmatig naar /onboarding te navigeren. Check redirect naar /dashboard.

Resultaat: State persistent over sessies, geen dubbele data, onboarding is eenmalig.

EC-3 Upload validatie (foto’s en documenten)

Section titled “EC-3 Upload validatie (foto’s en documenten)”

Foute bestanden uploaden bij hondprofiel en vaccinaties.

Versterkt: S-1a.1, S-1a.3

  1. Upload hondfoto groter dan max grootte. Foutmelding met limiet.
  2. Upload bestand met verkeerd formaat (bijv. .exe als foto). Geweigerd.
  3. Upload vaccinatiedocument groter dan limiet. Foutmelding.
  4. Upload vaccinatie met vervaldatum in het verleden. Waarschuwing (status meteen “verlopen”).
  5. Upload vaccinatie zonder vervaldatum. Verplicht veld fout.
  6. Controleer dat bestandsnaam gesanitiseerd wordt (geen path traversal).
  7. Ga naar /dogs. Check dat een hond zonder geuploadde foto een placeholder afbeelding toont.
  8. Upload een nieuw vaccinatiedocument voor een vaccin dat al een document heeft. Check dat het oude document wordt overschreven (re-upload).
  9. Check dat na re-upload het document weer op “In afwachting van goedkeuring” staat.

Resultaat: Alle uploads gevalideerd op type en grootte, placeholder bij ontbrekende foto, re-upload overschrijft correct en reset verificatie.

Testen van vaccinatiestatus op grensmomenten.

Versterkt: S-1a.3, S-2.7

  1. Vaccinatie die vandaag verloopt. Status “verlopen” of “geldig”? (definitie vastleggen)
  2. Vaccinatie die morgen verloopt. Status “bijna verlopen”.
  3. Vaccinatie exact 30 dagen voor verval. Reminder verstuurd.
  4. Vaccinatie 31 dagen voor verval. Nog geen reminder.
  5. Hond met 1 van 3 vaccinaties verlopen. Vaccinatiestatus hond = “verlopen” (striktste).
  6. Admin keurt vaccinatie goed (verified_by_admin = true). Klant uploadt daarna een nieuw document voor hetzelfde vaccin. Check dat verified_by_admin reset naar false.
  7. Check dat de admin opnieuw moet goedkeuren na de reset.

Resultaat: Grensgevallen consistent behandeld, striktste vaccin bepaalt hondstatus, nieuwe upload reset altijd de verificatiestatus.

EC-5 Belastingberekening en afrondingsfouten

Section titled “EC-5 Belastingberekening en afrondingsfouten”

Correcte AWG berekeningen bij oneven bedragen.

Versterkt: S-1a.5

  1. Dienst met prijs 33 AWG. BBO (6%) = 1,98. BAZV (1,5%) = 0,495. Check afronding.
  2. Meerdere factuurregels. Belasting per regel of over totaal? (consistentie)
  3. Factuur met korting. Belasting over bedrag NA korting.
  4. Factuurnummer: check dat nummering geen gaten heeft na een geannuleerde factuur.
  5. Twee facturen snel na elkaar aanmaken. Geen duplicaat factuurnummers (race condition).

Resultaat: Consistente afronding, belasting altijd na korting, geen gaten in nummering.

Alle foutpaden bij Sentoo betalingen.

Versterkt: S-1a.8

  1. Klant start betaling maar breekt af bij de bank. Factuur blijft “openstaand”.
  2. Sentoo stuurt webhook met ongeldige signature. 401, niet verwerkt.
  3. Sentoo stuurt webhook voor onbekende factuur. Gelogd, geen crash.
  4. Sentoo stuurt webhook met status “failed”. Factuur blijft openstaand, klant geinformeerd.
  5. Netwerk timeout tijdens webhook verwerking. Sentoo retry, idempotent afgehandeld.
  6. Betaallink verlopen. Klant ziet melding “Deze betaallink is verlopen.” en kan een nieuwe aanvragen.
  7. Dubbele webhook (retry door Sentoo). Geen dubbele betaalmarkering.
  8. Klant sluit browser tijdens betaling. Webhook komt alsnog binnen als betaling gelukt is, factuurstatus wordt bijgewerkt.

Resultaat: Geen enkele betaalfout leidt tot inconsistente data of crashes.