Files
NuklearRabbit 38f654b97a docs(demo): add demo concept, scenarios, data, guide and runbook docs
Documents the demo-productization work from this branch: the Northstar
Mobility fictional concept and scope, the five named scenarios and their
fixed records, the seed/date-anchoring strategy (including the real bug
it fixed), the in-app Demo Guide's design and the English-suggested-
questions decision, and an operational runbook covering 5/10-minute demo
flows, reset, Unraid redeploy and rollback. Updates README with current
test counts and pointers to the new docs.
2026-08-03 15:24:35 +02:00

4.2 KiB

Demo data strategy

Three separate concepts

It's important to keep these distinct — they solve different problems:

  1. Deterministic records — every seeded entity has a stable public reference (BK-DEMO-RETURN, DQ-DEMO-DUPLICATE, MO-024, CUS-0012, ...). These references never change between seed generations or resets; they are what the five demo scenarios, the Demo Guide, and docs/13-seed-and-demo-scenarios.md all link against.
  2. Date anchoring — the mechanism that keeps "today"/"near-future"/"currently overlapping" scenarios true to whenever the environment was actually last reset, described below.
  3. The reset date — the real wall-clock moment a reset actually happened. This changes every time someone resets; it's the input to date anchoring, not a fixed record.

Generating the seed dataset

python seed/generate_seed.py --anchor 2026-08-01 --seed 20260801

This produces the committed CSVs in seed/*.csv with absolute ISO timestamps authored relative to a fixed anchor date (2026-08-01). Target scale: 50 vehicles, 180 customers (including three duplicate pairs), ~245 historical/current/future bookings, realistic inspections and maintenance history, and the fixed quality/workflow scenarios described in demo-scenarios.md. Names, towns and vehicle makes are drawn from believable Flemish/Kempen-region pools; all emails use the .test domain.

Date anchoring

backend/app/seed_loader.py defines:

SEED_AUTHORED_ANCHOR = date(2026, 8, 1)  # matches generate_seed.py's --anchor

Every seed/reset computes shift = today - SEED_AUTHORED_ANCHOR and applies it to every seeded booking, inspection, maintenance and outbox timestamp before insertion. Public references and entity relationships are never touched by the shift — only datetime columns move. This means:

  • BK-DEMO-RETURN always ends "today" (or very close to it) relative to whenever you actually reset, not relative to the frozen 2026-08-01 authoring date.
  • BK-DEMO-NEXT and the overlap-scenario bookings always read as "near future".
  • The shift is recomputed fresh on every reset, so scenarios never decay as real time passes between resets — this was a real, confirmed bug before this fix (see docs/demo-release/current-demo-gap-audit.md, gap #3): the environment would drift further out of sync with every day it wasn't reset, and a reset didn't fix it because nothing re-anchored the underlying stored dates.

load_seed() returns the resolved anchor_date (real today) and seeded_at timestamp, and records a demo_data_seeded audit event carrying both the resolved anchor and the original authoring anchor, so the shift applied on any given reset stays traceable via the audit trail.

dashboard.py::_today() uses real wall-clock UTC date (not a frozen setting) to filter "today's movements", consistent with the shifted data.

Reset

POST /api/v1/demo/reset (Operations Manager only, and only if DEMO_ALLOW_RESET=true) clears all MobilityOps tables, reloads the seed with a fresh date shift, re-runs the data-quality scan, and runs a server-side scenario-integrity check (scenario_integrity_report() in backend/app/services/demo_manifest.py) confirming all five named scenarios are actually present and ready — recorded in both the response body and the demo_reset audit event's metadata. Reset only ever affects MobilityOps's own tables; it never touches shared n8n, RAGcore, or MCP data, other containers, or volumes.

Seed-validation tests

backend/tests/test_seed.py proves, after every reset:

  • S1 (BK-DEMO-RETURN/MO-024) is active with no end odometer recorded yet.
  • S2 (CUS-0012/CUS-0178/DQ-DEMO-DUPLICATE) is open with matching evidence.
  • S4 (MO-016/BK-DEMO-OVERLAP-A/-B/DQ-DEMO-OVERLAP) genuinely overlaps in time.
  • S5 (the seeded failed outbox event) is durably failed immediately after reset, not silently auto-healed by the background dispatcher (which only claims pending rows).
  • The date-anchoring shift and the demo_data_seeded audit marker are both correct.

backend/tests/test_demo_manifest.py additionally proves that all five manifest scenarios report ready: true with no blocked_reason right after a fresh reset.