4ca40bf2b55cd8e643060fb5e653e5ecd31f9560
Critical: computeAvailableSlots looped forever when slot_minutes was
0 or negative -- reachable in production, since AdminSchedule's
slot-length input has no validation and clearing it yields Number('')
=== 0. Guarded the computation, added min="5"/required to the admin
input as defense in depth, and added a regression test.
Important fixes:
- Removed the one eslint-disable that slipped into the branch
(InquiryModal.test.tsx), replacing it with the explicit vi.fn<...>
generic type pattern already used everywhere else. Also cleaned up
a similar unused-var workaround in useBooking.test.ts for
consistency.
- Added a submitting/in-flight guard to both booking and inquiry
submission, so a double-click can no longer produce a false
"slot already taken" error after a booking actually succeeded (or
a duplicate inquiry row).
- Added loading states to Home.tsx (services/products) and Book.tsx
(services list, date/slot step) -- previously only Shop.tsx had
one, though the spec named all three pages.
- Restored the full date -> slot -> contact -> confirmation ->
persisted-booking test in Book.test.tsx, which had been replaced
rather than supplemented by a narrower slot-fetching test.
Deferred to a follow-up (explicit decision, not silently dropped):
duration-aware slot conflicts. The current model only blocks an exact
(date, time) match, so a 4-hour service booked at 9:00 AM doesn't
block 11:00 AM even though they'd physically overlap. Inherited from
the Phase 2A data model; this branch is what makes it reachable by
real customers, so it needs a recorded decision before go-live rather
than silent inheritance.
Claude-Session: https://claude.ai/code/session_01NhxA4npAXAxmCDEJt6kxSH
Braids by Mira
Public marketing site for Braids by Mira — landing page, product showcase, booking flow, and salon policies.
Scripts
npm run dev— start the local dev servernpm test(ornpx vitest run) — run the frontend test suitenpm run build— type-check and build for productionnpm run lint— run ESLintnpm run test:functions— run the Deno tests for the Edge Functions' shared email builders (requires Deno installed)npm run seed— seed products, services, and the default schedule into a Supabase project (see below). Re-running it after admin-panel edits will revert those rows to the hardcoded seed defaults — use it for initial setup / disaster recovery, not routine use.
Backend (Supabase)
The backend lives in supabase/ — Postgres schema/RLS migrations, pgTAP tests, and Deno Edge Functions for booking/inquiry email notifications.
npx supabase start— start the local Docker-based Supabase dev stack (Postgres, Studio, Auth, Storage, Edge Functions runtime). Requires Docker.npx supabase db reset— replay all migrations from scratch against the local database.npx supabase test db— run the pgTAP test suite insupabase/tests/database/against the local database.
Environment variables
Copy .env.example to .env.local and fill in:
VITE_SUPABASE_URL,VITE_SUPABASE_ANON_KEY— frontend Supabase client config (exposed to the browser).SUPABASE_URL,SUPABASE_SERVICE_ROLE_KEY— used only byscripts/seed.ts(server-side, never expose the service role key to the browser). These are distinct from theVITE_-prefixed frontend variables above.
Description
Languages
TypeScript
77.5%
PLpgSQL
14.6%
CSS
7.1%
HTML
0.5%
JavaScript
0.3%