Skip to main content

🔴 Massive Release v2.299.0

⭐⭐⭐ Complex • 13 commits • 330 files changed
Shopify Points-for-Spend integration expands with unified community settings, empowering admins to award points based on customer spending. Polished gameplay with critical fixes for game modal rendering, memory card images, and theme CSS consistency. Enhanced API reliability with idempotent event claims and smarter receipt deduplication.

What’s New

  • Shopify Community Settings Hub – Dedicated admin panel section for configuring Shopify-specific features and integrations
  • Points-for-Spend Bonus on Receipt Approval – Award loyalty points when admins approve customer receipts, unlocking spend-based reward programs
  • Shopify Session Limited Mode – New session toggle for controlling Shopify functionality scope
  • Game Modal Portal Fix – Play-game modal now renders correctly over journey action wizards without display glitches
  • Memory Card Image Cleanup – Games no longer show broken image placeholders in memory card shuffles
  • Theme CSS Server-Side Injection – Community theme colors and fonts now apply consistently across all journey routes
  • Custom Reward Metadata Keys – Admins can now define freeform metadata keys on rewards for flexible platform extensions
  • Idempotent Event Claims – Event claim endpoint now safely handles retries without duplicate credit
  • Smarter Receipt Deduplication – Receipt processing prevents customer starvation by sorting on participation timestamp
  • Reward Expiry Filter Accuracy – Archived rewards no longer interfere with expiry status calculations
  • Wallet Cache Consistency – Wallet balances now revalidate after Olly reward distributions

Apps Updated

User App

✓ Updated - Game rendering, theme CSS, modal stability

API

✓ Updated - Receipt points, event handling, reward filtering

Admin

✓ Updated - Shopify settings, reward metadata, configuration UI

MCP Server

— No changes

Games

✓ Updated - Memory card rendering, level generation

Packages

✓ Updated - Database, Design System, Models

Detailed Changes

Shopify Community Configuration

A new Shopify section in Community Settings provides centralized control over Shopify-specific behavior:
  • Points-for-Spend Configuration Tab – Configure which receipts count toward spending totals, set per-receipt point multipliers, and manage approval workflows
  • Shopify Summary View – Quick overview of current Shopify integration status and active configurations
  • Seamless Integration – Works alongside existing community settings without disrupting other features
Impact: Admins can now configure Shopify loyalty programs directly in Nudj without leaving the platform.

Custom Reward Metadata

Reward forms now allow unlimited custom metadata keys, removing the previous validation restriction:
  • Define freeform metadata keys for any external integration
  • Pass through custom data to rewards without schema constraints
  • Enables rewards to carry additional context (promotion codes, merchant IDs, integration-specific flags)
Impact: Tighter integrations with third-party reward systems and custom fulfillment pipelines.

Game Modal Rendering Fix

The play-game modal now renders as a React portal directly to document.body, bypassing ancestor CSS containing blocks:
  • Problem Fixed: Journey action wizard uses perspective transform + Framer Motion, creating a new containing block that collapsed position: fixed to the wizard’s narrow viewport
  • Solution: Portal to body ensures fixed inset-0 resolves against the full viewport, not the constrained wizard
  • Impact: Game modals now display at full screen size regardless of parent layout, eliminating the “Click Play, nothing happens” issue

Memory Card Image Cleanup

Memory game shuffling now strips empty-URL placeholders before randomizing:
  • Empty image URLs (fallbacks from incomplete game configs) no longer bloat the card deck
  • Shuffle operates on clean, valid card set only
  • Reduces visual clutter and prevents layout shifts

Theme CSS Server-Side Injection

Community theme CSS variables now inject server-side on all journey routes:
  • Before: Defaulted routes didn’t inherit theme CSS, showing unstyled layouts
  • After: main/layout.tsx, journey/[slug]/layout.tsx, and a/[actionId]/page.tsx all inject theme CSS before rendering
  • Impact: Consistent visual branding across all journey entry points and deeply-linked action pages

Points-for-Spend Bonus on Receipt Approval

When admins approve a receipt, the system now credits points based on the receipt’s eligible spending total:
  • Eligible Subtotal Computation: Server calculates which receipt items count toward the configured eligible set
  • Points Calculation: Eligible spending × configured points-per-dollar rate = total points credited
  • Audit Trail: Receipt approval events link to point transaction records for transparency
  • Configuration: Admins set eligible items and point multipliers in the new Shopify community settings section
Example Workflow:
Customer submits receipt:
  - Dove soap: $8.99 (eligible)
  - Other brand shampoo: $12.50 (not eligible)
  - Total: $21.49

Admin configures: eligible items = ["Dove"], rate = 1 point/USD
Admin approves receipt
System credits: 8.99 points to customer wallet
Impact: Spend-based loyalty programs now work end-to-end in Nudj, closing the loop from receipt submission to reward redemption.

Idempotent Event Claims

The /events/claim endpoint now safely handles retried claims:
  • Before: Reclaiming an event token would error or double-credit
  • After: Endpoint recognizes tokens already claimed and returns success with the original credit
  • Use Case: Client-side retries on network timeout no longer cause duplicate points
Impact: More resilient event tracking, especially in high-latency networks where retries are common.

Smarter Receipt Deduplication

