5 Commits

Author SHA1 Message Date
belviskhoremk
ba4d022a6a docs: expand README and add CLAUDE.md
README now covers site structure, storage buckets, admin user
creation, and deployment. CLAUDE.md documents project conventions
(French UI copy, styling tokens, data-fetching patterns, migration
style) and working constraints (no git remote, manual deploys/db
pushes require confirmation).

Claude-Session: https://claude.ai/code/session_01NhxA4npAXAxmCDEJt6kxSH
2026-08-25 11:02:44 +02:00
belviskhoremk
c8d24a2a3a docs: warn that re-seeding reverts admin-panel edits 2026-08-12 20:27:15 +02:00
belviskhoremk
c74f1bb6cb fix: prevent double-booking, clean up booked_slots, harden Edge Function error handling
Fast follow-up to the Phase 2A backend review (4 deferred Important items):

1. Add a partial unique index (date, time) where status = 'confirmed' on
   public.bookings so two concurrent bookings for the same slot can no longer
   both succeed. Previously sync_booked_slot()'s `on conflict do nothing`
   masked the second insert as a silent no-op on the mirror table instead of
   rejecting it.

2. Extend sync_booked_slot() (new migration, the applied 20260808000002 is
   left untouched) to also fire on `update of status` and `delete`, removing
   the booked_slots mirror row once no confirmed booking remains for a slot.
   Also tightened the insert path to only mirror bookings that are actually
   'confirmed' -- the original trigger mirrored every insert regardless of
   status, so a booking inserted directly with status='cancelled' (allowed by
   the public insert policy) would incorrectly block a slot nobody confirmed.

3. supabase/functions/{on-booking-created,on-inquiry-created}: guard
   req.json() and payload.record with try/catch (400 + console.error on
   failure), check the Resend response's .ok and log failures instead of
   swallowing them, and skip the Resend call entirely (with a log) instead of
   sending "Authorization: Bearer undefined" when RESEND_API_KEY is unset.
   Still return 200 when only the notification leg fails, since the booking/
   inquiry row itself already committed successfully by the time this handler
   runs -- a non-200 would make pg_net retry, but retrying re-sends against
   the same already-inserted row and won't fix a Resend outage or bad
   payload, so it isn't the right signal.

4. README: document the Supabase-side dev loop (supabase start/db reset/test
   db), npm run seed and its SUPABASE_URL/SUPABASE_SERVICE_ROLE_KEY env vars,
   and npm run test:functions (Deno tests for the Edge Functions' shared
   email builders).

pgTAP suite grew from 12 to 23 tests (11 new: 4 for the uniqueness
constraint, 7 for booked_slots cleanup on cancel/delete). Verified locally:
supabase db reset, supabase test db (23/23 pass), vitest run (51/51 pass),
npm run build, npm run lint, and npm run test:functions (Deno installed for
this session; 6/6 pass) all succeed. Nothing here touches the live Supabase
project -- deploying is a separate follow-up step.

Claude-Session: https://claude.ai/code/session_01NhxA4npAXAxmCDEJt6kxSH
2026-08-12 10:29:37 +02:00
belviskhoremk
9f3e037cdc fix: address final review findings — Hero3D static class, InquiryModal a11y, date guards, shared email validation, README
Claude-Session: https://claude.ai/code/session_01NhxA4npAXAxmCDEJt6kxSH
2026-08-03 20:40:16 +00:00
belviskhoremk
4771d3ead7 chore: set up Vitest, routing, and design tokens
Includes the base Vite+React+TS scaffold files (package.json, index.html,
tsconfigs, etc.) which had never been committed to git.
2026-08-03 16:53:05 +00:00