Backend: - Add enriched response types (EditSnapshot, EnrichedEditRequest) with original vs proposed snapshots - Add 4 new GET endpoints for viewing edit requests (user and admin scoped) - Remove github.com/lib/pq dependency — use native PostgreSQL array scanning - Clean up edit requests, time blockers, and notifications on booking cancellation - Validate exceptional closed hours on admin approve (409 Conflict) - Notification upsert on edit request replace (no duplicate admin notifications) Frontend: - New user EditRequestModal with time/services/both modes and lunch protection - New admin EditRequestModal with side-by-side diff (date/time, services, notes) - Integrate edit requests into PendingApprovals card and notifications page - Preload 3 months of availability to prevent calendar snap-back - Apply lunch protection to isDateUnavailable in BookingFlow and BookingCreateModal - Fix accessibility: card list items use <button> instead of <div> Dev & Docs: - Seed edit requests in local-dev-2.sh - Update all Obsidian manuals with enriched edit request documentation - 42 new tests (438/441 passing)
100 lines
3.7 KiB
Markdown
100 lines
3.7 KiB
Markdown
# Crussell
|
|
|
|
Nail salon booking platform — Go 1.25 backend + SvelteKit 5 frontend + Docker. Built for a UK sole-trader nail artist.
|
|
|
|
## Features
|
|
|
|
- **Three booking flows**: self-service (customer), walk-in (admin), call-in (admin)
|
|
- **Slot reservations**: temporary holds prevent double-booking (4 TTL types)
|
|
- **Guest accounts**: disposable accounts for one-off bookings, GDPR-compliant anonymization
|
|
- **Service eligibility**: age requirements + patch test validation
|
|
- **Deposit system**: 3-strike rule for late cancellations, 24-hour threshold
|
|
- **Square payments**: in-person Terminal + online Web Payments SDK (dev mock + prod stub, build-tagged)
|
|
- **Payment methods**: Card (Square Terminal/online), cash, gift card — with saved cards, refunds, and webhook handling
|
|
- **Payment types**: deposit, full, partial, balance, tip — admin can override service prices during payment
|
|
- **Scheduling**: default hours, holiday overrides, time blockers
|
|
- **Loyalty & discounts**: stamp-based loyalty, time-based and milestone campaigns
|
|
- **Portfolio gallery**: S3/R2 storage with tag/category filtering
|
|
- **CardDAV sync**: profile photos synced to SabreDAV contacts
|
|
- **Admin notifications**: priority-sorted queue with bell icon, `/notifications` page, acknowledge flow
|
|
- **User notification preferences**: per-channel toggles (email, SMS, browser) in account settings
|
|
- **Enriched edit requests**: side-by-side original vs proposed booking snapshots (time, services, prices, durations, user details) for admin review
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
Crussell/
|
|
├─ backend/ # Go 1.25 + chi router API
|
|
│ ├─ handlers/ # API handlers (auth, bookings, payments, scheduling, etc.)
|
|
│ │ ├─ payments/ # Square payment handlers (terminal, online, refunds, tips)
|
|
│ │ └─ webhooks/ # Square webhook handler
|
|
│ ├─ internal/ # Internal packages
|
|
│ │ └─ square/ # Square client (dev mock + prod stub, build-tagged)
|
|
│ └─ testutils/ # Test helpers (fixtures, testdb, JWT)
|
|
├─ frontend/ # SvelteKit 5 SPA (static build)
|
|
│ └─ src/lib/components/
|
|
│ ├─ payments/ # PaymentModal (admin), UserPaymentModal (user)
|
|
│ └─ booking/ # BookingFlow (5-step wizard)
|
|
├─ sabredav/ # PHP + Composer for DAV
|
|
├─ nginx/ # Nginx reverse-proxy for HTTP & HTTPS
|
|
├─ init-scripts/ # PostgreSQL init SQL
|
|
├─ compose.yml # Docker-Compose definition
|
|
├─ local-dev-2.sh # Dev helper using tmux (seeds DB with test data)
|
|
└─ README.md
|
|
```
|
|
|
|
## Prerequisites
|
|
|
|
| Tool | Version |
|
|
|------|---------|
|
|
| Docker & Docker Compose | >= 20.10 |
|
|
| Go | >= 1.22 |
|
|
| Node | >= 18 (npm) |
|
|
| tmux | >= 3.0 |
|
|
|
|
## Getting Started
|
|
|
|
### Docker Compose
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
# Edit .env — set POSTGRES_*, JWT_SECRET_KEY
|
|
docker compose up --build -d
|
|
```
|
|
|
|
| Service | URL |
|
|
|---------|-----|
|
|
| Frontend | http://localhost |
|
|
| API | http://localhost/api |
|
|
| SabreDAV | http://localhost/dav |
|
|
|
|
### Local Development
|
|
|
|
```bash
|
|
chmod +x local-dev-2.sh
|
|
./local-dev-2.sh
|
|
```
|
|
|
|
Launches a tmux session (`crussell-dev`) with 4 panes: psql console, Go dev server, Svelte dev server, and Rustfs logs. Seeds the database with 20 users, 12 services, 43 bookings, guest accounts, time blockers, and exceptional hours.
|
|
|
|
Default login (all password: `password`):
|
|
- Admin: `admin@example.com`
|
|
- User: `user@example.com`
|
|
|
|
## Building & Testing
|
|
|
|
```bash
|
|
# Backend
|
|
cd backend && go build -o bin/backend ./main.go
|
|
|
|
# Frontend
|
|
cd frontend && npm ci && npm run build
|
|
|
|
# Tests (438/441 passing, 3 skipped)
|
|
cd backend && go test -tags "test,dev" ./...
|
|
```
|
|
|
|
## Full Documentation
|
|
|
|
For detailed user journeys, admin workflows, architecture, API reference, and database schema, see [obsidian/Crussell/](obsidian/Crussell/).
|