DocDoeAI / .env.example
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
6515ef9
Raw
History Blame Contribute Delete
7.27 kB
APP_NAME="AI Exam Success API"
ENVIRONMENT="development"
# PostgreSQL target for production/local DB work.
# If DATABASE_URL is not set, the app falls back to a local SQLite file so the
# mock backend can run immediately during early development.
DATABASE_URL="postgresql+psycopg://postgres:postgres@localhost:5432/exam_success"
# Production recovery controls. Development does not require these.
DATABASE_BACKUP_STRATEGY=""
DATABASE_BACKUP_RETENTION_DAYS="14"
DATABASE_RESTORE_TESTED_AT=""
DATABASE_BACKUP_DIR=""
CORS_ORIGINS="http://localhost:3000,http://127.0.0.1:3000,http://localhost:3003,http://127.0.0.1:3003"
UPLOAD_DIR="uploads"
# AI provider settings.
# Use AI_PROVIDER="mock" for local free development without an API key.
# Use AI_PROVIDER="sarvam" with SARVAM_API_KEY for real AI outputs (recommended).
# Use AI_PROVIDER="openrouter" with OPENROUTER_API_KEY for OpenRouter models.
AI_PROVIDER="sarvam"
SARVAM_API_KEY=""
SARVAM_BASE_URL="https://api.sarvam.ai/v1"
SARVAM_MODEL_MAIN="sarvam-30b"
SARVAM_MODEL_HEAVY="sarvam-105b"
SARVAM_MODEL_NOTES="sarvam-30b"
SARVAM_MODEL_QUIZ="sarvam-30b"
SARVAM_MODEL_FLASHCARDS="sarvam-30b"
SARVAM_MODEL_EXAM_MODE="sarvam-105b"
SARVAM_MODEL_PYQ_ANALYSIS="sarvam-105b"
SARVAM_MODEL_VIDEO_SCRIPT="sarvam-105b"
SARVAM_TIMEOUT_SECONDS="90"
SARVAM_MAX_RETRIES="2"
AI_FALLBACK_TO_MOCK="true"
MOCK_AI_MODEL_NAME="mock-exam-tutor-v1"
# Exa is used only when the student explicitly asks to search the web or asks
# for current/latest information. Keep this backend-only; never use NEXT_PUBLIC_.
EXA_API_KEY=""
EXA_BASE_URL="https://api.exa.ai"
EXA_SEARCH_TIMEOUT_SECONDS="15"
EXA_SEARCH_MAX_RESULTS="6"
# Legacy OpenRouter settings (set AI_PROVIDER="openrouter" to use)
OPENROUTER_API_KEY=""
OPENROUTER_BASE_URL="https://openrouter.ai/api/v1"
OPENROUTER_MODEL_MAIN="deepseek/deepseek-v4-flash"
OPENROUTER_MODEL_LLAMA="qwen/qwen3-next-80b-a3b-instruct"
AI_MAX_RETRIES="2"
AI_TIMEOUT_SECONDS="120"
# Learn Anything lesson authoring (OpenAI-compatible chat via Groq).
# Server-side only — never put this in NEXT_PUBLIC_*.
GROQ_API_KEY=""
# Z.AI / GLM free Flash models (text + vision). Server-side only.
# Text: glm-4.7-flash Vision: glm-4.6v-flash
# https://docs.z.ai/ base: https://api.z.ai/api/paas/v4/
ZAI_API_KEY=""
ZAI_BASE_URL="https://api.z.ai/api/paas/v4"
ZAI_MODEL_TEXT="glm-4.7-flash"
ZAI_MODEL_VISION="glm-4.6v-flash"
ZAI_TIMEOUT_SECONDS="90"
# Scale knobs for ~1k concurrent students (raise in production Postgres deploys).
DATABASE_POOL_SIZE="10"
DATABASE_MAX_OVERFLOW="20"
RATE_LIMIT_ENABLED="true"
RATE_LIMIT_AI_REQUESTS_PER_DAY="80"
# TTS provider settings.
# AI4Bharat Indic Parler is the local Indian-English + Malayalam teacher voice.
# Accept its free Hugging Face access terms once, then set HUGGINGFACE_API_KEY.
# Use TTS_PROVIDER="mock" only for silent timing tests.
TTS_PROVIDER="ai4bharat"
TTS_DEFAULT_PROVIDER="ai4bharat"
VIDEO_TTS_PROVIDER="ai4bharat"
TTS_DEFAULT_VOICE="nila"
TTS_OUTPUT_DIR="public/generated/audio"
AI4BHARAT_TTS_MODEL="ai4bharat/indic-parler-tts"
AI4BHARAT_TTS_SPEAKER="Anjali"
AI4BHARAT_TTS_ENGLISH_SPEAKER="Mary"
AI4BHARAT_TTS_DEVICE="auto"
AI4BHARAT_TTS_PRECISION="float32"
AUDIO_SCENE_TIMEOUT_SECONDS="45"
AUDIO_TOTAL_TIMEOUT_SECONDS="300"
AUDIO_MAX_RETRIES="2"
AUDIO_MAX_CONCURRENCY="3"
KOKORO_VOICE="af_heart"
KOKORO_SPEED="0.95"
INDIC_TTS_MODEL=""
INDIC_TTS_LANGUAGE="ml"
EDGE_TTS_VOICE_EN="en-US-JennyNeural"
EDGE_TTS_VOICE_ML="ml-IN-SobhanaNeural"
EDGE_TTS_RATE="+15%"
ELEVENLABS_API_KEY=""
ELEVENLABS_VOICE_ID=""
AUDIO_NORMALIZE="true"
# Local Remotion final render settings.
GENERATED_VIDEO_JOBS_DIR="generated-video-jobs"
GENERATED_VIDEO_OUTPUT_DIR="generated-videos"
VIDEO_RENDER_TIMEOUT_SECONDS="420"
VIDEO_MIN_OUTPUT_BYTES="4096"
VIDEO_BETA_MAX_SCENES="5"
VIDEO_BETA_MAX_DURATION_SECONDS="90"
VIDEO_SCENE_TEXT_MAX_CHARS="700"
VIDEO_MAX_CONCURRENT_RENDER_JOBS_PER_USER="1"
VIDEO_ENFORCE_BETA_LIMITS_IN_DEVELOPMENT="false"
# Storage provider settings.
# Local generated media is delivered through authenticated /generated routes.
# Use STORAGE_PROVIDER="r2" or "s3" with an S3-compatible bucket for cloud media.
STORAGE_PROVIDER="local"
STORAGE_BUCKET=""
STORAGE_REGION=""
STORAGE_ENDPOINT_URL=""
STORAGE_ACCESS_KEY_ID=""
STORAGE_SECRET_ACCESS_KEY=""
STORAGE_PUBLIC_BASE_URL=""
STORAGE_UPLOAD_PREFIX="uploads"
STORAGE_AUDIO_PREFIX="generated-audio"
STORAGE_VIDEO_PREFIX="generated-videos"
# Auth settings.
# Demo auth is permitted only when explicitly enabled for localhost development.
AUTH_ENABLED="false"
AUTH_PROVIDER="dev"
ALLOW_INSECURE_DEV_AUTH="true"
FRONTEND_BASE_URL="http://127.0.0.1:3000"
JWT_SECRET_KEY="change-this-before-real-users"
JWT_ALGORITHM="HS256"
ACCESS_TOKEN_EXPIRE_MINUTES="10080"
SUPABASE_URL=""
SUPABASE_JWT_SECRET=""
SUPABASE_ANON_KEY=""
# Backend only. Required to fully remove Supabase Auth identities when
# AUTH_PROVIDER="supabase". Never copy this into a NEXT_PUBLIC_* variable.
SUPABASE_SERVICE_ROLE_KEY=""
# Transactional account email. Required for password recovery when
# AUTH_PROVIDER="jwt" in production.
EMAIL_PROVIDER="disabled" # disabled | resend
RESEND_API_KEY=""
EMAIL_FROM="DocDoe <support@docdoe.in>"
PASSWORD_RESET_TOKEN_MINUTES="30"
PASSWORD_RESET_REQUEST_COOLDOWN_SECONDS="60"
# Optional Google sign-in.
# Create OAuth credentials in Google Cloud and add this redirect URI:
# http://127.0.0.1:8000/auth/google/callback
GOOGLE_CLIENT_ID=""
GOOGLE_CLIENT_SECRET=""
GOOGLE_OAUTH_REDIRECT_URI="http://127.0.0.1:8000/auth/google/callback"
# Beta invite gate.
# Set BETA_ACCESS_ENABLED=true and a strong BETA_INVITE_CODE to require an invite
# code at signup. Leave BETA_ACCESS_ENABLED=false for open signup (dev/demo).
BETA_ACCESS_ENABLED="false"
BETA_INVITE_CODE=""
# Per-user AI rate limiting.
# Set RATE_LIMIT_ENABLED=true outside local development. It prevents a single
# user from exhausting credits and applies per user (JWT sub) or server-observed
# client IP when no token is present. Resets every 24 hours from first request.
RATE_LIMIT_ENABLED="false"
RATE_LIMIT_AI_REQUESTS_PER_DAY="50"
# --- Stripe Billing (Popular 299 + Premium 599 subscriptions) ---
# Prefer a restricted TEST key (rk_test_...) with only the Checkout, Customers,
# Subscriptions, and Billing Portal permissions this backend needs.
# Create recurring test Prices for both active plans. Checkout stays disabled
# until the key, webhook secret, and requested Price are all present.
# Example:
# STRIPE_PRICE_IDS=popular_299=price_sub_abc,premium_599=price_sub_def
# For webhook testing: `stripe listen --forward-to http://127.0.0.1:8000/billing/webhook`
# (this prints a local whsec_... you paste here; in prod use the dashboard endpoint secret).
STRIPE_SECRET_KEY=""
STRIPE_WEBHOOK_SECRET=""
STRIPE_PRICE_IDS=""
# ── Observability + scaling (optional; A+ when set) ───────────────────────────
# Shared rate-limit + prompt cache across replicas (e.g. Upstash free tier):
REDIS_URL=
# Error tracking — paste a Sentry project DSN to capture backend + frontend errors:
SENTRY_DSN=
SENTRY_TRACES_SAMPLE_RATE=0.1