Commit Graph
5 Commits
Author SHA1 Message Date
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
popertots e73c96b653 refactor: optimize test DB setup — TestMain per package, truncate-only between tests
- Add TestMain to all 10 test packages (schema DROP+CREATE runs once per package)
- Convert per-test setupTestDB to resetTestData (TRUNCATE only, ~60% faster)
- Add 3 missing tables to TruncateTables (booking_edit_requests, exceptional_group_applications, business_settings)
- Remove dead truncateDiscountTables helper
- Consolidate discount_test.go into package bookings (was external test package)
- Update testutils.SetupTestDB to truncate-only
- Fix unused imports across user, bookings, and handlers packages
- Verify: 286 passing, 2 skipped, 0 failures with -count=2 (no state leakage)
2026-05-10 17:27:51 +01:00
popertots e1c815ed09 fix(loyalty): correct stamp accumulation, one-per-day guard, and test coverage
- Handler: apply existing redemption BEFORE incrementing stamps (was creating
  and applying redemption to same booking)
- Handler: guard stamp increment behind bookingTotal > 0 (free bookings don't
  earn stamps)
- Handler: fix global milestone off-by-one (globalCount already includes
  current booking since status updated before discount logic)
- Schema: chk_milestone constraint only requires milestone_unit for anniversary
  type, not per_user_booking_count or global_booking_count
- Tests: rewrite from scratch with 12 focused tests:
  - FullCycle, ExistingRedemptionApplies, OneStampPerDay, ZeroTotalNoStamp,
    CycleRepeats, TimeBasedCampaign, PerUserMilestone, GlobalMilestone,
    AnniversaryMilestone, LoyaltyPriority, NoDiscountOnZeroTotal,
    CampaignMaxRedemptions
- Tests: fix path parameter extraction in makeProgressRequest
- Vendor: go mod tidy + vendor for testify dependency
2026-05-10 13:17:08 +01:00
popertots 79a794de58 fix: remove discount_eligible from booking creation, fix modal scrolling, lower default to 5%
- Remove all discount_eligible checks from CreateBookingHandler and AdminCreateBookingForUserHandler
- Discounts are only calculated at completion/payment time, not at booking time
- Remove discount_eligible from frontend Booking type and pending_redemption from BookingUser
- Remove TestDiscount_EligibilityFlag test (no longer relevant)
- Fix modal scrolling: add max-h-[90vh] overflow-y-auto to match ServicesManagement pattern
- Lower default discount from 10% to 5%
- Clarify max_redemptions label as 'campaign total' (per campaign, not per person)
2026-05-08 18:08:59 +01:00
popertots 1f54d8565c feat: loyalty/discount system with milestone campaigns, auto-redemption, and admin UI
- Database: loyalty_redemptions, discount_campaigns, booking_discounts tables
- Backend: auto-create pending redemption at 10 stamps, apply discounts at completion
- Backend: discount_eligible flag on booking creation (user + admin flows)
- Backend: campaign CRUD handlers (GET/POST/PUT/DELETE + stats)
- Backend: milestone campaigns (per-user, global, anniversary)
- Frontend: customer account page shows 'card full' status at 10 stamps
- Frontend: admin discounts page with campaign management UI
- Frontend: TypeScript types for all discount entities
- Tests: 9 integration tests covering loyalty, campaigns, milestones, edge cases
2026-05-08 17:32:20 +01:00