SCORM API Architecture Overview

SCORM API Architecture Overview

Introduction

The AllureLMS SCORM API is a standalone, API-first service that provides SCORM 1.2 and SCORM 2004 package hosting, session management, and learning analytics. Built with Next.js 14 and Supabase, it serves as a backend service for any client system (TrainingOS, AllureLMS, or external applications) that needs SCORM functionality.

High-Level Architecture

System Components

┌─────────────────────────────────────────────────────────────┐
│                    Client Applications                       │
│  (TrainingOS, AllureLMS, Custom LMS, WordPress, etc.)        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     │ HTTPS / REST API
                     │
┌────────────────────▼────────────────────────────────────────┐
│              SCORM API Service (Next.js 14)                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │   API Layer  │  │  Auth Layer  │  │  Player UI   │      │
│  │  (REST API)  │  │ (API Keys +  │  │  (Browser)   │      │
│  │              │  │    Clerk)    │  │              │      │
│  └──────────────┘  └──────────────┘  └──────────────┘      │
│                                                               │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐      │
│  │   Business   │  │   Storage    │  │   Webhooks   │      │
│  │    Logic     │  │   Manager    │  │   Service    │      │
│  └──────────────┘  └──────────────┘  └──────────────┘      │
└────────────┬───────────────┬───────────────┬───────────────┘
             │               │               │
    ┌────────▼──────┐  ┌──────▼──────┐  ┌──────▼──────┐
    │   Supabase    │  │ Cloudflare  │  │   Upstash   │
    │  PostgreSQL   │  │     R2      │  │    Redis    │
    │   (Database)  │  │  (Storage)  │  │ (Rate Limit)│
    └───────────────┘  └─────────────┘  └───────────────┘

Core Architecture Principles

  1. API-First Design: All functionality exposed via RESTful API endpoints
  2. Multi-Tenancy: Complete data isolation per tenant using Row Level Security (RLS)
  3. Stateless Services: Serverless functions for horizontal scalability
  4. Separation of Concerns: Clear boundaries between API, business logic, and storage
  5. Security by Default: Authentication required, tenant isolation enforced, rate limiting enabled

Technology Stack

Runtime & Framework

  • Next.js 14 (App Router): Serverless API routes and React UI
  • TypeScript 5.x: Type-safe development
  • Node.js 18+: Runtime environment

Backend Services

  • Supabase PostgreSQL: Primary database with Row Level Security
  • Supabase Storage: Default file storage (SCORM packages)
  • Cloudflare R2: Optional S3-compatible storage (production recommended)
  • Upstash Redis: Distributed rate limiting (optional)

Authentication & Authorization

  • API Keys: Tenant-scoped keys with SHA-256 hashing
  • Clerk: Web application authentication for admin dashboard
  • JWT Tokens: Launch tokens and dispatch tokens for secure package access

Validation & Utilities

  • Zod: Schema validation for API requests
  • date-fns: Date manipulation utilities

Multi-Tenancy Architecture

Tenant Isolation Strategy

The SCORM API implements database-level multi-tenancy using PostgreSQL Row Level Security (RLS):

  1. Tenant ID in Every Table: All data tables include tenant_id column
  2. RLS Policies: Database policies automatically filter queries by tenant
  3. API Key Scoping: API keys are bound to a specific tenant
  4. Automatic Filtering: All queries automatically include tenant context

Tenant Data Model

interface Tenant {
  id: string; // UUID
  name: string;
  created_at: string;
  // Quota limits
  max_packages?: number;
  max_storage_bytes?: number;
}

Data Isolation Flow

API Request
    ↓
Extract tenant_id from API Key or Clerk session
    ↓
Query Database with tenant_id filter
    ↓
RLS Policy enforces tenant isolation
    ↓
Return only tenant's data

API Architecture

API Route Organization

