Architecture
Data Flow

Data Flow & Integration

Understanding how data flows through the AltSportsLeagues.ai ecosystem, from user interactions to database storage and back.

πŸ”„ Complete Data Flow


πŸ“– Flow Example 1: User Browsing Leagues

Step-by-Step Flow

User Visits Page

User navigates to https://altsportsleagues.ai/leagues

Action: Browser sends HTTPS request to Cloudflare
Next: Cloudflare routes to Vercel

Page Renders (SSR/SSG)

Vercel serves the Next.js page (server-side rendered or static)

Action: Next.js App Router renders page
Data Needed: League list from API
Next: Component makes API call

Frontend Calls API

Browser executes: fetch('/api/v1/leagues')

URL Seen by Browser: altsportsleagues.ai/api/v1/leagues
Vercel Rewrite: api.altsportsleagues.ai/v1/leagues
Note: Rewrite is invisible to browser!

Backend Processes Request

Cloud Run receives request at /v1/leagues endpoint

Router: FastAPI router handles /v1/leagues
Validation: Pydantic models validate request
Next: Query databases

Database Queries

Backend queries Neo4j and Supabase in parallel

Neo4j Query: Get league graph relationships
Supabase Query: Get league metadata
Merge: Combine results

Response Returns

JSON response flows back through the chain

Backend: Serializes to JSON
Cloudflare: Proxies response
Vercel: Forwards to browser
Browser: Receives data (same origin, no CORS!)

Frontend Renders

React component updates with league data

React Query: Caches response
Zustand: Updates global state
UI: Displays league list

Total Time: ~300-500ms (end-to-end)


πŸ“‘ Flow Example 2: External API Consumer

API Request Example

curl https://api.altsportsleagues.ai/v1/leagues \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"

Response:

{
  "leagues": [
    {
      "id": "league_123",
      "name": "Sample League",
      "tier": 1,
      "sport": "basketball"
    }
  ],
  "total": 1,
  "page": 1
}

πŸ€– Flow Example 3: n8n Automation

Webhook Configuration

n8n Webhook URL:

https://n8n.altsportsleagues.ai/webhook/league-intake

Trigger Example:

{
  "event": "new_questionnaire",
  "email_id": "msg_abc123",
  "attachment_count": 1
}

πŸ“Š Data Layer Integration

Cross-Service Data Sharing

How It Works

Backend (Python):

from data_layer.schemas.league import LeagueSchema
from data_layer.shared.python import validators
 
league = LeagueSchema(**data)
validated = validators.validate_league(league)

Frontend (TypeScript):

import type { League } from '@/types/league';
import { validateLeague } from '@/lib/validators';
 
const league: League = await response.json();
const validated = validateLeague(league);

Docs Site (Schema Injection):

<!-- In MDX file -->
{{schema:schemas/league/tier_classification.py}}
 
<!-- Renders as formatted schema documentation -->

πŸ”„ Real-Time Data Flow

WebSocket Integration (Future)

Firebase Real-Time Pattern

Frontend subscribes to updates:

import { onSnapshot } from 'firebase/firestore';
 
// Subscribe to league updates
const unsubscribe = onSnapshot(
  leagueRef,
  (snapshot) => {
    const updatedLeague = snapshot.data();
    updateUI(updatedLeague);
  }
);

Backend publishes updates:

from firebase_admin import firestore
 
# Update league and trigger real-time sync
league_ref.update({
    'status': 'active',
    'updated_at': firestore.SERVER_TIMESTAMP
})

πŸ“¦ Batch Processing Flow

Large Dataset Processing

Use Cases:

  • Daily league data updates
  • Weekly statistics aggregation
  • Monthly report generation
  • Bulk league onboarding

🎯 Request Routing Logic

Intelligent Routing

Path Routing in Backend

FastAPI router configuration:

from fastapi import FastAPI, APIRouter
 
app = FastAPI()
 
# Version 1 API Router
v1_router = APIRouter(prefix="/v1")
 
# Include domain routers
v1_router.include_router(leagues_router)
v1_router.include_router(teams_router)
v1_router.include_router(players_router)
 
# Mount v1 router
app.include_router(v1_router)
 
# Health check (no version prefix)
@app.get("/health")
async def health_check():
    return {"status": "healthy"}
 
