Commit Graph
116 Commits
Author SHA1 Message Date
popertots ad15127777 fix: remove nonDepositPaymentType dead code, wire dead handlers to routes 2026-07-11 15:01:26 +01:00
popertots 9b235a1298 fix: add error logging to 3 non-aggregate nolint:errcheck sites (duration lookup, deposit-paid scans) 2026-07-11 14:41:06 +01:00
popertots b549014a68 fix: add nolint:errcheck to AdminGetInProgressBookingHandler json.Encode
CI / Docker compose check (push) Successful in 21s
CI / Env docs check (push) Successful in 23s
CI / Nginx config check (push) Successful in 27s
CI / Frontend deps check (push) Successful in 30s
CI / Frontend major deps (push) Successful in 30s
CI / Go build (push) Successful in 38s
CI / Secrets scan (push) Successful in 43s
CI / Frontend build (push) Successful in 46s
CI / Knip (push) Successful in 1m10s
CI / Go vet (prod) (push) Successful in 1m21s
CI / Go vet (dev) (push) Successful in 1m53s
CI / Frontend a11y check (push) Successful in 2m16s
CI / go mod tidy (push) Successful in 50s
CI / Staticcheck (dev) (push) Successful in 2m48s
CI / Frontend QC (audit) (push) Successful in 59s
CI / golangci-lint (push) Successful in 3m13s
CI / Go vulnerabilities (push) Successful in 1m35s
CI / Staticcheck (prod) (push) Successful in 3m28s
CI / Frontend QC (typecheck) (push) Successful in 1m32s
CI / Security scan (prod) (push) Successful in 3m49s
CI / Security scan (dev) (push) Successful in 4m45s
CI / Frontend QC (lint) (push) Successful in 2m8s
CI / Svelte strict check (push) Successful in 1m16s
CI / Tests (prod) (push) Successful in 3m2s
CI / Tests (dev) (push) Successful in 3m3s
CI / Race (prod) (push) Successful in 7m3s
CI / Race (dev) (push) Successful in 7m15s
2026-07-11 13:30:09 +01:00
popertots 28620f69a5 fix: restore dead functions properly, match test expectations, fix vet/lint
CI / Docker compose check (push) Successful in 13s
CI / Env docs check (push) Successful in 14s
CI / Nginx config check (push) Successful in 14s
CI / Frontend major deps (push) Successful in 25s
CI / Frontend deps check (push) Successful in 25s
CI / Secrets scan (push) Successful in 39s
CI / Go build (push) Successful in 39s
CI / Frontend build (push) Successful in 45s
CI / Knip (push) Successful in 27s
CI / Frontend a11y check (push) Successful in 1m27s
CI / Go vet (prod) (push) Successful in 1m53s
CI / go mod tidy (push) Successful in 43s
CI / Go vet (dev) (push) Successful in 2m6s
CI / Frontend QC (audit) (push) Successful in 45s
CI / Staticcheck (prod) (push) Successful in 2m51s
CI / Staticcheck (dev) (push) Successful in 3m5s
CI / Frontend QC (typecheck) (push) Successful in 1m50s
CI / Go vulnerabilities (push) Successful in 2m8s
CI / golangci-lint (push) Failing after 4m3s
CI / Security scan (prod) (push) Successful in 4m35s
CI / Security scan (dev) (push) Successful in 4m47s
CI / Tests (prod) (push) Has been skipped
CI / Tests (dev) (push) Has been skipped
CI / Race (prod) (push) Has been skipped
CI / Race (dev) (push) Has been skipped
CI / Frontend QC (lint) (push) Successful in 2m8s
CI / Svelte strict check (push) Successful in 38s
2026-07-11 13:23:27 +01:00
popertots a3c0be2890 fix: audit nolint:errcheck — fix dangerous suppression patterns
CI / Nginx config check (push) Successful in 14s
CI / Docker compose check (push) Successful in 14s
CI / Env docs check (push) Successful in 15s
CI / Frontend major deps (push) Successful in 25s
CI / Frontend deps check (push) Successful in 26s
CI / Secrets scan (push) Successful in 36s
CI / Go build (push) Successful in 42s
CI / Frontend build (push) Successful in 48s
CI / Knip (push) Successful in 28s
CI / Frontend a11y check (push) Successful in 1m26s
CI / Go vet (prod) (push) Failing after 2m9s
CI / go mod tidy (push) Successful in 59s
CI / Go vet (dev) (push) Failing after 2m10s
CI / Staticcheck (prod) (push) Failing after 2m42s
CI / Staticcheck (dev) (push) Failing after 2m56s
CI / Frontend QC (audit) (push) Successful in 1m7s
CI / golangci-lint (push) Successful in 3m38s
CI / Go vulnerabilities (push) Successful in 1m40s
CI / Frontend QC (typecheck) (push) Successful in 1m45s
CI / Frontend QC (lint) (push) Failing after 1m21s
CI / Svelte strict check (push) Has been skipped
CI / Security scan (prod) (push) Successful in 4m18s
CI / Security scan (dev) (push) Successful in 4m28s
CI / Tests (prod) (push) Has been skipped
CI / Tests (dev) (push) Has been skipped
CI / Race (prod) (push) Has been skipped
CI / Race (dev) (push) Has been skipped
2026-07-11 12:57:41 +01:00
popertots 19be37171b fix: remove 3 dead code blocks (UserCancelBookingHandler, AdminGetInProgressBookingHandler, processImage) 2026-07-11 12:51:42 +01:00
popertots 844df4c127 fix: use raw clock.Now()+40h for booking test times (avoids time-sensitive boundaries)
CI / Nginx config check (push) Successful in 24s
CI / Docker compose check (push) Successful in 25s
CI / Env docs check (push) Successful in 28s
CI / Frontend deps check (push) Successful in 44s
CI / Frontend major deps (push) Failing after 44s
CI / Secrets scan (push) Successful in 49s
CI / Go build (push) Successful in 53s
CI / Frontend build (push) Successful in 55s
CI / Knip (push) Successful in 41s
CI / Frontend a11y check (push) Successful in 2m14s
CI / Go vet (prod) (push) Successful in 2m3s
CI / Go vet (dev) (push) Successful in 2m5s
CI / go mod tidy (push) Successful in 32s
CI / Frontend QC (audit) (push) Successful in 41s
CI / Staticcheck (dev) (push) Successful in 2m56s
CI / Staticcheck (prod) (push) Successful in 3m2s
CI / golangci-lint (push) Successful in 3m16s
CI / Go vulnerabilities (push) Successful in 1m21s
CI / Frontend QC (typecheck) (push) Successful in 1m29s
CI / Security scan (prod) (push) Successful in 4m16s
CI / Security scan (dev) (push) Successful in 4m46s
CI / Frontend QC (lint) (push) Successful in 2m4s
CI / Svelte strict check (push) Successful in 1m51s
CI / Tests (prod) (push) Successful in 3m54s
CI / Tests (dev) (push) Failing after 3m59s
CI / Race (prod) (push) Successful in 7m14s
CI / Race (dev) (push) Successful in 7m25s
2026-07-11 10:35:59 +01:00
popertots abd53baf35 fix: time-sensitive tests use savepoint pattern, avoid 48h auto-approval boundary
CI / Env docs check (push) Successful in 17s
CI / Docker compose check (push) Successful in 19s
CI / Nginx config check (push) Successful in 20s
CI / Frontend deps check (push) Successful in 27s
CI / Frontend major deps (push) Failing after 27s
CI / Secrets scan (push) Successful in 39s
CI / Go build (push) Successful in 40s
CI / Frontend build (push) Successful in 43s
CI / Knip (push) Successful in 41s
CI / Frontend a11y check (push) Successful in 1m37s
CI / Go vet (prod) (push) Successful in 1m53s
CI / go mod tidy (push) Successful in 31s
CI / Frontend QC (audit) (push) Successful in 51s
CI / Go vet (dev) (push) Successful in 2m50s
CI / Staticcheck (prod) (push) Successful in 2m57s
CI / Staticcheck (dev) (push) Successful in 3m19s
CI / Go vulnerabilities (push) Successful in 1m35s
CI / golangci-lint (push) Successful in 3m37s
CI / Frontend QC (typecheck) (push) Successful in 1m35s
CI / Security scan (prod) (push) Successful in 4m10s
CI / Security scan (dev) (push) Successful in 4m38s
CI / Frontend QC (lint) (push) Successful in 1m58s
CI / Svelte strict check (push) Successful in 1m12s
CI / Tests (prod) (push) Successful in 3m8s
CI / Tests (dev) (push) Failing after 4m8s
CI / Race (prod) (push) Successful in 7m34s
CI / Race (dev) (push) Failing after 7m40s
2026-07-11 10:14:12 +01:00
popertots 3029fd5179 test: add coverage tests across backend + fix mock for PENDING checkout support
CI / Nginx config check (push) Successful in 13s
CI / Env docs check (push) Successful in 15s
CI / Docker compose check (push) Successful in 15s
CI / Frontend major deps (push) Failing after 24s
CI / Frontend deps check (push) Successful in 30s
CI / Secrets scan (push) Successful in 38s
CI / Go build (push) Successful in 39s
CI / Frontend build (push) Successful in 1m3s
CI / Knip (push) Successful in 45s
CI / Go vet (prod) (push) Failing after 1m42s
CI / Frontend a11y check (push) Successful in 2m34s
CI / Go vet (dev) (push) Successful in 2m29s
CI / Staticcheck (prod) (push) Failing after 2m38s
CI / go mod tidy (push) Successful in 1m3s
CI / Staticcheck (dev) (push) Successful in 2m55s
CI / Frontend QC (audit) (push) Successful in 51s
CI / golangci-lint (push) Successful in 3m22s
CI / Go vulnerabilities (push) Successful in 1m26s
CI / Frontend QC (typecheck) (push) Successful in 2m18s
CI / Security scan (prod) (push) Successful in 4m18s
CI / Security scan (dev) (push) Successful in 4m40s
CI / Tests (prod) (push) Has been skipped
CI / Tests (dev) (push) Has been skipped
CI / Race (prod) (push) Has been skipped
CI / Race (dev) (push) Has been skipped
CI / Frontend QC (lint) (push) Successful in 2m18s
CI / Svelte strict check (push) Successful in 43s
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)
2026-07-10 18:13:44 +01:00
popertots ef3cfe8c4f fix: replace crypto/md5 with crypto/sha256 for IP hashing 2026-07-10 12:04:49 +01:00
popertots d1e85bb855 fix: add missing err checks and fix loop termination in tests 2026-07-10 12:03:11 +01:00
popertots cf0cd8de15 fix: remove 10 unused test functions flagged by staticcheck U1000 2026-07-10 12:01:02 +01:00
popertotsandSisyphus 407de74b51 fix: restore test-used functions, silence tx.Rollback closed errors, prune knip dead code
CI / Frontend deps check (push) Successful in 22s
CI / Go vulnerabilities (push) Successful in 32s
CI / Go build (push) Successful in 32s
CI / go mod tidy (push) Successful in 13s
CI / Knip (push) Failing after 33s
CI / Frontend build (push) Successful in 1m12s
CI / Svelte strict check (push) Has been skipped
CI / Frontend QC (audit) (push) Has been skipped
CI / Frontend QC (typecheck) (push) Has been skipped
CI / Frontend QC (lint) (push) Has been skipped
CI / Go vet (push) Successful in 57s
CI / golangci-lint (push) Successful in 1m8s
CI / Tests (prod) (push) Successful in 1m45s
CI / Tests (dev) (push) Successful in 2m5s
CI / Race (prod) (push) Successful in 3m27s
CI / Race (dev) (push) Successful in 4m52s
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>
2026-07-09 19:20:25 +01:00
popertotsandSisyphus ed9cb1489c fix: resolve golangci-lint violations (errcheck, unused, gosimple, ineffassign)
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>
2026-07-09 18:53:51 +01:00
popertotsandSisyphus 510828c924 chore: run go fix for Go 1.26 modernization
CI / Go vulnerabilities (push) Successful in 1m10s
CI / Build & Vet (push) Successful in 1m39s
CI / Frontend build (gate) (push) Successful in 1m42s
CI / Frontend QC (audit) (push) Successful in 56s
CI / Frontend QC (typecheck) (push) Successful in 1m36s
CI / Frontend QC (lint) (push) Successful in 1m51s
CI / Tests (prod) (push) Has been cancelled
CI / Tests (dev) (push) Has been cancelled
CI / Race (prod) (push) Has been cancelled
CI / Race (dev) (push) Has been cancelled
106 files: interface{}→any, strings.Split→SplitSeq, CutPrefix/Cut, strings.Builder, slices.Contains, remove redundant // +build directives, gofmt import ordering and indentation.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-09 17:25:23 +01:00
popertotsandSisyphus e86248b27c refactor: move auth, GDPR, and booking cleanup to centralized scheduler
Convert CleanupRevokedJTIs to return (int, error) and remove StartJTICleanup goroutine. Add CleanupStaleLoginEntries and CleanupGDPRExportCache for centralized scheduler. Add clock.London timezone location.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-07 00:10:00 +01:00
popertotsandSisyphus 72161e8c4f docs(backend): clarify auth fallback rationale in reserve handler
CI / Go vulnerabilities (push) Successful in 37s
CI / Tests (push) Successful in 1m33s
CI / Frontend lint & types (push) Successful in 1m46s
CI / Race detector (push) Successful in 3m38s
Expands inline comments to explain why the Bearer token fallback is deliberately kept — it serves 22+ test invocations that call ReserveSlotHandler directly without middleware, never executes in production, and acts as defense-in-depth.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-06 19:22:08 +01:00
popertots c2aa0b93cb feat(api): add admin reservation cancel endpoint
Add DELETE /api/admin/bookings/reserve to release admin walk-in/call-in reservations.

