Update READMEs for user access control and new deploy flow

- Root README: add Environments section (dev live, prod pending),
  replace sandbox-era deploy block with deploy.sh usage, add user
  access to Capabilities.
- Backend README: rewrite Admin Panel section for user_access.json
  + User Access tab, add User Access Control feature, replace
  Production Deployment with deploy.sh/rollback.sh/health-check.sh,
  add the four admin/user_access API endpoints.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
nickviljoen 2026-04-22 18:49:24 +02:00
parent 57f1848eb1
commit eaf68b1247
2 changed files with 56 additions and 15 deletions

View file

@ -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 <server>
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

View file

@ -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 <server>
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 <commit-hash> # 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/<email>` | Set client list for a user (admin only) |
| POST | `/api/admin/user_access/<email>/promote` | Grant admin role (admin only) |
| POST | `/api/admin/user_access/<email>/demote` | Remove admin role (admin only; blocked if last admin) |
| GET | `/api/client_usage_stats` | Client-scoped usage report |
### Media Plans