Gift-card rolling expiry (setting-driven, was dead config):
- GetGiftCardExpiryMonths(): single source of truth (business_settings
gift_card_expiry_months, fallback 24) shared by payment handlers and the
CleanupExpiredGiftCards job (was hardcoded 24).
- expiry_date now maintained on ALL 9 gift-card write sites (buy, topup,
transfer, redeem, terminal payment, refund credit, till) so the refund-time
guard at refunds.go actually fires. Schema default 12->24 + migration note;
test-DB seed aligned. Stale "expiry_date IS NULL" test rewritten; new
expired-card-rejected regression test.
Frontend SvelteDate purge (docs' stated convention, wide):
- All 180+ raw `new SvelteDate(...)` uses across routes/components replaced
with parseWallClockDate (backend UTC ISO) or new Date (wall-clock
constructors). SvelteDate imports removed. timeSlots.ts getDayWithOrdinal
fixed. Zero SvelteDate references remain; svelte-check clean.
Strict timezone/DST testing + QA fixes:
- 8 new hermetic boundary tests: clock.DST transitions (both 2026 folds),
closing-hours GMT vs BST, booking date-window midnight, refund-tier
elapsed-time independence, deposit-window UTC-instant, scheduling
LondonDateString midnight, today AT TIME ZONE window + UTC round-trip.
- today.go summary date labels fixed to London wall-clock (were showing the
previous UTC day during BST) + regression test.
- pgx ScanLocation fixed to UTC via AfterConnect (was host-local -> JSON
offsets depended on deployment TZ, contradicting the documented UTC
invariant) + regression test. Registered as a new *Type to avoid a data
race on the shared type map (caught by -race).
Admin Business Settings (setting now functional => legal floor):
- gift_card_expiry_months validation floor raised 1 -> 12 months (CMA/
Consumer Rights Act 2015 unfair-contract-term guidance) in endpoint + UI,
with rolling-expiry semantics shown in both display and edit form.
- 3 new expiry validation tests; 2 pre-existing message assertions updated.
Full suite 25/25 + race clean via run-tests.sh lockfile; svelte-check 0
errors/warnings; production build succeeds.
Replace clock.Now() with fixed London-timezone times in TestGetCurrentNext_WithMultipleDataPoints to prevent near-midnight UTC failures where bookings fall outside the London 'today' window.
New test files cover previously untested paths across DAV, validators,
S3, Square, mw, bookings, user, and payments packages.
Includes mock fix: HoldCheckouts flag on MockClient allows tests to
pause auto-complete goroutine for testing PENDING checkout states.
Coverage: 50.4% → 65.0% (+14.6pp)
Restore processImage (images.go) and nonDepositPaymentType (handlers.go) with //nolint:unused — used in test files.
Fix 97 tx.Rollback defers to silently discard expected "tx is closed" error after commit.
Frontend: remove 44 unused shadcn-svelte files, 2 dead components, 9 stale npm deps, prune unused exports.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
errcheck: add proper error handling with slog.Error for tx.Rollback, key generation, and s3/dav operations. Add nolint comments for intentionally discarded DB scan errors and HTTP write errors.
unused: remove dead code (svcRow type, processImage, nonDepositPaymentType, generateSecureCode, colorBold, nGreen, nRed)
gosimple S1021: merge var declaration with assignment in manage.go
ineffassign: remove dead assignments in settings.go, till.go, images.go
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Simplify auto-transition queries in GetCurrentAndNextHandler by using bookings.end_time computed column instead of inline start_time + duration calculations. Remove ::text casts from end_time columns.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Migrate all test files from SetupTestDB/db.DB pattern to per-test transactions:
- Replace SetupTestDB(t) with SetupTestTx(t) for context + transaction
- Replace db.DB.Query/QueryRow/Exec with tx.Query/QueryRow/Exec
- Replace context.Background() with context from SetupTestTx
- Replace defer rows.Close() pattern with explicit rows.Close()
- Add testdb.SeedBaseline(pool) to all TestMain functions
- Wire db.Conn = db.NewPoolProxy(pool) in all TestMain functions
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Replace direct *pgxpool.Pool usage with PoolProxy wrapper across the entire backend:
- db.DB renamed to db.Conn (*pgxpool.Pool -> *PoolProxy)
- JWT functions now accept context.Context instead of using context.Background()
- Handler DB calls route through PoolProxy for per-test transaction support
- Fixture/helper/testdb functions accept Querier interface for decoupling
- Query ordering fixed in bookings handlers: COUNT after data query to avoid pgx conn busy
- Time truncation fixed: time.Date instead of Truncate(24*time.Hour) for week start calc
- testmain_test.go files updated with SeedBaseline and NewPoolProxy
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add comprehensive test suite for today package handlers.
- Add tests for current/next appointment, today appointments, and pending approvals
- Uses testutils.SetupTestDB for isolated test database
- Follows established test patterns in the codebase
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Name history system tracks user name changes and displays former names on bookings, appointments, and admin views until consumed by the first completed booking post-change.
- Add name_history queries to today.go, bookings.go, manage.go, profile.go
- Show previous first/last name on today appointments, pending approvals,
booking details, edit requests, and admin user views
- Paginate bookings by start_time instead of created_at (more intuitive ordering)
- Add name change detection in UpdateProfileHandler with history insert
- Support DAV_BASE_URL env var for configurable CardDAV endpoint
- Add referral_savings to profile response
- Add ParseCursor3 validator for user list cursor pagination
- Consume name_history entries when a booking is completed (ProgressBookingHandler)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Add CreateTestDatabase function for parallel isolated test databases per package.
- Add CreateTestDatabase() for isolated test DBs (parallel-safe)
- Move all TestMain functions to per-package testmain_test.go files
- Remove old TestMain from handlers_test.go, jwt_test.go, main_test.go
- Add JWT init guard in main.go to skip when -test.* flags detected
- Update testdb.go with admin DSN and proper cleanup
- Rename test database to crussell_test_db for consistency
- Replace testdb.NewPool + testdb.Migrate pattern with CreateTestDatabase
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Introduce DoneForDay state and DailySummary struct in current-next endpoint. Adds computeAggregateSummary for daily/weekly revenue, tips, duration, customer stats, and new booking services. Adds isDayOpen, findWeekSummaryRange, and getClosingTime with exceptional hours lookup. Scopes all current/next queries to today's date range.
Ultraworked with Sisyphus
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Update booking create/confirm/progress/reserve handlers to support custom_service_ids and custom overrides. Add UNION ALL queries to include custom_services in booking detail, payment summary, scheduling availability, today dashboard, and customer relationship queries.
Ultraworked with Sisyphus (https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
- 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