# WESP Orchestrator — production deploy

## Bootstrap

1. Copy env template and run install secrets (`site/scripts/` or admin UI).
2. Start stack: `docker compose -f site/infra/docker/docker-compose.prod.yml up -d`.
3. Run migrations: `docker compose exec api alembic upgrade head`.
4. Sync WESP static UI: `site/scripts/sync-wesp-ui.sh`.

## Hub pairing

1. Open Enterprise cabinet → **Generate pairing code**.
2. On farm hub (K-hub server role): Admin → Orchestrator sync → enter VPS URL + code.
3. Verify heartbeat and sync metrics in cabinet.

## Worker

- Default loop: `python -m app.worker` (reconcile every 5 min).
- Celery (recommended prod): `celery -A app.celery_app worker --loglevel=info` (service `celery-worker` in compose).

## Hub (WESP)

1. Run migration: `flask db upgrade` (revision `0025` / `web_user_lab_access` → orchestrator tables).
2. Configure orchestrator sync in hub admin (URL + pairing code).
3. Catalog edits enqueue `orchestrator_outbox`; reports enqueue `report_outbox`.

## nginx

- Zootech static: `/recipes`, `/components`, … → `public/wesp/*.html` (see `infra/nginx/default.tls.conf`).
- API: `/api/` → FastAPI.

## Security checklist

- Rotate `JWT_ACCESS_SECRET`, `JWT_REFRESH_PEPPER`, hub API keys.
- Enable PostgreSQL RLS in production (`DATABASE_URL=postgresql+psycopg://...`).
- Review `site/docs/security.md` before go-live.

## Tests (CI gate)

```bash
cd site/apps/api && .venv/bin/python -m pytest tests/modules/sync/test_orchestrator_dual_hub_e2e.py -q
```

Dual-hub E2E must pass before merge.