# Result:
# /v1/leagues  ← API endpoints
# /v1/teams
# /health      ← Utility endpoints
# /docs        ← Documentation

πŸ’Ύ Database Access Patterns

Neo4j (Graph Queries)

Use Case: Complex relationship traversals

Example Query:

// Find all players who played for multiple teams in a league
MATCH (l:League {id: $leagueId})-[:HAS_TEAM]->(t:Team)
MATCH (t)-[:HAS_PLAYER]->(p:Player)
WITH p, count(DISTINCT t) as team_count
WHERE team_count > 1
RETURN p.name, team_count
ORDER BY team_count DESC

Backend Code:

from data_layer.shared.python.neo4j_utils import run_query
 
async def get_multi_team_players(league_id: str):
    query = """
    MATCH (l:League {id: $leagueId})-[:HAS_TEAM]->(t:Team)
    MATCH (t)-[:HAS_PLAYER]->(p:Player)
    WITH p, count(DISTINCT t) as team_count
    WHERE team_count > 1
    RETURN p.name, team_count
    ORDER BY team_count DESC
    """
    
    results = await run_query(query, {"leagueId": league_id})
    return results

Supabase (Relational Queries)

Use Case: Structured data retrieval

from data_layer.shared.python.supabase_client import get_client
 
async def get_league_schedules(league_id: str):
    supabase = get_client()
    
    response = await supabase.table('schedules') \
        .select('*') \
        .eq('league_id', league_id) \
        .order('game_date', desc=False) \
        .execute()
    
    return response.data

Firebase (Auth & Real-Time)

Use Case: User authentication and live updates

// Frontend: Subscribe to real-time updates
import { onAuthStateChanged } from 'firebase/auth';
import { onSnapshot } from 'firebase/firestore';
 
// Auth listener
onAuthStateChanged(auth, (user) => {
  if (user) {
    // User signed in
    subscribeToLeagues(user.uid);
  }
});
 
// Real-time data listener
const unsubscribe = onSnapshot(
  collection(db, 'leagues'),
  (snapshot) => {
    const leagues = snapshot.docs.map(doc => doc.data());
    updateUI(leagues);
  }
);

πŸ”„ Data Synchronization

Cross-Database Consistency

Implementation:

from contextlib import asynccontextmanager
 
@asynccontextmanager
async def transaction_handler():
    """Ensure consistency across databases"""
    neo4j_tx = await neo4j.begin_transaction()
    supabase_tx = await supabase.begin()
    
    try:
        yield (neo4j_tx, supabase_tx)
        
        # Commit all or none
        await neo4j_tx.commit()
        await supabase_tx.commit()
        
        # Trigger Firebase real-time update
        await firebase.notify_update()
        
    except Exception as e:
        await neo4j_tx.rollback()
        await supabase_tx.rollback()
        raise e

🎨 Frontend State Management

Zustand + React Query Pattern

Code Example:

// Zustand store
import { create } from 'zustand';
 
export const useLeagueStore = create((set) => ({
  selectedLeague: null,
  setLeague: (league) => set({ selectedLeague: league })
}));
 
// React Query hook
import { useQuery } from '@tanstack/react-query';
 
export function useLeagues() {
  return useQuery({
    queryKey: ['leagues'],
    queryFn: () => fetch('/api/v1/leagues').then(r => r.json()),
    staleTime: 5 * 60 * 1000, // 5 minutes
  });
}
 
// Component usage
function LeaguesList() {
  const { data: leagues } = useLeagues();
  const { setLeague } = useLeagueStore();
  
  return (
    <div>
      {leagues?.map(league => (
        <div key={league.id} onClick={() => setLeague(league)}>
          {league.name}
        </div>
      ))}
    </div>
  );
}

πŸ“ˆ Performance Optimization

Data Flow Optimizations:

  • Parallel database queries (Neo4j + Supabase)
  • React Query caching (reduce API calls)
  • Vercel edge caching (static content)
  • Redis caching (backend, optional)
  • Firebase local persistence

Caching Strategy


Platform

Documentation

Community

Support

partnership@altsportsdata.comdev@altsportsleagues.ai

2025 Β© AltSportsLeagues.ai. Powered by AI-driven sports business intelligence.

πŸ€– AI-Enhancedβ€’πŸ“Š Data-Drivenβ€’βš‘ Real-Time