2 Commits

Author SHA1 Message Date
mivanchenko 644c99ee30 Booking confirmation email + customer self-service cancel/reschedule (#18)
Sends a confirmation email (best-effort, fire-and-forget SMTP via mailer.py)
on booking creation, with a manage-booking link embedding the ticket-2 signed
token. Adds /manage/<token>, a stateless cancel/reschedule page that reuses
the existing slot-picker against booking_api's create/cancel/reschedule API,
distinguishing an invalid/expired link from an already-cancelled one. Sender
address uses the client's own domain when configured, falling back to a
mivanchenko.de address otherwise.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 15:40:45 +02:00
mivanchenko b895663c3a Public booking page + iframe embed (#17)
Adds the customer-facing /book/<slug> page: service/slot picker, booking
form, and confirmation screen, built on #16's existing booking JSON API.
Includes iframe auto-fit height reporting (mirroring
deploy/booking/booking_layout.js's eaBookingHeight message), brand-color
theming via a ?color= query param, a honeypot field with a fake-success
response indistinguishable from a real booking, and a clear "just taken"
message on slot-conflict. Caddy per-IP rate limiting is documented in
deploy/booking/RATE_LIMIT.md for manual application (no Caddyfile is
tracked in this repo).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 15:15:29 +02:00