feat(booking): stepped public booking flow with service/staff selection

The public booking page showed a capped flat preview of slots with no way
to pick a service, day, or staff member. Replaces it with a stepped flow:
pick service, optional staff preference, pick a day, pick a time.

Backend: availability accepts serviceId/staffId/date filters (default
response unchanged for the embed widget), a new public catalog endpoint
exposes bookable services and active staff, and slots carry staffName.
Slot generation and booking creation now honor tenant-wide and per-staff
blocked days; appointment requests must fit inside a matching
availability rule and reference tenant-owned, active staff and locations.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-18 10:18:03 +02:00
1 parent 09f780e7a6
commit d9aa29dbcb
9 files changed
+940 -118

No files matched your search

+9 -1
View File
@@ -59,6 +59,13 @@
- booking modal service field is a select bound to the tenant's real services; blocked-day creation supports optional per-staff scoping
- deleting a service or staff member preserves bookings (FK `SET NULL`) and removes the member's availability rules (`CASCADE`), mirrored in the in-memory repository
- live staging validation, real Neon Auth/Stripe/SMS provider checks, and operational hardening are still open
- `[done/partial]` Milestone 9: Public booking flow with real service/staff selection
- public booking page is now a stepped flow: pick service → optional staff preference → pick day → pick time; class sessions still listed below
- `GET /v1/public/tenants/{slug}/catalog` exposes bookable services and active staff for the booking page
- availability endpoint accepts `serviceId`, `staffId`, and `date` filters; default response is unchanged for the embeddable widget
- slots now carry `staffName`, respect tenant-wide and per-staff blocked days, and are generated per-day without the preview cap when `date` is given
- booking creation hardened: appointment requests must fit inside a matching availability rule, not overlap a blocked day, and staff/location IDs must belong to the tenant with staff active
- remaining: per-staff availability UI, class/session template management, live staging validation
## Overview
Bookra is a Czech-first booking SaaS for small local service businesses. It targets salons, massage therapists, small clinics, repair shops, and small studios/clubs that need a simple public booking flow, internal schedule management, reminders, and basic business reporting without becoming a full ERP.
@@ -287,6 +294,8 @@ Key entities:
- `/dashboard` now includes first-run onboarding instead of only a passive empty state for unassigned authenticated users.
- Catalog management now covers services and staff end-to-end; staff creation enforces `MaxStaff` entitlements and staff location assignment validates tenant ownership.
- Dashboard summary computes `setupCompletion` from real configured state (brand, location, service, staff, availability rules) rather than a static value.
- Public booking flow offers real service and staff selection via a stepped picker backed by `GET /v1/public/tenants/{slug}/catalog` and filtered availability (`serviceId`, `staffId`, `date`).
- Appointment creation validates that requested times fit inside availability rules, skip blocked days, and reference tenant-owned staff and locations.
## Current Gaps
- Neon Auth token extraction is wired structurally, but still needs live browser validation against a real Neon Auth environment.
@@ -302,7 +311,6 @@ Key entities:
- validate Stripe checkout/webhooks/portal and reminder dispatch against live staging infrastructure
- replace noop notification providers with the first production email transport and a gated SMS transport
- add management UI for class/session templates and per-staff availability rules so service duration, capacity, and staff schedules are editable after onboarding
- surface service selection and staff assignment on the public booking flow (services currently auto-resolve to the first match)
## Product Principles
- calm, premium, structured UX