Commit Graph
41 Commits
Author SHA1 Message Date
popertotsandSisyphus a358c8c0ea docs: README test count, Technical Manual default hours table, local-dev-2.sh config
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-22 00:34:51 +01:00
popertots 1d9c87d6d6 docs: README + obsidian parity with SCA-only posture, flood caps, lockout tiers; dev-script secret bootstrap, stale-backend kill, patch-test backdate
- README: payments/2FA sections rewritten for the SCA-only posture (no
  TWO_FACTOR_FALLBACK, tokenize-result wire contract, 402 refusal), deposit
  carve-out clarified, gift-card 12-hex codes + 14-day cancellation, flood-cap
  insert sites enumerated, escalating lockout tiers documented, ICO
  registration note, updated test counts (2,555 backend + 129 frontend).
- local-dev-2.sh: fail-closed dev secret bootstrap (auto-generates
  JWT_SECRET_KEY / TWO_FACTOR_PEPPER into the gitignored .env), kills stale
  backends holding :8080 before the tmux reset, passes
  RUSTFS_ENDPOINT/GO_TESTING=1 to the dev backend, and backdates seeded patch
  tests 60 days so past gel bookings pass the 24h notice gate.
- Obsidian manuals (Technical/Admin/User/Feature Catalog/Overview/Gift Card
  T&C/Privacy/T&C/Testing Architecture/payments and money processes + p14 plan
  + workspace state) updated to the post-round-2 state.
2026-08-22 00:34:50 +01:00
popertots 3894f53778 fix: local-dev-2.sh reset order — stop container before port check
The round-7 port pre-flight ran BEFORE , so a
healthy postgres container from a previous run (which owns host port 5432) was
mistaken for a squatter and the script exited. Down the container first, then
check for any remaining non-Docker process on 5432 and fail loudly with the
offending pid.
2026-08-22 00:34:49 +01:00
popertots 5cc5a7f6d2 fix: review round 7 — fresh-eyes audit fixes (6 agents) + full test suites for every backend change
Fresh-eyes review round with 6 independent agents (money-safety, concurrency,
Square wire parity, security, frontend flow, testing-gaps). Every finding was
independently verified against the code before fixing. All backend changes
now carry full test suites (10+ new tests, each verified to FAIL without its
guard). All 20 packages green, race detector clean.

Money-safety:
- Gift-card purchase refunds no longer create money: manual refunds of a
  no-booking (gift-card purchase) payment are rejected with a clear message
  in the direct handler AND never re-issued by the sweep-resume path
  (processManualPaymentGroup skips them; reconcile-then-fail, no re-issue).
- BuyGiftCard no-client-key fallback: derived deterministically under the
  advisory lock (pending-row reuse fixes lost-response double-charge;
  completed-row sequence advance preserves distinct-purchase collapse fix).
- Terminal completion is never unrecorded: activeTerminalCheckoutID now calls
  recordUntrackedTerminalPayment when a provisional (tmp-) checkout is found
  COMPLETED at Square (previously only marked the row COMPLETED — a lost poll
  left the payment invisible and unrefundable).
- Sweep: provisional tmp- checkout rows are resolved against Square first
  (COMPLETED → record; live → keep guard; NOT_FOUND/CANCELED → fail;
  ambiguous → leave pending) instead of blind-failing a possibly-live
  checkout. recordUntrackedTerminalPayment re-checks the booking status
  (FOR UPDATE) and refuses to record on a cancelled booking, inserting a
  critical_payment_log admin notification instead. Till-sale post-charge
  UPDATE now requires status='pending' (no resurrection of a clawed-back sale).

Frontend (Svelte 5):
- UserPaymentModal keeps CardSelection mounted through processing (bind:this
  ref + Square iframe survive the loyalty/tokenize awaits) — new-card
  payments work again.
- BookingFlow clears the cached nonce/verification pair on any failure (retry
  re-tokenizes fresh; idempotency key retained for dedup); 409 'already paid'
  refetches the booking and reconciles depositPaid so the confirmation gate
  opens; Back button disabled during processing.
- Synchronous double-submit guards on buyGiftCard/redeemGiftCard/submitTip.

