Commit Graph
15 Commits
Author SHA1 Message Date
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 5dae0bba08 feat: Square 3DS2 SCA primary authorisation for saved-card charges; 2FA demoted to audited backup
SCA is now the PRIMARY authorisation for saved-card (ccof) charges (PSR 2017 /
chargeback liability shift); the homegrown 2FA becomes a BACKUP used only when
SCA is unavailable (e.g. a bank without in-app approval), with a strict audit
trail. The 'approve in your banking app' UX comes from Square buyer
verification. Email/SMS remains the intended 2FA delivery channel; the [2FA]
stdout-log relay (TWO_FACTOR_ALLOW_LOG_DELIVERY=true) is the explicit-insecure
pre-email/SMS stopgap.

BACKEND:
- CreateTerminalPaymentRequest gains VerificationToken (forwarded to Square in
  the admin saved-card branch; validated like the other charge handlers)
- Structured SCA-required error surfacing: isVerificationRequiredError +
  writeVerificationRequiredResponse (HTTP 402 with {code:'verification_required'})
  at all 5 charge error sites — the frontend keys on it to trigger the challenge
- requireTwoFactorForCardAccess reworked: SCA token present => 2FA skipped
  (SCA primary); no token => 2FA fallback requires delivery channel + consume +
  insertTwoFAFallbackAudit (admin_audit_log reason 2fa_fallback_charge,
  {sca_performed:false,...}); TWO_FACTOR_FALLBACK env flag (default true) gates
  the fallback; false => SCA-only posture
- MIT vs CIT: admin till saved-card + admin booking saved-card charges now flag
  customer_initiated=false (merchant-initiated, no SCA, no liability shift);
  customer-initiated online flows keep true

FRONTEND:
- square_card_id threaded through SavedCard/SelectableCard + admin lists
- isVerificationRequiredSignal + shouldFallbackTo2FA helpers (402 + code / text
  fallback); VERIFICATION_REQUIRED_MESSAGE
- tokenizeSavedCardWithVerification (Square SDK tokenize(details, squareCardId))
  with verified/challenge-cancelled/sca-unavailable/sca-failed outcomes
- Per-surface SCA retry with the SAME idempotency key + fresh verification_token
  (booking/tip/till/gift-card/admin); 'waiting for approval in your banking
  app' state on admin surfaces; 2FA backup-only UX in the shared composable

MOCK PARITY:
- SimulateSavedCardVerificationRequired toggle (default off) + grandfathering
- Challenge state (ApprovePendingVerification/DenyPendingVerification,
  ChallengeResult config, token-encoded _ok|_deny outcome)
- One-time-use verify_mock_ token ledger + amount/source binding
- MockCardForm saved-card verification simulation + mock Approve button
- Tests: saved-card SCA gate, one-time-use, denied, amount-mismatch,
  grandfathered; frontend helper tests

DOCS: payments-doc SCA appendix, Technical Manual 2FA section, README,
Overview, Feature Catalog updated to SCA-primary + 2FA-backup; env-var
documented (42/42).

26/26 backend packages; 95/95 frontend tests + build; env-docs 42/42.
2026-08-22 00:34:50 +01:00
popertotsandSisyphus 96ec3f3e33 docs: update README and obsidian documentation
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-18 16:27:22 +01:00
popertots d77f330bda chore: commit pending changes before custom services implementation 2026-06-13 11:27:47 +01:00
popertotsandSisyphus ceb33f7b3a chore(obsidian): update workspace state
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-11 22:08:33 +01:00
popertotsandSisyphus 06efdfdac0 chore(obsidian): update workspace state
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-05 15:40:51 +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 c3501ae89a dependancies and docs 2026-05-16 19:06:33 +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 88ee265603 refactor: remove auto deposit penalty on no-shows, add comprehensive tests
- 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
2026-05-03 15:59:40 +01:00
popertots 94adc7f54c test: clarify 1h advance requirement is USER-ONLY, add admin walk-in tests
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)
2026-03-07 18:05:17 +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
popertots 28815d3b25 Update readme 2025-11-06 16:05:33 +00:00
popertots f1dc375c5f update obsidian 2025-11-03 23:47:58 +00:00
popertots 2b7ec96d37 obsidian 1 2025-11-03 23:25:04 +00:00