New handler AdminCancelReservationHandler targets only RESERVATION:admin:%
entries (partitioned from user RESERVATION:user:% by WHERE clause). Includes
12 tests covering walkin + callin success, isolation, no-op, unauth, empty ctx,
walkin+callin coexistence, anon untouched, response format parity, overlapping
reservations deleted, user reservations untouched, and idempotent double-cancel.

Inverse-isolation tests in cancel_reservation_test.go prove the user-side
DELETE /api/bookings/reserve does not touch admin or anon reservations.
2026-07-06 17:58:03 +01:00
popertotsandSisyphus 2e0760f083 feat: add IP-based anon reservation cleanup to admin reserve handler
Extend AdminReserveSlotHandler's pre-overlap DELETE to also clean up anonymous RESERVATION:anon entries matching the admin's IP address. This handles the edge case where an admin previously reserved a slot without authentication. Also reorganise imports to follow goimports conventions.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-05 20:26:33 +01:00
popertotsandSisyphus 33c945159c feat: add cancel reservation handler and background cleanup
Add CancelReservationHandler (DELETE /api/bookings/reserve) to release authenticated user's active reservation. Register route in main.go. Add background goroutine for periodic reservation cleanup using CleanupOldReservations. Add idx_time_blockers_created_at index and extend anon cleanup to cover edit_request reservations in init-script.sql.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-05 11:47:54 +01:00
popertotsandSisyphus 2386bd0ca2 test: add tests for reservation self-block prevention
Add TestReserveSlot_DoesNotSelfBlock, TestAdminReserveSlot_DoesNotSelfBlock and TestReserveSlot_CleansUpAnonReservation. Add UserIDKey context to admin approve edit request tests. Remove weekend-day adjustment in TestAdminApproveEditRequest_OverlapWithBooking_Regression and TestAdminApproveEditRequest_EvictsPendingRelease (no longer needed).

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-05 11:47:43 +01:00
popertotsandSisyphus c1a9f35ea5 feat: prevent reservation self-block in booking handlers
Pass excludeUserID to CheckTimeBlockerOverlap in AdminReserveSlotHandler, CreateBookingHandler, EditBookingHandler, AdminRescheduleBookingHandler, AdminCreateBookingForUserHandler, AdminApproveEditRequestHandler, and ReserveSlotHandler. Also clean up stale reservations before overlap check in AdminReserveSlotHandler and ReserveSlotHandler via db.Conn.Exec for cross-connection visibility. Improve error handling in RequestEditHandler's service update block.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-07-05 11:45:02 +01:00
popertotsandSisyphus 40bbd9ba49 refactor(bookings): migrate remaining handlers and tests to clock.Now()
Replace time.Now() with clock.Now() in bookings handlers and all test files. Includes deposit, discount, dedup, overlap, and edit request test updates.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-24 23:43:32 +01:00
popertotsandSisyphus 0ea1bb64b4 feat(bookings): add closing_time validation and repo layer
Extract closing hours check into reusable checkClosingHours helper. Add repo.go for shared DB query helpers. Update admin_reserve to use closing_time and move overlap check inside transaction with FOR UPDATE.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-24 23:43:23 +01:00
popertotsandSisyphus 37a9ba3517 fix(bookings): use transaction context for discount check in approve edit
Use tx.QueryRow instead of db.Conn.QueryRow for discount count check in AdminApproveEditRequestHandler to ensure consistency within the transaction.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-22 17:06:18 +01:00
popertotsandSisyphus 8ab7408e00 feat(bookings): support out_of_hours flag in admin create booking
Add OutOfHours field to AdminCreateBookingForUserRequest. When true, skip exceptional hours closed check and include out_of_hours in INSERT. Add tests verifying: bypass of exceptional closure, rejection without flag, overlap detection still works, and time blocker warning.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-22 12:55:00 +01:00
popertotsandSisyphus 7698ca636b feat(bookings): support out_of_hours flag in admin reserve handler
Add OutOfHours field to AdminReserveSlotRequest. When true, skip the closing hours check allowing admin to reserve slots outside normal business hours. Add tests for call-in, walk-in, without-flag failure, and time blocker interaction.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-22 12:54:52 +01:00
popertotsandSisyphus 260c760971 feat(bookings): add out_of_hours field to Booking struct and admin queries
Include out_of_hours in GetAllAdminBookings, GetAdminBooking, and SearchAdminBookings queries. Add tests verifying out_of_hours appears in single and list booking responses.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-22 12:54:44 +01:00
popertotsandSisyphus 0d940e8608 refactor(bookings): use computed booking fields and LATERAL joins
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-22 00:57:55 +01:00
popertotsandSisyphus 5bdac7d275 feat(bookings): add trigger tests for booking computed fields
Add test suite for PL/pgSQL trigger that auto-recalculates bookings.total_duration_minutes, bookings.total_amount, and bookings.end_time when booking_services or booking_custom_services change.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-21 21:47:35 +01:00
popertotsandSisyphus 7ea6fab3af refactor(bookings): replace inline computed queries with booking fields
Simplify bookings handlers by using bookings.total_duration_minutes, bookings.total_amount, and bookings.end_time computed columns instead of inline UNION sub-queries against booking_services/booking_custom_services.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-21 21:47:12 +01:00
popertotsandSisyphus 96dd9e191c refactor(bookings): remove AdminEditBookingHandler and streamline booking creation/edit overlap checks
- manage.go: remove AdminEditBookingHandler (superseded by EditBookingHandler with overlap detection)

