Skip to content

Latest commit

 

History

History
234 lines (176 loc) · 8.03 KB

File metadata and controls

234 lines (176 loc) · 8.03 KB

Setup Guide

Prerequisites

  • Docker ≥ 24 and Docker Compose v2
  • GNU Make
  • A .env file placed in backend/ (see variable reference below)

First-Time Setup

# Clone the repository
git clone <repo-url> studymation && cd studymation

# Copy the env template and fill in values
cp backend/.env.example backend/.env
# Edit backend/.env — see variable reference below

# Build images
make build

# Start all services in background
make up-detached

# Apply all database migrations
make migrate

# (Optional) Create an admin user
make create-admin email=you@example.com

The API is now available at http://localhost:8000.


Development Workflow

make dev              # Backend (Docker) + frontend (local) simultaneously
make logs-api         # Tail API logs
make shell            # Open bash inside the API container
make down             # Stop all services
make db-reset         # Drop + recreate dev DB (destructive — dev only)

Creating Migrations

# Auto-generate a migration from model changes
make migrate-create msg="add_column_foo_to_users"

# Apply pending migrations
make migrate

Environment Variables Reference

All variables are read by app/config.py via pydantic-settings. Never read os.environ directly — always import settings from app/config.py.

Application

Variable Default Description
APP_NAME Studymation Application name
APP_URL Public URL of the app (HTTPS in prod)
APP_ENV development development / staging / production
DEBUG false Enable debug mode (must be false in prod)
ALLOWED_ORIGINS Comma-separated CORS origins

Database

Variable Default Description
DATABASE_URL Async PostgreSQL: postgresql+asyncpg://user:pass@host:5432/db
DATABASE_URL_TEST Test DB URL (same format)

LLM — Legacy (per-plan)

Variable Default Description
LLM_PROVIDER Default provider: openai / deepseek / anthropic
LLM_MODEL_FREE Model for free plan
LLM_MODEL_PRO Model for pro plan
LLM_MODEL_MAX Model for max plan
OPENAI_API_KEY OpenAI API key
ANTHROPIC_API_KEY Anthropic API key (Claude models)
DEEPSEEK_API_KEY DeepSeek API key

LLM — Granular (per-plan × per-task, override legacy)

Pattern: LLM_{PLAN}_{TASK}_PROVIDER and LLM_{PLAN}_{TASK}_MODEL

Where {PLAN} = FREE / PRO / MAX and {TASK} = CONVERSATION_EXTRACTION / STRUCTURE_GENERATION / JSON_REPAIR / CONTENT_GENERATION.

Example:

LLM_FREE_CONTENT_GENERATION_PROVIDER=deepseek
LLM_FREE_CONTENT_GENERATION_MODEL=deepseek-chat
LLM_PRO_CONTENT_GENERATION_PROVIDER=openai
LLM_PRO_CONTENT_GENERATION_MODEL=gpt-4o-mini

Auth

Variable Default Description
JWT_SECRET_KEY Random 32+ char string. Must not be the default in prod.
JWT_EXPIRE_DAYS 7 Token lifetime in days
GOOGLE_CLIENT_ID Google OAuth client ID
GOOGLE_CLIENT_SECRET Google OAuth client secret
GOOGLE_REDIRECT_URI OAuth callback URL
FRONTEND_URL Used for CSRF redirect and cookie domain
AUTH_COOKIE_NAME studymation_token Cookie name for JWT
AUTH_COOKIE_SAMESITE lax Cookie SameSite policy
AUTH_COOKIE_DOMAIN Cookie domain (set in prod)

Storage (DigitalOcean Spaces / S3-compatible)

Variable Default Description
STORAGE_ENDPOINT S3-compatible endpoint URL
STORAGE_ACCESS_KEY Spaces access key
STORAGE_SECRET_KEY Spaces secret key
STORAGE_BUCKET Bucket name
STORAGE_REGION Region identifier
FREE_DOCUMENT_TTL_HOURS 72 Hours before free-plan docs expire

Payments

