πŸ”βŒ˜K

Start typing to search docs.

System Architecture

v1

Four-level architecture, domain management, and Supabase project structure.

On this page
  1. App Factory Platform - Architecture Documentation
  2. 🎯 Executive Summary
  3. Key Features
  4. πŸ—οΈ Four-Level Architecture
  5. πŸ“Š Detailed Architecture Breakdown
  6. Level 1: Platform Infrastructure
  7. Level 2: Customer Organizations
  8. Level 3: Customer Applications
  9. Level 4: End Users (Public)
  10. πŸ” Authentication Architecture
  11. Three Separate Auth Contexts
  12. πŸ—„οΈ Database Architecture
  13. Single Supabase Project Strategy
  14. Database Organization
  15. Naming Convention
  16. Row-Level Security (RLS)
  17. 🌐 Domain Management System
  18. Custom Domain Architecture
  19. Domain Setup Flow
  20. Domain Verification
  21. SSL Certificate Management
  22. πŸ”¨ Forge CLI Architecture
  23. Purpose
  24. Core Commands
  25. Forge Workflow
  26. Forge Configuration
  27. πŸ“¦ Technology Stack
  28. Frontend
  29. Backend
  30. Infrastructure
  31. Payments
  32. Monitoring
  33. πŸš€ Deployment Architecture
  34. Platform Apps (Landing, Dashboard)
  35. Customer Apps
  36. Environment Strategy
  37. πŸ”„ Data Flow Examples
  38. Example 1: Customer Signs Up
  39. Example 2: Customer Creates App
  40. Example 3: End User Plays Game
  41. πŸ”’ Security Considerations
  42. Authentication Security
  43. Database Security
  44. API Security
  45. Domain Security
  46. πŸ“ˆ Scalability Considerations
  47. Current Limits (Free/Pro Tier)
  48. Scaling Strategy
  49. 🎯 Key Design Decisions
  50. Decision 1: Single Supabase Project
  51. Decision 2: Prefixed Tables for Apps
  52. Decision 3: Custom Domains Only
  53. Decision 4: Vercel Deployment
  54. Decision 5: Multi-Tenant Dashboard
  55. πŸ› οΈ Development Workflow
  56. Local Development
  57. Adding a New App Type
  58. 🚨 Common Pitfalls & Solutions
  59. Pitfall 1: DNS Propagation Delays
  60. Pitfall 2: Supabase RLS Policy Conflicts
  61. Pitfall 3: Prefixed Table Name Conflicts
  62. Pitfall 4: Cross-Origin Auth Issues
  63. Pitfall 5: Large Database Schema
  64. πŸ“š Additional Resources
  65. Internal Documentation
  66. External Resources
  67. πŸŽ“ For AI Agents
  68. Quick Context Summary

App Factory Platform - Architecture Documentation

Version: 1.0
Last Updated: 2025-01-14
Purpose: High-level architecture guide for AI agents, developers, and stakeholders


🎯 Executive Summary

App Factory is a multi-tenant SaaS platform that enables customers to rapidly create, deploy, and manage web and mobile applications through a unified dashboard. The platform handles infrastructure provisioning, authentication, database management, and custom domain configuration automatically.

Key Features

  • Rapid App Generation: Create apps via Forge CLI or Dashboard UI
  • Custom Domain Support: Deploy apps to customer-owned domains
  • Unified Authentication: Supabase-powered auth across all levels
  • Multi-Tenant Architecture: Shared platform with org-level isolation
  • Database Management: Prefixed tables for app data isolation
  • Infrastructure as Code: Pulumi-managed cloud resources

πŸ—οΈ Four-Level Architecture