Square wire parity (mock vs real):
- processing_fee sign unified (negated at paymentFromSquare; mock agrees).
- SimulateSourceUsed (SOURCE_USED, 400) matches real CreateCard.
- GetCardsOnFile excludes disabled cards (matches ListCards).
- ForcePaymentStatus toggle + tests prove the charge path can't be status-blind.
- CreateCheckout rejects empty device_id (env fallback SQUARE_TERMINAL_DEVICE_ID);
  completed terminal checkout's payment resolvable by id.

Security:
- 2FA attempt-map data race fixed: lastAt is atomic.Int64 (nanos) — eviction
  scan reads race-free; concurrent verify+evict tests under -race.
- Backend refuses to start on weak/placeholder JWT_SECRET_KEY (<32 chars or
  known public placeholders) with openssl rand -hex 32 guidance.
- Dockerfile no longer COPYs .env (secrets injected via compose env_file).
- SabreDAV requires DAV_ADMIN_PASSWORD (no admin/admin default); compose
  fails at config time when missing.

Testing gaps closed (each verified to FAIL without its guard):
- refunded-dedup 409 (CreateBookingPayment), keyed sweep past-retention
  blind-fail, reconcile status-switch (CANCELED/FAILED/APPROVED/PENDING/unknown
  in both by-key and by-id paths), resolveChargeSource Square-failure branches,
  structured 500 / CARD_DECLINED / cancelled-context E2E (row stays pending),
  deriveBookingPaymentIdempotencyKey >45-char truncation, webhook
  findPaymentByDisputeID fallback, clawbackOneTillSale non-gift-card branch,
  dispute.evidence / terminal.checkout dispatch.

Infra:
- local-dev-2.sh fails loudly on port-5432 squatters / docker compose failures
  (previously died silently under ERR_EXIT with hidden output).
- Test harness defaults SQUARE_TERMINAL_DEVICE_ID; money_safety_fixes_test.go
  gained the missing build tag.

Verification: go test -tags test,dev -count=1 -parallel 8 ./... (20/20 ok),
-race clean on 2FA + payments money paths, go build ./... + -tags dev, go vet
clean, svelte-check 0 errors, env-docs gate OK (36 vars), docker compose
config valid.
2026-08-22 00:34:49 +01:00
popertots 67cf5b9a45 fix: review round 6 — P0 deposit charge, idempotency rotation, dev-safety guard, 2FA/webhook hardening
Sixth fresh-eyes review pass (5 agents: goal, QA, code-quality, security,
context-mining). QA FAILED the deposit-required new-card flow; the P0 root
cause was backend + frontend, now fixed. All 20 packages green.

P0 money-safety:
- Deposit-required bookings now actually charge the deposit on new-card
  payment. Two-part fix: (1) CreateBookingHandler re-reads the
  trigger-maintained total_amount/total_duration_minutes from the DB after the
  booking_services insert (the INSERT..RETURNING row predates the recalc
  trigger, so TotalAmount serialized as 0 and DepositPaid computed TRUE on an
  unpaid booking — the frontend gate trusted deposit_paid:true, never charged,
  and confirmed the booking with zero payment rows); (2) BookingFlow.svelte
  gates the confirmation view on depositPaid and guards against re-creating a
  booking on retry. Regression test
  TestBookings_Create_DepositPaidFalseOnUnpaidBooking.

Payments (idempotency + money):
- deriveBookingPaymentIdempotencyKey: no-client-key fallback now advances a
  sequence for repeatable types (partial) and rotates past refunded completed
  rows, so refund-then-repay and equal-amount partials diverge onto distinct
  keys; an un-refunded completed row keeps its key (double-charge protection
  holds). Dedup hits on refunded rows now 409, never stale success.
- chargeFailureStatus default is 503 (ambiguous), never 402; table test.
- Flaky TestBookingPayment_FullPayment_SplitsIntoDepositAndBalance fixed
  (ORDER BY payment_type).
- resolveChargeSource: orphaned card-on-file disabled via DeleteCardOnFile
  when SaveCardForUser fails (best-effort, redacted log); retry path preserved.

Square client:
- Dev builds HARD-FAIL (panic) on SQUARE_ENVIRONMENT=production without
  SQUARE_ALLOW_REAL_API=1; sandbox routes with a loud banner.
