Navigation

๐Ÿ€ Slam Dunk Idioms Child App Architecture

Secure standalone deployment for external developers

Architecture Overview

The Slam Dunk Idioms game will be spun off as a standalone child app that:

  • Runs independently on its own domain (e.g., play.snappyidioms.basketball)
  • Connects to the main app's Mothership API for data and authentication
  • External developers have zero access to the main SnappyIdioms.com codebase
  • Uses the same security model as your existing Scrabble game (JWT tokens, API keys, HMAC signing)
Security Model

๐Ÿ” What External Developers Get:

Game API Key - Public identifier (e.g., slam_dunk_01)

HMAC Secret Key - For signing requests (never sent over wire)

API Documentation - Endpoints, schemas, examples

Starter Template - React boilerplate with auth already wired

๐Ÿšซ What They DON'T Get:

Direct database access

Main app source code

User passwords or sensitive data

Admin or service role access

Other games' API keys or data

Data Flow Architecture
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  User's Browser                                             โ”‚
โ”‚  (play.snappyidioms.basketball)                            โ”‚
โ”‚                                                             โ”‚
โ”‚  1. User clicks "Play Slam Dunk Idioms"                   โ”‚
โ”‚  2. Child app redirects to SnappyIdioms.com/auth           โ”‚
โ”‚  3. User logs in (if needed)                               โ”‚
โ”‚  4. Main app generates JWT token                           โ”‚
โ”‚  5. Redirects back with ?auth=TOKEN                        โ”‚
โ”‚  6. Child app validates token via Mothership API           โ”‚
โ”‚  7. Game starts with authenticated user                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Child App Server (External Developer Controls)            โ”‚
โ”‚  - React/Next.js frontend                                   โ”‚
โ”‚  - Game logic and UI                                        โ”‚
โ”‚  - API proxy to Mothership                                  โ”‚
โ”‚  - NO direct database access                                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ†“
                    HTTPS + HMAC
                           โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Mothership API (SnappyIdioms.com - YOU control)          โ”‚
โ”‚                                                             โ”‚
โ”‚  Endpoints:                                                 โ”‚
โ”‚  โ€ข POST /api/game/verify-token                             โ”‚
โ”‚    โ†’ Validates JWT, returns user data                      โ”‚
โ”‚                                                             โ”‚
โ”‚  โ€ข GET /api/game/idioms                                    โ”‚
โ”‚    โ†’ Returns basketball idioms (filtered by game_id)       โ”‚
โ”‚                                                             โ”‚
โ”‚  โ€ข GET /api/game/user-progress                             โ”‚
โ”‚    โ†’ Returns user's pearls, badges, stats                  โ”‚
โ”‚                                                             โ”‚
โ”‚  โ€ข POST /api/game/award-pearls                             โ”‚
โ”‚    โ†’ Awards pearls (with validation + fraud checks)        โ”‚
โ”‚                                                             โ”‚
โ”‚  โ€ข POST /api/game/save-score                               โ”‚
โ”‚    โ†’ Saves game results to leaderboard                     โ”‚
โ”‚                                                             โ”‚
โ”‚  Security: HMAC signature validation on every request      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Base44 Database (Main App - YOU control)                  โ”‚
โ”‚  - User accounts                                            โ”‚
โ”‚  - Idioms library                                           โ”‚
โ”‚  - Pearls of Wisdom                                         โ”‚
โ”‚  - Golden Eggs                                              โ”‚
โ”‚  - Leaderboard                                              โ”‚
โ”‚  - Achievement badges                                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
Implementation Steps for You

Step 1: Register the Game in Your System

Create a new GameDeveloper entity record:

{
  "developer_name": "Basketball Team",
  "developer_email": "basketball@external.dev",
  "game_name": "Slam Dunk Idioms",
  "game_id": "slam_dunk_01",
  "secret_key": "GENERATE_RANDOM_SECRET_HERE",
  "base_pearl_rate": 5,
  "status": "active",
  "allowed_endpoints": [
    "verify-token",
    "get-idioms",
    "get-user-progress",
    "award-pearls",
    "save-score"
  ]
}

Step 2: Create Mothership API Endpoints

You already have this pattern from your Scrabble game! Reuse and adapt these functions:

  • โœ… functions/generateGameToken - Generate JWT for auth
  • โœ… functions/verifyGameToken - Validate JWT
  • โœ… functions/gameAPI - Main API handler
  • โœ… functions/awardPearlsAtomic - Award rewards

โš ๏ธ Important: Filter idioms by category: "basketball" or create a new game_id field on the Idiom entity.

