diff --git a/docs/demo-release/demo-runbook.md b/docs/demo-release/demo-runbook.md index ec3f82b..d1cfd33 100644 --- a/docs/demo-release/demo-runbook.md +++ b/docs/demo-release/demo-runbook.md @@ -1,88 +1,64 @@ # Demo runbook -## Starting the demo (any environment) +## Starting the demo -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: +Open the configured deployment URL, for example `https://fleetops.example.com`, or `http://localhost:1228` for local development. The login screen names the fictional organisation, states that all data is synthetic 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. +- **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 without the guide. -No password is shown or required for either path. +No password is shown or required for either synthetic-demo path. -## Five-minute demo (guided) +## Five-minute demo 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. +2. Follow steps 1–3: dashboard, booking needing attention, and the pre-filled odometer-anomaly return. +3. Resolve the data-quality issue created by the return. “Retain canonical” is the fastest demonstration path. +4. Ask a suggested knowledge question and show the cited source. +5. Show the automation/audit-trail link-through. +6. Close with the About page’s real/synthetic/not-connected breakdown. -## Ten-minute demo (guided + one extra scenario) +## Ten-minute demo -Do the five-minute path above, then from `/scenarios`: +Complete the five-minute path, then use `/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. +- scenario 2: duplicate customer merge; +- scenario 3: booking overlap, resolved through `/data-quality`; +- scenario 4: failed automation retry through `/automation`. -All five scenarios can be run in any order and are independent of each other. +All scenarios are deterministic and independent after a reset. ## 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. +An Operations Manager can reset from the sidebar, Demo Guide or About page. Reset requires confirmation, rebuilds only the deterministic MobilityOps dataset, runs a server-side integrity check and invalidates the acting session. It never mutates shared n8n, RAGcore, MCP data, unrelated containers or volumes. Disable reset entirely with `DEMO_ALLOW_RESET=false` where required. -## Redeploying to Unraid +## Deployment contract -```bash -# From a clean local checkout on the exact commit: -git archive --format=tar.gz -o /tmp/mobilityops-source.tar.gz HEAD -sha256sum /tmp/mobilityops-source.tar.gz -scp /tmp/mobilityops-source.tar.gz unraid:/mnt/user/appdata/mobilityops/.deploy/ -ssh unraid "/mnt/user/appdata/mobilityops/deploy/unraid/deploy-release.sh \ - /mnt/user/appdata/mobilityops/.deploy/mobilityops-source.tar.gz \ - " -``` +Create a source archive from the exact reviewed commit, record its SHA-256 and full Git SHA, transfer it through the operator-approved channel, and invoke `deploy/unraid/deploy-release.sh` with those immutable identifiers. -The deployer verifies the archive checksum, extracts into a new commit-named release -directory, builds revision-labelled immutable images, promotes without reseeding, and -checks application, backup and observability health. Reset demo data only as a separate, -deliberate demo-preparation action. +Keep the following values in operator-local configuration rather than repository documentation: + +- deployment host or SSH alias; +- SSH key selection; +- persistent appdata directory; +- public application URL; +- n8n and RAGcore endpoints; +- tokens and callback secrets. + +An Unraid installation commonly uses a path such as `/mnt/user/appdata/mobilityops`, but that is an example only. See `deploy/unraid/README.md` for the parameterized deployment layout. + +The deployer verifies the archive checksum, extracts into a commit-named release directory, builds revision-labelled immutable images, promotes without reseeding and checks application, backup and observability health. Reset demo data only as a separate deliberate action. ## Rollback -`.deploy/source-revision` and `.deploy/release-history.log` record the live commit and -image tags. A failed readiness check automatically restores the previous image IDs. -Database rollback remains a separate, explicitly guarded restore operation. +`.deploy/source-revision` and `.deploy/release-history.log` record the live commit and image tags. A failed readiness check restores the previous image IDs. Database rollback remains a separate explicitly guarded restore operation. -## Server safety (Unraid) +## Server safety -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. +Only touch the `mobilityops` Compose project’s own `api` and `web` services, and interact with `db` only through migrations or the guarded backup/restore flow. Never stop unrelated containers, run broad Docker pruning, delete unrecognised resources, overwrite the server `.env`, print secrets, start a second permanent n8n instance or activate guessed integration URLs. PostgreSQL must remain unexposed. ## 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"**: use a suggested question in - NL, EN or FR and inspect provider health/citations; the adapter refuses ungrounded - answers when RAGcore is slow, unavailable or lacks evidence. -- **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. +- **Scenario unavailable:** it was already resolved since the last reset; reset the synthetic dataset. +- **Knowledge question returns insufficient evidence:** use a suggested question and inspect provider health/citations; the adapter refuses ungrounded answers. +- **Unexpected failed n8n delivery:** use the automation view and bounded retry path; inspect operator-side n8n logs without committing them.