diff --git a/README.md b/README.md index c51e097..88b84e4 100644 --- a/README.md +++ b/README.md @@ -48,15 +48,30 @@ cd backend/ # Access at http://localhost:7183 ``` -### Production Deployment +### Deploying to Dev / Prod + +Code changes ship through Bitbucket branches (`develop` → dev server, tagged releases on `main` → prod server). Deploys are run manually on each server: + ```bash -ssh user@server +ssh cd /opt/ai_qc -git pull origin main -sudo chown -R www-data:www-data uploads output media_plans brand_guidelines backend/usage_logs -sudo systemctl restart ai_qc.service +backend/scripts/deploy.sh dev # dev — pulls latest develop +backend/scripts/deploy.sh prod v1.2.0 # prod — checks out a specific tag +backend/scripts/deploy.sh dev --dry-run # preview without applying +backend/scripts/rollback.sh last # revert the most recent deploy +backend/scripts/health-check.sh # quick "is it alive?" ``` +See `backend/CLAUDE.md` for the full environment / branch / deploy reference. + +## Environments + +| Env | URL | Branch | Status | +|---|---|---|---| +| Local | `http://localhost:7183` | any | For active development | +| Dev | `https://optical-dev.oliver.solutions/ai_qc/` | `develop` | Live | +| Prod | `https://optical-prod.oliver.solutions/ai_qc/` | `main` (tagged) | Not yet stood up | + ## Clients Diageo, Unilever, L'Oreal, Amazon, Boots, Dow Jones, Honda, General @@ -69,7 +84,8 @@ Diageo, Unilever, L'Oreal, Amazon, Boots, Dow Jones, Honda, General - **PDF Guidelines**: Multi-page PDF upload with automatic LLM summarization - **Media Plans**: Excel media plan parsing with asset spec validation - **Enterprise Auth**: Azure AD with MSAL/PKCE and silent token refresh -- **Admin Panel**: Usage analytics, user tracking, cost estimation +- **User Access Control**: Default-deny per-user client access with admin grant/revoke and audit log +- **Admin Panel**: Usage analytics, user tracking, cost estimation, access management - **Profile Versioning**: Automatic version control on profile edits ## Documentation diff --git a/backend/README.md b/backend/README.md index 08c1da2..7aacbd4 100644 --- a/backend/README.md +++ b/backend/README.md @@ -17,7 +17,8 @@ Visual AI QC is an intelligent quality control platform that uses advanced AI (O - **PDF Brand Guidelines**: Upload multi-page PDF guidelines with automatic LLM summarization - **Media Plan Integration**: Upload Excel media plans for automatic asset spec validation - **Enterprise Authentication**: Microsoft Azure AD with MSAL/PKCE and silent token refresh -- **Admin Panel**: Platform-wide usage analytics, user tracking, and cost estimation +- **User Access Control**: Default-deny per-user client access. Admins grant/revoke client visibility; all changes audit-logged +- **Admin Panel**: Platform-wide usage analytics, user tracking, cost estimation, and user-access management - **Client-Scoped Reporting**: Per-client usage dashboards with date range filtering - **Profile Versioning**: Automatic version control when profiles are edited @@ -77,16 +78,31 @@ Visual AI QC Platform # Access at http://localhost:7183 ``` -### Production Deployment +### Deploying to Dev / Prod + +The dev server (`optical-dev.oliver.solutions/ai_qc/`) tracks the `develop` branch. Prod will track tagged releases on `main`. Both use the same deploy scripts; only the mode argument differs. ```bash -ssh user@server +ssh cd /opt/ai_qc -git pull origin main -sudo chown -R www-data:www-data uploads output media_plans brand_guidelines backend/usage_logs -sudo systemctl restart ai_qc.service + +# Deploy +backend/scripts/deploy.sh dev # pulls develop +backend/scripts/deploy.sh prod v1.2.0 # checks out tag v1.2.0 +backend/scripts/deploy.sh dev --dry-run # preview only + +# Recover +backend/scripts/rollback.sh last # revert last deploy +backend/scripts/rollback.sh # revert to specific commit + +# Check +backend/scripts/health-check.sh # exits 0 if healthy ``` +The deploy script captures a rollback checkpoint before applying, re-runs `pip install` only if `requirements.txt` changed, restarts the systemd service, and auto-rolls back on smoke-test failure. + +See `CLAUDE.md` for full environment and branch strategy. + ## Clients | Client | Profiles | Description | @@ -191,9 +207,14 @@ OCR provides Tesseract pixel-level measurements to the 3 layout-sensitive checks - localStorage-based MSAL cache for cross-tab persistence ### Admin Panel -- Accessible to users in the `ADMIN_USERS` list (`backend/client_config.py`) -- Platform-wide usage stats: total users, analyses, estimated cost -- Per-user breakdown: analyses, checks, clients used, last active +Two tabs — **Usage Overview** and **User Access**: +- **Usage Overview**: platform-wide stats (users, analyses, cost) + per-user breakdown +- **User Access**: search users, toggle per-client visibility, promote/demote admins + +Admin role and per-user client grants live in `backend/user_access.json` (bootstrapped on first start with `nick.viljoen@brandtech.plus` as the sole admin). All grant/revoke/promote/demote actions are logged as `access_change` events in `backend/usage_logs/`. + +### User Access Control +New users default to the **General** client only. Admins grant per-client visibility through the admin panel. Client-scoped endpoints enforce access server-side (403 with `code: "client_access_denied"` on denied requests), so frontend filtering alone isn't the security boundary. Revocation during an active session bounces the user back to the client picker with a toast. ## API Endpoints @@ -225,6 +246,10 @@ OCR provides Tesseract pixel-level measurements to the 3 layout-sensitive checks |--------|----------|-------------| | GET | `/api/admin/check` | Check if user is admin | | GET | `/api/admin/users` | Get all platform users (admin only) | +| GET | `/api/admin/user_access` | List users with their client grants (admin only) | +| PUT | `/api/admin/user_access/` | Set client list for a user (admin only) | +| POST | `/api/admin/user_access//promote` | Grant admin role (admin only) | +| POST | `/api/admin/user_access//demote` | Remove admin role (admin only; blocked if last admin) | | GET | `/api/client_usage_stats` | Client-scoped usage report | ### Media Plans