Skip to main content

Backend

TechnologyPurpose
Python 3.13Primary language
FastAPIWeb framework and API routing
SQLAlchemyORM and database models
PostgreSQLPrimary database
pgvectorSemantic embeddings and similarity search
SendGridTransactional email delivery
OpenAIText embeddings (text-embedding-3-small)
S3 / Cloudflare R2Media file storage
PillowImage optimization and processing
FFmpegGIF-to-video conversion

Frontend

TechnologyPurpose
Vanilla JavaScriptNo framework — lightweight, fast loading
Jinja2Server-side HTML templating
CSS Custom PropertiesTheming and dark mode
ES6 ModulesComponent architecture for editors

Infrastructure

TechnologyPurpose
RailwayHosting and deployment
DockerContainerization
MintlifyDocumentation site

Architecture Overview

Sports Index follows a layered architecture:
Frontend (Vanilla JS + Jinja2 Templates)
    ↓ HTTP/JSON
Routes / API Layer (FastAPI, ~120 endpoints)
    ↓ Function calls
Service Layer (8 services + 7 post type handlers)
    ↓ Function calls
Data Access Layer (28 repository singletons)
    ↓ ORM/SQL
PostgreSQL + pgvector

Key Patterns

  • Post Type Handlers: Abstract base class pattern for 7 content types (external_media, chart, data_table, uploaded_media, timeline, page, collection)
  • Canonical Deduplication: External URLs stored once globally, users link via relationships
  • Dual Tagging: Owned posts use content_post_tags, canonical posts use topic_post_index
  • Denormalized Caches: TopicPostIndex, TopicTimelineCache, UserLibraryCache for fast reads
  • Feature-Flagged Embeddings: Semantic search gated behind EMBEDDING_ENABLED