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:
@@ -0,0 +1,93 @@
|
||||
# CI Agent — Competitive Intelligence Monitoring
|
||||
|
||||
CI Agent monitors companies you choose, collects publicly available information from multiple sources on a schedule, analyzes it with an LLM into an evidence-linked report, detects meaningful changes between runs, and alerts you by email (and optionally SMS) with a severity and confidence score.
|
||||
|
||||
See [`PLAN.md`](PLAN.md) for the build strategy, [`ARCHITECTURE.md`](ARCHITECTURE.md) for system design, [`SECURITY.md`](SECURITY.md) for the threat model, [`TASKS.md`](TASKS.md) for the live implementation checklist, [`KNOWN_LIMITATIONS.md`](KNOWN_LIMITATIONS.md) for what's stubbed vs. fully live, and [`docs/FIREBASE_MIGRATION.md`](docs/FIREBASE_MIGRATION.md) for a (skeptical) look at what moving to Firebase would take.
|
||||
|
||||
## Quick start (Docker)
|
||||
|
||||
```bash
|
||||
git clone <repository>
|
||||
cd ci-agent
|
||||
cp .env.example .env
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
Then visit:
|
||||
|
||||
| Service | URL |
|
||||
|---|---|
|
||||
| Frontend | http://localhost:3000 |
|
||||
| Backend API | http://localhost:8000 |
|
||||
| API docs (Swagger) | http://localhost:8000/docs |
|
||||
|
||||
The default `.env.example` runs in `AUTH_MODE=local` (no login required, fixed dev user) with `LLM_PROVIDER=mock` and `SEARCH_PROVIDER=mock` — the whole demo workflow works with zero paid API keys.
|
||||
|
||||
`api`, `worker`, and `beat` build from the same Dockerfile but are separate images — after adding a Python dependency, run `docker compose build api worker beat` (not just `restart`) or they'll crash with `ModuleNotFoundError` on stale images.
|
||||
|
||||
Similarly, after adding an npm dependency to `apps/web`, a plain rebuild isn't enough either — `web`'s `node_modules` *and* `.next` are both persistent anonymous Docker volumes that survive `docker compose build web` and even a plain `docker compose restart web`. This means a new package can still 404, and — on Windows + Docker Desktop — an edited existing file can keep serving its pre-edit output after a restart, since the on-disk `.next` build cache isn't cleared by a restart. Run `docker compose rm -f -s -v web && docker compose up -d web` to actually pick up new packages or force a clean recompile.
|
||||
|
||||
## Running without Docker
|
||||
|
||||
**Backend:**
|
||||
|
||||
```bash
|
||||
cd apps/api
|
||||
python -m venv .venv
|
||||
./.venv/Scripts/activate # or `source .venv/bin/activate` on macOS/Linux
|
||||
pip install -e ".[dev]"
|
||||
cp ../../.env.example ../../.env # edit DATABASE_URL to the sqlite line if you don't have Postgres running
|
||||
alembic upgrade head
|
||||
uvicorn app.main:app --reload
|
||||
```
|
||||
|
||||
**Frontend:**
|
||||
|
||||
```bash
|
||||
cd apps/web
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Common commands
|
||||
|
||||
```bash
|
||||
# Database migrations
|
||||
cd apps/api && alembic upgrade head
|
||||
cd apps/api && alembic revision --autogenerate -m "description"
|
||||
|
||||
# Run a Celery worker + beat (only needed outside Docker)
|
||||
cd apps/api && celery -A app.tasks.celery_app worker --loglevel=INFO -Q default,collection,analysis,notifications,maintenance
|
||||
cd apps/api && celery -A app.tasks.celery_app beat --loglevel=INFO
|
||||
|
||||
# Backend tests / lint / format
|
||||
cd apps/api && pytest
|
||||
cd apps/api && ruff check app tests
|
||||
cd apps/api && black app tests
|
||||
|
||||
# Frontend tests / lint / format / typecheck
|
||||
cd apps/web && npm test
|
||||
cd apps/web && npm run lint
|
||||
cd apps/web && npm run format
|
||||
cd apps/web && npm run typecheck
|
||||
|
||||
# End-to-end test (requires `docker compose up -d` already running)
|
||||
cd apps/web && npx playwright install --with-deps chromium # one-time
|
||||
cd apps/web && npm run e2e
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
All configuration is via environment variables — see [`.env.example`](.env.example) for the full list with comments. Highlights:
|
||||
|
||||
- `AUTH_MODE=local|jwt` — local single-user dev mode vs. real email/password accounts.
|
||||
- `LLM_PROVIDER=mock|anthropic|ollama|gemini` — set `ANTHROPIC_API_KEY`/`ANTHROPIC_MODEL`, `OLLAMA_BASE_URL`/`OLLAMA_MODEL`, or `GEMINI_API_KEY`/`GEMINI_MODEL` to go live. Gemini has a genuine free tier — grab a key at [aistudio.google.com/apikey](https://aistudio.google.com/apikey) — so it's the cheapest provider to actually try against a real model.
|
||||
- `SEARCH_PROVIDER=mock|brave` — set `BRAVE_SEARCH_API_KEY` to go live.
|
||||
- `SMTP_HOST`/`RESEND_API_KEY` — no bundled local mail sink; point SMTP at a real relay or set `RESEND_API_KEY` to actually test email delivery (alerts and security email both use this).
|
||||
- `NOTIFICATION_SMS_ENABLED=false` by default — set to `true` and provide `TWILIO_*` to enable SMS.
|
||||
|
||||
Every paid/external provider defaults to a mock/console implementation. Automated tests always run against mocks and never call a paid API.
|
||||
|
||||
## Known limitations
|
||||
|
||||
See [`KNOWN_LIMITATIONS.md`](KNOWN_LIMITATIONS.md).
|
||||
Reference in New Issue
Block a user