POST /api/analyze submits an analysis job and returns job_id instantly.
GET /api/analyze/{job_id} returns progress + result; frontend polls every 2s.
Analysis runs as asyncio.create_task in the background — each HTTP request
completes in milliseconds, well within the 30s GCP Load Balancer limit.
- Add backend/app/services/job_store.py: in-memory AnalysisJob store with
30-min TTL cleanup
- Add backend/app/api/analysis_routes.py: POST + GET /api/analyze endpoints
with full analysis pipeline (hash check, DB persistence, PDF pages, etc.)
- Remove backend/app/websocket/: handlers.py, manager.py, __init__.py
- Update backend/app/main.py: wire analysis_router, store analysis_service
in app.state, drop all WebSocket imports and endpoint
- Update frontend/services/geminiService.ts: replace WS with fetch+poll;
function signatures unchanged so App.tsx / WIPReviewer.tsx need no edits
- Remove VITE_BACKEND_WS_URL from vite.config.ts, deploy.sh, .env.deploy.example
- Update cloudrun.yaml: remove WebSocket-specific session affinity annotation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The deploy script now generates both env files automatically — no more
manual file creation on the server. All secrets and VITE_ vars are
centralised in .env.deploy (gitignored). Updated .env.deploy.example
with all required variables and inline documentation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DATABASE_URL is set via the environment block in docker-compose.yml
and does not need to be present in backend/.env.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The script previously only checked that backend/.env existed, allowing
deployments with unset or placeholder values. This meant GEMINI_API_KEY
could be missing, causing every analysis to fail at 80% with a
PERMISSION_DENIED error from the Gemini API.
Now checks GEMINI_API_KEY, AZURE_TENANT_ID, AZURE_CLIENT_ID, and
DATABASE_URL are set to real values before any build step runs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ensures new code changes are picked up by using --force-recreate
flag when starting the backend container.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The package-lock.json changes when npm install runs on different
platforms/npm versions. Since deploy.sh runs npm install anyway,
discard local changes to this file before pulling to avoid conflicts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove auto-generation of frontend/.env.local
- Instead, check that it exists and fail with helpful message if not
- Update .env.deploy.example to document manual .env.local setup
This allows manual management of frontend credentials without
the deploy script overwriting them.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Include VITE_AZURE_CLIENT_ID, VITE_AZURE_TENANT_ID, and
VITE_AZURE_REDIRECT_URI in frontend .env.local generation
- Document these variables in .env.deploy.example
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Add PostgreSQL service to docker-compose with health checks
- Add SQLAlchemy async models for all entities (Agency, User, Campaign,
Proof, ProofVersion, FlaggedItem, ResolvedItem, ErrorItem)
- Add Alembic migration framework with initial schema migration
- Add repository layer for CRUD operations
- Add REST API endpoints for campaigns, proofs, and audit items
- Add file storage service for proof uploads
- Update WebSocket handler to optionally persist analysis results
Frontend:
- Add apiService.ts for REST API communication
- Update geminiService.ts to support database persistence options
Deployment:
- Update deploy.sh to handle database migrations (6-step process)
- Update Dockerfile to include alembic configuration
- Add PostgreSQL environment variables to .env templates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The deploy script now creates a .env file with COMPOSE_PROJECT_NAME
and BACKEND_PORT so that manual docker compose commands (ps, logs, etc.)
work without needing to set environment variables.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add COMPOSE_PROJECT_NAME for unique container names
- Add BACKEND_PORT for configurable port mapping
- Update deploy.sh to export variables for docker compose
- Update health checks to use configured port
Allows running prod and dev instances simultaneously by cloning
the repo twice with different .env.deploy configurations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add deploy.sh for automated deployment (idempotent)
- Add .env.deploy.example template for server configuration
- Update .gitignore to exclude .env.deploy
The script handles both first-time install and updates:
- Pulls latest code from git
- Builds frontend with production URLs
- Deploys to Apache document root
- Rebuilds and restarts Docker backend
- Includes health check verification
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>