Initial commit: CI Agent competitive-intelligence monitoring app

FastAPI + Celery + Next.js + Postgres/Redis app with company monitoring,
source collection, LLM-based change analysis, enrichment, and account
security (Turnstile, escalating lockout, email verification).
This commit is contained in:
2026-08-05 10:48:20 -04:00
commit 1a4c80958f
365 changed files with 43541 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
## ---------------------------------------------------------------------------
## CI Agent environment configuration
## Copy to .env and adjust. Nothing here is a real secret.
## ---------------------------------------------------------------------------
# --- App -----------------------------------------------------------------
APP_ENV=development
APP_NAME=CI Agent
# Comma-separated list of allowed CORS origins. Add your LAN address here
# (e.g. http://localhost:3000,http://192.168.1.190:3000) to reach the app
# from another device on your network - find your LAN IP with `ipconfig`
# (Windows) or `ifconfig`/`ip a` (Mac/Linux).
FRONTEND_URL=http://localhost:3000
BACKEND_URL=http://localhost:8000
# What the *browser* uses to reach the API - baked into the frontend build,
# so for LAN access this must be the host's LAN IP, not localhost (e.g.
# http://192.168.1.190:8000). Leave unset for localhost-only access.
NEXT_PUBLIC_API_URL=http://localhost:8000
# --- Reverse proxy (only relevant once deployed behind Cloudflare/Nginx) -----
# Empty = trust the direct connection for client-IP resolution (correct for
# this Docker/local setup - no proxy exists). Set to CF-Connecting-IP once
# behind Cloudflare's proxy, or the IP throttle/ban system and is_localhost
# will treat every visitor as sharing the proxy's own address.
TRUSTED_PROXY_IP_HEADER=
# --- Local-dev convenience --------------------------------------------------
# Comma-separated extra IPs that is_localhost treats as loopback-equivalent.
# Needed under Docker Desktop, where even host-originated traffic arrives at
# the containers via the bridge gateway rather than real loopback - find
# yours from a recent ip_throttle_state/user_security_events row, or leave
# blank to keep the strict default (only real 127.0.0.1/::1 count as local).
# Never set this in a real deployment.
ADDITIONAL_TRUSTED_LOCAL_IPS=
# --- Auth ------------------------------------------------------------------
# local = single fixed dev user, no login screen required
# jwt = real email/password accounts
AUTH_MODE=local
JWT_SECRET=dev-only-change-me-32-characters-minimum
JWT_ACCESS_TOKEN_MINUTES=15
JWT_REFRESH_TOKEN_DAYS=7
# --- Database ----------------------------------------------------------------
# Postgres (Docker Compose default):
DATABASE_URL=postgresql+psycopg://ciagent:ciagent@postgres:5432/ciagent
# SQLite fallback for running the API without Docker:
# DATABASE_URL=sqlite+aiosqlite:///./ciagent_dev.db
# --- Redis / Celery --------------------------------------------------------
REDIS_URL=redis://redis:6379/0
CELERY_TASK_ALWAYS_EAGER=false
# --- LLM ---------------------------------------------------------------------
# mock | anthropic | ollama | gemini
LLM_PROVIDER=mock
ANTHROPIC_API_KEY=
ANTHROPIC_MODEL=claude-sonnet-5
OLLAMA_BASE_URL=http://host.docker.internal:11434
OLLAMA_MODEL=llama3.1
# Free-tier option: create a key at https://aistudio.google.com/apikey
GEMINI_API_KEY=
GEMINI_MODEL=gemini-2.0-flash
LLM_MAX_TOKENS_PER_REQUEST=4000
LLM_MAX_RETRIES=2
# --- Search / company discovery --------------------------------------------
# mock | brave
SEARCH_PROVIDER=mock
BRAVE_SEARCH_API_KEY=
SERPAPI_API_KEY=
BING_SEARCH_API_KEY=
# --- Patents -----------------------------------------------------------------
# Free key via account registration at data.uspto.gov/apis/getting-started
# (now requires ID.me identity verification). PatentSourceCollector falls
# back to its honest disabled/fixture behavior when this is empty.
USPTO_API_KEY=
# --- Company enrichment (NinjaPear / nubela.co) -------------------------------
# Paid, per-credit API - get a key from nubela.co/dashboard after
# registering. Only ever called once per company, at creation time (never
# on a recurring schedule) - see app/services/enrichment_service.py.
# Leave empty to skip this feature entirely; nothing else in the app
# depends on it.
NINJAPEAR_API_KEY=
NINJAPEAR_MAX_LEADERSHIP_LOOKUPS=5
# --- Email (SMTP) ------------------------------------------------------------
# Fallback transport when RESEND_API_KEY (below) isn't set - alert emails
# and, if Resend is unconfigured, security emails go through this. Point it
# at any real SMTP relay (e.g. your own mail server, or Resend's own SMTP
# endpoint at smtp.resend.com). Nothing in this stack runs a local catch-all
# mail sink - a real relay (or a real Resend account) is required to
# actually test email delivery locally.
SMTP_HOST=
SMTP_PORT=587
SMTP_USERNAME=
SMTP_PASSWORD=
SMTP_FROM_EMAIL=[email protected]
SMTP_USE_TLS=true
# --- Resend (transactional security email: verify/reset/lockout) ------------
# Unset by default - falls back to the SMTP block above. Get a key from
# resend.com after verifying your sending domain.
RESEND_API_KEY=
RESEND_SECURITY_FROM_EMAIL=[email protected]
# --- Cloudflare Turnstile (CAPTCHA on register/login/password-reset) --------
# Unset by default - skipped when the caller is on loopback, or when this
# isn't configured at all (neither here nor via the Settings page's admin
# "Server secrets" box, which takes priority over these when set - see
# app/services/system_secret_service.py). The site key is safe to expose
# publicly; /system/status serves it live to the frontend, so there's no
# separate NEXT_PUBLIC_* build-time variable for it.
TURNSTILE_SITE_KEY=
TURNSTILE_SECRET=
# --- SMS (optional) -----------------------------------------------------------
NOTIFICATION_SMS_ENABLED=false
# twilio | telnyx
SMS_PROVIDER=twilio
TWILIO_ACCOUNT_SID=
TWILIO_AUTH_TOKEN=
TWILIO_FROM_NUMBER=
# Telnyx: portal.telnyx.com -> API Keys for TELNYX_API_KEY; the number must
# be assigned to a Messaging Profile (portal.telnyx.com -> Messaging).
TELNYX_API_KEY=
TELNYX_FROM_NUMBER=
SMS_MONTHLY_CAP=50
# --- GitHub collector (optional, raises rate limit) --------------------------
GITHUB_TOKEN=
# --- Scheduling defaults -----------------------------------------------------
DEFAULT_TIMEZONE=America/New_York
DEFAULT_MONITORING_FREQUENCY=weekly
MINIMUM_MONITORING_INTERVAL_MINUTES=60
# --- Scraper behavior ---------------------------------------------------------
SCRAPER_USER_AGENT=CIAgentBot/1.0 (+https://ci-agent.local/bot)
MAX_PAGES_PER_DOMAIN=25
SCRAPER_REQUEST_TIMEOUT_SECONDS=30
SCRAPER_DOMAIN_DELAY_SECONDS=2
# --- Cost / abuse controls -----------------------------------------------------
MAX_COMPANIES_PER_USER=25
MAX_MANUAL_RUNS_PER_DAY=10
# --- Retention & logging -------------------------------------------------------
DATA_RETENTION_DAYS=365
LOG_LEVEL=INFO