Step 3: Provide Developer Package

Give external developers:

  • ๐Ÿ“ฆ Starter template repository (React + TypeScript)
  • ๐Ÿ“– API documentation (endpoints, request/response formats)
  • ๐Ÿ”‘ Game API credentials (game_id + secret_key)
  • ๐Ÿ’ก Example code for auth flow
  • ๐Ÿงช Test environment URL

Step 4: Monitor & Control

You maintain full control via:

  • ๐ŸŽ›๏ธ Kill switch: Set status: "suspended" to block all API calls instantly
  • ๐Ÿ“Š Usage tracking: Monitor api_calls_count and last_api_call
  • ๐Ÿ” Audit logs: Track all pearl awards and score submissions
  • โš™๏ธ Rate limiting: Enforce request limits per game
  • ๐Ÿ›ก๏ธ Fraud detection: Validate scores, detect cheating patterns
Developer Starter Template (What They Build With)

External developers get a clean React template with authentication pre-wired:

File: src/config.ts

export const config = {
  gameId: 'slam_dunk_01',
  secretKey: process.env.HMAC_SECRET_KEY!, // From environment
  mothershipUrl: 'https://snappyidioms.com/api/game',
  authRedirectUrl: 'https://snappyidioms.com/auth',
};

File: src/lib/mothership.ts

import crypto from 'crypto';
import { config } from '../config';

// Generate HMAC signature for request
function signRequest(payload: any): string {
  const message = JSON.stringify(payload);
  return crypto
    .createHmac('sha256', config.secretKey)
    .update(message)
    .digest('hex');
}

// Call Mothership API
export async function callMothership(
  endpoint: string,
  data: any
) {
  const payload = { ...data, game_id: config.gameId };
  const signature = signRequest(payload);
  
  const response = await fetch(
    `${config.mothershipUrl}/${endpoint}`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Game-ID': config.gameId,
        'X-Signature': signature,
      },
      body: JSON.stringify(payload),
    }
  );
  
  if (!response.ok) {
    throw new Error('Mothership API error');
  }
  
  return response.json();
}

File: src/hooks/useAuth.ts

import { useState, useEffect } from 'react';
import { callMothership } from '../lib/mothership';
import { config } from '../config';

export function useAuth() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const token = params.get('auth');
    
    if (token) {
      // Validate token via Mothership
      callMothership('verify-token', { token })
        .then((data) => {
          setUser(data.user);
          localStorage.setItem('gameToken', token);
        })
        .catch(() => redirectToLogin())
        .finally(() => setLoading(false));
    } else {
      const savedToken = localStorage.getItem('gameToken');
      if (savedToken) {
        callMothership('verify-token', { token: savedToken })
          .then((data) => setUser(data.user))
          .catch(() => redirectToLogin())
          .finally(() => setLoading(false));
      } else {
        redirectToLogin();
      }
    }
  }, []);
  
  function redirectToLogin() {
    const returnUrl = window.location.href;
    window.location.href = 
      `${config.authRedirectUrl}?return=${encodeURIComponent(returnUrl)}`;
  }
  
  return { user, loading };
}

Usage in Game Component:

import { useAuth } from './hooks/useAuth';
import { callMothership } from './lib/mothership';

function SlamDunkGame() {
  const { user, loading } = useAuth();
  
  async function loadIdioms() {
    const data = await callMothership('get-idioms', {
      category: 'basketball',
      difficulty: 'rookie'
    });
    return data.idioms;
  }
  
  async function awardPearls(amount: number) {
    await callMothership('award-pearls', {
      user_email: user.email,
      amount,
      reason: 'Completed basketball round'
    });
  }
  
  if (loading) return <div>Loading...</div>;
  
  return <div>Game UI here...</div>;
}
Benefits of This Architecture

โœ… For You (Main App Owner):

  • โ€ข Full control over data and users
  • โ€ข Can revoke access instantly
  • โ€ข Monitor all game activity
  • โ€ข No risk to main codebase
  • โ€ข Shared reward economy (pearls, badges)
  • โ€ข Reuse existing infrastructure

โœ… For External Developers:

  • โ€ข Clean separation of concerns
  • โ€ข Can deploy anywhere (Vercel, Netlify, etc.)
  • โ€ข No database setup needed
  • โ€ข Authentication handled for them
  • โ€ข Focus only on game UI/UX
  • โ€ข Access to existing user base

๐Ÿ“Œ Note: This is the exact same architecture as your Scrabble game (Famous.ai integration). You already have all the backend infrastructure built โ€” just register a new game_id and hand developers the starter template!