- Mock fault-injection FailAfterCommit (commit-then-5xx) exercises the exact
  lost-response same-key retry; SimulateCardTokenUsed; 45-char idempotency-key
  cap parity; SquareEnvironment/SquareLocationID shared env helpers used by
  the sweep (env contract no longer comment-only).
- listRefunds truncation now errors (money-sensitive reconcile retries
  instead of over-refunding); getCardsOnFile truncation loudly logged.

Webhooks + 2FA:
- square-environment header checked fail-closed (403) when configured env is
  production/sandbox; dispatch DB work bounded by 30s timeout contexts.
- 2FA codes HMAC-SHA256 pepper'd (TWO_FACTOR_PEPPER) with legacy-hash
  migration + upgrade-on-verify; disable-flow mint cooldown (1/min, 429) caps
  the brute-force loop; in-lockout records never LRU-evicted.

Repo hygiene:
- env-docs CI gate green again (FRONTEND_ORIGIN + SQUARE_ALLOW_REAL_API +
  TWO_FACTOR_PEPPER documented; Vite DEV built-in allowlisted).
- Dead square_deposits schema dropped; obsidian/README/legal-page drift fixed
  (consumeradvice.scot signposting, CORS allowlist, p11 R3/P13, T1).
- 2FA disable residual documented; P6 email/SMS delivery and P12 sandbox
  smoke test remain the pre-go-live gates.

Verification: go test -tags test,dev -count=1 -parallel 8 ./... (20/20 ok),
go build ./... + -tags dev, go vet clean, svelte-check 0 errors, env-docs
gate OK, live deposit-required flow re-verified end-to-end (deposit £11
charged, square_payment_id recorded).
2026-08-22 00:34:49 +01:00
popertots d2f5c25b3d fix(local-dev): pin test env vars to explicit values
Backend Tests / test (push) Successful in 59s
The test command (line 1478) inherits the tmux environment, which
includes POSTGRES_HOST=postgres from line 112 (sourced from .env).
Since db_dev.go now reads POSTGRES_HOST from env, the test runner
tried connecting to 'postgres:5432' which doesn't resolve from the
host — causing all TestMain functions to fail.

Fix: export explicit values (myuser/mypassword/localhost/crussell_test)
instead of re-exporting whatever the tmux session inherited.
2026-06-25 12:18:26 +01:00
popertots 1b982b118b fix: use ./... in CI and restore local dev host connection
Backend Tests / test (push) Successful in 1m3s
CI test command: switch from explicit package list to ./... so new
packages are automatically included.

local-dev-2.sh: override POSTGRES_HOST=localhost for the host-side
go run -tags dev ./main.go. The dev-tagged Connect() now reads
POSTGRES_HOST from env (needed for CI where service containers use
Docker DNS). Locally, .env sets POSTGRES_HOST=postgres, but that
name only resolves inside Docker — not from the host where the dev
server runs. Override to localhost so it connects via Docker's port
forwarding.
2026-06-25 12:11:45 +01:00
popertotsandSisyphus 21560ea451 chore: reduce test count in dev script
Change go test -count=3 to -count=1 to speed up local development iteration.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-22 17:06:24 +01:00
popertotsandSisyphus bb7de6640c chore: increase test count from 1 to 3 in dev script
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-22 12:56:04 +01:00
popertotsandSisyphus d171117e53 docs: update README, obsidian docs, dev scripts, and SQL init
Update documentation and configuration:

