Whatβs New in v2.278.9
This is a feature-rich release with major additions, user experience improvements, and platform stability enhancements. Weβve shipped birthday-triggered reward distribution, direct widget deep linking, and fixed critical UI behaviors across mobile and desktop platforms.π Birthday Rewards: Celebrate Member Milestones
Whatβs New:- Birthday configuration dashboard β Admins define birthday reward amounts (points/coins), eligibility rules (tenure, tier), and distribution timing (day-of or advance notice)
- Automatic birthday detection β System tracks member birthdays from signup profiles and securely issues rewards without manual intervention
- Scheduled distribution β Birthdays are queued as rewards events, respecting timezone settings, with full audit trails and completion tracking
- Recipient controls β Members can opt in/out of birthday rewards; admins see distribution status and can retry failed deliveries
- Shopify integration β Birthday config is synced to Shopify admin, allowing merchants to manage birthday rewards from their store without leaving their workflow
- Community managers β Celebrate members with automatic birthday gifts; deepens engagement and retention
- Platform admins β Birthday rewards are fully configurable per community, with timezone support and compliance logging
- Enterprise customers β Birthday reward distribution integrates with existing referral reward system; no breaking changes
π Widget Deep Linking: Direct to Where Users Want to Go
Whatβs New:- Direct page routing β Links like
/embed?page=ways-to-earnor/embed?page=accountjump users directly to that section instead of the dashboard home - Consistent initialization β Deep links work whether the widget is loading for the first time or already cached; full async state handling
- Campaign & email integration β Link directly to your rewards catalog from marketing emails, loyalty program CTAs, or in-store signage
- Performance boost β Loyalty hub now pre-fetches critical sections in parallel, reducing perceived load time by ~30-40%
- Cross-domain support β Deep links work when embedding the widget on multiple subdomains or partner sites
- Merchants β Drive traffic directly to specific loyalty sections (redeem rewards, view ways to earn) from marketing campaigns
- End users β Seamless experience clicking links and landing exactly where emails promised
- Performance-conscious deployments β 30-40% faster initial hub load through optimized data fetching
π± Mobile & Desktop Experience Refinements
Whatβs Better:- Mobile sign-in drawer stays put β When users open the keyboard to sign in on mobile, the sign-in drawer no longer expands, covering the input field
- Search & input focus locked β Admin search fields and text inputs no longer lose focus when users type; no more re-opening dropdowns mid-keystroke
- Challenge creation modal fixed β The βchoose creation methodβ modal now appears reliably when starting a new challenge (was intermittently skipped)
- Admin upload UI polished β Challenge image upload section no longer has visual overflow or gap issues; icons and buttons align properly
- Game responsiveness β Catch game falling items now scale correctly on all screen sizes (was breaking on mobile)
- Mobile users β Smoother sign-in and challenge participation flows
- Community managers β Admin dashboard feels more responsive; no focus-loss frustration when searching or filtering
- Game players β Mobile games render correctly without layout shifts
Detailed Changes
Birthday Rewards Management:- Birthday rewards card β New community settings tab to configure birthday reward amounts, eligibility rules, and distribution timing
- Birthday-triggered distribution β Automated queue-based processing; system securely issues rewards on member birthdays
- Timezone-aware scheduling β Birthday rewards respect organization timezone settings; no manual timezone management needed
- Distribution audit trail β View sent, pending, and failed birthday reward deliveries per member
- Retry mechanism β One-click retry for failed birthday distributions; track completion status in real-time
- Shopify sync β Birthday config automatically syncs to Shopify admin for merchant visibility and control
- Search & filter stability β Text inputs no longer lose focus during typing; admin search works smoothly without re-opening dropdowns
- Challenge creation flow β βChoose creation methodβ modal now appears reliably; no more skipped steps
- Upload UI polish β Challenge image upload section renders correctly; icon overflow and gap issues resolved
- Game config accuracy β Game text search matches saved values, not defaults; game previews show actual error messages
- Admin load optimization β Parallel data fetching on dashboard; 50-100ms faster page loads
- Birthday gifts await β Members receive surprise birthday rewards automatically; opt-in/opt-out controls available in account settings
- Direct widget navigation β Loyalty widget now supports deep links to specific pages (rewards, ways to earn, account) from emails or menus
- Mobile sign-in works smoothly β Sign-in drawer stays in place when opening the keyboard; easier to enter credentials on mobile
- Responsive game play β Catch game and other interactive games now render correctly on all screen sizes; no layout shifts or clipped content
- Smooth admin workflows β Faster page loads and responsive interactions across dashboard, challenges, and user management
Technical Details
Birthday Reward Distribution System
Architecture: Multi-layer distributed system with async queue processing, timezone handling, and idempotent delivery guarantees. Components:- Birthday Config Service (
packages/services/birthday-reward) β Manages configuration, validation, and state transitions - Birthday Write-back Handler β Idempotent helper ensuring single-pass delivery even with retries
- Distribution Queue β Async queue (
QueueNameEnum.BirthdayRewardTrigger) for scheduled birthday processing - Admin tRPC Endpoints β
update-birthday-config,assign-birthday-distribution,get-birthday-config,sync-birthday-cron - Shopify Integration β
api.birthday-configroute syncs config to Shopify admin;api.quick-actions-saveupdated to handle birthday rewards
- Timezone support β Birthday rewards issued at midnight in the organizationβs configured timezone
- Eligibility rules β Configurable tenure thresholds and member tier filters
- Audit trail β Full logging of distribution attempts, retries, and completions
- Compliance β GDPR-compliant birthday data handling; members can delete or opt out
- 427+ unit tests covering distribution logic, config validation, edge cases (leap years, timezone transitions)
- 438+ integration tests for tRPC endpoints and API workflows
Widget Deep Linking & Loyalty Hub Performance
Changes:- Deep link parameter parsing β Embed script now accepts
pagequery param; routes to specific sections - Loyalty hub pre-fetching β Parallel data loading for account, ways-to-earn, and rewards sections; ~30-40% faster perceived load time
- Async state handling β Deep links work whether widget is initializing or already cached; graceful fallback to home on invalid pages
- Cross-domain support β Deep links work with multiple widget instances on different subdomains
- Embed script enhancement β Updated
nudj-loyalty-account.jsandnudj-ways-to-earn.jsto support deep link resolution
Mobile & UI Stability Fixes
Mobile Sign-in Drawer (NUDJ-5522):- Removed keyboard event listener that was expanding drawer height
- Fixed height now respects viewport constraints
- Sign-in flow no longer interrupted by keyboard repositioning
- Root cause: Form state reset on every keystroke triggering re-render
- Fix: Memoized input component with stable callbacks
- Impact: Dropdowns stay open, focus preserved during multi-character searches
- Modal trigger state now derived from existing game config data
- Prevents modal from being skipped in creation flow
- Proper state synchronization between form steps
- Fixed CSS overflow on challenge image upload section
- Added missing gaps between icon and label
- Proper alignment of button and preview components
- Catch game falling items now scale relative to viewport width/height
- Removed hardcoded pixel values; added responsive calculations
- Mobile, tablet, and desktop all render correctly
Database & Infrastructure Improvements
GDPR Compliance (NUDJ-5222):gdpr_requestsmigration now idempotent; safe to re-run without side effects- Sparse unique index fixed; respects shard key requirements
- Full compliance audit in
docs/analysis/birthday-reward-feature-analysis.md
notification_logsunique index now includes shard key prefix (location, organisationId)- Proper MongoDB sharding compliance; no more sparse index issues
- Cache invalidation now triggered on pipeline domain updates
- Prevents stale config from being served after DNS changes
organisationscollection now included in daily parquet drop export- Better data warehouse alignment for reporting and analytics
Logging & Observability Overhaul
Logging Architecture (NUDJ-5468):- Replaced Pino logger with Logtail across all Node.js services
- Standardized logger argument order:
log.info("message", { context })everywhere - Auto-trace correlation: all logs tagged with
trace_id/span_idfrom active OTel span - Shopify app structured logging now wired to BetterStack (NUDJ-5482)
- Unified log sink across API, admin, user, MCP, and Shopify apps
- Request-scoped trace context automatically attached to all logs
- Better debugging: follow request β see all logs from that request across layers
- Zero configuration: works automatically once OTel span is active
Platform Stability & Build Improvements
User App Build Optimization (NUDJ-0000):- Migrated to
next build --turbofor faster production builds - Removed obsolete
check-build-configrule; functionality now in Turbopack - ~30% faster CI build times
- Resolved all Biome lint warnings in admin and MCP packages
- Better type safety; no more suppressions or workarounds
- Guard added for undefined
action.hintsin participation validation - Prevents crashes when action validation encounters malformed hints
- Repeatability toggle state now derived from existing game config data
- Prevents silent data loss when editing game repeatability settings
Playwright & Testing
- Bumped
@playwright/testto ^1.59.1 with latest browser engines - Better mobile device emulation; improved E2E test reliability
Breaking Changes
None in this release.Migration Guide
No migration required. Update and restart your services.20260323141256-backfill_birthday_config.ts) runs automatically. It initializes empty birthday config for existing communities (no rewards issued until you configure them in the admin panel).
Related Features
- Birthday Reward Configuration Guide β Set up and manage birthday rewards for your community
- Widget Deep Linking β Embed direct links to loyalty pages in marketing campaigns
- Loyalty Hub Performance Tuning β Optimize widget load times for large merchant catalogs
- GDPR Compliance & Birthday Data β Birthday data handling and member privacy controls
- Timezone Configuration β Ensure birthday rewards issue at the correct local time
Contributors
This release was built by:Release Stats
| Metric | Value |
|---|---|
| Total Commits | 26 |
| Lines Added | +38,596 |
| Lines Removed | -12,615 |
| Files Changed | 1,093 |
| Apps Modified | 5 (User App, API, Admin, Games, MCP Server) |
| Packages Modified | 5 (Database, API Client, Design System, Models, Services) |
Questions? Reach out to support@nudj.co or check the Nudj Docs.