The API is organized into logical route groups:

  • /api/v1/*: Public API endpoints (API key authenticated)

    • /api/v1/packages: Package management
    • /api/v1/sessions: Session and CMI data
    • /api/v1/webhooks: Webhook management
    • /api/v1/dispatches: Dispatch package distribution
    • /api/v1/xapi: xAPI telemetry endpoints
  • /api/customer/*: Customer-facing endpoints (Clerk authenticated)

    • Dashboard functionality
    • Self-service API key management
    • Usage reports
    • Billing portal
  • /api/admin/*: System admin endpoints (Clerk + system admin role)

    • System health monitoring
    • Tenant management
    • SaaS metrics
    • Churn detection
  • /api/learner/*: Learner-facing endpoints

    • Progress tracking
    • Certificates

Request Flow

1. Client Request
   ↓
2. Authentication Middleware
   - Validate API Key or Clerk session
   - Extract tenant_id
   ↓
3. Authorization Check
   - Verify scopes (read/write/admin)
   - Check tenant access
   ↓
4. Business Logic
   - Validate input (Zod schemas)
   - Execute business rules
   - Apply tenant isolation
   ↓
5. Database Operation
   - RLS automatically filters by tenant_id
   ↓
6. Response
   - Format JSON response
   - Include rate limit headers

Storage Architecture

Storage Backends

The SCORM API supports two storage backends:

  1. Supabase Storage (Default)

    • Integrated with database
    • Automatic RLS enforcement
    • CDN support
  2. Cloudflare R2 (Recommended for Production)

    • S3-compatible API
    • Lower egress costs
    • Global CDN
    • Automatic failover if configured

Storage Structure

scorm-packages/
├── {tenant_id}/
│   ├── scorm-extracted/
│   │   └── {package_id}/
│   │       ├── imsmanifest.xml
│   │       ├── index.html
│   │       └── assets/
│   └── uploads/
│       └── {temp_upload_id}.zip

Upload Flow

  1. Direct Upload (Small files < 100MB)

    • Client → API → Storage
    • Immediate processing
  2. Multipart Upload (Large files 10GB+)

    • Initialize upload → Get presigned URLs
    • Upload parts directly to storage
    • Complete upload → Process package
  3. Presigned URL Upload (Medium files)

    • Request presigned URL
    • Upload directly to storage
    • Notify API for processing

Security Architecture

Authentication Methods

  1. API Key Authentication

    • SHA-256 hashed in database
    • Tenant-scoped
    • Scope-based permissions (read/write/admin)
    • Expiration support
  2. Clerk Authentication

    • Web application users
    • Session-based
    • Tenant resolution via user_tenants table
  3. Launch Tokens

    • JWT tokens for secure package launches
    • Short-lived (default 600 seconds)
    • Signed with secret key
  4. Dispatch Tokens

    • JWT tokens for dispatch package distribution
    • Configurable expiration
    • Domain allowlisting support

Security Features

  • Row Level Security (RLS): Database-level tenant isolation
  • Rate Limiting: Per-tenant rate limits (local or distributed via Redis)
  • Input Validation: Zod schemas for all API inputs
  • HMAC Signatures: Webhook payload verification
  • HTTPS Only: All connections encrypted
  • CORS Protection: Configurable allowed origins

Scalability Architecture

Horizontal Scaling

  • Stateless API: All API routes are stateless serverless functions
  • Database Connection Pooling: Supabase handles connection pooling
  • CDN Caching: Static assets cached at edge
  • Distributed Rate Limiting: Optional Redis-based rate limiting

Performance Optimizations

  • Database Indexes: Optimized indexes on tenant_id, package_id, session_id
  • Query Optimization: Efficient queries with proper joins
  • Caching Strategy: Response caching for read-heavy endpoints
  • Lazy Loading: On-demand package processing

Resource Limits

  • Tenant Quotas: Per-tenant package and storage limits
  • Rate Limits: Per-tenant API rate limits
  • Upload Limits: Configurable max upload size (default 10GB)

Integration Patterns

Client Integration

  1. API Key Integration (Server-to-Server)

    const response = await fetch('https://api.scorm.com/v1/packages', {
      headers: {
        'X-API-Key': 'your-api-key',
        'Content-Type': 'application/json'
      }
    });
    
  2. Clerk Integration (Web Application)

    • User authenticates via Clerk
    • API automatically resolves tenant
    • No API key needed for web UI
  3. Launch Integration (SCORM Player)

    • Request launch URL with user/session context
    • Receive signed launch token
    • Embed player in iframe

Webhook Integration

  • Event-Driven: Webhooks for package processing, session completion
  • Retry Logic: Exponential backoff with jitter
  • HMAC Verification: Secure webhook payload verification
  • Delivery Tracking: Persistent delivery status tracking

Deployment Architecture

Vercel Deployment (Recommended)

  • Serverless Functions: Automatic scaling
  • Edge Network: Global CDN
  • Environment Variables: Secure secret management
  • Preview Deployments: Per-branch preview URLs

Docker Deployment (Alternative)

  • Multi-stage Build: Optimized production image
  • Health Checks: Container health monitoring
  • Volume Mounts: Optional local storage

Monitoring & Observability

Health Monitoring

  • Health Endpoint: /api/health for system status
  • Database Health: Connection and query performance
  • Storage Health: R2 and Supabase storage accessibility
  • Rate Limiting Status: Distributed vs local rate limiting

Metrics & Analytics

  • SaaS Metrics: MRR, ARR, churn rate, subscription metrics
  • Usage Analytics: Package uploads, storage usage, session activity
  • Tenant Activity: Active tenants, churn indicators
  • API Key Usage: Usage statistics per API key

Admin Dashboard

  • System Health: Real-time system status
  • Tenant Management: Tenant overview with churn detection
  • API Key Management: Create, revoke, monitor API keys
  • Usage Reports: Custom reports and exports

Data Flow Examples

Package Upload Flow

1. Client → POST /api/v1/packages
2. API validates request (Zod schema)
3. API extracts tenant_id from API key
4. API uploads file to storage (Supabase/R2)
5. API processes package (extract, parse manifest)
6. API creates package record in database
7. API triggers webhook (if configured)
8. API returns package metadata

Session Launch Flow

1. Client → POST /api/v1/packages/{id}/launch
2. API validates package access (tenant check)
3. API creates/retrieves session record
4. API generates signed launch token
5. API returns launch URL with token
6. Client embeds player in iframe
7. Player loads SCORM content
8. Player communicates via SCORM API Bridge
9. API updates session CMI data

CMI Data Update Flow

1. SCORM Player → API Bridge → PUT /api/v1/sessions/{id}
2. API validates session ownership (tenant check)
3. API implements optimistic locking (version check)
4. API merges CMI data updates
5. API updates session record
6. API logs event for audit trail
7. API converts to xAPI statement (if enabled)
8. API triggers webhook (if configured)
9. API returns updated session

Error Handling

Error Response Format

{
  "error": {
    "code": "PACKAGE_NOT_FOUND",
    "message": "Package with ID xyz not found",
    "details": {
      "package_id": "xyz",
      "tenant_id": "abc"
    }
  }
}

Error Categories

  • 4xx Client Errors: Invalid requests, authentication failures
  • 5xx Server Errors: Internal errors, database failures
  • Rate Limit Errors: 429 Too Many Requests
  • Validation Errors: 422 Unprocessable Entity

Future Architecture Considerations

Planned Enhancements

  • GraphQL API: Alternative query interface
  • WebSocket Support: Real-time session updates
  • Advanced Analytics: Machine learning insights
  • Multi-Region Deployment: Geographic distribution
  • Event Sourcing: Complete audit trail

Last Updated: 2025-01-12
Version: 1.0

For detailed system design, see System Design Documentation.