Update README and obsidian documentation with the new admin reservation
cancel endpoint (DELETE /api/admin/bookings/reserve), updated API route tables,
reservation TTL descriptions, and test count from 1,180 to 1,198.
Document self-blocking prevention (excludeUserID), explicit reservation cancellation endpoint, background cleanup goroutine, and edit_request reservation scrubbing. Bump test counts from 1,169 to 1,180 and package count from 19 to 20. Add race detector command to README.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Update README with middleware section, FOR UPDATE + closing_time in bookings, pending-payment-first VAT flow in gift cards, and bumped test counts (1,043 run / 1,190 defined). Update Overview.md with transaction pattern documentation, middleware details, and new files (closing_time, repo). Update Technical Manual.md test count (1,190). Update Testing Architecture with new test additions and timing.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Update project documentation and development scripts.
- Update README test counts (953/957 passing, 8 skipped)
- Simplify dev script: remove test DB seeding, add name history creation,
clean up stale test databases on startup, remove -p 1 test flag
- Update obsidian documentation for new features:
- Name history system docs
- Referral discount system docs
- Database migration docs (CHAR(12) short IDs)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Admin Manual: add summary card section (end-of-day/closed-day states). Technical Manual: update today.go, API docs for current-next and bookings endpoints, fix exceptional_group_applications column name. Testing Architecture: add working hours seeding, exceptional hours seeding, pagination test patterns, and current test suite status.
Ultraworked with Sisyphus
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Update README feature list with GDPR compliance system details. Update Overview.md Data & Compliance section with full Article 15 SAR details. Update Technical Manual: add /gdpr route, gdpr_export.go handler, GET /api/user/gdpr-export endpoint, update Key Functions table, update Guest User System section. Update Future Work backlog: mark #7 GDPR export as complete, update dependency map and Phase 3 execution order. Update test count: 446/449 -> 576/579.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
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)
Split Crussell Nails.md (822 lines) into 5 focused documents:
- README.md: slimmed to 84 lines (elevator pitch + run instructions)
- Overview.md: expanded landing page with architecture diagram and quick links
- User Manual.md: 358 lines, customer-facing journeys in plain English
- Admin Manual.md: 493 lines, staff operations guide with zero technical jargon
- Technical Manual.md: 736 lines, full API reference, schema, key systems
All user/admin manuals rewritten for non-technical audiences — no API
endpoints, component names, or implementation details.
Reflect new PUT /api/admin/bookings/{id} services endpoint, EditBookingModal
component, and updated test count (306/308). Mark handleEdit() stub resolved
in gap backlog.
- Add time blocker management for booking edit requests
- Add closing_time field to admin today/current-next endpoint
- Update UserBookingModal and CurrentAppointment UI components
- Fix fmt import in bookings_test.go (was missing)
- Fix created_by FK in TestAdminApproveEditRequest_TimeBlockerOverlap
- Update test coverage for edit request time blocker overlap
- Update gap backlog documentation
- Remove automatic deposits_required=3 on no-shows, give admin flexibility
- Add tests for no-show deposit logic (forgiven, over 24h, under 24h)
- Add tests for reservation cleanup TTL (admin walk-in/call-in 15min)
- Add tests for EXIF GPS data stripping in portfolio images
- Add tests for contact info endpoint
- Add tests for guest account anonymization
- backend/handlers/bookings/admin_reserve.go:
- Add explicit reservation_type field ("walkin" | "callin") to request struct
- Remove TTL-based heuristic for type detection
- Walk-in: uses duration_minutes, allows null user_id, 1min past grace
- Call-in: requires service_ids, validates future time, calculates duration from services
- Both types now use 15-minute TTL
- backend/handlers/scheduling/time-blockers.go:
- Update CleanupOldReservations: both walkin and callin use 15min TTL (was 10min/60min)
- frontend/WalkInBooking.svelte:
- Full rewrite of reservation logic
- If available now and >15min remaining: reserve from now to slot end
- If <=15min or not available: reserve next full slot
- Always reserves before opening modal (never open without hold)
- Passes reservedDuration to modal
- TTL changed from 5 to 15 minutes
- frontend/WalkInCreateModal.svelte:
- Replace dead commented-out guest code with working guest creation
- Guest account created at submit time (not earlier)
- Phone defaults to +447700900000 if blank
- Phone field marked optional with helper text
- Name split into firstName/lastName for backend
- Validation relaxed: only name required for guests
- frontend/BookingCreateModal.svelte:
- TTL changed from 60 to 15 minutes
- Add reservation_type: "callin" to reserve payload
- Guest creation uses correct firstName/lastName fields
- Default guest phone to +447700900000
- Reservation no longer requires selectedUserId (works for guests)
- docs: Update Future Work backlog to mark completed items
- backend/handlers/user/account.go: Wire DELETE /api/user/account to call
anonymize_user() for registered users and delete_guest_user() for guests,
with CardDAV contact cleanup
- backend/handlers/user/profile_test.go: Add TestAccount_DeleteGuest and
enhance TestAccount_Delete to verify anonymization results
- backend/main.go: Add GET /api/health endpoint with DB ping and S3 status
check; add HSTS and Referrer-Policy security headers; replace
http.ListenAndServe with http.Server + graceful SIGTERM/SIGINT shutdown
- frontend/routes/+layout.svelte: Replace alert() with toast notifications
for email verification flow
- frontend/routes/login/+page.svelte: Replace alert() with toast.info for
social login prototype buttons
- frontend/booking/BookingFlow.svelte: Remove 2 console.log debug calls;
add cancellation policy note in Step 3; add timezone policy comment
- frontend/ImageUpload.svelte: Comment out debug console.log
- init-scripts/init-script.sql: Add delete_guest_user() SQL function
- docs: Update README.md and Obsidian notes to reflect completed items
FIXES:
- Clarified that 1-hour minimum advance requirement applies to USER bookings only
- Admins can create walk-in bookings with no advance notice via AdminCreateBookingForUserHandler
- Updated test comments to reflect this distinction
NEW TESTS ADDED:
- TestAdminBookings_Create_WalkIn: Admin creates booking with < 1h notice (walk-in)
- TestAdminBookings_Create_WalkInWithDeposits: Admin walk-in with outstanding deposits + enforce_deposits=false
TEST SCENARIOS VERIFIED:
✓ User: Cannot book < 1h in advance (400 error)
✓ Admin: CAN book < 1h in advance (walk-in, 201 created)
✓ Admin: Can create walk-ins even with user deposits (with enforce_deposits bypass)
✓ Admin: Can bypass minimum advance requirement
BUILD STATUS:
✓ go build -tags test ./handlers/bookings
✓ go build -tags test ./handlers/admin
✓ go build -tags dev ./main.go
Documentation now clearly distinguishes:
- User journey: 1h minimum advance (universal)
- Admin journey: No minimum advance (accept walk-ins)
Backend:
- Fix GetAllAdminBookingsHandler and SearchAdminBookingsHandler to
return totalPages in response
- Auto-record patch tests when booking status progresses to "completed"
- Add GET/POST /api/admin/users/{id}/patch-tests endpoints
Frontend:
- BookingsCard: proper pagination with 4 per page, prev/next buttons
- UsersCard, BookingCreateModal, WalkInCreateModal: per_page=4 for user
search
- Add PatchTestModal for manual patch test entry in UserModal
- Hide patch test section when user has no eligible services
Database:
- Add UNIQUE constraint on user_service_patch_tests(user_id, service_id)
- 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