App Factory operates across four distinct levels:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Level 1: Platform Infrastructure                        β”‚
β”‚ - Landing & Dashboard (infiniteapps.ai)                β”‚
β”‚ - Shared by all customers                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Level 2: Customer Organizations                         β”‚
β”‚ - Users sign up and create organizations               β”‚
β”‚ - All use same dashboard URL                           β”‚
β”‚ - Data isolated via RLS                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Level 3: Customer Applications                          β”‚
β”‚ - Apps created via Forge CLI or Dashboard              β”‚
β”‚ - Deployed to CUSTOM DOMAINS (customer-owned)          β”‚
β”‚ - Prefixed database tables per app                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Level 4: End Users                                      β”‚
β”‚ - Public users who visit customer apps                 β”‚
β”‚ - Sign up on custom domains                            β”‚
β”‚ - Isolated per app                                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“Š Detailed Architecture Breakdown

Level 1: Platform Infrastructure

Purpose: Core platform that serves all customers

Components:

  • Landing App (landing.infiniteapps.ai)

    • Marketing and customer acquisition
    • Stripe billing integration
    • Sign-up flow
    • Hosted on Vercel
  • Dashboard App (dashboard.infiniteapps.ai)

    • Multi-tenant admin interface
    • Organization management
    • App creation and deployment UI
    • Secret management
    • Hosted on Vercel

Technology Stack:

  • Framework: Next.js 14 (App Router)
  • Authentication: Supabase Auth
  • Database: Supabase PostgreSQL
  • Payments: Stripe
  • Hosting: Vercel
  • CDN: Vercel Edge Network

Key Files:

  • apps/landing/ - Landing page application
  • apps/dashboard/ - Dashboard application
  • ops/apps.yaml - Platform configuration

Level 2: Customer Organizations

Purpose: Multi-tenant organization management with data isolation

User Flow:

1. User visits landing.infiniteapps.ai
2. Signs up with Google/GitHub OAuth
3. Creates/joins organization
4. Accesses dashboard.infiniteapps.ai
5. All orgs use SAME dashboard URL
6. Data scoped via organization_id

Data Model:

-- Platform users (customers using the dashboard)
users
  β”œβ”€ id (UUID)
  β”œβ”€ email
  β”œβ”€ name
  └─ created_at

-- Customer organizations
organizations
  β”œβ”€ id (UUID)
  β”œβ”€ name
  β”œβ”€ slug (unique)
  └─ owner_id β†’ users.id

-- Organization membership
organization_members
  β”œβ”€ id (UUID)
  β”œβ”€ user_id β†’ users.id
  β”œβ”€ organization_id β†’ organizations.id
  └─ role (OWNER, ADMIN, MEMBER)

Isolation Strategy:

  • Row-Level Security (RLS) policies
  • All queries filtered by organization_id
  • Users only see their org's data
  • No cross-org data access

Example RLS Policy:

CREATE POLICY "Users see own org data"
ON apps FOR SELECT
USING (organization_id = (
  SELECT organization_id 
  FROM organization_members 
  WHERE user_id = auth.uid()
));

Level 3: Customer Applications

Purpose: Apps created and deployed by customers

Critical Distinction: Apps deploy to CUSTOMER-OWNED DOMAINS, not platform domains!

