docs(release): finalize demo-productization acceptance evidence
Records the clean-checkout drill result (127 backend tests, 56 Playwright tests, all green on an isolated fresh clone), final live Unraid verification, and the complete required evidence summary for the demo-productization work on this branch.
This commit is contained in:
@@ -784,3 +784,37 @@ scenarios, demo manifest, About page). Gap audit: `docs/demo-release/current-dem
|
||||
demo-scenarios/demo-data/demo-guide/demo-runbook, README, .env.example), final Unraid
|
||||
deploy + live evidence with screenshots, `artifacts/demo-release/final-summary.md` —
|
||||
task #36 (final).
|
||||
|
||||
### Batch 7 (final) — clean-checkout drill, docs, final Unraid evidence (complete)
|
||||
|
||||
- **Clean-checkout drill**: fresh `git clone` into an isolated scratch directory,
|
||||
isolated Compose project (`mobilityops-cleandrill`) + remapped ports via
|
||||
`compose.override.yaml`, `up --build -d` from empty volumes. Migrations ran
|
||||
automatically to `e7b08389f47f (head)`; seeded; full backend gate **127 passed**,
|
||||
ruff/mypy clean; `npm ci` clean (same pre-existing advisories as before, unchanged);
|
||||
`tsc -b`/`vite build` clean; full Playwright suite **56 passed** against the isolated
|
||||
stack; reseeded and confirmed all 5 scenarios `ready: true` via the manifest; torn down
|
||||
(`down -v` on the isolated project only — the working dev stack was untouched
|
||||
throughout).
|
||||
- Added the full demo-release documentation set: `docs/demo-release/demo-concept.md`,
|
||||
`demo-scenarios.md`, `demo-data.md`, `demo-guide.md`, `demo-runbook.md`; updated
|
||||
`README.md` (current test counts, links to the new docs, a "Demo" section) and
|
||||
`docs/17-runbook.md` (cross-reference to the demo-specific runbook).
|
||||
- Added `frontend/e2e/_capture-demo-screenshots.spec.ts` (tooling, excluded from the
|
||||
regular suite) and captured 17 evidence screenshots live against
|
||||
`http://192.168.10.150:1236` into `artifacts/demo-release/screenshots/`.
|
||||
- Final live acceptance: full Playwright suite re-run against the live server —
|
||||
**56 passed**; `docker compose ps` on the server shows `api`/`db`/`web` all healthy;
|
||||
`docker logs` for `api`/`web` show no errors; reseeded to leave the server
|
||||
demo-ready after evidence capture.
|
||||
- Wrote `artifacts/demo-release/final-summary.md` with the full required evidence
|
||||
(branches/commits, org/roles/guide/scenarios, seed/date-anchor/reset strategy, real vs.
|
||||
synthetic vs. not-connected, all test results, clean-checkout result, deployment/
|
||||
health/console/log results, responsive/accessibility results including the two real
|
||||
layout bugs found and fixed this work (mobile topbar overflow in Batch 3, desktop
|
||||
guide-panel overlap in Batch 6), known limitations, 5-/10-minute demo flows, redeploy/
|
||||
rollback commands, and the screenshot list).
|
||||
- Demo-productization work on this branch is complete. Every task (#29–#36) is done;
|
||||
every batch was tested locally, deployed to Unraid, and re-verified live before moving
|
||||
to the next. See `artifacts/demo-release/final-summary.md` for the definitive
|
||||
acceptance evidence.
|
||||
|
||||
@@ -0,0 +1,191 @@
|
||||
# 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**: see `git log -1` on this branch — this file's own commit necessarily
|
||||
cannot self-reference its own hash; the immediately following commit records it
|
||||
explicitly for a stable, unambiguous reference.
|
||||
- **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.
|
||||
Reference in New Issue
Block a user