Fase 1a: Platformkern
Fase 1a bouwt de gedeelde basis die alle diensten nodig hebben: klant-onboarding, hondprofielen met vaccinaties, het complete facturatiesysteem, online betalen via Sentoo, emailnotificaties en het basisbeheer voor admins. Na deze fase kan de eerste dienst (trainingen, Fase 1b) live.
1. Onboarding flow
Section titled “1. Onboarding flow”Route: /onboarding
De onboarding is verplicht voor elke nieuwe klant. Zolang onboarding_completed = false is, wordt de klant bij elke login hierheen gestuurd. De flow bestaat uit drie stappen met een voortgangsbalk bovenaan.
Stap 1: Jouw gegevens
Section titled “Stap 1: Jouw gegevens”Wat de gebruiker ziet:
Een formulier met persoonlijke gegevens en noodcontact.
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
| Voornaam | text | Ja | |
| Achternaam | text | Ja | |
| Telefoonnummer | tel | Ja | |
| WhatsApp nummer | tel | Nee | Vaak hetzelfde als telefoon |
| Adres | text | Ja | |
| Stad | text | Ja | |
| Noodcontact naam | text | Ja | |
| Noodcontact telefoon | tel | Ja | |
| Notities | textarea | Nee | Vrij tekstveld |
Onderaan: knop “Volgende” om naar stap 2 te gaan.
Wat er gebeurt:
- Client-side validatie met Zod. Verplichte velden worden gecontroleerd, telefoonnummers op geldig formaat.
- Bij “Volgende”: de gegevens worden opgeslagen via
PATCH /api/clients/:id. De klant kan later terugkomen en verder gaan. - Bij succesvolle opslag: doorsturen naar stap 2.
Foutmeldingen:
Inline per veld, bijvoorbeeld “Voornaam is verplicht” of “Voer een geldig telefoonnummer in.”
Stap 2: Je hond(en)
Section titled “Stap 2: Je hond(en)”Wat de gebruiker ziet:
Een uitgebreid formulier om de eerste hond toe te voegen. De velden zijn gegroepeerd in secties.
Basisgegevens:
| Veld | Type | Verplicht |
|---|---|---|
| Naam | text | Ja |
| Ras | text | Ja |
| Geboortedatum | date | Ja |
| Geslacht | select (Reu/Teef) | Ja |
| Gesteriliseerd/gecastreerd | checkbox | Nee |
| Gewicht (kg) | number | Ja |
| Kleur | text | Ja |
| Microchipnummer | text | Nee |
| Hondenpaspoort nummer | text | Nee |
| Foto | file upload | Nee |
Dierenarts:
| Veld | Type | Verplicht |
|---|---|---|
| Naam dierenarts | text | Ja |
| Naam kliniek | text | Nee |
| Telefoonnummer | tel | Ja |
Voeding:
| Veld | Type | Verplicht |
|---|---|---|
| Voedingsmerk | text | Ja |
| Hoeveelheid | text | Ja |
| Tijden | text | Ja |
| Bijzonderheden | textarea | Nee |
Medisch:
| Veld | Type | Verplicht |
|---|---|---|
| Medische aandoeningen | textarea | Nee |
| Medicijnen | textarea | Nee |
| Allergieen | textarea | Nee |
| Verzekerd | checkbox | Nee |
Gedrag:
| Veld | Type | Verplicht |
|---|---|---|
| Gedragsnotities | textarea | Nee |
Een vrij tekstveld waar de klant beschrijft hoe de hond zich gedraagt met andere honden, met mensen en eventuele bijzondere aandachtspunten.
Vaccinaties:
Per vaccin (DHLPP, Bordetella, Rabies):
| Veld | Type | Verplicht |
|---|---|---|
| Datum toegediend | date | Ja (per vaccin) |
| Vervaldatum | date | Ja |
| Document | file upload | Ja |
De vaccinaties worden opgeslagen met verified_by_admin = false. Een admin moet ze later goedkeuren.
Nog een hond toevoegen:
Onderaan het formulier staat een knop “Nog een hond toevoegen”. Hiermee verschijnt hetzelfde formulier opnieuw, leeg, voor de volgende hond. Er is geen limiet in de app, maar het papieren formulier ondersteunt max 3 honden in de onboarding.
Knoppen: “Vorige” (terug naar stap 1), “Volgende” (naar stap 3).
Wat er gebeurt:
- Bij “Volgende”:
POST /api/dogsper hond met alle gegevens. Vaccinatiedocumenten worden geupload naar Supabase Storage. - Per vaccinatie:
POST /api/vaccinationsmet datum, vervaldatum en bestandsreferentie.
Stap 3: Voorwaarden
Section titled “Stap 3: Voorwaarden”Wat de gebruiker ziet:
- Een scrollbaar tekstvak met de algemene voorwaarden en huisregels van Dog Hotel Aruba.
- Een scrollbaar tekstvak met de aansprakelijkheidsverklaring.
- Checkbox: “Ik heb de algemene voorwaarden en huisregels gelezen en ga hiermee akkoord.”
- Knop “Afronden”
De checkbox is verplicht. Zonder akkoord kan de onboarding niet worden afgerond.
Wat er gebeurt:
- Bij “Afronden”:
PATCH /api/clients/:idmetterms_accepted_at = now()enonboarding_completed = true. - Er wordt een welkomstmail verstuurd via Resend.
- Redirect naar
/dashboard.
Foutmeldingen:
| Situatie | Melding |
|---|---|
| Checkbox niet aangevinkt | ”Je moet akkoord gaan met de voorwaarden om verder te gaan.” |
| Server error | ”Er ging iets mis bij het opslaan. Probeer het opnieuw.” |
2. Hond toevoegen flow
Section titled “2. Hond toevoegen flow”Route: /dogs/new
Wat de gebruiker ziet
Section titled “Wat de gebruiker ziet”Hetzelfde formulier als stap 2 van de onboarding, maar dan als losse pagina. De klant kan na de onboarding extra honden toevoegen.
Wat er gebeurt
Section titled “Wat er gebeurt”- Client-side validatie.
POST /api/dogsmet alle gegevens.- Vaccinaties worden apart opgeslagen via
POST /api/vaccinations. - Na succes: redirect naar
/dogsmet een succesmelding “Hond toegevoegd.”
Foutmeldingen
Section titled “Foutmeldingen”Dezelfde inline validatie als bij de onboarding. Bij een serverfout: “Er ging iets mis. Probeer het opnieuw.”
3. Hondprofiel bekijken en bewerken
Section titled “3. Hondprofiel bekijken en bewerken”Overzicht: /dogs
Section titled “Overzicht: /dogs”Wat de gebruiker ziet:
Een lijst van alle honden van de klant. Per hond een kaart met:
- Foto (of placeholder als er geen foto is)
- Naam
- Ras
- Leeftijd (berekend uit geboortedatum)
- Vaccinatiestatus-indicator: geldig (groen), bijna verlopen (oranje, binnen 30 dagen), verlopen (rood)
Bovenaan: knop “Hond toevoegen” die naar /dogs/new gaat.
Detail: /dogs/[id]
Section titled “Detail: /dogs/[id]”Wat de gebruiker ziet:
Het volledige hondprofiel in readonly modus:
- Alle profielgegevens gegroepeerd (basis, dierenarts, voeding, medisch, gedrag)
- Vaccinaties: een lijst per vaccin met status, datum, vervaldatum en eventueel het geuploade document
- Upload-knop om een nieuw vaccinatiebewijs toe te voegen
- Bezoekhistorie: de laatste 5 boekingen van deze hond
- Knop “Bewerken” die naar
/dogs/[id]/editgaat
Vaccinatiebewijs uploaden:
- Klant klikt op “Vaccinatie uploaden” bij het betreffende vaccin.
- Er opent een modal of inline formulier met: datum, vervaldatum, document upload.
- Bij opslaan:
POST /api/vaccinationsmetverified_by_admin = false. - De vaccinatie verschijnt in de lijst met status “In afwachting van goedkeuring”.
Bewerken: /dogs/[id]/edit
Section titled “Bewerken: /dogs/[id]/edit”Wat de gebruiker ziet:
Hetzelfde formulier als bij het toevoegen van een hond, maar voorgevuld met de bestaande gegevens.
Wat er gebeurt:
- Bij opslaan:
PATCH /api/dogs/:idmet de gewijzigde velden. - Na succes: redirect naar
/dogs/[id]met succesmelding.
4. Klant dashboard
Section titled “4. Klant dashboard”Route: /dashboard
Wat de gebruiker ziet
Section titled “Wat de gebruiker ziet”Een overzichtspagina met vier blokken:
Aankomende boekingen (max 3):
- Per boeking: hond(en), dienst, datum, status
- Als er geen boekingen zijn: “Geen aankomende boekingen” met een link naar “Nieuwe boeking”
Openstaande facturen:
- Per factuur: factuurnummer, bedrag, status
- Als er openstaande facturen zijn: totaalbedrag bovenaan
- Link “Alle facturen” naar
/invoices
Vaccinatiestatus:
- Honden met verlopen of bijna verlopen vaccinaties
- Per hond: naam + welk vaccin aandacht nodig heeft
- Link naar het betreffende hondprofiel
Snelkoppelingen:
- Knop “Nieuwe boeking” naar
/bookings/new - Knop “Facturen betalen” naar
/invoices(gefilterd op openstaand)
5. Factuur bekijken en betalen
Section titled “5. Factuur bekijken en betalen”Overzicht: /invoices
Section titled “Overzicht: /invoices”Wat de gebruiker ziet:
Een lijst met alle facturen, filterbaar op status.
Filters (tabs of dropdown):
- Alle
- Openstaand
- Betaald
- Verlopen
Bovenaan bij “Openstaand”: het totaal openstaande bedrag.
Per factuur in de lijst:
- Factuurnummer (format: jaarXXXXXX)
- Datum
- Bedrag (incl. BBO en BAZV)
- Status-badge: openstaand (geel), betaald (groen), verlopen (rood)
Klikken op een factuur opent de detailpagina.
Detail: /invoices/[id]
Section titled “Detail: /invoices/[id]”Wat de gebruiker ziet:
De volledige factuur:
- Factuurnummer, factuurdatum, vervaldatum
- Gegevens Dog Hotel Aruba (naam, adres, bankgegevens)
- Klantgegevens
- Factuurregels: per hond per dienst een regel met beschrijving, eenheid, aantal, bedrag
- Subtotaal
- BBO (6%) en BAZV (1.5%) apart uitgesplitst
- Totaalbedrag
- Betaalstatus
Als de factuur openstaand is:
- Knop “Betalen” die de Sentoo betaalflow start (zie sectie 6)
- Knop “PDF downloaden”
Als de factuur betaald is:
- Alleen “PDF downloaden”
6. Sentoo betaalflow (klant perspectief)
Section titled “6. Sentoo betaalflow (klant perspectief)”Deze flow start wanneer een klant klikt op “Betalen” bij een openstaande factuur, of wanneer een betaallink per email is ontvangen.
Stap voor stap
Section titled “Stap voor stap”-
Klant klikt op “Betalen” in het portaal of opent de betaallink uit de email.
-
De app maakt een Sentoo transactie aan:
POST /api/invoices/:id/pay. De API roept Sentoo aan met bedrag, beschrijving en vervaldatum. Sentoo retourneert eenpayment_urlen QR code. -
De klant ziet een tussenpagina met:
- Het te betalen bedrag
- Een QR code (voor mobiel bankieren)
- Een knop “Ga naar betalen” die doorlinkt naar de Sentoo betaalpagina
-
Op de Sentoo tussenpagina kiest de klant zijn bank: Aruba Bank, CMB, Banco di Caribe, etc.
-
De klant wordt doorgestuurd naar zijn eigen bankapp en autoriseert de betaling met PIN, vingerafdruk of token.
-
Na betaling stuurt Sentoo een webhook naar
POST /api/payments/webhook:- De API verifieert de
x-sentoo-signatureheader. - De API checkt of de factuur niet al betaald is (idempotent).
- De factuurstatus wordt bijgewerkt naar “betaald”.
- Er wordt een bevestigingsmail gestuurd naar de klant.
- De API verifieert de
-
De klant keert terug naar het portaal en ziet de factuur als “Betaald”.
Foutmeldingen en edge cases
Section titled “Foutmeldingen en edge cases”| Situatie | Wat er gebeurt |
|---|---|
| Betaling mislukt bij de bank | Sentoo stuurt status failed. De klant krijgt een melding en kan opnieuw proberen. |
| Betaallink verlopen | De klant ziet “Deze betaallink is verlopen.” Er kan een nieuwe link worden aangemaakt. |
| Klant sluit browser tijdens betaling | De webhook komt alsnog binnen als de betaling is gelukt. De factuurstatus wordt bijgewerkt. |
| Dubbele webhook | De API is idempotent: als de factuur al betaald is, wordt de webhook genegeerd. |
7. Admin klantenbeheer
Section titled “7. Admin klantenbeheer”Overzicht: /admin/clients
Section titled “Overzicht: /admin/clients”Wat de admin ziet:
- Zoekbalk bovenaan: zoeken op naam, email of telefoonnummer.
- Een tabel met alle klanten:
| Kolom | Omschrijving |
|---|---|
| Naam | Voor- en achternaam |
| Honden | Aantal honden (of namen) |
| Laatste boeking | Datum van de meest recente boeking |
| Status | Accountstatus (actief, onboarding niet voltooid) |
- Knop “Klant toevoegen” (deze functionaliteit komt in Fase 2, knop is zichtbaar maar nog niet actief).
Detail: /admin/clients/[id]
Section titled “Detail: /admin/clients/[id]”Wat de admin ziet:
Een uitgebreid klantprofiel met meerdere secties:
Persoonsgegevens:
- Alle gegevens uit de onboarding, bewerkbaar via een “Bewerken” knop die de velden editeerbaar maakt.
Honden:
- Lijst van alle honden van deze klant met vaccinatiestatus.
- Klikken op een hond opent
/admin/dogs/[id].
Boekingshistorie:
- Lijst van alle boekingen, gesorteerd op datum (nieuwste eerst).
- Status per boeking.
Factuuroverzicht:
- Alle facturen met betaalstatus.
- Totaal openstaand.
Wat er gebeurt bij bewerken:
- Admin wijzigt gegevens en klikt “Opslaan”.
PATCH /api/admin/clients/:idmet de gewijzigde velden.- Succesmelding bij de klantgegevens.
8. Admin hondenbeheer
Section titled “8. Admin hondenbeheer”Overzicht: /admin/dogs
Section titled “Overzicht: /admin/dogs”Wat de admin ziet:
- Zoekbalk: zoeken op hondnaam of eigenaar.
- Filter: vaccinatie verlopen, bijna verlopen, alles.
- Tabel:
| Kolom | Omschrijving |
|---|---|
| Naam | Naam van de hond |
| Ras | Ras |
| Eigenaar | Naam van de klant |
| Vaccinatiestatus | Geldig / bijna verlopen / verlopen |
Detail: /admin/dogs/[id]
Section titled “Detail: /admin/dogs/[id]”Wat de admin ziet:
Het volledige hondprofiel, vergelijkbaar met wat de klant ziet maar met extra mogelijkheden:
Profielgegevens:
- Alle velden zijn bewerkbaar.
- Extra veld: “Bijzonderheden” (
special_notes), een tekstveld voor terugkerende aandachtspunten die bij de volgende check-in worden getoond.
Vaccinaties beheren:
- Lijst van alle vaccinaties met status.
- Per vaccinatie: goedkeuren of afkeuren. De klant uploadt vaccinatiebewijzen met
verified_by_admin = false. De admin reviewt het document en kan op “Goedkeuren” klikken. - Knop “Vaccinatie toevoegen” voor handmatig toevoegen (als de klant het bewijs fysiek heeft meegenomen).
Boekingshistorie:
- Alle boekingen van deze hond.
Wat er gebeurt bij goedkeuren vaccinatie:
- Admin klikt “Goedkeuren” bij een vaccinatie.
PATCH /api/admin/vaccinations/:idmetverified_by_admin = true.- De vaccinatiestatus wordt direct bijgewerkt in de UI.
9. Admin factuurbeheer
Section titled “9. Admin factuurbeheer”Overzicht: /admin/invoices
Section titled “Overzicht: /admin/invoices”Wat de admin ziet:
- Filters: openstaand, betaald, verlopen.
- Totaalbedragen per filter bovenaan.
- Tabel:
| Kolom | Omschrijving |
|---|---|
| Factuurnummer | Format jaarXXXXXX |
| Klant | Naam van de klant |
| Datum | Factuurdatum |
| Bedrag | Totaalbedrag incl. belasting |
| Status | Openstaand / betaald / verlopen |
- Knop “PDF genereren” per factuur.
- Export als CSV (voor de boekhouder).
Detail: /admin/invoices/[id]
Section titled “Detail: /admin/invoices/[id]”Wat de admin ziet:
De volledige factuur zoals de klant die ziet, plus extra acties:
Factuurgegevens:
- Gespecificeerd per hond per dienst.
- BBO (6%) en BAZV (1.5%) apart.
- Bankgegevens Dog Hotel Aruba.
Acties:
| Actie | Wanneer beschikbaar | Wat er gebeurt |
|---|---|---|
| Handmatig markeren als betaald | Factuur is openstaand | Modal: kies betaalmethode (Cash / PIN), bevestig bedrag. PATCH /api/admin/invoices/:id/mark-paid met methode, tijdstip, medewerker-ID. |
| Herinnering sturen | Factuur is openstaand of verlopen | Stuurt een herinneringsmail naar de klant met betaallink. |
| PDF genereren | Altijd | Genereert een PDF via Forme PDF (Rust/WASM op CF Workers) en opent een download. |
Handmatig betaald markeren:
- Admin klikt “Markeer als betaald”.
- Modal verschijnt: kies Cash of PIN.
- Het bedrag wordt getoond ter bevestiging.
- Bij bevestigen: de factuur wordt als betaald gemarkeerd met de methode, het tijdstip en wie het heeft geregistreerd.
- De klant ontvangt een bevestigingsmail.
10. Admin instellingen
Section titled “10. Admin instellingen”Route: /admin/settings
De instellingenpagina is opgedeeld in tabs of secties.
Diensten
Section titled “Diensten”Wat de admin ziet:
- Tabel met alle diensten: naam, type (single/bundle/subscription), prijs, eenheid, actief/inactief.
- Toggle om een dienst actief of inactief te maken.
- Knop “Dienst bewerken” per rij.
- Knop “Nieuwe dienst” bovenaan.
Dienst bewerken:
- Naam, beschrijving.
- Prijs en eenheid (per dag, per nacht, per les, per maand).
- Type: single, bundle of subscription.
- Actief/inactief toggle.
Wat er gebeurt:
PATCH /api/admin/services/:idofPOST /api/admin/services.- Prijswijzigingen gelden alleen voor nieuwe boekingen. Bestaande boekingen houden de snapshot-prijs.
Contactgegevens
Section titled “Contactgegevens”Wat de admin ziet:
- Hotelnaam
- Logo (upload)
- Adres
- Telefoonnummer
Deze gegevens worden getoond op facturen en in emails.
Wat er gebeurt:
PATCH /api/admin/settingsmet de gewijzigde velden.- Het logo wordt geupload naar Supabase Storage.
Medewerkers
Section titled “Medewerkers”Wat de admin ziet:
- Lijst van alle medewerkers met naam, email en rol.
- Knop “Medewerker toevoegen”.
- Per medewerker: bewerken of deactiveren.
Medewerker toevoegen:
- Admin vult naam, email en rol (admin / medewerker / trainer) in.
POST /api/admin/usersmaakt een account aan.- De medewerker ontvangt een uitnodigingsmail met een link om een wachtwoord in te stellen.
Rollen:
admin: volledige toegang tot alle admin functies.medewerker: toegang tot dagelijkse operatie (boekingen, check-in/out, honden, klanten). Geen toegang tot instellingen en financieel overzicht.trainer: kan lessen inplannen en notities toevoegen bij trainingen.
11. Klant accountbeheer
Section titled “11. Klant accountbeheer”Route: /account
Wat de gebruiker ziet
Section titled “Wat de gebruiker ziet”Een pagina met drie secties:
Persoonlijke gegevens:
- Dezelfde velden als stap 1 van de onboarding, voorgevuld.
- Knop “Opslaan” om wijzigingen door te voeren.
Wachtwoord wijzigen:
- Veld “Huidig wachtwoord”
- Veld “Nieuw wachtwoord” (min. 8 karakters)
- Veld “Bevestig nieuw wachtwoord”
- Knop “Wachtwoord wijzigen”
Taalvoorkeur:
- Keuze tussen NL en EN.
- Wordt direct opgeslagen en toegepast.
Wat er gebeurt
Section titled “Wat er gebeurt”Gegevens bewerken:
- Klant wijzigt velden en klikt “Opslaan”.
PATCH /api/clients/:id.- Succesmelding “Gegevens opgeslagen.”
Wachtwoord wijzigen:
supabase.auth.updateUser({ password })na verificatie van het huidige wachtwoord.- Succesmelding “Wachtwoord gewijzigd.”
Foutmeldingen:
| Situatie | Melding |
|---|---|
| Huidig wachtwoord onjuist | ”Het huidige wachtwoord is onjuist.” |
| Nieuwe wachtwoorden komen niet overeen | ”Wachtwoorden komen niet overeen.” |
| Nieuw wachtwoord te kort | ”Wachtwoord moet minimaal 8 karakters zijn.” |
Emailnotificaties (achtergrond)
Section titled “Emailnotificaties (achtergrond)”Fase 1a introduceert de eerste emailnotificaties. Ze worden verstuurd via Resend met React Email templates, in de voorkeurstaal van de gebruiker (NL of EN).
| Trigger | Ontvanger | Inhoud |
|---|---|---|
| Registratie voltooid | Klant | Welkomstmail met link naar het portaal |
| Boeking bevestigd | Klant | Boekingsdetails, datum, hond(en), betaallink |
| Betaling ontvangen | Klant | Bevestiging met factuurnummer en bedrag |
| Nieuwe boekingsaanvraag | Admin | Melding dat er een nieuwe aanvraag is met link naar de boeking |