- README: reflect new test patterns and architecture
- Obsidian docs: update Technical Manual, Overview, Testing Architecture
- init-script.sql: schema updates
- local-dev-2.sh: dev script adjustments

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-21 19:29:32 +01:00
popertotsandSisyphus f2e8e3eb77 docs: update README, dev scripts, and documentation
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>
2026-06-20 16:59:56 +01:00
popertotsandSisyphus 3ff14fdd5a chore: update SQL script, dev script, and add zxcvbnjs
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-18 16:26:52 +01:00
popertots 6d4bc4d637 feat(loyalty-discount): implement loyalty and discount system
- Add discount campaign management and validation logic
- Update booking handlers with discount application flow
- Add customer relationship endpoints for loyalty tracking
- Update frontend modals (booking, approval, payment, reschedule)
- Add DiscountsManagement and loyalty reference documentation
- Update dev scripts and database init for discount tables
- Clean up completed plan files
2026-06-04 23:13:02 +01:00
popertotsandSisyphus 068ae79462 chore: update dev seed data with loyalty stamps
Primary test user (user@example.com) now has 4 loyalty stamps in seed data for testing the redesigned stamp card.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-04 01:09:33 +01:00
popertotsandSisyphus d23ed1831a chore: update init scripts, dev script, and remove stale HAR file
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-28 16:34:13 +01:00
popertots 8574bf2221 feat: enriched edit request system with side-by-side snapshots, calendar preloading, and admin review UI
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)
2026-05-26 11:59:07 +01:00
popertotsandSisyphus f553ebad99 fix: booking duration calculation, tip page auth, and UI polish across frontend
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-05-25 18:04:43 +01:00
popertots 2e1ab9d745 feat: Square payment integration, booking flow redesign, and timezone/weekday fixes
- Add Square payment integration (mock + handlers + UI): terminal/online payments,
  refunds, tips, saved cards, webhooks. Build-tagged dev/prod clients.
- Redesign booking flow: Step 4 conditional (deposit only), Step 5 confirmation
  screen with booking ID, auto-submit on transition.
- Redesign schedule modal: 2x3 button grid with Pay Deposit/Pay Early logic.
- Add deposit warning banner at Step 1 for users with outstanding deposits.
- Fix weekday conversion bug: Go 0=Sunday vs DB 0=Monday mismatch in 6 locations.
- Fix timezone bug: UTC vs London time in closing hours validation.
- Fix frontend error parsing: plain text backend errors now displayed correctly.
- Fix crypto.randomUUID fallback for environments without Web Crypto.
- Add 7 new regression tests: closing hours, advance check, active booking limit,
  weekday conversion, UTC/London, deposit snapshot, exceptional hours.
