docs: client portal design + milestone plan (M1 live view → M4 full auth) #61
@@ -132,6 +132,32 @@ live data, all from cache.
|
||||
magic-link (passwordless email) and/or accounts, proper sessions, password
|
||||
reset, and likely auth for the *internal* app too. Reverse-proxy + TLS posture.
|
||||
|
||||
## Going to prod (M1)
|
||||
|
||||
1. **Run the migration on the prod DB** — `migrate_add_client_portal.py` adds
|
||||
`projects.client_id` (the new tables auto-create via `create_all`). Skipping it
|
||||
500s anything that touches `Project.client_id`. This is the silent killer.
|
||||
```bash
|
||||
docker compose exec web-app python3 backend/migrate_add_client_portal.py
|
||||
```
|
||||
2. **Set a real `SECRET_KEY`** in the prod env (compose). The portal signs session
|
||||
cookies with it; the insecure dev default (it logs a warning at boot) is
|
||||
forgeable. Non-negotiable for an internet-facing portal.
|
||||
3. **SLMM_BASE_URL** — prod base compose already points at `:8100` (correct; the
|
||||
`:9100` mismatch is a dev-only override quirk). For full live data (L1/L10 +
|
||||
chart backfill) prod SLMM must be on the `dev` build with its migrations
|
||||
(`migrate_add_ln_percentiles`, `migrate_add_monitor_enabled`) and **keepalive on**
|
||||
for the client's units — otherwise the portal degrades gracefully (cards show
|
||||
`--`, chart empty), it just isn't fully populated.
|
||||
4. **Seed real clients** with the CLI (`backend/portal_admin.py`): `create-client`
|
||||
→ `link-project` (a real sound project with an active SLM assignment) →
|
||||
`mint-link` → send the client the printed URL (shown once).
|
||||
5. **Exposure** — portal routes are auth-gated, but port 8001 still serves the
|
||||
whole *internal* app with no auth. Before real clients are on it, the portal
|
||||
should sit behind the reverse proxy with only `/portal/*` exposed (or the app
|
||||
restricted). This is the point where the parked reverse-proxy/TLS work becomes
|
||||
load-bearing.
|
||||
|
||||
## Security notes
|
||||
|
||||
- Portal is auth-gated from day one (even the interim gate) — never wide-open like
|
||||
|
||||
Reference in New Issue
Block a user