# Demo runbook ## Starting the demo (any environment) Open the deployed URL (Unraid review: `http://192.168.10.150:1236`; local: `http://localhost:1228`). The login screen names the fictional organisation, states that all data is synthetic and all workflows are really implemented, and offers: - **Start begeleide demo** — logs in as Operations Manager and opens the Demo Guide at step 1. - **Verken als Operations Manager** / **Verken als Rental Employee** — free exploration, no guide. No password is shown or required for either path. ## Five-minute demo (guided) 1. Click **Start begeleide demo**. 2. Follow steps 1–3: dashboard → the booking needing attention → confirm the pre-filled odometer-anomaly return. 3. Step 4: resolve the data-quality issue the return just created (any decision is fine for a quick pass — "Retain canonical" is the fastest). 4. Step 6: ask a suggested knowledge question and show the cited source. 5. Step 7: show the automation/audit trail link-through. 6. Close with step 8, the About page's honest real/synthetic/not-connected breakdown. ## Ten-minute demo (guided + one extra scenario) Do the five-minute path above, then from `/scenarios`: - Run **scenario 2** (duplicate customer merge) if not already done via the guide's own step 5. - Run **scenario 3** (booking overlap) — `/data-quality`, resolve `DQ-DEMO-OVERLAP`. - Run **scenario 4** (failed automation retry) — `/automation`, filter to failed, retry. All five scenarios can be run in any order and are independent of each other. ## Resetting the environment Any Operations Manager can reset from: the sidebar ("Reset demo data"), the Demo Guide panel ("Demo opnieuw voorbereiden"), or the About page (points to the sidebar control). Reset requires confirmation, rebuilds the deterministic dataset with a fresh date anchor, runs a server-side scenario-integrity check, and signs the acting session out (the server invalidates the session as part of reset). It only ever touches MobilityOps's own tables — never shared n8n, RAGcore, or MCP data, other containers, or volumes. It can be disabled entirely via `DEMO_ALLOW_RESET=false` if an environment must not be rebuildable. ## Redeploying to Unraid ```bash # From a clean local checkout on the target branch/commit: git archive --format=tar.gz -o /tmp/mobilityops-source.tar.gz HEAD scp /tmp/mobilityops-source.tar.gz unraid:/mnt/user/appdata/mobilityops/.deploy/source-.tar.gz ssh unraid "cd /mnt/user/appdata/mobilityops \ && tar -xzf .deploy/source-.tar.gz \ && echo > .deploy/source-revision" # Rebuild only what changed (api and/or web); db is never rebuilt: ssh unraid "cd /mnt/user/appdata/mobilityops \ && docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml up --build -d api web" # Confirm migrations and reseed: ssh unraid "cd /mnt/user/appdata/mobilityops \ && docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml exec -T api python -m alembic current \ && docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml exec -T api python -m app.cli seed --reset" ``` Extraction preserves the server's existing `.env` and named volumes (Postgres data, n8n data) — the tarball never contains `.env` since it's gitignored. Never edit source directly on the server; never deploy uncommitted changes. ## Rollback `.deploy/source-revision` on the server records exactly which commit is live. Prior source tarballs remain in `.deploy/` for rollback: extract an earlier `source-.tar.gz`, update `source-revision` to match, and re-run the rebuild step above. Database rollback is out of scope for this demo (migrations are additive; there has been no destructive migration on this branch). ## Server safety (Unraid) Only touch the `mobilityops` Compose project's own `api`/`web` services (and `db` only via migrations, never manually). Never stop other containers, run `docker system prune`, delete unrecognised images/networks/volumes, delete the MobilityOps database, overwrite the server `.env`, print secrets, start a second permanent n8n instance, or activate guessed RAGcore/MCP URLs. PostgreSQL is never exposed externally. ## Troubleshooting - **A scenario shows "Niet beschikbaar" on `/scenarios`**: it has already been resolved since the last reset (expected once you've worked through it) — reset to restore it. - **Knowledge question returns "insufficient evidence"**: check the question is in English and close to one of the suggested phrasings — the demo knowledge base is English-only (see `demo-guide.md`). - **n8n shows a failed delivery that isn't the seeded demo one**: check `/automation`'s filter and retry — bounded retries mean it should self-heal within `n8n_max_attempts` attempts, or can be retried manually by an Operations Manager.