feat(booking): add service eligibility based on age and patch tests
- Add eligibility filtering to /api/services: exclude services below
user's
age, gray out services requiring patch tests that are missing/expired
- Add new endpoint /api/services/eligible-for/{user_id} for admin
booking
flows to check eligibility for a specific user
- Add image metadata stripping: uploads now strip all EXIF/GPS data
via imaging library (security improvement)
- Update ServiceCard frontend: show grayed-out state for ineligible
services with "contact us" link (public) or just warning (admin)
- Add 2 patch test services to seed data: Gel Polish Full Set,
Luxury Gel Manicure (48h each)
- Remove deprecated local-dev.sh script
This commit is contained in:
@@ -21,6 +21,14 @@
|
||||
- [x] Login rate limiting (1 attempt per 5 seconds)
|
||||
- [x] Global rate limiting middleware (per-endpoint: 120/min public, 10/min register, 60/min filters, none admin)
|
||||
- [x] Security headers (X-Content-Type-Options, X-Frame-Options, X-XSS-Protection)
|
||||
- [x] **Image metadata stripping** - All EXIF/GPS stripped on upload via `imaging` library (security)
|
||||
- [x] Service eligibility system - Age and patch test filtering for bookings
|
||||
- `/api/services` - Returns services with eligibility for authenticated users
|
||||
- `/api/services/eligible-for/{user_id}` - Returns services with eligibility for specific user (admin booking flows)
|
||||
- Age < minimum_age_required → Service EXCLUDED
|
||||
- Patch test required + no record → Service GRAYED OUT
|
||||
- Patch test expired → Service GRAYED OUT
|
||||
- Patch test valid / not required → Normal
|
||||
- [ ] **Strict-Transport-Security (HSTS)** - Tell browsers to only access via HTTPS, prevents downgrade attacks. Add after HTTPS is working in prod.
|
||||
- [ ] **Referrer-Policy** - Track referrer sources for analytics (social media tracking). Use `strict-origin-when-cross-origin` to send origin but not full URLs.
|
||||
- [ ] **Rate limiter + Cloudflare** - Currently doesn't read CF-Connecting-IP header, so behind Cloudflare all users share one rate limit bucket.
|
||||
@@ -106,10 +114,12 @@
|
||||
|
||||
#### Booking Flow
|
||||
- [x] Service selection with pricing/duration
|
||||
- [x] **Service eligibility display** - Gray out services requiring patch test or below minimum age
|
||||
- [x] Calendar with availability detection
|
||||
- [x] Time slot generation with gap logic
|
||||
- [x] Customer details form (guest or authenticated)
|
||||
- [x] Auth store with token refresh logic
|
||||
- [x] **Admin booking flows** - Call-in and walk-in use `/api/services/eligible-for/{user_id}` for user-specific eligibility
|
||||
- [ ] **Customer booking submit** - `submitBooking()` only logs, needs `POST /api/bookings`
|
||||
- [ ] Payment integration (Square placeholder)
|
||||
|
||||
@@ -203,7 +213,8 @@ flowchart TD
|
||||
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/services` | List active services |
|
||||
| GET | `/api/services` | List active services (with eligibility for authenticated users) |
|
||||
| GET | `/api/services/eligible-for/{user_id}` | List services filtered by user's age and patch test status (admin only) |
|
||||
| POST | `/api/register` | Create new user account |
|
||||
| POST | `/api/login` | Authenticate and receive JWT |
|
||||
| GET | `/api/scheduling/default-hours` | Get weekly default hours |
|
||||
@@ -502,7 +513,7 @@ Running `local-dev-2.sh` creates:
|
||||
| Resource | Count | Details |
|
||||
|----------|-------|---------|
|
||||
| Users | 18 | 1 admin, 17 regular users |
|
||||
| Services | 6 | Classic Manicure, Gel Manicure (BIAB), Luxury Pedicure, Express Mani & Pedi, Gel Removal, Nail Art Add-on |
|
||||
| Services | 8 | 6 standard (no patch test) + 2 requiring patch tests (Gel Polish Full Set 48h, Luxury Gel Manicure 48h) |
|
||||
| Bookings | 45 | 8 past, 3 today, 4 tomorrow, 30 future (spread over 15 days) |
|
||||
| Confirmed | ~50% | Random selection of upcoming bookings auto-confirmed |
|
||||
| Exceptional | 2 | November Break (closed), Christmas Holiday (reduced hours) |
|
||||
|
||||
Reference in New Issue
Block a user