System Ready

Rewards System Documentation

A comprehensive walkthrough for the implementation of Scratch Cards, Bonus Coins, and In-App Purchases within the Bites Apps ecosystem.

Project Scope

This documentation covers the synchronization between the moviebites-api backend and the bites-fe-rn-v1 React Native frontend.

Core Features

Daily Check-in

7-day streak logic with dynamic bonus coin rewards based on server-side configurations.

Scratch Cards

Interactive SVG masking for a premium mobile feel, with randomized backend reward calculation.

Coin Purchases

Full integration with Adapty SDK and REST API for secure purchase verification.

Backend Architecture

Details on Drizzle schemas, API routes, and reward processing logic in moviebites-api.

Database Schema (Drizzle ORM)

Core Tables (src/db/schema/rewards.ts)

  • user_balances: Tracks coins (paid) and bonus (earned).
  • reward_transactions: Audit log for every change. Includes type, source, amount.
  • reward_settings: Key-value store for daily_check_in, streak_7_bonus, etc.

Deep-Dive: Feature Nesting & Flow

1. Scratch Card Lifecycle

Trigger

API receives POST /scratch/:instanceId from frontend.

Validation

Verifies card ownership, ensures isScratched is false, and checks expiresAt.

Logic

Calculates reward based on template (Fixed vs Random minAmount to maxAmount).

Atomic Batch

Updates card status, increments balance, and logs transaction in one D1 batch.

2. Daily Check-in Streak

Logic

Compares today with lastCheckInDate. If split by 1 day, newStreak = (old % 7) + 1.

Reward

Awards streak_7_bonus if newStreak == 7, otherwise daily_check_in.

3. Purchase Verification

Handshake

Calls Adapty REST API to fetch the user's transaction truth.

Idempotency

Checks if transactionId exists in purchase_logs to prevent double-spending.

4. Episode Unlocking (Spend Flow)

Check

Verifies series/episode existence and user's current bonus or coins balance.

Batch Update

Deducts cost, records unlocked_content, and logs transaction in a single atomic operation.

5. AdMob SSV Flow

Callback

AdMob server pings GET /ad-ssv-callback with signed reward metadata.

Verification

Backend validates `transaction_id` unique check before granting bonus points.

Async Processing

Uses Cloudflare Queues via reward-processor.ts for reliable reward granting from external webhooks (Adapty, Tapjoy) with retry logic and idempotency checks.

Frontend Implementation

Implementation details for bites-fe-rn-v1 using React Native and Reanimated.

Interactive Scratch Card (ScratchCard.tsx)

UI Thread

Uses SharedValue for SVG path string and point counts to ensure 60fps.

Gesture

Gesture.Pan() onUpdate appends coordinates to the mask path.

Trigger

Once pointsCount > 100, calls runOnJS(onScratchComplete)().

Technical Touchpoints

Coin Purchase Flow

  1. Initiation: rewardsService.trackPurchaseInitiate logs intent.
  2. Payment: adapty.makePurchase(product) triggers OS sheet.
  3. Verification: Success sends profileId to POST /verify-purchase.
  4. Refresh: Frontend calls loadData() to update UI balances locally.

Ad Reward Flow

  1. Initiation: RewardsScreen calls rewardsService.trackAdInitiate.
  2. Display: adMobHelper.showRewardedAd is triggered.
  3. Refresh: Frontend waits 2s (for SSV) then calls loadData().

Episode Unlock Flow

  1. Check: Page loads and checks RewardsService.isUnlocked.
  2. Unlock: If locked, clicking "Unlock" triggers RewardsService.unlockEpisode.

Social Reward Flow

  1. Redirect: User clicks social icon -> opens platform URL.
  2. Claim: User returns and clicks "Claim" -> POST /social/claim.
  3. Validation: Backend verifies platform and grants reward once per user.

Service Mapping (rewardsService.ts)

Method Endpoint
getBalance GET /balance/:userId
scratchCard POST /scratch/:id
verifyPurchase POST /verify-purchase

Replication Guide

Step-by-step instructions for porting the Rewards system to your new project.

Database Setup

1. Migrations: Create the user_balances, reward_transactions, user_scratch_cards, and reward_settings tables.

2. Initial Config: Seed reward_settings with default values (check_in=10, streak=50, ad_reward=10).

Backend Implementation

1. Service Layer: Implement a RewardProcessor to handle balance updates. Use transactions.

2. Routes: Create the /rewards endpoints. Ensure idempotency via transactionId checks.

Frontend Integration

1. API Service: Port rewardsService.ts and update the baseURL.

2. UI Implementation: For Web/HTML5, adapt ScratchCard to use HTML5 Canvas or CSS masking.

External Services Setup

Configure AdMob SSV, OneSignal App IDs, and Adapty Secret Keys in your environment variables.

Admin Tools

Implement admin routes to create Scratch Card Templates and assign cards to users based on targeting (all, platform, or specific user).