Verifies the actual branch HEAD against the deployed Unraid revision (they match) and corrects a one-commit-behind final-commit hash in artifacts/demo-release/final-summary.md (its own "record the hash" follow-up commit couldn't self-reference). Catalogues remaining MobilityOps/PoC mentions (including in knowledge-base procedure prose that gets quoted in answers), confirms no i18n exists, documents the Demo Guide's single-behaviour-at-all-desktop-widths gap, the inconsistent radio-vs-card decision styling in Data Quality, automation/ audit density, and exactly which dashboard rows aren't fully clickable. Notes the repository's primary branch is `master`, not `main`.
196 lines
11 KiB
Markdown
196 lines
11 KiB
Markdown
# Demo-productization final summary
|
||
|
||
## Branches and commits
|
||
|
||
- **Gitea repository**: `ssh://git@192.168.10.150:222/Jens/MobilityOps.git` (browsable at
|
||
`http://192.168.10.150:3000/Jens/MobilityOps`)
|
||
- **Branch**: `feat/mobilityops-functional-completion` (no new branch created; no merge
|
||
to `main`; no rebase/reset/squash/force-push; full git history preserved, as required)
|
||
- **Start commit** (functional-completion baseline, already accepted):
|
||
`e0c7ed60112510687627d20a957af91c8b9db7f8`
|
||
- **Final commit**: `4a268c73515dc4f1d56c1aa2f231714654bffbb8` — verified via
|
||
`git rev-parse HEAD` on `feat/mobilityops-functional-completion` and confirmed to match
|
||
`/mnt/user/appdata/mobilityops/.deploy/source-revision` on the Unraid server exactly.
|
||
(This corrects a self-reference gap in the immediately preceding pair of commits, which
|
||
necessarily could not know their own hash at the time they were written; this is now
|
||
the single, unambiguous, verified reference. The repository's primary branch is
|
||
`master`, not `main` — no branch named `main` exists in this repository.)
|
||
- **Live URL**: `http://192.168.10.150:1236`
|
||
|
||
## Demo organisation and context
|
||
|
||
**Northstar Mobility** — a fictitious Belgian camper/van rental company (~50 vehicles,
|
||
one main location, rental team, an Operations Manager, a small workshop). This name was
|
||
already a locked internal decision (`ragcore_tenant: northstar-mobility-demo`,
|
||
`PROJECT_STATE.md`'s "Locked decisions") before this work — this pass surfaces it in the
|
||
UI rather than inventing it. Full concept: `docs/demo-release/demo-concept.md`.
|
||
|
||
## Roles
|
||
|
||
- **Operations Manager** — full access: data-quality resolution, workflow retries, audit
|
||
trail, demo reset, the Demo Guide.
|
||
- **Rental Employee** — scoped access: bookings, returns, fleet, knowledge assistant.
|
||
|
||
Both are reachable from the login screen with no password.
|
||
|
||
## Demo Guide
|
||
|
||
An 8-step, sessionStorage-persisted guided tour (Operations-Manager-only, since every
|
||
step requires that role). Full design: `docs/demo-release/demo-guide.md`. Steps: (1)
|
||
understand operational state, (2) open the booking needing attention, (3) process the
|
||
odometer-anomaly return, (4) handle the created data-quality issue, (5) merge the
|
||
duplicate customer, (6) ask the knowledge assistant, (7) check automation + audit, (8)
|
||
review real vs. synthetic vs. not-connected.
|
||
|
||
## Scenarios (all 5, full detail in `docs/demo-release/demo-scenarios.md`)
|
||
|
||
| # | Scenario | Fixed records | Role |
|
||
|---|---|---|---|
|
||
| 1 | Odometer regression on return | `BK-DEMO-RETURN` / `MO-024` | Either |
|
||
| 2 | Possible duplicate customer | `CUS-0012` / `CUS-0178` / `DQ-DEMO-DUPLICATE` | OM |
|
||
| 3 | Overlapping bookings | `MO-016` / `BK-DEMO-OVERLAP-A/B` / `DQ-DEMO-OVERLAP` | OM |
|
||
| 4 | Failed automation, retried | outbox event `...020` / `BK-H-0020` | OM |
|
||
| 5 | Grounded procedure question | (no fixed record; suggested questions) | Either |
|
||
|
||
`GET /api/v1/demo/manifest`'s `scenarios` array derives `ready`/`blocked_reason` from the
|
||
live underlying records, never hardcoded — confirmed via `backend/tests/
|
||
test_demo_manifest.py` (`test_demo_manifest_scenarios_ready_after_fresh_reset`) and
|
||
live-checked after every reset throughout this work.
|
||
|
||
## Seed strategy and date-anchoring
|
||
|
||
`seed/generate_seed.py --anchor 2026-08-01 --seed 20260801` produces deterministic CSVs
|
||
with absolute timestamps authored against a fixed anchor. `backend/app/seed_loader.py`
|
||
shifts every seeded datetime by `(real today − authored anchor)` on every seed/reset, so
|
||
"today"/"near-future"/"currently overlapping" scenarios stay true to the actual reset
|
||
moment instead of decaying. This fixed a real, confirmed bug (`BK-DEMO-RETURN` was found
|
||
sitting 2 days in the past before this fix). Full detail: `docs/demo-release/demo-data.md`.
|
||
|
||
## Reset strategy
|
||
|
||
`POST /api/v1/demo/reset` (Operations Manager only, gated by `DEMO_ALLOW_RESET`) clears
|
||
MobilityOps's own tables, reseeds with a fresh date anchor, re-runs the data-quality scan,
|
||
and runs a server-side scenario-integrity check (`scenario_integrity_report()`) recorded
|
||
in both the response and the `demo_reset` audit event. Reachable from the sidebar, the
|
||
Demo Guide, and the About page. Never touches shared n8n/RAGcore/MCP data, other
|
||
containers, or volumes.
|
||
|
||
## Real vs. synthetic vs. not-connected
|
||
|
||
See `docs/demo-release/demo-concept.md` for the full breakdown. In short: auth/roles,
|
||
vehicle/booking management, return preview/commit, the 5 data-quality rules and their
|
||
resolutions, the audit trail, n8n orchestration, Docker deployment, and the automated
|
||
test suite are all really implemented. The organisation, all people, vehicles, bookings,
|
||
procedures, and the 5 named scenarios are synthetic. RAGcore and the ITWorx MCP Hub are
|
||
not live-connected (honestly labelled "Demomodus"/"Niet gekoppeld" everywhere, never a
|
||
fabricated success).
|
||
|
||
## Test results
|
||
|
||
### Backend (clean checkout, isolated stack)
|
||
- `pytest`: **127 passed**
|
||
- `ruff check .`: clean
|
||
- `mypy app`: clean (48 source files)
|
||
|
||
### Frontend (clean checkout, isolated stack)
|
||
- `npm ci`: clean (pre-existing esbuild-moderate/react-router-RSC-high advisories,
|
||
unchanged from before this work — not introduced by it)
|
||
- `tsc -b`: clean
|
||
- `npm run build`: clean
|
||
- Full Playwright suite: **56 passed** (against the isolated clean-checkout stack)
|
||
|
||
### Guided-demo test
|
||
`frontend/e2e/guided-demo-full.spec.ts` — one comprehensive test walking a fresh
|
||
Operations Manager session through all 8 Demo Guide steps performing the real action at
|
||
each step (processes the actual odometer-anomaly return, resolves the resulting
|
||
data-quality issue, merges the duplicate customer, asks a suggested knowledge question,
|
||
checks automation + audit, reviews the About page), then resets the demo data again to
|
||
restore the environment. **Passed**, confirmed stable across repeated runs both locally
|
||
and against the live Unraid deployment.
|
||
|
||
### Clean-checkout drill
|
||
Fresh `git clone` of this branch/commit into an isolated scratch directory, `.env` from
|
||
`.env.example`, isolated Compose project name (`mobilityops-cleandrill`) and remapped
|
||
host ports (`compose.override.yaml` with `!override` merge tags — no shared state with
|
||
any other stack), `docker compose up --build -d` from empty volumes → migrations ran
|
||
automatically (`e7b08389f47f (head)`) → seeded → full backend gate (127 passed, ruff/
|
||
mypy clean) → `npm ci`/`tsc -b`/`vite build` clean → full Playwright suite (56 passed)
|
||
→ reseeded and confirmed all 5 scenarios `ready: true` via the manifest → torn down
|
||
(`docker compose down -v` on the isolated project only; the working dev stack was never
|
||
touched).
|
||
|
||
### Server deployment
|
||
Deployed incrementally after every batch (10 deploy cycles across this work); final
|
||
state: both `api` and `web` rebuilt and healthy at the final commit, `db` untouched
|
||
across all of them (no destructive migrations on this branch). Migrations at
|
||
`e7b08389f47f (head)` throughout. `.deploy/source-revision` on the server matches the
|
||
final commit exactly.
|
||
|
||
### Container health
|
||
`docker compose ps` on the server: `api`, `db`, `web` all `healthy`, no restart loops.
|
||
|
||
### Browser console / network
|
||
No unexpected console errors on login, dashboard, scenarios, About, or with the Demo
|
||
Guide open (verified via `demo-accessibility.spec.ts`; the one benign 401 from the app's
|
||
own session-probe on first load is expected and explicitly accounted for, not silenced
|
||
blindly). No unresolved server errors in `docker logs` for `api`/`web` at the time of
|
||
this evidence capture.
|
||
|
||
### Responsive / accessibility
|
||
- Demo Guide renders as a correctly-anchored bottom sheet at 390px with no horizontal
|
||
overflow (`demo-accessibility.spec.ts`).
|
||
- **Real bug found and fixed**: the Demo Guide's fixed desktop side panel overlapped
|
||
main content with no reflow, making the return form's "Review return" button
|
||
unclickable while the guide was open at ordinary desktop widths — this surfaced while
|
||
writing the full guided-demo test. Fixed via a `guide-open` layout class that reserves
|
||
space for the panel; regression-tested.
|
||
- Demo badge and Demo Guide triggers are keyboard-focusable and operable (Enter to open,
|
||
explicit close controls).
|
||
- Existing responsive-overflow checks (390/768/1280/1440px) remain green throughout.
|
||
|
||
## Known limitations
|
||
|
||
- RAGcore and the ITWorx MCP Hub are not live-connected in this environment (by design
|
||
— see scope). The knowledge assistant uses a local, English-only demo knowledge base;
|
||
a Dutch question against it returns "insufficient evidence" (verified empirically), so
|
||
suggested questions and the Demo Guide's step 6 instructions deliberately stay in
|
||
English rather than silently breaking the demo's centerpiece grounded-answer feature.
|
||
- Existing operational screens (Dashboard, Vehicles, Bookings, Data Quality workbench,
|
||
Audit, Automation internals) remain in English; only new demo-productization surfaces
|
||
(login, Demo Guide, scenario overview, About page, demo badge, plain-language
|
||
integration labels) are in Dutch — a deliberate, documented scope decision, not an
|
||
oversight (`docs/demo-release/current-demo-gap-audit.md`, gap #11).
|
||
- Scenario S3 ("missing inspection before next booking", `MO-031`) is seeded and visible
|
||
in the attention queue but isn't one of the 5 scenarios surfaced on `/scenarios`,
|
||
matching the brief's request for exactly 5.
|
||
|
||
## 5-minute and 10-minute demo flows
|
||
|
||
See `docs/demo-release/demo-runbook.md` for the exact click-through scripts.
|
||
|
||
## Redeploy commands and rollback procedure
|
||
|
||
See `docs/demo-release/demo-runbook.md` — `git archive` → `scp` → extract → rebuild
|
||
`api`/`web` → confirm migrations → reseed. Rollback: extract an earlier
|
||
`.deploy/source-<short-sha>.tar.gz` and update `.deploy/source-revision` to match.
|
||
|
||
## Evidence screenshots
|
||
|
||
All captured live against `http://192.168.10.150:1236` (`artifacts/demo-release/screenshots/`):
|
||
|
||
1. `01-demo-entry-desktop.png` / `02-demo-entry-mobile.png` — demo entry, both sizes
|
||
2. `03-dashboard-with-scenarios.png` — dashboard with the scenario teaser panel
|
||
3. `04-demo-guide.png` — the Demo Guide panel open
|
||
4. `05-return-preview.png` / `06-return-result.png` — the return flow
|
||
5. `07-data-quality-resolution.png` — a data-quality issue with its plain-language explainer
|
||
6. `08-duplicate-customer-merge.png` — the duplicate-customer comparison/merge UI
|
||
7. `09-knowledge-assistant.png` — a grounded answer with cited sources
|
||
8. `10-integration-status.png` — plain-language integration status on Automation
|
||
9. `11-automation-retry-before.png` / `11-automation-retry-after.png` — a workflow retry
|
||
10. `12-audit-trail.png` / `13-audit-related-events.png` — audit trail + correlation drill-down
|
||
11. `14-about-demo.png` — the About page
|
||
12. `15-demo-badge-popover.png` — the permanent synthetic-demo badge popover
|
||
13. `16-reset-confirm.png` — the reset confirmation flow
|
||
|
||
No secrets appear in any screenshot or in this document.
|