grantforge-api / backend /.env.example
GrantForge Bot
Deploy sha-565ad85979610064f6d1c18ab3b6404357d61073 β€” source build (no GHCR)
ce8f04a
Raw
History Blame Contribute Delete
7.74 kB
# Dotacje AI - Backend Environment Variables Example
# LLM Providers
GOOGLE_API_KEY="YOUR_GOOGLE_API_KEY"
# xAI / Grok (HF Space Secret: XAI_API_KEY) β€” fallback gdy Gemini 403/billing/dunning
XAI_API_KEY="YOUR_XAI_API_KEY"
GROK_API_KEY="YOUR_GROK_API_KEY"
# XAI_MODEL="grok-4.3"
# XAI_BASE_URL="https://api.x.ai/v1"
# KolejnoΕ›Δ‡ providerΓ³w (primary,fallback).
# Na Hugging Face Spaces: ustaw PREFER_XAI=true LUB LLM_PRIMARY=xai ΕΌeby od razu
# iΕ›Δ‡ na Grok i pominΔ…Δ‡ nieudane prΓ³by Gemini (szybszy generate-full przy 403/billing).
# LLM_FALLBACK_ORDER=gemini,xai
# LLM_PRIMARY=xai
# PREFER_XAI=false
# GEMINI_HEALTH_PROBE=true
GEMINI_EMBEDDING_MODEL="gemini-embedding-001"
GEMINI_EMBEDDING_DIMENSIONS="768"
# EMBEDDINGS_PROVIDER=auto # auto | hash (hash gdy Gemini embeddings 403)
# Vector Store (Pinecone) β€” wymagane do ingestu i semantycznego wyszukiwania
PINECONE_API_KEY="YOUR_PINECONE_API_KEY"
PINECONE_INDEX_NAME="dotacje"
# PINECONE_ENVIRONMENT="us-east-1" # opcjonalnie, zaleΕΌnie od regionu indeksu
# ENABLE_PINECONE_SEMANTIC="true"
# Database (PostgreSQL production / Hugging Face Spaces)
# Local docker-compose: postgresql://user:password@localhost:5432/dotacje
# Managed / HF Spaces (Aiven, Neon, Supabase, Render): ALWAYS use SSL β€”
# DATABASE_URL="postgresql://user:pass@host:5432/dbname?sslmode=require"
# Or omit ?sslmode= and set:
# DB_SSLMODE=require
# Remote hosts default to sslmode=require; localhost defaults to prefer.
# HF: set secrets in Space Settings β†’ Variables (repo .env is NOT deployed).
# Neon β†’ Aiven: docs/MIGRATION_NEON_TO_AIVEN.md
# DB_POOL_RECYCLE=1800
# Tracing and Observability
LANGCHAIN_API_KEY="YOUR_LANGSMITH_API_KEY"
LANGCHAIN_TRACING_V2="true"
LANGCHAIN_PROJECT="GrantForgeAI"
# Frontend (Vercel): optional Sentry browser DSN β€” omit to skip init (ErrorBoundary still works)
# VITE_SENTRY_DSN="https://...@o....ingest.sentry.io/..."
# VITE_POSTHOG_KEY="phc_..."
# VITE_CLERK_PUBLISHABLE_KEY="pk_..."
# VITE_API_URL="https://your-api.example.com/api"
# Graph Database (GraphRAG)
NEO4J_URI="neo4j+s://your-neo4j-instance.databases.neo4j.io"
NEO4J_USERNAME="neo4j"
NEO4J_PASSWORD="your-secure-password"
# Web Scraping (Required for Grant extraction)
# Crawl4AI β€” darmowy scraper (bez klucza API). Ustaw CRAWL4AI_USE_BROWSER=1 dla stron wymagajΔ…cych JS.
# CRAWL4AI_USE_BROWSER=0
# Regional RPO BIP parsers (F4.4)
# ENABLE_RPO_BIP_FETCH=true # 6 woj.: lubelskie, podkarpackie, Ε‚Γ³dzkie, mazowieckie, Ε›lΔ…skie, wielkopolskie β€” cache 6h
# Development Flags
# Set to 'true' to serve fallback mock data if scraping yields < 3 results
MOCK_GRANTS="false"
# ── Auth / Clerk (P0 security) ──────────────────────────────────────────────
# Required in production (HF Spaces Secrets) β€” fail-closed without these:
# CLERK_ISSUER="https://YOUR_INSTANCE.clerk.accounts.dev"
# Or pin JWKS directly (preferred if custom domain):
# CLERK_JWKS_URL="https://YOUR_INSTANCE.clerk.accounts.dev/.well-known/jwks.json"
# Optional JWT audience check (enable when Clerk JWT template sets aud):
# CLERK_AUDIENCE="grantforge-api"
# Clerk webhook signing secret (Dashboard β†’ Webhooks β†’ Signing Secret):
# CLERK_WEBHOOK_SECRET="whsec_..."
# Without it, POST /api/webhooks/clerk returns 500 (fail-closed). Startup logs a warning.
# Dev-only backdoor (NEVER set on HF production):
# ENV=dev
# ALLOW_DEV_TOKEN=true
# Internal seed endpoint (admin JWT required; also blocked in prod unless):
# ALLOW_INTERNAL_SEED=true
# Explicit frontend origins for CORS (comma-separated); FRONTEND_URL also added:
# CORS_ORIGINS="https://grantforge-ai.vercel.app,https://grantforge.pl"
# FRONTEND_URL="https://grantforge-ai.vercel.app"
# ── Multi-worker SSE tickets (generator stream) ──────────────────────────────
# Optional Redis; otherwise SQLite file under TMPDIR is used (multi-worker safe).
# REDIS_URL=redis://localhost:6379/0
# TICKET_REDIS_URL=redis://localhost:6379/1
# STREAM_TICKET_TTL_SECONDS=90
# TICKET_STORE_PATH=/tmp
# ── Company registries (enrichment) ──────────────────────────────────────────
# GUS_API_KEY= # BIR1.1 production key (20 chars)
# CEIDG_API_KEY= # dane.biznes.gov.pl CEIDG v2
# CEIDG_API_BASE=https://dane.biznes.gov.pl/api/ceidg/v2
# CEIDG_DISABLED=false
# SUDOP_API_BASE=https://api-sudop.uokik.gov.pl/sudop-api/1.0.0
# SUDOP_DISABLED=false
# BizRaport financial control β€” official API /api/dane (never commit real credentials)
# BIZRAPORT_EMAIL=your@email.pl
# BIZRAPORT_PASSWORD=
# BIZRAPORT_BASE_URL=https://api.bizraport.pl
# BIZRAPORT_ROZSZERZ_POLACZENIA=false
# BIZRAPORT_API_URL=https://your-proxy.example/bizraport/{nip}
# BIZRAPORT_API_KEY=
# BIZRAPORT_DISABLED=false
# BIZRAPORT_TIMEOUT=12
# ── Grant Pulse (phases A–D) ─────────────────────────────────────────────────
# ENABLE_PULSE_WORKER=true # process ResearchJob + eurlex batch in scheduler
# DISABLE_PULSE_WORKER=false
# PULSE_WORKER_MAX_JOBS=25
# PULSE_NEW_DAYS=14 # "new" window
# PULSE_CLOSING_DAYS=30 # "closing" window
# ENABLE_DEADLINE_BACKFILL=true # enqueue/persist missing deadlines from text
# DOC_INTEL_MIN_CHARS=120 # HTML thinner than this β†’ Crawl4AI fallback
# ENABLE_STEALTH_FETCH=true # curl_cffi Chrome fingerprint (PARP/BGK/WAF)
# STEALTH_IMPERSONATE=chrome # chrome|chrome120|chrome124|chrome131
# STEALTH_TIMEOUT=30
# STEALTH_DOMAINS=parp.gov.pl,bgk.pl,ncbr.gov.pl
# SSL_RELAXED_DOMAINS=wfosigw.pl,zus.pl # PDF/HTML TLS verify=False after primary fail
# FLAKY_FETCH_DOMAINS=funduszeeuropejskie.gov.pl
# FLAKY_FETCH_TIMEOUT=45
# FLAKY_PREFER_CACHE=true
# FLAKY_CACHE_ONLY=false # true = skip live scrape for flaky domains
# ENABLE_LIVE_RESEARCH=true # detect_grant_changes (false on HF free by default)
# ENABLE_EURLEX_BATCH=true # batch CELEX/DU grounding (legal-ID only, never free-text)
# ENABLE_EURLEX_NETWORK=false # true = live EUR-Lex SPARQL (off for CI/HF)
# ENABLE_LAW_WATCH=true
# ENABLE_STRATEGY_CASCADE=true # strategy recommend cascade 2026 (default on); false β†’ paths still returned, cascade_enforced=false
# ENABLE_ELIGIBILITY_SPINE=true # eligibility spine gates for readiness (default on)
# ENABLE_TAX_PATHS=true # tax checklist attach on tax_psi_ulgi (default on)
# ENABLE_BK2021=false # BK2021 B2B stub (default OFF); ON = draft alert only, never live scrape
# LAW_WATCHLIST_JSON=[{"program":"FENG","url":"https://..."}]
# LAW_WATCHLIST_PATH=/path/to/watchlist.json
# CLERK_WEBHOOK_SECRET=whsec_... # required for Clerk webhooks (fail-closed without)
# GUS_API_KEY= # BIR 1.1 company lookup (prod)
# REDIS_URL= # multi-worker SSE tickets (falls back to SQLite)
# ADMIN_EMAIL=bogmaz1@gmail.com # Nexus Control allowlist (or ADMIN_EMAILS=a@x,b@y)
# ADMIN_USER_IDS=user_xxx # Clerk user ids (comma-separated)
# ADMIN_CLERK_IDS= # alias of ADMIN_USER_IDS
# CLERK_SECRET_KEY= # optional: enrich admin check from Clerk user API
# GENERATOR_STREAM_TICKET_TTL=1800 # SSE ticket lifetime (seconds) for autopilot stream
# STREAM_TICKET_TTL_SECONDS=90 # default for other short-lived tickets