diff --git a/README.md b/README.md index bab38b2..2111c71 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,13 @@ Nail salon booking platform — Go 1.25 backend + SvelteKit 5 frontend + Docker. - **Today page enhancements**: interactive daily calendar grid with visual time blockers, today stats summary, responsive layout improvements - **Auto-select availability**: all booking flows (self-service, admin create, edit request) automatically select the first available date when data loads - **Shared time slot utilities**: extracted common time slot generation, lunch protection, and formatting logic into a reusable module +- **Shared formatting utilities**: `formatDuration`, `formatDateTime`, `formatDate`, `formatTime`, `calculateAge` in `lib/utils/format.ts` +- **Referral code registration**: new users can enter a 12-character referral code during registration; relationship recorded in `user_referrals` table +- **Admin schedule page**: Google Calendar-style week view at `/admin/schedule` with drag-scroll, booking details modal, and working hours overlays +- **BookingFlow welcome step**: unauthenticated users see a welcome card (Step 0) encouraging login before guest checkout, with clear messaging about lost loyalty/discount benefits +- **Admin login redirect**: admins are redirected to `/today` after login instead of the home page +- **Patch test duration on services**: `patch_test_duration_hours` exposed on Service type; creating a service with duration > 0 auto-creates a patch test record +- **`created_by_name` on bookings**: admin booking details now show who created the booking (admin name) ## Project Structure @@ -43,7 +50,7 @@ Crussell/ │ ├─ admin/ # BookingCreateModal, RescheduleModal, TimeBlockers, WeeklySchedule, HolidayHours, etc. │ ├─ today/ # TodayCalendar (interactive grid), CurrentAppointment, PendingApprovals, TodayStats │ └─ account/ # EditRequestModal, UserBookingModal -├─ frontend/src/lib/utils/ # Shared utilities (timeSlots.ts) +├─ frontend/src/lib/utils/ # Shared utilities (timeSlots.ts, format.ts) ├─ sabredav/ # PHP + Composer for DAV ├─ nginx/ # Nginx reverse-proxy for HTTP & HTTPS ├─ init-scripts/ # PostgreSQL init SQL @@ -99,7 +106,7 @@ cd backend && go build -o bin/backend ./main.go # Frontend cd frontend && npm ci && npm run build -# Tests (444/447 passing, 3 skipped) +# Tests (446/449 passing, 3 skipped) cd backend && go test -tags "test,dev" ./... ``` diff --git a/obsidian/Crussell/Admin Manual.md b/obsidian/Crussell/Admin Manual.md index fcd7ffe..14268ad 100644 --- a/obsidian/Crussell/Admin Manual.md +++ b/obsidian/Crussell/Admin Manual.md @@ -14,6 +14,7 @@ Go to the website and log in with your admin email and password. Once logged in - **Today** — your daily operations hub. This is where you manage today's appointments, approve new bookings, and handle walk-ins. - **Admin** — the management dashboard. This is where you set up services, manage customers, adjust schedules, and handle the salon's settings. +- **Schedule** — a weekly calendar view showing all appointments across the week in a Google Calendar-style layout. Access it from the navigation bar. --- @@ -230,6 +231,7 @@ This is where you manage the list of treatments the salon offers. - Set the price - Set how long the service takes (in minutes) - Set a minimum age requirement (if the service isn't suitable for under-16s, for example) +- Set a **patch test duration** (in hours) — if you enter a value greater than 0, the system automatically creates a patch test record linked to this service. Customers will need to complete this patch test before they can book the service. **Edit a Service:** - Click on any service to change its name, description, price, duration, or age requirement @@ -289,6 +291,31 @@ This is where you set your regular, week-to-week opening hours. - Toggle any day on or off — for example, if you decide to start opening on Saturdays, just turn Saturday on and set the hours - Changes take effect immediately — customers will see the updated availability right away +### Schedule (Weekly Calendar View) + +The **Schedule** page (`/admin/schedule`) gives you a bird's-eye view of the entire week's appointments in a Google Calendar-style layout. + +**What you'll see:** +- A week grid with each day as a column, showing your working hours +- Each appointment shown as a coloured bar spanning its start time to end time +- The customer's name and services inside each bar +- Colour-coded status indicators (pending, confirmed, in progress, completed, cancelled) +- Days when the salon is closed are greyed out + +**Navigating the week:** +- Use the **Previous** and **Next** buttons to move between weeks +- Click **Today** to jump back to the current week +- On touch devices, you can **drag** the calendar horizontally to scroll through the day + +**Interacting with appointments:** +- **Click any appointment** to open its full details window (BookingModal) +- From the details window, you can edit, reschedule, cancel, or take payment + +**Why use this view:** +- See your entire week at a glance instead of just today +- Spot gaps in your schedule where you could fit additional appointments +- Check for busy days that might need extra preparation + ### Discount Campaigns This is where you set up promotional discounts. @@ -401,8 +428,8 @@ This section shows the customer's patch test history. ### Loyalty and Referrals - **Loyalty stamps** — their current stamp count -- **Referral code** — their unique code they can share with friends -- **Referral history** — who they've referred and who referred them +- **Referral code** — their unique 12-character code they can share with friends +- **Referral history** — who they've referred (referred users) and who referred them (their referrer). The `user_referrals` table tracks these relationships, created automatically when a new user registers with a valid referral code. ### Privacy and Consent diff --git a/obsidian/Crussell/Future Work - Gap Backlog.md b/obsidian/Crussell/Future Work - Gap Backlog.md index eb4257e..44cc74f 100644 --- a/obsidian/Crussell/Future Work - Gap Backlog.md +++ b/obsidian/Crussell/Future Work - Gap Backlog.md @@ -1,4 +1,4 @@ -**Last Updated:** May 2026 — Admin reschedule modal, time blockers UI, Today calendar with interactive grid, auto-select across all booking flows, shared time slot utilities, GetBookingsByCreatedRange endpoint, 444/447 tests passing (3 skipped) +**Last Updated:** May 2026 — Admin schedule page (weekly calendar view), referral code registration, BookingFlow welcome step for guests, patch_test_duration_hours on services, shared format utilities, created_by_name on bookings, admin login redirect, 446/449 tests passing (3 skipped) **Status:** Living backlog — add to this as gaps are discovered --- @@ -15,6 +15,13 @@ No external dependencies. No paid services. No API keys needed. | 2 | ~~**WalkInCreateModal guest booking errors out**~~ ✅ | S (1-2h) | Frontend | Guest creation now fires at submit time in both walk-in and call-in flows. Phone defaults to +447700900000 if left blank. | | 3 | ~~**ApprovalModal decline/cancel stub**~~ ✅ | S (2-3h) | Frontend | `handleDecline()` now calls `POST /api/admin/bookings/{id}/cancel`. Backend sets status to `we_cancelled`, acknowledges pending notification, creates cancelled_booking notification. | | 4 | **CurrentAppointment action stubs** | M (1d) | Frontend | `handleEdit()` ✅ — opens `EditBookingModal` for service management. `handleTakePayment()` ✅ — wired to multi-method PaymentModal. `handleReschedule()` ✅ — opens RescheduleModal with available slot lookup and conflict detection. `handleExtend()`, `handleCancel()` — dead buttons. | +| 52 | ~~**Referral code registration**~~ ✅ | S (2-3h) | Full-stack | **Complete May 2026.** Backend validates 12-char alphanumeric codes during registration, looks up referrer, records in `user_referrals`. Frontend login page has formatted input (xxxx-xxxx-xxxx). Tests: valid + invalid referral code scenarios. | +| 53 | ~~**Admin schedule page**~~ ✅ | M (1-2d) | Frontend | **Complete May 2026.** `/admin/schedule` — Google Calendar-style week view with drag-scroll, booking details modal, working hours overlays, status-coloured bars. Responsive: single-day view on mobile. | +| 54 | ~~**BookingFlow welcome step**~~ ✅ | S (1h) | Frontend | **Complete May 2026.** Unauthenticated users see Step 0 welcome card encouraging login (loyalty stamps, seasonal discounts messaging). "Log In" → `/login`, "Continue as Guest" → Step 1. Step indicator adapts `startAt` based on auth state. | +| 55 | ~~**Shared format utilities**~~ ✅ | S (1h) | Frontend | **Complete May 2026.** `lib/utils/format.ts` — `formatDuration`, `formatDateTime`, `formatDate`, `formatTime`, `calculateAge`. Used across components for consistent display. | +| 56 | ~~**patch_test_duration_hours on services**~~ ✅ | S (1h) | Full-stack | **Complete May 2026.** Service type includes `patch_test_duration_hours`. Creating service with duration > 0 auto-creates patch test record. All service list endpoints LEFT JOIN patch_tests to populate field. | +| 57 | ~~**created_by_name on bookings**~~ ✅ | XS (15min) | Full-stack | **Complete May 2026.** Booking type includes `created_by_name`. Admin booking handler LEFT JOINs users to resolve creator name. | +| 58 | ~~**Admin login redirect**~~ ✅ | XS (15min) | Frontend | **Complete May 2026.** Admins redirected to `/today` after login instead of home page. Token payload decoded to check role. | ## P1 — High @@ -42,7 +49,7 @@ No external dependencies. No paid services. No API keys needed. | 18 | ~~**HSTS header**~~ ✅ | XS (15min) | Backend | Added as a TODO-comment in the security headers middleware. Will be uncommented when HTTPS is enabled in production. | | 19 | ~~**Referrer-Policy header**~~ ✅ | XS (15min) | Backend | Added as a TODO-comment in the security headers middleware. Will be uncommented when ready for production. | | 20 | **Business settings management UI** | M (1-2d) | Full-stack | `business_settings` table exists (VAT registration, business name, etc.). No admin page to configure. Changes require direct SQL. | -| 21 | **Referral system UI** | M (1-2d) | Full-stack | `user_referrals` table exists. Users can't see their referral code or track uses. Admin can't manage referral campaigns. | +| 21 | **Referral system UI** | M (1-2d) | Full-stack | `user_referrals` table exists. **Backend complete** — registration accepts and validates referral codes, relationships recorded automatically. Remaining: users can't see their referral code or track uses in their account page. Admin can't manage referral campaigns. | | 22 | **Analytics endpoints** | M (1-2d) | Backend | `handlers/admin/analytics.go` is 1 line. `get_monthly_business_summary()`, `get_sales_totals()` SQL functions exist. No admin dashboard stats. | | 23 | ~~**console.log debug statements**~~ ✅ | XS (15min) | Frontend | Removed from BookingFlow.svelte and ImageUpload.svelte. | | 24 | ~~**Alert-based prototype UX**~~ ✅ | XS (30min) | Frontend | Replaced all `alert()` calls with `toast.success/error/info` from svelte-sonner. | @@ -212,7 +219,7 @@ Require paid accounts, API approval, or external service credentials. **Do not a ### Phase 5 — Growth + Polish (Week 5+) -31. **#21** Referral system UI (1-2d) +31. **#21** Referral system UI (1-2d) — **Backend complete**, remaining: user-facing referral code display, tracking dashboard 32. **#22** Analytics endpoints (1-2d) 33. ~~**#25**~~ ~~Customer relationship view~~ ✅ — implemented 34. **#26** CSV/Excel export (1d) @@ -231,6 +238,16 @@ Require paid accounts, API approval, or external service credentials. **Do not a 47. **#43** PWA support (3-5d) 48. **Gift card management UI** — Create/redeem gift cards, track balances (E4 backend + admin payment UI complete, management UI pending) +### Phase 6 — Latest (Week 6+) + +49. ~~**#52**~~ ~~Referral code registration~~ ✅ — backend + frontend complete +50. ~~**#53**~~ ~~Admin schedule page~~ ✅ — weekly calendar view complete +51. ~~**#54**~~ ~~BookingFlow welcome step~~ ✅ — guest login encouragement complete +52. ~~**#55**~~ ~~Shared format utilities~~ ✅ — format.ts complete +53. ~~**#56**~~ ~~patch_test_duration_hours on services~~ ✅ — auto-creates patch tests +54. ~~**#57**~~ ~~created_by_name on bookings~~ ✅ — admin booking details +55. ~~**#58**~~ ~~Admin login redirect~~ ✅ — redirects to /today + ### ⏳ Waiting on External Access | Item | Blocked On | Unblocks | diff --git a/obsidian/Crussell/Overview.md b/obsidian/Crussell/Overview.md index c9baf7f..2ab074b 100644 --- a/obsidian/Crussell/Overview.md +++ b/obsidian/Crussell/Overview.md @@ -84,11 +84,13 @@ flowchart TD ### Authentication & Identity - JWT authentication (HS256, 30-day expiry) with auto-refresh - User registration with input validation (names, UK phone, email, age 16+) +- **Referral code support**: optional 12-character alphanumeric code during registration; validated against `users.referral_code`, relationship recorded in `user_referrals` table - Password hashing with bcrypt - Role-based access: `unverified_email`, `verified_email`, `admin`, `guest`, `affiliate` - Refresh token with role-change detection (forces re-login if role changed) - Email verification and password reset endpoints (backend ready, frontend not wired) - Guest/disposable accounts for one-off bookings +- **Admin login redirect**: admins are redirected to `/today` after login instead of the home page ### Booking System - Three booking flows: self-service (customer), walk-in (admin), call-in (admin) @@ -100,6 +102,7 @@ flowchart TD - **Enriched edit requests**: side-by-side original vs proposed snapshots with service details, end-time calculation, and user info - Admin booking service editing with overlap detection and price/duration overrides - Idempotency keys for booking deduplication +- **`created_by_name`**: admin booking details include the name of the admin who created the booking ### Scheduling - Default weekly working hours (Mon-Fri, closed Sat/Sun) @@ -107,6 +110,7 @@ flowchart TD - Time blockers (admin-defined unavailable periods, plus slot reservations) — with full UI for creation and management - Available hours calculation accounting for bookings, blockers, and gaps - **GetBookingsByCreatedRange**: admin endpoint to query bookings within a created_at date range +- **Admin schedule page** (`/admin/schedule`): Google Calendar-style week view with drag-scroll, booking details modal, working hours overlays, and status-coloured booking bars ### Customer Features - Profile management with profile picture upload (cropper, separate S3 bucket) @@ -118,10 +122,12 @@ flowchart TD - **Saved cards**: manage cards in Account → Cards tab — add/remove cards for faster checkout (soft-deleted on removal, 7-year retention) - **Tip page**: percentage-based tips (10%, 15%, 20%) or custom amount on completed bookings via `/pay-tip/[id]` - **Auto-select**: booking flows automatically select the first available date when availability data loads +- **BookingFlow welcome step**: unauthenticated users see a welcome card (Step 0) encouraging login before guest checkout, with messaging about lost loyalty stamps and seasonal discounts ### Admin Features - Today page (/today): current/next appointment, today's interactive calendar grid, pending approvals, today stats summary - Admin dashboard (/admin): services CRUD, user management, bookings list, scheduling, time blockers UI +- **Admin schedule page** (`/admin/schedule`): Google Calendar-style week view with drag-scroll, booking details, working hours overlays - Walk-in booking wizard (3-step) with slot reservation - Call-in booking wizard (4-step) with slot reservation - **Reschedule modal**: full reschedule UI on Today page — search available slots, detect conflicts, one-click confirm @@ -201,7 +207,7 @@ All flows integrate with holiday/exceptional hours and time blockers. All bookin ## Test Coverage -**444/447 tests passing** (3 skipped) across 12+ test packages. Comprehensive coverage of online payments (deposit, full, partial, balance), saved card operations, tip payments, terminal payments, refunds, idempotency, webhook handling, cash/gift card payments, enriched edit request workflows, GetBookingsByCreatedRange endpoint, and scheduling exceptional hours. +**446/449 tests passing** (3 skipped) across 12+ test packages. Comprehensive coverage of online payments (deposit, full, partial, balance), saved card operations, tip payments, terminal payments, refunds, idempotency, webhook handling, cash/gift card payments, enriched edit request workflows, GetBookingsByCreatedRange endpoint, scheduling exceptional hours, and referral code validation. | Package | Coverage Area | |---------|--------------| diff --git a/obsidian/Crussell/Technical Manual.md b/obsidian/Crussell/Technical Manual.md index 784ffff..3162242 100644 --- a/obsidian/Crussell/Technical Manual.md +++ b/obsidian/Crussell/Technical Manual.md @@ -47,14 +47,14 @@ Backend (:8080) | Package | File(s) | Purpose | |---------|---------|---------| -| `handlers/auth` | local.go, social.go | Registration, login, refresh, email verification | -| `handlers/bookings` | bookings.go, reserve.go, manage.go, admin_reserve.go | Booking CRUD, reservations, admin management, edit requests, discounts, closing hours validation, active booking limits, GetBookingsByCreatedRange | +| `handlers/auth` | local.go, social.go | Registration (with referral code validation), login, refresh, email verification | +| `handlers/bookings` | bookings.go, reserve.go, manage.go, admin_reserve.go | Booking CRUD, reservations, admin management, edit requests, discounts, closing hours validation, active booking limits, GetBookingsByCreatedRange, created_by_name resolution | | `handlers/payments` | handlers.go, service.go, validators.go | Square payments: terminal, online, refunds, tips, saved cards | | `handlers/webhooks` | square.go | Square webhook handler for payment status updates | | `handlers/admin` | users.go, analytics.go, discount_campaigns.go | Admin user management, discount campaigns, analytics (stub) | | `handlers/today` | today.go | Current/next appointment, today's grid, pending approvals | | `handlers/user` | profile.go, account.go, guest.go, loyalty.go, customer_relationship.go | User profile, guest creation, loyalty, contact info | -| `handlers/services` | services.go | Service catalog, eligibility filtering | +| `handlers/services` | services.go | Service catalog, eligibility filtering, patch_test_duration_hours auto-creates patch test records | | `handlers/scheduling` | default-hours.go, exceptional-hours.go, time-blockers.go | Working hours, exceptional groups, time blockers | | `handlers/portfolio` | images.go | Image upload, listing, tags, filters | | `handlers/notifications` | notifications.go | Admin notifications (GET, acknowledge) | @@ -103,6 +103,7 @@ Backend (:8080) | `/portfolio` | portfolio/+page.svelte | Image gallery with tag/category filtering | | `/prices` | prices/+page.svelte | Service price list | | `/schedule` | schedule/+page.svelte | User's upcoming appointments with .ics export, payment buttons | +| `/admin/schedule` | admin/schedule/+page.svelte | Admin weekly calendar view — Google Calendar-style week grid with drag-scroll, booking details modal, working hours overlays | | `/contact` | contact/+page.svelte | Dynamic contact info from first admin user | | `/manage` | manage/+page.svelte | Booking management | | `/demo` | demo/+page.svelte | Demo mode | @@ -118,14 +119,14 @@ src/lib/components/ ├── admin/ │ ├── ApprovalModal.svelte # Booking approval/decline │ ├── BookingCreateModal.svelte # Admin booking creation (4-step, uses shared timeSlots utils) -│ ├── BookingModal.svelte # View booking details +│ ├── BookingModal.svelte # View booking details (shows created_by_name) │ ├── BookingsCard.svelte # Bookings list │ ├── CallInBooking.svelte # Call-in booking flow │ ├── EditBookingModal.svelte # Edit booking services │ ├── HolidayHours.svelte # Exceptional schedule management │ ├── ImageUpload.svelte # Portfolio image upload │ ├── PatchTestModal.svelte # Record patch test -│ ├── ServicesManagement.svelte # Service CRUD +│ ├── ServicesManagement.svelte # Service CRUD (patch_test_duration_hours) │ ├── DiscountsManagement.svelte # Discount campaign management │ ├── UserModal.svelte # User details + relationship data │ ├── UsersCard.svelte # Users list @@ -177,6 +178,13 @@ src/lib/components/ - `getDayWithOrdinal()` — formats a CalendarDate with ordinal suffix (e.g., "January 15th") - Types: `DayHours`, `DayAvailability` — shared type definitions for working/available hours data +- **`lib/utils/format.ts`**: Shared formatting utilities for consistent display across the app + - `formatDuration(minutes)` — converts minutes to human-readable string (e.g., 90 → "1h 30m") + - `formatDateTime(date)` — formats to "Weekday, Month Day at HH:MM AM/PM" + - `formatDate(date)` — formats to "Weekday, Month Day" (no time) + - `formatTime(date)` — formats to "HH:MM AM/PM" + - `calculateAge(dateOfBirth)` — calculates age in years from DOB string + --- ## API Reference @@ -187,7 +195,7 @@ src/lib/components/ |--------|------|------|------------|-------------| | GET | `/api/services` | Optional | 120/min | List active services (eligibility for authenticated) | | GET | `/api/services/eligible-for/{user_id}` | Admin | 120/min | Services filtered by user's age/patch test | -| POST | `/api/register` | None | 10/min | Create user account | +| POST | `/api/register` | None | 10/min | Create user account (optional `referralCode` field) | | POST | `/api/login` | None | 1/5s | Authenticate, receive JWT | | POST | `/api/verify/generate` | None | — | Generate email verification or password reset code | | POST | `/api/verify/check` | None | — | Verify code | @@ -614,6 +622,8 @@ type EnrichedEditRequest struct { **Patch Test Filtering:** Services linked to `patch_tests` via `service_ids[]`. User must have valid `user_patch_tests` record. +**`patch_test_duration_hours`:** The `Service` and `ServiceResponse` types now include `patch_test_duration_hours`. All service list endpoints (`ServicesHandler`, `ServicesEligibleForUserHandler`, `AllServicesHandler`) `LEFT JOIN patch_tests` to populate this field. When creating a service with `patch_test_duration_hours > 0`, a corresponding `patch_tests` record is auto-created with the service ID in `service_ids`. + **Admin vs. Customer:** - `/api/services` — returns services with eligibility for authenticated users - `/api/services/eligible-for/{user_id}` — admin-only, returns services for specific user (used in admin booking flows) @@ -645,6 +655,61 @@ type EnrichedEditRequest struct { --- +### Referral Code System + +**How it works:** During registration, users can optionally provide a 12-character alphanumeric referral code. The backend validates the code format, looks up the referrer by their `referral_code`, and records the relationship in the `user_referrals` table. + +**Validation:** +- Code must be exactly 12 alphanumeric characters (`^[a-zA-Z0-9]{12}$`) +- Code is trimmed of whitespace before validation +- If code doesn't match any user's `referral_code`, registration returns 400 "invalid referral code" +- Referral code is optional — registration succeeds without it + +**Recording:** +- `INSERT INTO user_referrals (referrer_id, referred_id) VALUES ($1, $2) ON CONFLICT DO NOTHING` +- Wrapped in the same transaction as user creation — atomic with registration + +**Frontend:** +- Login/register page has a referral code input field with auto-formatting (xxxx-xxxx-xxxx) +- `handleReferralInput()` strips non-alphanumeric chars, limits to 12, inserts dashes +- On submit, dashes are stripped before sending to the API + +**Related:** `generate_referral_code()` SQL function creates 12-char codes with collision detection. + +--- + +### Admin Schedule Page + +**How it works:** `/admin/schedule` provides a Google Calendar-style week view for admin users. + +**Features:** +- Week navigation (previous/next week buttons) with "Today" reset +- Working hours overlay — days marked as closed are greyed out +- Booking bars positioned by start time and duration, colour-coded by status +- Drag-scroll for horizontal navigation on touch devices +- Click any booking to open `BookingModal` with full details +- Responsive: collapses to single-day view on mobile + +**Data loading:** +- Fetches `GET /api/admin/bookings` for the week's date range +- Fetches `GET /api/scheduling/working-hours` for each day +- JSON diff-based refresh — only re-renders when data actually changes + +--- + +### BookingFlow Welcome Step + +**How it works:** Unauthenticated users see a "Welcome" step (Step 0) before the service selection step. + +**Behaviour:** +- `currentStep` starts at 0 for unauthenticated users, 1 for authenticated users +- Step 0 shows a card explaining benefits of logging in (loyalty stamps, seasonal discounts) +- Two buttons: "Log In" (navigates to `/login`) and "Continue as Guest" (advances to Step 1) +- Step indicator shows `startAt={0}` for guests, `startAt={1}` for logged-in users +- Back button on Step 1 is hidden for authenticated users (they don't have a welcome step to go back to) + +--- + ### Idempotency Keys **How it works:** `Idempotency-Key` header (optional, 64-char max). If provided, backend checks for existing booking with that key. If found, returns existing booking (200, no duplicate). If not found, creates new booking with key stored. @@ -738,8 +803,8 @@ go test -tags "test,dev" -v -p 1 -count=2 ./... # Run twice for flaky detection ### Test Coverage -**444/447 tests passing** (3 skipped) across 12+ packages. Comprehensive coverage of online payments (deposit, full, partial, balance), saved card operations, tip payments, terminal payments, refunds, idempotency, webhook handling, and cash/gift card payments, GetBookingsByCreatedRange endpoint, and scheduling exceptional hours validation. -- `handlers/auth` — Authentication +**446/449 tests passing** (3 skipped) across 12+ packages. Comprehensive coverage of online payments (deposit, full, partial, balance), saved card operations, tip payments, terminal payments, refunds, idempotency, webhook handling, and cash/gift card payments, GetBookingsByCreatedRange endpoint, scheduling exceptional hours validation, and referral code registration. +- `handlers/auth` — Authentication (login, register, referral code validation, refresh, verification) - `handlers/bookings` — User booking flow, guest bookings, reservations, edit requests, discounts, closing hours validation, active booking limits, GetBookingsByCreatedRange - `handlers/payments` — Square payments (terminal, online, refunds, tips, saved cards) - `internal/square` — Square client dev mock tests diff --git a/obsidian/Crussell/User Manual.md b/obsidian/Crussell/User Manual.md index 4c75c8f..d90d1b0 100644 --- a/obsidian/Crussell/User Manual.md +++ b/obsidian/Crussell/User Manual.md @@ -15,6 +15,10 @@ When you open the website, you'll see the salon's homepage with: Tap or click **Book an Appointment** to start. +**If you're not logged in**, you'll see a welcome screen before selecting services. This screen explains the benefits of logging in — specifically that guest bookings don't earn loyalty stamps or qualify for seasonal discounts. You can choose to: +- **Log In** — takes you to the login/register page +- **Continue as Guest** — proceeds to service selection without an account + ### Step 2: Choose Your Services You'll see a list of all available treatments. Each one shows: @@ -126,6 +130,7 @@ To create a permanent account, go to the **Login** page and choose to register. - **Email address**: A standard email format - **Date of birth**: You must be at least 16 years old to create an account - **Password**: Up to 72 characters +- **Referral code** (optional): If a friend gave you a referral code, enter it here. The code is 12 characters and will be formatted automatically as you type (xxxx-xxxx-xxxx). Using a referral code links your account to the person who referred you. After registering, your account starts in an "unverified" state. An email verification system exists but isn't fully connected yet — for now, you can still log in and book.