- manage.go: move overlap check inside transaction in AdminCreateBookingForUserHandler

- manage.go: add error handling to unchecked QueryRow calls in RequestEditHandler

- manage.go: reorder time_blocker deletion before overlap check in AdminApproveEditRequestHandler

- admin/bookings_test.go: remove tests for removed AdminEditBookingHandler

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-21 21:01:27 +01:00
popertotsandSisyphus ed14df9a99 fix(bookings): add error handling for unchecked QueryRow and improve overlap detection
- admin_reserve.go, reserve.go: wrap unchecked QueryRow.Scan with error handling

- bookings.go: replace next-booking overlap check with COUNT(*) in UpdateBookingServicesHandler

- bookings.go: wrap EditBookingHandler in a transaction with EvictPendingReleaseOverlapping

- bookings.go: add error handling for QueryRow and Evict in ConfirmBookingHandler

- bookings.go: add error handling and eviction reorder in AdminRescheduleBookingHandler

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-21 21:01:22 +01:00
popertotsandSisyphus e23cc3cc6f feat(bookings): add comprehensive overlap detection tests
Covers admin create, user edit, auto-approve, service duration extension, reserve, admin reserve, admin reschedule, confirm, and admin approve edit request — all with overlap edge cases.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-21 21:01:17 +01:00
popertotsandSisyphus 220a0ef6e8 refactor(backend): update test files for PoolProxy and per-test transactions
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>
2026-06-21 19:29:24 +01:00
popertotsandSisyphus 3d0e2afc4c refactor(backend): migrate db.DB to db.Conn PoolProxy across all handlers
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>
2026-06-21 19:28:54 +01:00
popertotsandSisyphus 8efb8d93bf feat(backend): add name history tracking, booking pagination, and CardDAV improvements
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>
2026-06-20 16:58:29 +01:00
popertotsandSisyphus efd3ad5405 refactor(backend): migrate from sql.ErrNoRows to pgx.ErrNoRows
Replace all database/sql.ErrNoRows checks with pgx.ErrNoRows across backend handlers.

