- AGENTS.md: canonical project entry point (Quick Nav, pipeline, constraints) - docs/: complete docs tree — architecture, API spec, DB schema, infra, runbook, requirements, tech stack, principles, reference ADRs, guides, tasks backlog, testing strategy - tests/README.md: test commands, structure, known gaps - README.md / CLAUDE.md / DEPLOYMENT.md: updated with canonical doc links - .archive/: backup of pre-documentation-pipeline originals - backend/uv.lock: uv dependency lockfile - Delete committed __pycache__ .pyc files (should have been gitignored) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
213 lines
6.3 KiB
Markdown
213 lines
6.3 KiB
Markdown
# Runbook — Accessible Video Processing Platform
|
|
|
|
<!-- SCOPE: runbook | owner: ln-115 | generated: 2026-04-29 -->
|
|
|
|
## Local Development Setup
|
|
|
|
### Prerequisites
|
|
|
|
| Requirement | Version |
|
|
|-------------|---------|
|
|
| Docker | 20.10+ |
|
|
| Docker Compose | V2 (bundled with Docker Desktop) |
|
|
| Node.js | 20+ |
|
|
| Python | 3.11+ (for local scripts only; app runs in Docker) |
|
|
| GCP credentials file | `./secrets/gcp-credentials.json` |
|
|
|
|
### First-Time Setup
|
|
|
|
| Step | Command / Action |
|
|
|------|-----------------|
|
|
| 1. Copy env template | `cp .env.prod.example .env.local` — fill in all values |
|
|
| 2. Copy frontend env | `cp frontend/.env.example frontend/.env.local` |
|
|
| 3. Place GCP credentials | Copy service account JSON to `./secrets/gcp-credentials.json` |
|
|
| 4. Set permissions | `chmod 600 ./secrets/gcp-credentials.json` |
|
|
|
|
### Starting the Local Environment
|
|
|
|
**Step 1 — Backend (Docker):**
|
|
|
|
`./scripts/run-local.sh`
|
|
|
|
Services after start:
|
|
|
|
| Service | URL |
|
|
|---------|-----|
|
|
| API | http://localhost:8003 |
|
|
| API docs (Swagger) | http://localhost:8003/docs |
|
|
| MongoDB | mongodb://localhost:27017 |
|
|
| Redis | redis://localhost:6379 |
|
|
|
|
**Step 2 — Frontend (Vite dev server, separate terminal):**
|
|
|
|
`cd frontend && npm install && npm run dev`
|
|
|
|
Frontend URL: http://localhost:6001/video-accessibility
|
|
|
|
### Common Local Commands
|
|
|
|
| Action | Command |
|
|
|--------|---------|
|
|
| Rebuild containers after code change | `./scripts/run-local.sh --rebuild` |
|
|
| Stop all services | `./scripts/run-local.sh --stop` |
|
|
| Tail all logs | `docker compose logs -f` |
|
|
| Tail API logs | `docker compose logs -f api` |
|
|
| Tail worker logs | `docker compose logs -f worker` |
|
|
| Restart a service | `docker compose restart api` |
|
|
|
|
### Test Credentials (Local Only)
|
|
|
|
| Role | Email | Password |
|
|
|------|-------|---------|
|
|
| Admin | admin@example.com | admin |
|
|
| Reviewer | reviewer@example.com | reviewer |
|
|
| Client | client@example.com | client123 |
|
|
|
|
Production uses Microsoft SSO — these credentials do not work in production.
|
|
|
|
---
|
|
|
|
## Production Deployment
|
|
|
|
**Server:** optical-web-1
|
|
**Deploy path:** `/opt/video-accessibility/`
|
|
**URL:** https://ai-sandbox.oliver.solutions/video-accessibility/
|
|
|
|
### Full Deployment (code + frontend)
|
|
|
|
Run on server (requires explicit user instruction — NEVER run via SSH without user approval):
|
|
|
|
`./scripts/full-deploy.sh`
|
|
|
|
This script:
|
|
|
|
| Step | Action |
|
|
|------|--------|
|
|
| 1 | Pull latest code from git |
|
|
| 2 | Build Docker images |
|
|
| 3 | Restart containers |
|
|
| 4 | Build frontend bundle |
|
|
| 5 | Copy bundle to Apache webroot |
|
|
| 6 | Run DB seed if needed |
|
|
|
|
### Frontend-Only Deployment
|
|
|
|
`./scripts/build-frontend.sh`
|
|
|
|
Builds the React bundle and copies to `/var/www/html/video-accessibility/`.
|
|
|
|
### Verification After Deploy
|
|
|
|
| Check | Command / URL |
|
|
|-------|--------------|
|
|
| API health | `curl https://ai-sandbox.oliver.solutions/video-accessibility-back/health` |
|
|
| Container status | `docker compose ps` |
|
|
| Frontend loads | Visit https://ai-sandbox.oliver.solutions/video-accessibility |
|
|
| Worker running | `docker compose logs --tail=20 worker` |
|
|
|
|
---
|
|
|
|
## Database Operations
|
|
|
|
### Backup MongoDB
|
|
|
|
| Step | Command |
|
|
|------|---------|
|
|
| Dump to container | `docker compose exec mongodb mongodump --out=/data/backup` |
|
|
| Copy to host | `docker cp accessible-video-mongodb:/data/backup ./mongodb-backup-$(date +%Y%m%d)` |
|
|
|
|
### Restore MongoDB
|
|
|
|
| Step | Command |
|
|
|------|---------|
|
|
| Copy to container | `docker cp ./mongodb-backup accessible-video-mongodb:/data/restore` |
|
|
| Restore | `docker compose exec mongodb mongorestore /data/restore` |
|
|
|
|
### MongoDB Shell
|
|
|
|
`docker compose exec mongodb mongosh`
|
|
|
|
---
|
|
|
|
## Restarting Services
|
|
|
|
| Action | Command |
|
|
|--------|---------|
|
|
| Restart all | `docker compose restart` |
|
|
| Restart API only | `docker compose restart api` |
|
|
| Restart worker only | `docker compose restart worker` |
|
|
| Rebuild + restart one service | `docker compose up -d --build api` |
|
|
|
|
---
|
|
|
|
## Updating Application
|
|
|
|
| Step | Command |
|
|
|------|---------|
|
|
| Pull code | `git pull origin main` |
|
|
| Full redeploy | `./scripts/full-deploy.sh` |
|
|
| Frontend only | `./scripts/build-frontend.sh` |
|
|
|
|
---
|
|
|
|
## Linting and Type Checking
|
|
|
|
| Check | Command | Must pass before deploy |
|
|
|-------|---------|------------------------|
|
|
| Backend lint | `cd backend && ruff check .` | Yes |
|
|
| Backend type check | `docker compose exec api python -m mypy app/` | Yes |
|
|
| Frontend lint | `cd frontend && npm run lint` | Yes |
|
|
| Frontend type check | `cd frontend && npm run type-check` | Yes (currently 0 errors) |
|
|
|
|
---
|
|
|
|
## Monitoring
|
|
|
|
| Tool | Access | Purpose |
|
|
|------|--------|---------|
|
|
| Docker stats | `docker stats` | Container CPU/memory usage |
|
|
| API logs | `docker compose logs -f api` | Request errors |
|
|
| Worker logs | `docker compose logs -f worker` | Task errors |
|
|
| Sentry | sentry.io | Exception capture + stack traces |
|
|
| Prometheus | localhost:8001/metrics | Metrics (internal only) |
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
| Symptom | Check | Fix |
|
|
|---------|-------|-----|
|
|
| 502 Bad Gateway on API | `docker compose ps api` + logs | Restart: `docker compose restart api` |
|
|
| Frontend 404 | `ls /var/www/html/video-accessibility/` | Rebuild: `./scripts/build-frontend.sh` |
|
|
| WebSocket fails | `apache2ctl -M | grep proxy_wstunnel` | `sudo a2enmod proxy_wstunnel && sudo systemctl restart apache2` |
|
|
| Worker not processing | `docker compose logs -f worker` | Check Redis URL + GCP credentials mount |
|
|
| Upload fails (GCS) | Test credentials in container | Check `./secrets/gcp-credentials.json` exists + permissions |
|
|
| MongoDB auth fails | Check `MONGODB_URI` env var | Verify Atlas connection string |
|
|
|
|
---
|
|
|
|
## Apache Configuration
|
|
|
|
Required modules:
|
|
|
|
`sudo a2enmod rewrite proxy proxy_http proxy_wstunnel headers && sudo systemctl restart apache2`
|
|
|
|
Config file: `/etc/apache2/sites-available/ai-sandbox.oliver.solutions-ssl.conf`
|
|
|
|
Key directives needed:
|
|
|
|
| Directive | Purpose |
|
|
|-----------|---------|
|
|
| `Alias /video-accessibility /var/www/html/video-accessibility` | Serve frontend |
|
|
| `ProxyPass /video-accessibility-back http://localhost:8000` | Proxy API |
|
|
| `RewriteRule ^ /video-accessibility/index.html [L]` | SPA routing |
|
|
| `RewriteEngine On` with WebSocket rules | WS proxy |
|
|
|
|
---
|
|
|
|
## Maintenance
|
|
|
|
**Update triggers:** New deploy script, new service port, new server.
|
|
**Verification:** All commands in this runbook execute without error on a clean checkout. Test credentials are not committed to production env files.
|
|
|
|
<!-- END SCOPE: runbook -->
|