- Fix 3 flaky tests: dynamic dates instead of fixed, no-show timing.
2026-05-23 11:29:34 +01:00
popertots 7fc58f58d9 feat: admin notification system with priority ordering, bell icon, and /notifications page
Two-tier notification system: new_booking (all public bookings) + pending_booking (notes/today).
Priority-sorted queue, unread count polling, enriched responses with user_name/booking_start_time.
Fix critical bug: edit_requested cleanup was broken (wrong reason string in 3 handlers).
Add 15 new tests covering priority ordering, enrichment, and notification creation flows.
Update Admin Manual, Technical Manual, and gap backlog docs.
2026-05-16 23:41:18 +01:00
popertots aa4a569a43 docs: update README, Obsidian docs, and gap backlog after test optimization
- Update test count: 286/288 passing (was 222/224)
- Document TestMain per-package architecture
- Document TruncateTables optimization (~60% faster)
- Add local-dev-2.sh tee streaming for real-time test output
- Fix flaky admin reserve walk-in tests (time.Now → noon tomorrow)
- Add gap backlog item #51 for completed test optimization work
2026-05-10 19:48:36 +01:00
popertots bec4100e4d feat: customer relationship view, idempotency keys, approval decline, seed payments, backlog cleanup
- #3: Wire ApprovalModal handleDecline to POST /api/admin/bookings/{id}/cancel
- #25: New GET /api/admin/users/{id}/relationship endpoint with spend, tips, visits, customer-for duration, top services
- #25: UserModal reorganized — Personal Info, Booking History, Customer Relationship, Loyalty, Patch Tests
- #36: Idempotency keys on user and admin booking creation (UUID header, duplicate detection)
- local-dev-2.sh: seed payments via PL/pgSQL for completed bookings (5 randomized scenarios)
- local-dev-2.sh: shrink guest/time-blocker output, add payments to summary
- Backlog: mark #3/#25/#35/#36/#49 done, plan #36/#45, remove #46/#48, update #45 with milestone campaigns
- Remove notes history table, avg visits/year metric, Account Information, Privacy & Consent from UserModal
2026-05-04 12:20:03 +01:00
popertots 7b396b7a9d fix: resolve guest booking failures from router conflict, reservation self-block, and closed-day miscalculation
- backend/main.go: Flatten /bookings/* sub-Route to explicit paths to prevent
  RequireAuth middleware from bleeding into OptionalAuth POST /bookings
- backend/handlers/scheduling/time-blockers.go: Exclude RESERVATION:* entries
  from GetTimeBlockersInRange so overlap checks dont reject the users own
  reservation before CreateBookingHandler can delete it
- local-dev-2.sh: Fix open_day to skip Saturday (6) not Monday (1), matching
  working_hours schema; move guest booking dates to +16/+20/+22 days beyond
  the upcoming loop range; add reserve-then-book step mirroring frontend flow
2026-04-30 16:06:51 +01:00
popertotsandSisyphus 819a7afb76 fix: move guest booking dates to avoid slot conflicts with existing seeded bookings
All slots on tomorrow were occupied by existing bookings.
Shifted guest bookings to day 3 and day 5 where specific
slots (B, C, D) are guaranteed free by the upcoming pattern.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-30 11:58:22 +01:00
popertotsandSisyphus 861fa5227f refactor: rename Alice to Nina across test and seed scripts
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-30 11:52:26 +01:00
popertotsandSisyphus acd50e0210 seed: add guest booking scenarios and time blockers
Guest bookings: create 4 guest accounts (3 unique + 1 shared-email),
3 guest bookings across different days, and verify registered-email
collision is properly blocked.

Time blockers: staff meeting, holiday morning block, and late start
block to demonstrate unavailable-time behaviour.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-30 11:48:18 +01:00
popertotsandSisyphus 60ec5a0a8c ui: polish navbar visibility and home page greetings
Hide My Schedule link from admin users (they have dashboard instead).
Add 60+ randomized greeting strings split between returning and new users.
Update dev script admin seed name.

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

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-29 22:56:35 +01:00
popertots c7c10bc177 Fixed user cancelation logic 2026-03-07 21:00:16 +00:00
popertots 861dd11c5b Deposit tracking 2026-03-03 21:40:39 +00:00
popertots 74b6f039c0 Fix tests 2026-03-02 19:57:44 +00:00
popertots ea1a80dbda fix: resolve flaky holiday hours test and clean up dev scripts
- Use fixed date (Thursday Feb 26, 2026) instead of dynamic tomorrow
  to avoid timezone-related test flakiness
- Remove orphaned SQL fragment from init-script.sql
- Clean up duplicate color code definitions in local-dev-2.sh
- Add Rustfs data wipe and SabreDAV startup to dev script
- Add composer.lock to .gitignore
2026-02-24 23:42:40 +00:00
popertots c6fe9e92a7 refactor: migrate patch test schema from service-level to dedicated tables
- Remove patch_test_duration_hours from services table
- Add new patch_tests table with service_ids array, notice_duration_hours, expiry_months
- Add new user_patch_tests table linking users to patch_tests with tested_at
- Update services handler to check patch_tests.service_ids for eligibility
- Update booking creation to validate patch test requirements (24h notice, 6mo expiry)
- Update booking completion to extend patch test validity (reset tested_at)
- Update admin handlers for new patch test CRUD operations
- Update test fixtures and test cases for new schema
- Update seeding script to create patch_tests and link to gel services
2026-02-24 22:17:50 +00:00
popertots df3439bd70 fix: improve test infrastructure and add ID validation
- Add TestMain to set test env vars and testdb.TruncateTables for test
  isolation
- Add chi routing context to test helpers for path parameter extraction
- Fix SQL error handling to use errors.Is() instead of ==
- Add validators package with ID validation
- Fix admin test middleware chain (RequireAdmin wrapper)
- Update test user inserts to include phone and date_of_birth fields
- Update service delete test to check soft-delete (is_active=false)
- Update holiday hours test to use new schema (weekday, is_open)
- Add phone number validation tests for UK mobile numbers
2026-02-23 00:59:32 +00:00
popertots 03e2d8343e fix: add 5-second buffer after PostgreSQL startup before database operations
- PostgreSQL reports ready (SELECT 1 succeeds) but internal initialization still in progress
- Add explicit 5-second sleep after 'PostgreSQL is ready' message
- Ensures database system fully initialized before creating/seeding test database
- Prevents 'database system is starting up' errors
- Also increase sleep after database creation from 1s to 2s for stability
2026-02-22 00:25:55 +00:00
popertots 2abf6653ba fix: add PostgreSQL startup wait loop before test database setup
- PostgreSQL container takes time to fully initialize after docker compose up
- Previous fix didn't account for container startup time
- Add explicit wait loop (30 second timeout) for PostgreSQL service to be ready
- Only create test database AFTER PostgreSQL itself responds to connections
- Prevents 'database system is starting up' errors
- More robust and handles slower container startup scenarios
2026-02-22 00:24:03 +00:00
popertots fb0a7fa59b fix: test database setup and scheduling test build error
- Add explicit verification loop in local-dev-2.sh to wait for crussell_test database to be ready before running tests (prevents race condition)
- Remove unused 'handler' variable declaration in scheduling_test.go that was breaking the build
- Tests now properly execute without immediate 'database does not exist' errors
- Real test failures are now visible instead of being masked by setup issues
2026-02-22 00:20:28 +00:00
popertots 9ca102153b Add crussell_test database creation and schema seeding to dev script
- Create crussell_test database after PostgreSQL reset
- Seed test DB schema from init-script.sql so tests can run
- This fixes the TLS connection errors in test runs

Also:
- Fixed color variables in script (C_RESET, C_GREEN, etc.)
2026-02-22 00:06:03 +00:00
popertots 44cac94f64 Fix test setup and middleware chain - Handler tests now passing
- Fix TestRequireRoleMiddleware by chaining RequireAuth before RequireRole (role context requirement)
- Remove unused 'strings' import from testdb.go
- Create crussell_test database in Docker setup
- Tests now properly initialize authentication context for role-based tests

Result: handlers test suite passes (13/13 tests)
Remaining failures in admin/auth/bookings/portfolio/scheduling/services/user packages need further investigation (environment setup, database constraints, endpoint initialization)
2026-02-21 23:50:17 +00:00
popertots 41dc839830 feat(booking): add service eligibility based on age and patch tests
- 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
2026-02-20 18:46:38 +00:00
popertots 9259de9393 Portfolio: add filtering, URL sharing, and improved tag input
- Add category filters with dynamic counts that reduce as filters
  applied
- Add ?filter[category]=value URL params for filterable links
- Add ?img= timestamp param that bypasses filters to show specific image
- Update URL when opening/navigating/closing modal for shareable links
- Backend: add /api/portfolio/filters endpoint with filter logic
- Backend: add timestamp lookup fallback for GetImage endpoint
  Frontend:
- Portfolio page: filter dropdowns, keyboard nav, mobile improvements
- ImageUpload: live tag suggestions from API, arrow/Tab navigation,
  confirmation modal before upload, mobile-optimized touch targets
- Add scrollbar-hide utility and fix filter dropdown overflow
- Move Clear all button, add vertical separator on desktop
2026-02-20 00:32:09 +00:00
popertots dfd552b02f feat(storage): add S3/R2 abstraction with local Rustfs dev
- Add backend/internal/s3/ with build-tag pattern (dev vs prod)
- Dev: Uses local Rustfs container (S3-compatible)
- Prod: Stub for R2 Cloudflare (add AWS SDK to implement)
- Add S3 env vars to .env.example and .env
- Add Rustfs service to compose.yml
- Add Rustfs reset to local-dev-2.sh (wipes data on each run)
2026-02-17 22:47:38 +00:00
popertots 50746595e7 feat(bookings): improve admin booking wizard and user dashboard
Backend:
- Enriched GetAllUserBookings response with calculated total_amount,
  amount_paid, and duration_minutes.
- Refactored GetBookingHandler to return a flat booking object matching
  frontend expectations.
- Added account_role to admin user list response and sorted users by
  booking activity.
- Corrected function name oo to AdminCreateBookingForUserHandler.

Frontend:
- Rebuilt BookingCreateModal into a 4-step wizard supporting guest
  bookings, service overrides, and real-time availability checks.
- Fixed account dashboard logic to correctly identify upcoming vs past
  bookings and sort unpaid items to the top.
- Extracted booking flow into a shared BookingFlow component.
- Redirected admin users from home page to /today.
2026-02-12 22:15:10 +00:00