Migration includes: jwt.go, local.go, admin_reserve.go, custom_services.go,
discount_campaigns.go, services.go, account.go, customer_relationship.go,
guest.go. Also removes unused test_helpers.go resetTestData function.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-20 16:58:08 +01:00
popertotsandSisyphus b03c4f6247 refactor(backend): replace resetTestData with SetupTestDB and add new tests
Migrate all test files from resetTestData(t) to testutils.SetupTestDB(t) for isolated per-package test databases.

- Add new feature tests: name history assertions, referral discount preview,
  time blockers, email validation, GDPR export, loyalty manual redemption
- Update existing tests to use batch queries and SetupTestDB
- Remove test_helpers.go resetTestData infrastructure
- Add comprehensive user profile tests (442 new lines)

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-20 16:57:36 +01:00
popertotsandSisyphus 9c68918c20 refactor(backend): migrate test infrastructure to isolated databases
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>
2026-06-20 16:56:57 +01:00
popertotsandSisyphus e74f190cdd feat(backend): update loyalty tests for manual redemption model
Refactor all loyalty tests from auto-redemption to manual-redemption model: - applyLoyaltyRedemption helper with HTTP endpoint - New tests: DepositBeforeRedemption (rejected), RedemptionBeforeDeposit (locked-in), MultipleEarnCycles, NormalEarnNoRedemption, RedemptionAppliedBeforeStampIncrement - Move TestDiscount_Stacking_TimeBasedPlusMilestone to alphabetical position - Add getTotalPaymentCount, getAmountPaid helpers - Remove TestDiscount_RedemptionAppliedBeforeStampIncrement (replaced)

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-19 11:34:31 +01:00
popertotsandSisyphus 1e100e4db7 feat(backend): remove auto loyalty redemption from booking progress
Remove auto-apply of pending loyalty redemption during ProgressBookingHandler. Now only checks if loyalty was applied on this booking (via booking_discounts) to skip stamp award. Redemption is purely manual via ApplyLoyaltyRedemption. Use LoyaltyStampCost constant instead of hardcoded 10.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-19 11:34:26 +01:00
popertotsandSisyphus e1f51420f7 feat(backend): add booking dedup, deposit tests and test main
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-18 16:26:24 +01:00
popertotsandSisyphus c805fea7df feat(backend): update reservations
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-18 16:26:22 +01:00
popertotsandSisyphus 2493137c39 feat(backend): update bookings tests
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-18 16:26:21 +01:00
popertotsandSisyphus 493e2ae76f feat(backend): update bookings core handlers
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-18 16:26:18 +01:00
popertotsandSisyphus 032a6dedf7 feat(backend): update admin reserve handler
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-18 16:26:17 +01:00
popertotsandSisyphus e46df47a8f fix(backend): delete admin_notifications before booking hard-delete
The admin_notifications.booking_id FK has no ON DELETE CASCADE, so hard-deleting a booking with existing notifications fails with a FK constraint violation. Fix by explicitly deleting related notifications before the booking DELETE.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-15 23:19:35 +01:00
popertotsandSisyphus 2574baf099 feat(backend): fetch standard and custom services in bookings list
Populate booking.Services with a UNION query across booking_services and booking_custom_services tables, returning service name, price, duration, and override values.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-15 21:27:29 +01:00
popertotsandSisyphus 459adf7001 feat(backend): increase per_page cap to 500 in bookings list handler
Raise per_page limit from 100 to 500 in parseGetAllBookingsRequest to support large booking lists. Add test coverage for per_page=500 acceptance and per_page=600 rejection (fallback to 10).

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-15 20:27:41 +01:00