Variable Default Description
STRIPE_SECRET_KEY Stripe secret key (sk_live_... in prod)
STRIPE_WEBHOOK_SECRET Webhook signing secret (whsec_...)
USD_TO_MXN 17.44 Exchange rate for MXN pricing
USD_TO_MXN_LAST_UPDATED ISO date of last FX update. Staleness alert if >7 days old.
PROFIT_MARGIN_PCT 300 Markup percentage on LLM costs
MAX_NEGATIVE_BALANCE -20.0 Minimum allowed credit balance

Rate Limiting

Variable Default Description
RATE_LIMIT_BACKEND memory redis in production, memory in development
REDIS_URL Redis connection URL (redis://host:6379/0)

Citations

Variable Default Description
SEMANTIC_SCHOLAR_API_KEY Semantic Scholar API key
BRAVE_API_KEY Brave Search API key
CITATION_MIN_SCORE 0.50 Minimum relevance score for citation inclusion
CITATION_MIN_RELEVANCE 0.16 Minimum Jaccard similarity threshold
CITATION_MAX_CANDIDATES_PER_SECTION 12 Max candidates to evaluate per section
CITATION_CACHE_TTL_DAYS 30 Days before citation cache entries expire
CITATION_MIN_COUNT 2 Minimum citations required for a document

Images

Variable Default Description
OPENVERSE_ENABLED false Enable Openverse image search
PEXELS_API_KEY Pexels API key (optional)
PIXABAY_API_KEY Pixabay API key (optional)
UNSPLASH_API_KEY Unsplash API key (optional)
IMAGE_SEARCH_TIMEOUT_SECONDS Per-provider timeout
IMAGE_REQUIRED_MIN_COUNT Minimum images required per document

Timeouts

Variable Default Description
GENERATION_GLOBAL_TIMEOUT_SECONDS 420 Max end-to-end generation time (7 min)
LLM_TIMEOUT_SECONDS 60 Per LLM call timeout
CITATION_PROVIDER_TIMEOUT_SECONDS 10 Per citation provider timeout

File Upload

Variable Default Description
UPLOAD_MAX_FILE_SIZE_MB 10 Max size per uploaded file
UPLOAD_MAX_TOTAL_SIZE_MB 15 Max combined upload size per turn
UPLOAD_MAX_FILES_PER_TURN 5 Max files per conversation turn
UPLOAD_PARSE_TIMEOUT_SECONDS 20 Timeout for file parsing
UPLOAD_MAX_EXTRACTED_CHARS 80000 Max characters extracted from uploads
UPLOAD_PDF_MAX_PAGES 40 Max pages extracted from PDF
UPLOAD_DOCX_MAX_UNCOMPRESSED_MB 40 Zip-bomb guard for DOCX
UPLOAD_MAX_GENERATION_CHARS 20000 Max chars forwarded to generation pipeline

Quality Gate

Variable Default Description
QUALITY_GATE_ENABLED true Enable post-render quality checks
QUALITY_GATE_BLOCK_ON_P0 true Block generation on P0-severity failures
MERMAID_OMIT_ON_FAILURE true Omit diagram (don't insert raw code) on render failure
IMAGE_ENTITY_ANCHOR_REQUIRED true Image caption must mention topic entities

Production Safety Checks

config.py validates these conditions at startup when APP_ENV=production:

  • DEBUG must be false
  • JWT_SECRET_KEY must not be the default value
  • ALLOWED_ORIGINS must use https://
  • RATE_LIMIT_BACKEND must be redis
  • STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET must be set
  • GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET must be set
  • FRONTEND_URL and APP_URL must use https://

The app will refuse to start if any of these fail.


Testing Setup

Tests run inside the Docker container:

make test                           # All tests except slow
make test-unit                      # Unit tests only
make test-integration               # Integration (requires running DB)
make test-file f=tests/unit/test_auth.py  # Single file
make test-coverage                  # With HTML report
make test-slow                      # External API tests (Semantic Scholar, etc.)

conftest.py creates a studymation_test database at session start. Each test gets a transaction that auto-rolls back — no manual cleanup needed. Call get_settings.cache_clear() in tests before overriding env vars.