docs: update documentation for custom services feature

Update Technical Manual (handlers, API endpoints, component hierarchy, tables), Admin Manual (new Custom Services section, updated FAQ, booking creation), Overview (test count, admin features), and README (new feature line, admin updates).

Ultraworked with Sisyphus (https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-06-15 17:02:57 +01:00
co-authored by Sisyphus
parent 867f86978b
commit 6c27a44302
4 changed files with 34 additions and 8 deletions
+17 -2
View File
@@ -175,6 +175,21 @@ The Services section lets you manage the salon's treatment list:
**Patch test duration:** When you create a service, you can set how many hours a patch test takes. If the duration is more than 0 hours, the system automatically creates a patch test record for that service.
### Custom Services
Custom services are one-off or special-request treatments that aren't in the permanent catalog. For example, a bridal party wants a specific nail design that you don't normally offer.
You can manage custom services in the **Custom Services** section:
- **Create** — Add a custom service with name, description, price, duration, and minimum age. A custom service will not appear on the public price list.
- **Edit** — Update the name, price, duration, or other details.
- **Promote** — Convert a custom service into a permanent service. This migrates all existing booking references from the custom service to the new permanent service. Use this when a one-off design becomes popular enough to offer regularly.
- **Delete** — Remove a custom service. You can only delete custom services that have never been used in a booking.
- **Search** — Search by name or keyword.
- **Popular** — See which custom services are most frequently used.
Custom services can be added to bookings from the **Booking Create** and **Walk-In** flows, just like regular services.
### Scheduling
The Scheduling section has three parts:
@@ -282,7 +297,7 @@ When a customer calls to book over the phone:
2. Click **Create Booking**
3. Select the customer (search by name or email)
4. The system shows their patch test records and age — services they're not eligible for are greyed out
5. Select the services they want
5. Select the services they want — you can also add **custom services** (one-off services not in the public list) alongside regular services
6. Pick a date and time
7. The system holds the slot for 1 hour (call-in reservation)
8. Fill in notes if needed
@@ -616,4 +631,4 @@ Pending bookings need admin approval. If the booking has notes or is for today,
### "A customer says they want to create a custom service (bridal party, etc.)"
Currently, all services must be added to the permanent catalog. There's no way to create a one-off custom service. Add it to the Services list, then delete it after the appointment if needed.
You can now create **custom services** — one-off or special-request services that aren't part of the permanent catalog. Go to the **Admin** dashboard → **Custom Services** section. Create the custom service with name, price, and duration — it won't appear in the public service list. Custom services can be added to any booking from the admin booking flows. You can also promote a custom service to a permanent service if you decide to offer it regularly.
+2 -2
View File
@@ -65,7 +65,7 @@ Lunch protection: `findAllLunchGaps()` returns all gap durations in the middle w
**Today page** (`/today`): current + next appointment cards, interactive daily calendar grid, pending approvals queue, today stats summary (total/confirmed/pending/completed). Walk-in booking wizard (3-step) and call-in wizard (4-step) with slot reservation.
**Admin dashboard** (`/admin`): users list + detail modal (profile, bookings, relationship data, patch tests, loyalty/referrals, privacy/consent), services CRUD, bookings list with search, scheduling management (default hours, exceptional groups, time blockers), discount campaigns, portfolio image upload with tag management, gift card management, business settings.
**Admin dashboard** (`/admin`): users list + detail modal (profile, bookings, relationship data, patch tests, loyalty/referrals, privacy/consent), services CRUD, **custom services management** (one-off services with create/edit/promote/delete), bookings list with search, scheduling management (default hours, exceptional groups, time blockers), discount campaigns, portfolio image upload with tag management, gift card management, business settings.
**Reschedule modal**: search available slots, conflict detection (overlapping bookings), one-click confirm. Side-by-side enriched snapshots in Pending Approvals for edit requests.
@@ -202,7 +202,7 @@ npm run dev # Dev server with HMR
```bash
cd backend
go test -tags "test,dev" -p 1 -count=1 ./... # 633/636 passing, 3 skipped
go test -tags "test,dev" -p 1 -count=1 ./... # 682/685 passing, 3 skipped
go test -tags "test,dev" -v -run TestName ./... # Single test
```
+11 -2
View File
@@ -51,7 +51,7 @@ Backend (:8080)
| `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, giftcards.go, till.go | Square payments: terminal, online, refunds, tips, saved cards, gift cards (CRUD, topup, transfer, redeem, buy, expired balances, till sales) |
| `handlers/webhooks` | square.go | Square webhook handler for payment status updates |
| `handlers/admin` | users.go, analytics.go, discount_campaigns.go, settings.go | Admin user management, discount campaigns, analytics (stub), business settings (GET/PUT with VAT, gift card config) |
| `handlers/admin` | users.go, analytics.go, custom_services.go, discount_campaigns.go, settings.go | Admin user management, custom services CRUD (list/create/get/update/promote/delete), discount campaigns, analytics (stub), business settings (GET/PUT with VAT, gift card config) |
| `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, gdpr_export.go | User profile, guest creation (with CheckEmailHandler for registered-email detection), loyalty, contact info, GDPR export (async with 12h cache) |
| `handlers/services` | services.go | Service catalog, eligibility filtering, patch_test_duration_hours auto-creates patch test records |
@@ -121,6 +121,7 @@ src/lib/components/
│ ├── BookingCreateModal.svelte # Admin booking creation (4-step, uses shared timeSlots utils)
│ ├── BookingModal.svelte # View booking details (shows created_by_name)
│ ├── BookingsCard.svelte # Bookings list
│ ├── CustomServicesManagement.svelte # Custom services CRUD (list/create/edit/promote/delete)
│ ├── CallInBooking.svelte # Call-in booking flow
│ ├── EditBookingModal.svelte # Edit booking services
│ ├── HolidayHours.svelte # Exceptional schedule management
@@ -323,6 +324,12 @@ src/lib/components/
| POST | `/api/admin/gift-cards/{id}/transfer` | Transfer gift card to another user |
| POST | `/api/admin/gift-cards/{id}/redeem` | Redeem gift card to account balance |
| POST | `/api/gift-cards/buy` | User buys gift card online (with idempotency_key) |
| GET | `/api/admin/custom-services` | List custom services (search `q`, popular, pagination `page`/`per_page`) |
| POST | `/api/admin/custom-services` | Create custom service (name, price, duration, minimum age, notes) |
| GET | `/api/admin/custom-services/{id}` | Get single custom service |
| PUT | `/api/admin/custom-services/{id}` | Update custom service fields |
| POST | `/api/admin/custom-services/{id}/promote` | Promote custom service to regular service (migrates booking references) |
| DELETE | `/api/admin/custom-services/{id}` | Delete custom service (409 if usage_count > 0) |
---
@@ -347,7 +354,7 @@ src/lib/components/
| `discount_campaign_status` | `draft`, `active`, `completed`, `cancelled` |
| `till_item_type` | `gift_card`, `merchandise`, `service` |
### Tables (30 total)
### Tables (37 total)
| Table | Purpose |
|-------|---------|
@@ -357,6 +364,8 @@ src/lib/components/
| `patch_tests` | Patch test definitions (notice_duration_hours, expiry_months, service_ids) |
| `user_patch_tests` | User patch test completion records (tested_at, notes) |
| `services` | Service offerings |
| `custom_services` | One-off / special-request services (usage_count, created_by) |
| `booking_custom_services` | Custom services per booking (override_price, override_duration_minutes) |
| `bookings` | Appointment records (idempotency_key, deposit_required, deposit_paid, deposit_amount, deposit_deadline) |
| `booking_services` | Services per booking (override_price, override_duration_minutes) |
| `booking_edit_requests` | Pending customer edit requests |