Examples:

  • βœ… User A's game: memory-game.acmegames.com (User A's domain)
  • βœ… User B's blog: blog.betacompany.io (User B's domain)
  • βœ… Platform owner: app.infiniteapps.ai (platform owner's domain)
  • ❌ NO customer apps on infiniteapps.ai (except platform owner)

App Creation Flow:

1. User logs into dashboard.infiniteapps.ai
2. Clicks "Create New App"
3. Selects a template from the gallery (backed by `ops/apps.yaml`)
4. Confirms name, platforms, and IDs prefilled from the template
5. Forge queues a provisioning job (Supabase, code scaffolding, env bundles)
6. Domain configuration is handled afterwards from the app workspace (β€œDomains” tab)
7. Platform verifies DNS and issues SSL cert
8. Forge generates and deploys app code
9. App goes live at the customer’s domain

Data Model:

-- Apps registry
apps
  β”œβ”€ id (UUID)
  β”œβ”€ organization_id β†’ organizations.id
  β”œβ”€ name
  β”œβ”€ slug
  β”œβ”€ custom_domain (e.g., "acmegames.com")
  β”œβ”€ subdomain (e.g., "memory-game")
  β”œβ”€ full_domain (e.g., "memory-game.acmegames.com")
  β”œβ”€ dns_configured (boolean)
  β”œβ”€ ssl_certificate_issued (boolean)
  └─ created_at

-- Domain verification
domain_verifications
  β”œβ”€ id (UUID)
  β”œβ”€ app_id β†’ apps.id
  β”œβ”€ domain
  β”œβ”€ verification_token
  β”œβ”€ verified_at
  └─ created_at

Database Table Strategy: Prefixed Tables

Each app gets its own prefixed tables:

-- User A's memory game
CREATE TABLE memory_game_saves (
  id UUID PRIMARY KEY,
  user_id UUID REFERENCES app_users(id),
  level INTEGER,
  score INTEGER,
  created_at TIMESTAMPTZ
);

CREATE TABLE memory_game_leaderboards (
  id UUID PRIMARY KEY,
  user_id UUID REFERENCES app_users(id),
  score INTEGER,
  rank INTEGER,
  created_at TIMESTAMPTZ
);

-- User B's blog
CREATE TABLE myblog_posts (
  id UUID PRIMARY KEY,
  author_id UUID REFERENCES app_users(id),
  title TEXT,
  content TEXT,
  published BOOLEAN,
  created_at TIMESTAMPTZ
);

CREATE TABLE myblog_comments (
  id UUID PRIMARY KEY,
  post_id UUID REFERENCES myblog_posts(id),
  author_id UUID REFERENCES app_users(id),
  content TEXT,
  created_at TIMESTAMPTZ
);

Why Prefixed Tables?

  • βœ… Complete isolation per app
  • βœ… Easy to export/migrate apps
  • βœ… No accidental cross-app queries
  • βœ… Simpler to drop an app (just drop its tables)
  • βœ… App-specific indexing and optimization

Level 4: End Users (Public)

Purpose: Public users who interact with customer applications

Key Distinction: End users are NOT platform customers. They are users of the apps created by platform customers.

User Flow:

1. End user visits customer's domain (e.g., memory-game.acmegames.com)
2. Signs up with email or OAuth (on THAT domain)
3. Uses the app (plays game, reads blog, etc.)
4. Data stored in app-specific tables
5. Cannot access other apps or platform dashboard

Data Model:

-- End users (NOT platform users)
app_users
  β”œβ”€ id (UUID)
  β”œβ”€ email
  β”œβ”€ display_name
  β”œβ”€ avatar_url
  └─ created_at

-- App-specific data references app_users
-- (see prefixed tables above)

Isolation:

  • Each app's users stored in shared app_users table
  • App data stored in prefixed tables (e.g., memory_game_saves)
  • No cross-app data access via table separation
  • RLS policies optional (already isolated by table prefix)

πŸ” Authentication Architecture

Three Separate Auth Contexts

1. Platform Authentication (Levels 1-2)

  • Domain: landing.infiniteapps.ai, dashboard.infiniteapps.ai
  • Provider: Supabase Auth
  • Users: Platform customers (organization owners/members)
  • OAuth: Google, GitHub
  • Session: Stored in Supabase, shared across landing/dashboard

2. App User Authentication (Levels 3-4)

  • Domain: Customer domains (e.g., memory-game.acmegames.com)
  • Provider: Supabase Auth (same project, different context)
  • Users: End users (public)
  • OAuth: Configurable per app
  • Session: Scoped to app domain

3. Authentication Flow:

// Platform auth (Dashboard/Landing)
import { createServerSupabaseClient } from '@/lib/supabase/server';

async function getCurrentUser() {
  const supabase = createServerSupabaseClient();
  const { data: { user } } = await supabase.auth.getUser();
  // Returns platform user (customer)
  return user;
}

// App auth (Customer's app)
import { createClient } from '@supabase/supabase-js';

async function getAppUser() {
  const supabase = createClient(url, anonKey);
  const { data: { user } } = await supabase.auth.getUser();
  // Returns app user (end user)
  return user;
}

πŸ—„οΈ Database Architecture

Single Supabase Project Strategy

Decision: ONE Supabase project for entire platform

Rationale:

  • Cost-effective ($25/month vs $25/customer/month)
  • Simplified management
  • Shared authentication
  • Cross-platform analytics
  • Easy RLS implementation

Database Organization

Platform Supabase Project
β”œβ”€ Platform Tables
β”‚  β”œβ”€ users (platform customers)
β”‚  β”œβ”€ organizations
β”‚  β”œβ”€ organization_members
β”‚  β”œβ”€ apps (registry)
β”‚  └─ domain_verifications
β”‚
β”œβ”€ Shared Tables
β”‚  └─ app_users (all end users)
β”‚
└─ App-Specific Tables (Prefixed)
   β”œβ”€ memory_game_saves
   β”œβ”€ memory_game_leaderboards
   β”œβ”€ myblog_posts
   β”œβ”€ myblog_comments
   └─ [app_name]_[table_name]

Naming Convention

Platform tables: No prefix (users, organizations, apps)
Shared tables: No prefix (app_users)
App tables: {sanitized_app_slug}_{table_name}

Examples:
- memory_game_saves
- awesome_blog_posts
- my_store_products

Row-Level Security (RLS)

Platform Tables:

-- Users only see their org's apps
CREATE POLICY "org_isolation" ON apps
FOR SELECT USING (
  organization_id IN (
    SELECT organization_id 
    FROM organization_members 
    WHERE user_id = auth.uid()
  )
);

App Tables:

-- App users only see their own data
CREATE POLICY "user_owns_data" ON memory_game_saves
FOR ALL USING (user_id = auth.uid());

-- Anyone can view leaderboards
CREATE POLICY "public_leaderboard" ON memory_game_leaderboards
FOR SELECT USING (true);

🌐 Domain Management System

Custom Domain Architecture

Infrastructure Setup:

Customer's Domain (acmegames.com)
  └─ DNS CNAME: memory-game β†’ apps.infiniteapps.ai

Platform Load Balancer (apps.infiniteapps.ai)
  β”œβ”€ SSL Termination (Let's Encrypt/AWS ACM)
  β”œβ”€ Host Header Routing
  └─ Routes to App Deployment

App Deployment
  β”œβ”€ Vercel/Netlify (recommended)
  └─ Custom domain configured per app

Domain Setup Flow

1. User provides domain in dashboard
   ↓
2. Platform generates DNS instructions
   - Type: CNAME
   - Name: [subdomain]
   - Value: apps.infiniteapps.ai
   ↓
3. User configures DNS at registrar
   ↓
4. Platform verifies DNS propagation
   - Polls DNS every 30s
   - Timeout after 30 minutes
   ↓
5. Platform issues SSL certificate
   - Via Let's Encrypt (automatic)
   - Or AWS Certificate Manager
   ↓
6. App deployed to custom domain
   - Vercel: Add domain via API
   - AWS: Update CloudFront distribution
   ↓
7. App goes live!

Domain Verification

async function verifyDomain(appId: string, domain: string): Promise<boolean> {
  // 1. Generate verification token
  const token = crypto.randomUUID();
  await saveDomainVerification(appId, domain, token);
  
  // 2. Check DNS resolution
  const dns = require('dns').promises;
  const records = await dns.resolveCname(domain);
  
  // 3. Verify CNAME points to platform
  if (records.includes('apps.infiniteapps.ai')) {
    await markDomainVerified(appId, domain);
    return true;
  }
  
  return false;
}

SSL Certificate Management

Option A: Let's Encrypt (Self-Managed)

# Automated via certbot
certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d memory-game.acmegames.com

Option B: AWS Certificate Manager (Recommended)

import { ACM } from '@aws-sdk/client-acm';

async function requestCertificate(domain: string) {
  const acm = new ACM({ region: 'us-east-1' });
  
  const result = await acm.requestCertificate({
    DomainName: domain,
    ValidationMethod: 'DNS',
  });
  
  return result.CertificateArn;
}

Option C: Vercel/Netlify (Easiest)

// Vercel handles SSL automatically
await vercel.domains.add(projectId, domain);

πŸ”¨ Forge CLI Architecture

Purpose

Command-line tool for app generation, deployment, and management

Core Commands

# Create new app
forge create <app-name> [options]
  --type <game|blog|ecommerce|custom>
  --domain <custom-domain>
  --subdomain <subdomain>
  --supabase <platform|new|existing>
  --table-strategy <prefixed|app_id>

# Examples
forge create memory-game \
  --type game \
  --domain acmegames.com \
  --subdomain memory-game \
  --supabase platform \
  --table-strategy prefixed

# Deploy app
forge deploy [app-name]
  --environment <dev|staging|prod>
  
# Manage domains
forge domain add <domain>
forge domain verify <domain>
forge domain remove <domain>

# Database operations
forge db migrate <app-name>
forge db seed <app-name>
forge db reset <app-name>

Forge Workflow

forge create memory-game
  ↓
1. Validate inputs
   - Check app name availability
   - Validate domain format
   - Check org permissions
   ↓
2. Create app record in platform DB
   - Insert into apps table
   - Generate app_id
   ↓
3. Generate app code
   - Clone template (Next.js + Supabase)
   - Configure environment variables
   - Set up database schema (prefixed tables)
   ↓
4. Initialize database
   - Create prefixed tables
   - Apply RLS policies
   - Seed initial data
   ↓
5. Deploy app
   - Push to Git
   - Trigger Vercel deployment
   - Configure custom domain
   ↓
6. Verify deployment
   - Check app health
   - Verify SSL certificate
   - Test DNS resolution
   ↓
7. Done! πŸŽ‰

Forge Configuration

// forge.config.ts (per app)
export default {
  app: {
    name: 'memory-match-game',
    type: 'game',
    slug: 'memory-match-game',
  },
  
  domain: {
    custom: 'acmegames.com',
    subdomain: 'memory-game',
    full: 'memory-game.acmegames.com',
  },
  
  database: {
    provider: 'supabase',
    strategy: 'prefixed',
    tablePrefix: 'memory_game_',
  },
  
  deployment: {
    platform: 'vercel',
    region: 'us-east-1',
    environment: 'production',
  },
};

πŸ“¦ Technology Stack

Frontend

  • Framework: Next.js 14 (App Router)
  • Language: TypeScript
  • UI Library: React 18
  • Styling: Tailwind CSS
  • Components: Radix UI / shadcn/ui
  • State Management: React Context / Zustand

Backend

  • API: Next.js API Routes
  • Database: Supabase (PostgreSQL)
  • Authentication: Supabase Auth
  • ORM: Prisma (for Dashboard/Landing)
  • Real-time: Supabase Realtime

Infrastructure

  • Hosting: Vercel (Landing, Dashboard, Customer Apps)
  • CDN: Vercel Edge Network / CloudFront
  • DNS: Cloudflare / Route53
  • IaC: Pulumi (TypeScript)
  • Secrets: Doppler

Payments

  • Provider: Stripe
  • Products: Subscription-based pricing
  • Webhooks: Stripe webhooks for billing events

Monitoring

  • Analytics: Vercel Analytics / Mixpanel
  • Errors: Sentry
  • Logs: Vercel Logs / CloudWatch
  • Uptime: Better Uptime / Checkly

πŸš€ Deployment Architecture

Platform Apps (Landing, Dashboard)

GitHub Repository
  ↓
Vercel Integration (Auto-deploy)
  ↓
Vercel Edge Network
  β”œβ”€ landing.infiniteapps.ai
  └─ dashboard.infiniteapps.ai

Customer Apps

Forge CLI
  ↓
Generate App Code
  ↓
Push to Git (Customer repo or Platform repo)
  ↓
Vercel/Netlify Deployment
  β”œβ”€ Auto-deploy on push
  β”œβ”€ Custom domain configuration
  └─ SSL certificate issuance
  ↓
Custom Domain (e.g., memory-game.acmegames.com)

Environment Strategy

Development
β”œβ”€ Local: localhost:3000
β”œβ”€ DB: Local Supabase / Dev branch
└─ Branch: feature/*

Staging
β”œβ”€ URL: staging-*.infiniteapps.ai
β”œβ”€ DB: Staging Supabase project
└─ Branch: staging

Production
β”œβ”€ URL: infiniteapps.ai (platform)
β”‚        customer-domains.com (apps)
β”œβ”€ DB: Production Supabase project
└─ Branch: main

πŸ”„ Data Flow Examples

Example 1: Customer Signs Up

1. User visits landing.infiniteapps.ai
2. Clicks "Sign Up with Google"
3. Redirected to Supabase Auth (Google OAuth)
4. User authorizes
5. Redirected back with auth code
6. Supabase creates user record
7. Landing creates organization record
8. Redirected to dashboard.infiniteapps.ai
9. User sees empty dashboard (no apps yet)

Example 2: Customer Creates App

1. User in dashboard clicks "Create App"
2. Fills form:
   - Name: Memory Match Game
   - Type: Web Game
   - Domain: acmegames.com
   - Subdomain: memory-game
3. Submits form
4. Dashboard calls API: POST /api/apps
5. API validates inputs
6. API creates app record in Supabase
7. API triggers Forge CLI (via job queue)
8. Forge generates app code
9. Forge creates prefixed DB tables
10. Forge deploys to Vercel
11. Forge configures custom domain
12. Forge waits for DNS verification
13. Domain verified β†’ SSL issued
14. App goes live!
15. User sees "App Created" confirmation

Example 3: End User Plays Game

1. End user visits memory-game.acmegames.com
2. App loads from Vercel CDN
3. User sees "Sign Up" button
4. User signs up with email
5. Supabase Auth creates app_user record
6. User redirected to game
7. User plays and scores 100 points
8. App saves to memory_game_saves table
9. App updates memory_game_leaderboards table
10. User sees updated leaderboard

πŸ”’ Security Considerations

Authentication Security

  • OAuth 2.0 with Google/GitHub
  • Secure cookie-based sessions
  • CSRF protection via Supabase
  • HTTP-only cookies
  • SameSite=Lax policy

Database Security

  • Row-Level Security (RLS) enabled
  • Prepared statements (Prisma)
  • Connection pooling
  • Encrypted at rest (Supabase)
  • Encrypted in transit (TLS)

API Security

  • Rate limiting (Vercel)
  • CORS configuration
  • Input validation (Zod)
  • Environment variable encryption (Doppler)
  • API key authentication (for Forge CLI)

Domain Security

  • DNS verification required
  • SSL/TLS enforced
  • HSTS headers
  • Content Security Policy
  • XSS protection headers

πŸ“ˆ Scalability Considerations

Current Limits (Free/Pro Tier)

  • Supabase: 500MB DB / 8GB Pro
  • Vercel: 100GB bandwidth / Unlimited Pro
  • Users: No hard limit (RLS scales)
  • Apps: No hard limit (prefixed tables scale)

Scaling Strategy

Phase 1: Single Supabase Project (Current)

  • Handles: 100-1000 customers
  • Cost: $25-100/month
  • Bottleneck: Database size

Phase 2: Read Replicas

  • Handles: 1000-10,000 customers
  • Cost: $100-500/month
  • Bottleneck: Write throughput

Phase 3: Database Sharding

  • Handles: 10,000+ customers
  • Cost: $500-2000/month
  • Shard by: organization_id or app_id

Phase 4: Multi-Region

  • Handles: Global scale
  • Cost: Variable
  • Regions: US, EU, Asia

🎯 Key Design Decisions

Decision 1: Single Supabase Project

Why: Cost-effective for MVP, easier management
Trade-off: Shared resources, need RLS
Alternative: Supabase project per customer (expensive)

Decision 2: Prefixed Tables for Apps

Why: Complete isolation, easy to export apps
Trade-off: Schema "explosion" with many apps
Alternative: Shared tables with app_id column

Decision 3: Custom Domains Only

Why: Professional, allows white-labeling
Trade-off: Complex DNS/SSL management
Alternative: Subdomains on platform (simpler but less flexible)

Decision 4: Vercel Deployment

Why: Automatic SSL, global CDN, easy integration
Trade-off: Vendor lock-in
Alternative: AWS (more control, more complexity)

Decision 5: Multi-Tenant Dashboard

Why: Standard SaaS pattern, cost-effective
Trade-off: Limited white-labeling
Alternative: Dashboard instance per customer (expensive)


πŸ› οΈ Development Workflow

Local Development

# Clone repository
git clone https://github.com/yourusername/app-factory
cd app-factory

# Install dependencies
pnpm install

# Setup environment variables
cp .env.example .env.local
# Edit .env.local with your Supabase credentials

# Run landing page
cd apps/landing
pnpm dev
# Visit http://localhost:3000

# Run dashboard (in new terminal)
cd apps/dashboard
pnpm dev
# Visit http://localhost:3001

# Run Supabase locally (optional)
npx supabase start

Adding a New App Type

// 1. Add to Forge templates
// packages/forge/templates/[app-type]/

// 2. Update Forge CLI
// packages/forge/src/commands/create.ts

// 3. Add to Dashboard UI
// apps/dashboard/src/components/AppTypeSelector.tsx

// 4. Define database schema
// apps/dashboard/prisma/migrations/[timestamp]_add_[app_type].sql

// 5. Test end-to-end
forge create test-app --type [app-type]

🚨 Common Pitfalls & Solutions

Pitfall 1: DNS Propagation Delays

Problem: Custom domains take 5-30 minutes to propagate
Solution: Implement polling with progress indicator, timeout after 30min

Pitfall 2: Supabase RLS Policy Conflicts

Problem: Overlapping policies can cause unexpected access denials
Solution: Test policies thoroughly, use explicit naming conventions

Pitfall 3: Prefixed Table Name Conflicts

Problem: Two apps with similar names create conflicting table names
Solution: Sanitize app names, append UUID if needed

Pitfall 4: Cross-Origin Auth Issues

Problem: Auth sessions don't work across different domains
Solution: Use Supabase's cookie-based auth, proper CORS configuration

Pitfall 5: Large Database Schema

Problem: 100+ apps = 500+ tables (slow schema operations)
Solution: Consider table partitioning or migration to app_id strategy


πŸ“š Additional Resources

Internal Documentation

  • /docs/API.md - API reference
  • /docs/FORGE_CLI.md - Forge CLI guide
  • /docs/DEPLOYMENT.md - Deployment guide
  • /docs/SUPABASE_SETUP.md - Supabase configuration

External Resources


πŸŽ“ For AI Agents

Quick Context Summary

What is this platform?
Multi-tenant SaaS for rapid app creation and deployment with custom domains.

Who are the users?

  • Level 1-2: Platform customers (organizations) using the dashboard
  • Level 3-4: End users visiting customer-created apps

How does data flow?
Platform Supabase (shared) β†’ Organizations (isolated via RLS) β†’ Apps (isolated via prefixed tables) β†’ App Users (isolated via app tables)

What's unique?

  • Customers deploy apps to THEIR domains, not platform domain
  • Single Supabase project with prefixed tables per app
  • Complete isolation via table naming, not just RLS

Key files to understand:

  • docs/ARCHITECTURE.md (this file)
  • apps/landing/ - Landing page
  • apps/dashboard/ - Multi-tenant dashboard
  • ops/apps.yaml - Platform configuration
  • infra/pulumi-supabase/ - Supabase infrastructure

End of Architecture Documentation

This is a living document. Update as architecture evolves.