Changelog
What's New
Everything we've shipped. Features, improvements, and fixes.
improvement
Large-campaign pagination safety + audit logging
- fetchAllRows pagination helper — fetches entries in 5K batches instead of truncating at 10K rows
- Applied to draw execution, CSV export, cancellation notifications, and all cron jobs (send-draw-emails, auto-draw, daily-digest)
- throwOnError mode for critical paths — draw execution now throws on DB fetch errors instead of silently returning empty results
- Audit logging for sensitive organizer actions — draw execution, CSV export, and bulk entry status changes logged to admin_audit_log
- Browse giveaway stats now only count published campaigns — prevents inflated count from draft giveaways
feature
Wishlist collaboration + referral rewards + code quality audit
- Wishlist collaboration — invite collaborators by email with Editor (add/edit/remove items) or Viewer (browse only) roles
- Collaboration invite notifications — email + in-app notification on invite, with resend support for pending invitations
- Referral rewards — referrer earns 7 days of free Pro (up to 90 days), referred user gets 3 bonus AI suggestions
- Referral notifications — email + in-app notification to both referrer and referred user when a referral is completed
- Auto-generate referral code for users missing one on settings page load
- HTML attribute escaping in embed code dialog — prevents XSS via quote injection in titles
- 44px minimum touch targets on all suggestion card buttons for mobile accessibility
- Compact PWA install banner — single-row design with platform-specific messaging
- Mobile-responsive collaborator dialog — email input on its own row, proper overflow handling
- Budget input validation (clamped 0-100k), recipient name truncation, OG image parameter truncation
- Referral code enumeration prevention — invalid codes return 400 instead of 404
feature
"Powered by GiftDice" viral badge on shared pages
- Floating "Powered by GiftDice" badge on all public/shared pages — wishlists, giveaways, dice duels, group invites
- Badge hidden for Pro users — clean, unbranded experience as a Pro perk
- Dismissible with session persistence, 2-second fade-in entrance animation
- Enhanced PublicFooter with Dice5 icon and tagline across all shared pages
- Mobile-optimized: safe area insets for iOS notch, 44px touch targets, z-index layering above CTA banners
- Accessible: aria-live region, focus-visible rings, screen reader support
feature
Admin dashboard overhaul + CI pipeline
- Admin user search — find users by email or name, view full activity detail (wishlists, groups, giveaways, matches, dice duels)
- Clickable activity rows linking to public pages (wishlists via share code, giveaways via slug)
- User tier management — upgrade/downgrade users to Pro/Free with confirmation dialog
- Bulk tier actions — select multiple users and upgrade/downgrade at once
- User suspension — suspend/unsuspend accounts with visual indicators
- CSV user export with streaming for large datasets (100k+ users)
- Admin audit log — tracks all admin actions (tier changes, suspensions, exports, reminders)
- Activity feed — recent signups, groups, giveaways, and dice duels in one view
- Pro conversion tracking — pro users, active free users, conversion rate metrics
- Signups bar chart — daily signup trend for the last 14 days
- Wishlist analytics — top reserved items and price range distribution
- Group health warnings — amber alerts for draft groups approaching exchange date
- Search filters — filter users by tier, join period, and suspension status
- Tab-based admin layout (Overview, Users, Activity, Audit Log) with URL persistence
- GitHub Actions CI pipeline — type check, unit tests, build, E2E tests with Playwright caching
- 11 new database performance indexes
- Shared admin auth helpers (UUID validation, tier validation, rate limiting)
- 23 new unit tests for admin API routes
improvement
Dice Duel polish + security hardening + blog redesign
- Server-side answer_time_ms clamping prevents score manipulation in Dice Duel
- Validate selected_option bounds — out-of-range selections treated as wrong answers
- Host reconnect guard — currentQIdx clamped to valid question range
- Clear Draft now requires confirmation before wiping quiz setup
- Larger touch targets (40px) on correct-answer circles for mobile
- Auth-aware Sign In button across all marketing pages — signed-in users see Dashboard instead
- Blog page redesign — featured latest post, 3-column grid, publication dates, sticky header
- Footer added to Dice Duel results page with sticky bottom positioning
- Cleaned up duplicate player sorting in host broadcast functions (DRY)
- Host disconnect detection — players see a warning after 2 min of inactivity, with server-side game status polling
- Cron auto-finishes abandoned "playing" games after 2 hours (scores already saved per-question)
feature
Dice Duel: live multiplayer quiz game
- Dice Duel — create, host, and play live multiplayer quiz games with friends or groups
- AI question generator powered by GPT-4o-mini — free for all users
- Join games instantly via invite code or QR code
- Speed-based scoring with real-time leaderboard updates
- Results page with confetti celebration, animated podium, and per-question breakdown
- Game management: edit settings, cancel, delete, and view past results
- Branded email invites for game participants
- Ended game handling with proper messages for finished and cancelled games
- Draft auto-save to localStorage so you never lose your quiz setup
- Redis rate limiting on all Dice Duel API endpoints
- Cron cleanup job for stale lobby games
- Marketing: homepage showcase, pricing page integration, and dedicated landing page at /dice-duel
fix
Giveaway reliability + security audit
- Draw emails now processed via dedicated cron job — prevents serverless timeout on 100+ entry campaigns
- Batched .in() updates for draws with 200+ entries to stay within PostgREST URL limits
- Paginated entry fetching (fetchAllRows helper) to prevent Supabase silent row truncation on large campaigns
- Winners page now shows all winners (was truncated to first 100 entries)
- Self-referral prevention — users can no longer refer themselves for bonus entries
- CSV export formula injection hardening (strips tabs/carriage returns, prefixes dangerous chars)
- Slug collision retry (up to 3 attempts) on campaign creation
- Paginated auth user lookup replaces full listUsers() scan
- Rate limiting on wishlist item reservations (15 req/min)
- Explicit field selection on match route (replaces select('*'))
- Centralized server constants (BASE_URL, email rate limiting) across 8 files
- Fixed stale closure in useLoadMore hook causing pagination race conditions
feature
Wishlist share reminders + winner payment details
- Periodic "share your wishlist" reminder modal — shown after creating a wishlist with items, 3-day cooldown
- Payment details display on organizer winners page for monetary giveaways
- Winner name anonymization on public giveaway page ("John D.")
improvement
Aesthetic polish + analytics
- Countdown timers on giveaway cards approaching draw date
- Shimmer skeleton loading states across dashboard pages
- Confetti animation on wishlist creation and draw completion
- Pro-gate copy improvements on upgrade prompts
- Monetization, AI usage, and profile analytics on admin dashboard
- Budget formatting per currency
feature
Onboarding + recurring exchanges
- Recurring gift exchanges — set up groups that repeat on a schedule
- Giveaway sorting (newest, ending soon, most entries)
- Onboarding checklist with profile editor, nav badges, and email drip sequence
- Dedicated /admin page with platform metrics and nav links
improvement
Email infrastructure + security patches
- Daily entry digest emails for giveaway organizers
- Milestone emails (100 entries, 500 entries) for organizer motivation
- Resend Audience auto-sync for email deliverability
- Security audit patches — data leak fixes, cron auth hardening, entry flow improvements
- Markdown stripped from card titles, meta tags, and OG images
feature
Markdown prizes + welcome email dedup
- Markdown support in giveaway prize descriptions
- Welcome email deduplication (atomic flag prevents duplicates)
- Bonus entries hint shown on entry form before submission
- Dashboard layout polish and browse/drawn page improvements
feature
Referral awareness + auth fixes
- Referral awareness — dashboard banner and AI nudge toast for referral program
- Fixed PKCE code exchange errors when session already exists
- Consolidated middleware and callback cookie race condition fix
- Force-dynamic on authenticated layout to bypass Netlify durable cache
improvement
Payment UX overhaul + form fixes
- Collapsible payment details section on entry form — collapsed by default with required (*) indicator
- Pick-one payment method UX: users select Bank, Crypto, or Digital Wallet first, then only see those fields
- Auto-expand payment section on validation failure with targeted error toasts
- Fixed infinite loop / hydration error caused by nested <button> elements in checkbox wrappers
fix
Security hardening, DRY refactoring, mobile fixes
- Winner list no longer truncated when num_winners > 50 on public page
- Cache-Control: private, no-store on personalized results endpoint
- Case-insensitive email duplicate check on giveaway entry
- Referrer bonus_entries now decremented when entries are excluded (and re-incremented on restore)
- num_winners validation: cannot set below current pre-selected count
- Shared verifyCampaignOrganizer auth helper replacing duplicated checks across 4 API routes
- Shared DEFAULT_CAMPAIGN_FORM constant for create/edit pages
- Memoized status filter counts on campaign dashboard
- Email rate limiting (600ms delay) on draw notification loop
- Mobile grid fixes on create, edit, browse, results, and winners pages
feature
Monetary giveaways + file uploads
- Monetary giveaway toggle — collect payment details (bank transfer, cryptocurrency, or digital wallet) from entrants
- AI-powered monetary prize detection on campaign title/description
- File upload question type in eligibility form builder (up to 3 images per question)
- Image compression and resizing before upload (max 1200px, WebP/JPEG)
- Giveaway-uploads Supabase storage bucket with campaign-scoped paths
- Payment details confirmation dialog before entry submission
- File upload confirmation dialog with image preview thumbnails
improvement
Promotional nudges + scale optimizations
- Share buttons on giveaway winner results, organizer winners page, join success, and thank-you page
- Feature discovery cards on entry success (wishlists, exchanges, PuzzoFMe)
- "Browse More Giveaways" CTA for non-winners
- "Run Another Giveaway" CTA for organizers after draw
- Wishlist creation nudge on exchange join success
- Paginated entries API (page/pageSize params, max 200)
- CDN caching on public giveaway endpoint (30s TTL + stale-while-revalidate)
- O(n*k) weighted draw algorithm replacing O(n*bonus) pool expansion
- 5 new composite database indexes for giveaway and exchange queries
- Profile email lookup replaces listUsers fallback for entry deduplication
improvement
Comprehensive giveaway test coverage
- 68 new tests across 11 test files covering all giveaway API routes
- Scale tests for 10k-50k entry draws with weighted probability verification
- CSV export formula injection test
- Auto-draw cron tests with failure cap verification
feature
Giveaway growth features
- QR codes and share buttons on campaign dashboard and entry success page
- Giveaway creation templates (Twitter, Product Launch, Newsletter, Community)
- Duplicate (clone) campaign with fresh slug and reset state
- Bonus entries for sharing — referral links with weighted draw probability
- Collapsible social platform picker with badge summary
fix
Security and UX hardening
- CSV export formula injection sanitization (prefix = + - @ | with single quote)
- Crypto-secure Fisher-Yates shuffle for all randomization
- DRY extraction of shared giveaway utilities
- Mobile layout fixes for giveaway entry and dashboard pages
- Accessibility improvements on giveaway forms
feature
Giveaway eligibility questions
- Custom entry form builder with 7 question types (text, textarea, URL, select, radio, checkbox, paragraph)
- AI-suggested eligibility questions based on prize and campaign type
- Required/optional toggle per question
- Answers displayed on entry detail and CSV export
feature
Giveaway core
- Create and manage giveaway campaigns with title, prize, winners, draw date
- Public entry page with social handle collection
- Entry management: exclude, pre-select, vouch, search, filter by status
- Cryptographically random two-pool draw (pre-selected + open)
- Winner and non-winner email notifications
- Auto-draw via cron on scheduled date with failure notifications
- CSV export of all entries
- Browse public giveaways page
- Tier limits: 5 campaigns / 500 entries (free), unlimited / 10k (Pro)
feature
Tier limits bump + SEO landing pages
- Increased free tier limits across the board
- 10 SEO landing pages for high-intent keywords
- 5 blog posts with structured data and related posts
- Country-specific landing pages (Nigeria, Kenya, South Africa)
feature
Email notifications expansion
- Exchange approaching reminder (day before)
- Reservation reminder for gift-givers before event date
- Giveaway draw reminder for organizers
- Auto-draw failure notification with final notice variant
- Giveaway cancellation notification to all entrants
feature
Monetization: Pro tier + Lemon Squeezy
- Pro subscription via Lemon Squeezy ($2.99/mo or $19/yr)
- Tier-gated limits on groups, wishlists, giveaways, AI, bulk invites
- Subscription management portal in Settings
- Usage dashboard for free tier users
feature
AI features suite
- AI wishlist builder — describe a person, get a full gift list
- Photo/screenshot import — upload image, AI extracts items
- AI gift recommendations on wishlists and match reveal
- AI thank-you note generator with tone selection
- 10 free AI uses per day, unlimited on Pro
feature
PWA + push notifications
- Progressive Web App with installable manifest
- Browser push notifications for match-ready and giveaway winner events
- Push notification toggle in Settings
feature
White Elephant mode
- Yankee Swap / White Elephant gift exchange mode
- Random turn order draw instead of Secret Santa matching
- Animated turn number reveal
feature
Wishlist reservations + thank-you notes
- Wishlist item reservation system (junction table)
- Quantity support for wishlist items
- "Do Not Buy" flag with reason
- Thank-you notes between gift givers and receivers
- Budget helpers on match reveal page
feature
Core launch
- Gift exchange creation with 12 occasions and budget ranges
- Invite links, QR codes, and bulk email invites
- Secret Santa matching with exclusion rules and gender-aware pairing
- Animated match reveal with gift suggestions
- Wishlists with manual add, URL scraping, and shareable public links
- Google and email (magic link) authentication
- Welcome email on first sign-in