Files
NuklearRabbit 257a4cf6c0 docs(polish): audit finale demo-afwerking
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`.
2026-08-03 15:58:48 +02:00

11 KiB
Raw Permalink Blame History

Final product polish — audit

Performed 2026-08-03 against feat/mobilityops-functional-completion.

Commit state

  • Local/branch HEAD: 4a268c73515dc4f1d56c1aa2f231714654bffbb8
  • Deployed on Unraid (/mnt/user/appdata/mobilityops/.deploy/source-revision): 4a268c73515dc4f1d56c1aa2f231714654bffbb8matches exactly, no drift.
  • Repository's primary branch is master, not main — no branch named main exists (git branch -a / git remote show confirm only master, design/mobilityops-premium-ui, and feat/mobilityops-functional-completion). origin/master = local master = e0c7ed60112510687627d20a957af91c8b9db7f8, unchanged since the functional-completion baseline — this is the baseline to compare against before any future merge.
  • Evidence-file mismatch found and corrected: artifacts/demo-release/final-summary.md recorded final commit 294a8176d19... (one commit behind actual HEAD, because its own "record the hash" follow-up commit necessarily couldn't self-reference). Corrected to the verified, unambiguous 4a268c73515dc4f1d56c1aa2f231714654bffbb8, cross-checked against both git rev-parse HEAD and the server's source-revision.
  • Containers on Unraid: api/db/web all healthy; migrations at e7b08389f47f (head).

Remaining "MobilityOps" mentions (user-facing)

  • frontend/index.html:7<title>MobilityOps</title>; :6 meta description.
  • frontend/src/components/Layout.tsx:178 — sidebar brand lockup <strong>MobilityOps</strong>.
  • frontend/src/components/Layout.tsx:232 — global search aria-label/visually-hidden label "Search MobilityOps".
  • frontend/src/components/Layout.tsx:299 — footer <span>MobilityOps PoC</span> (also the "PoC" mention to remove).
  • frontend/src/pages/Login.tsx:27 — the manifest-fallback org description string.
  • frontend/src/pages/AboutDemo.tsx:32,63,71 — page heading and two body paragraphs.
  • frontend/src/pages/Knowledge.tsx:108 — empty-state copy.
  • frontend/src/pages/BookingDetail.tsx:80 — scenario callout copy.
  • frontend/src/data/demoGuideSteps.ts:91 — step 8's expected-outcome text.
  • backend/app/services/demo_manifest.py:24ORGANIZATION_DESCRIPTION (the string Login.tsx:27 falls back to when the manifest hasn't loaded yet — both need updating together to avoid a flash of stale branding).
  • backend/app/main.py:36 — FastAPI title="MobilityOps API" (visible in the OpenAPI/ Swagger UI a reviewer might open; low-risk to rename since it's a display string, not a route or contract field).
  • knowledge/procedures/*.md — user-facing, appears directly in cited answer text: 02-vehicle-return.md, 03-damage-handling.md (also says "PoC"), 05-cleaning- checklist.md, 07-customer-documents.md (also says "PoC"), 09-booking-conflicts.md all say "MobilityOps" in prose that gets quoted verbatim as a knowledge-assistant answer excerpt — these must be rebranded too, not just the app chrome.
  • e2e tests asserting on the string "MobilityOps" that must be updated alongside the rename (not gaps, just dependencies): demo-accessibility.spec.ts, demo-entry.spec.ts, guided-demo-full.spec.ts (About-page heading), ui-redesign.spec.ts (4× "Search MobilityOps" combobox name).

Kept as technical identifiers (per the brief, not renamed): Git repo Jens/MobilityOps, local repo folder name, Compose project mobilityops, deployment dir /mnt/user/appdata/mobilityops, Postgres db/user mobilityops, knowledge/manifest.json's "workspace": "mobilityops" (a RAGcore-workspace config value), frontend package name mobilityops-web, and the internal API route prefix conventions.

Language problems (no i18n exists at all)

  • frontend/package.json has no i18n library (i18next/react-i18next/etc. absent).
  • There is no language switcher anywhere and no persisted language preference.
  • The existing UI mixes English (Dashboard, Vehicles, Bookings, Data Quality workbench, Audit, Automation internals — all shipped in Task-B's demo-productization pass) and Dutch (Login, Demo Guide, Scenarios, About, demo badge — added in the same pass) by a documented, deliberate scope decision at the time. That decision must now be superseded: the brief requires one true default (nl-BE) with working en-GB/fr-BE switching across the entire application, so the English-language existing screens are now in scope for translation, not just new surfaces.
  • The demo knowledge base (knowledge/procedures/*.md) is English-only; a Dutch or French question against it returns insufficient evidence (verified empirically in the prior work) — this is a real gap for the trilingual guided demo requirement.

Remaining technical user-facing language

  • frontend/src/pages/Automation.tsx:183{r.event_type} rendered raw (e.g. vehicle.returned.v1) in the primary ledger table, no human label.
  • frontend/src/pages/Automation.tsx:91 — "delivered through the outbox" in primary copy.
  • frontend/src/pages/Audit.tsx:129{e.correlation_id.slice(0, 8)} shown as the visible <summary> trigger text for technical detail, not a meaningful reference.
  • frontend/src/pages/DataQualityIssueDetail.tsx:341,366 — "canonical odometer" used directly in primary decision copy, not translated to an operational phrase.
  • No central technical→human terminology mapping exists anywhere in the frontend.

Demo Guide panel problems

  • frontend/src/components/DemoGuide.tsx + the @media (min-width: 701px) rule in styles.css implement exactly one behaviour for every desktop/tablet width ≥701px: a fixed 400px right-side panel with .app-workspace.guide-open { padding-right: min(400px, 92vw) } reserving space. There is no distinction between "extra-wide desktop, dock + reflow with a guaranteed minimum content width" and "standard desktop/ tablet, floating non-modal sheet that auto-collapses to a progress chip" as the brief now requires — today the panel never collapses to a chip at all; it only fully opens or fully closes.
  • "Ga naar deze stap" (DemoGuide.tsx's goToStepRoute()) only calls navigate(...); it does not scroll to or focus the relevant target element, and does not auto-collapse the panel afterward.
  • No semantic target anchors exist on pages for the guide to scroll/focus toward.
  • Reduced-motion is not explicitly handled for the panel's open/close or any future collapse/expand transition.

Data Quality Workbench contrast and hierarchy

  • Confirmed by direct inspection of DataQualityIssueDetail.tsx: only the odometer- regression decision (lines 349,358) uses the higher-contrast .check-card treatment (background: var(--surface-subtle); border: 1px solid var(--line); padding: 10px 12px). Every other decision point — DuplicateCustomerPanel's survivor choice (134,143) and per-field merge choice (172,187), and BookingOverlapPanel's block-choice (459) — uses the bare .checkbox-label class: a small inline radio with no card background, no border, no selected-state treatment, and no visible risk/consequence copy next to the option. This is the inconsistency the brief describes as "kleine losse radioknoppen in een zwak omlijnde rij."
  • Resolve/defer/reject already have some visual differentiation (button-primary for the main resolution action inside each panel; a separate "Defer or reject" section below), but defer and reject are rendered as two identically-weighted plain <button> elements with no secondary/tertiary visual distinction from each other.
  • No sticky/always-visible action bar exists within longer resolution panels.

Automation/audit density

  • frontend/src/pages/Automation.tsx's delivery ledger renders every one of the ~20 seeded succeeded events as an individual flat table row with only a status-text filter (pending/delivering/succeeded/failed) — no grouping/summarization of repeated successes, and event references are raw 8-character UUID slices with no meaningful short display reference scheme.
  • frontend/src/pages/Audit.tsx shows one row per raw audit event; my prior "View related events" filter (added in the demo-productization pass) lets a user filter down to a correlation group, but does not present that group as one collapsed operational summary by default — a visitor still sees N separate technical rows even after filtering.
  • Before/after is already shown as a computed diff string (describeChanges()), not raw JSON, which partially satisfies 8C already — but the diff is a flat semicolon-joined string, not the labelled multi-line "Status: A → B" presentation the brief shows.

Rows that are not fully clickable

  • Attention Queue (Dashboard.tsx:126-146, .attention-list li): only the <Link> wrapping the item's title text is interactive; the severity badge, detail text, ref, and chevron are inert. Confirmed by direct markup inspection.
  • Today's movements (Dashboard.tsx:153-161, .movement-timeline li): only the <Link> wrapping the booking reference is interactive; each row unambiguously points to one booking, so this qualifies for the same fully-clickable-row treatment.
  • Recent activity (Dashboard.tsx:220-224, .recent-list li): has no link at all today, and there is no existing single-record detail page for an individual automation event to point to — out of scope for "make it clickable" per the brief's own "alleen wanneer de volledige rij ondubbelzinnig naar één bestemming verwijst" carve-out; left as-is unless a natural destination is introduced elsewhere in this pass.
  • Scenario cards (Scenarios.tsx) already use a single full-card "Start scenario" link per card with no competing interactive elements inside — already compliant, no change needed.

Plan (implementation order)

  1. Rebrand to Fleet Ops (frontend strings, backend description strings, knowledge procedure prose, index.html, e2e assertions) — batch, tested, committed.
  2. i18n architecture: add i18next/react-i18next, language switcher, persistence, html lang, Intl formatting, namespaces, fail-fast missing-key check.
  3. Translate all existing screens + new demo surfaces into nl-BE/en-GB/fr-BE.
  4. Backend message-code fields for data-quality reasons/recommended actions/return reasons/integration statuses/audit actions/errors; frontend localizes.
  5. Multilingual knowledge base (5 procedures × 3 locales) + locale-aware provider lookup.
  6. Adaptive Demo Guide: docked-rail / floating-sheet+chip / mobile-bottom-sheet behaviour, scroll-to-target + focus + highlight, reduced motion.
  7. Data Quality Workbench: choice cards everywhere, sticky action bar, de-emphasized defer/reject, contrast fixes.
  8. Central terminology mapping layer (nl/en/fr) used in Automation/Audit/Data-Quality.
  9. Automation ledger grouping/filtering + retry UX narration.
  10. Audit trail human action labels + correlation-grouped summary + labelled diffs.
  11. Fully clickable Attention Queue + Today's movements rows, with tests.
  12. Responsive pass across the 7 required breakpoints × 3 languages.
  13. Full test suite additions (i18n, branding, guide, quality, queue, automation/audit, trilingual guided demo).
  14. Clean-checkout drill.
  15. Deploy feature branch to Unraid for final validation.
  16. Safe merge to master (the repository's actual main branch) + redeploy + final evidence at artifacts/fleet-ops-release/final-summary.md.