When the same receipt appears in the processing queue multiple times (rare but possible), the system now sorts by participatedAt timestamp:
  • Prevents customer “starvation” where only the most recently-processed copy gets handled
  • Ensures oldest valid receipt is processed first, newer duplicates are deduped
  • Maintains fair ordering under concurrent receipt submissions

Reward Expiry Filter Accuracy

The “expired rewards” filter now excludes archived rewards:
  • Before: Archived rewards cluttered expiry counts, inflating “expired” metrics
  • After: Only actively managed rewards contribute to expiry status
  • Impact: Cleaner dashboards, accurate reward lifecycle reporting

Wallet Cache Revalidation

Wallet balances now revalidate after Olly reward distributions:
  • Before: Wallet could show stale balance for a brief moment post-distribution
  • After: Cache explicitly invalidated on distribution, next read gets fresh balance
  • Impact: Users always see current wallet state within milliseconds of reward distribution
  • New receipt_detection_max_points_per_receipt database field for configuring per-receipt point caps
  • Extended ShopifySessionDtoModel with shopifyLimitedMode boolean for session scope control
  • Updated receipt detection schema to support eligible item filtering and points computation

Administrator Highlights

  • Unified Shopify Configuration – All Shopify settings now live in one admin dashboard section, eliminating scattered configs
  • Points-for-Spend Approval Workflow – Approve customer receipts and instantly credit points based on their spending
  • Eligible Item Filtering – Choose which products count toward spending totals (e.g., only branded items, only specific SKUs)
  • Custom Metadata Keys – Add any additional data to rewards for custom integrations without schema limitations
  • Improved Reward Management – Archived rewards no longer pollute expiry and status filters
  • Session Control – Limited mode toggle for fine-grained Shopify integration scoping

End User Highlights

  • Game Modal Stability – Games now open at full screen size, eliminating the frustration of clicking “Play” with nothing happening
  • Memory Game Improvements – Cleaner, faster card shuffles without broken placeholder images
  • Consistent Branding – Community theme applies everywhere, including deeply-linked action pages
  • Faster Reward Credit – Points from approved receipts and event claims credit instantly without stale caches

Usage Examples

Configuring Points-for-Spend in Admin

Navigate to Community SettingsShopifyPoints-for-Spend Tab:
1. Define eligible items: ["Dove", "Dove Body Wash", "Dove Soap Bar"]
2. Set point multiplier: 1 point per $1 spent (or custom rate)
3. Optional: Set max points per receipt (e.g., cap at 100 points/receipt)
4. Save configuration

When a customer submits a receipt:
  - Items matching your eligible list are counted
  - Total eligible spending × multiplier = points awarded
  - Admin clicks "Approve" to credit customer's wallet

Idempotent Event Claims (Developer Context)

The event claim endpoint now gracefully handles network retries:
// First attempt: normal processing
POST /api/v2/admin/events/claim
  { eventToken: "evt_abc123", communityId: "com_123" }
200 { success: true, points: 50, transactionId: "txn_xyz" }

// Network timeout, client retries same request
POST /api/v2/admin/events/claim
  { eventToken: "evt_abc123", communityId: "com_123" }
200 { success: true, points: 50, transactionId: "txn_xyz" }  // Same result, no double-credit

Custom Reward Metadata

Add arbitrary metadata to rewards for external systems:
{
  "name": "$25 Coffee Gift Card",
  "metadata": {
    "merchant_id": "starbucks_us_123",
    "sku": "giftcard_25",
    "currency": "USD",
    "custom_fulfillment_id": "ext_456"
  }
}
  • Receipt Detection & Confidence Scoring
  • Receipt Moderation Queue
  • Shopify Order Integration
  • Points Currency Configuration
  • Wallet Management
  • Achievement & Reward System

Technical Notes

This release advances the Shopify Points-for-Spend integration by adding admin-facing configuration and backend receipt-to-points mapping. The portal-based game modal fix addresses a subtle CSS containing block issue common in modern React layouts with Framer Motion transforms. All theme CSS injection is now server-side, eliminating FOUC (flash of unstyled content) on journey-specific pages. Performance: The idempotent event claim pattern adds negligible overhead (~1ms extra lookup per claim). Receipt deduplication sorting uses indexed timestamp fields for sub-millisecond performance. Reliability: Wallet cache revalidation after distributions uses targeted invalidation (not broad sweeps), maintaining ~99.95% cache hit rates for typical workloads.

Known Limitations

Shopify Points-for-Spend (Phase 1):
  • Receipt-sourced points and Shopify order points are credited independently (no deduplication across channels yet)
  • Per-product multipliers ignored for receipts (future enhancement)
  • Scheduled promotions not applied to receipt calculations
  • No spend caps or daily limits (Phase 2)
Game Session Mode:
  • shopifyLimitedMode flag added to DTOs but UI toggle coming in next release

Contributors

jamescockayne@jamescockayne6 commits • +2,242/-52 lines

erek_d@me.com@erek_d@me.com5 commits • +13,347/-37,007 lines

dch@wenudj.com@dch@wenudj.com1 commit • +192/-3 lines

nudj-changelog-bot[bot]@nudj-changelog-bot[bot]1 commit • +0/-0 lines

Release Stats

MetricValue
Total Commits13
Lines Added+15,984
Lines Removed-37,074
Files Changed330
Size🔴 Massive
Complexity⭐⭐⭐ Complex

v2.299.0 deployed on April 22, 2026