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`.
11 KiB
11 KiB
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):4a268c73515dc4f1d56c1aa2f231714654bffbb8— matches exactly, no drift. - Repository's primary branch is
master, notmain— no branch namedmainexists (git branch -a/git remote showconfirm onlymaster,design/mobilityops-premium-ui, andfeat/mobilityops-functional-completion).origin/master= localmaster=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.mdrecorded final commit294a8176d19...(one commit behind actual HEAD, because its own "record the hash" follow-up commit necessarily couldn't self-reference). Corrected to the verified, unambiguous4a268c73515dc4f1d56c1aa2f231714654bffbb8, cross-checked against bothgit rev-parse HEADand the server'ssource-revision. - Containers on Unraid:
api/db/weball healthy; migrations ate7b08389f47f (head).
Remaining "MobilityOps" mentions (user-facing)
frontend/index.html:7—<title>MobilityOps</title>;:6meta description.frontend/src/components/Layout.tsx:178— sidebar brand lockup<strong>MobilityOps</strong>.frontend/src/components/Layout.tsx:232— global searcharia-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:24—ORGANIZATION_DESCRIPTION(the stringLogin.tsx:27falls 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— FastAPItitle="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.mdall 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.jsonhas 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 returnsinsufficientevidence (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 instyles.cssimplement 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'sgoToStepRoute()) only callsnavigate(...); 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-cardtreatment (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), andBookingOverlapPanel's block-choice (459) — uses the bare.checkbox-labelclass: 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-primaryfor 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 seededsucceededevents 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.tsxshows 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)
- Rebrand to Fleet Ops (frontend strings, backend description strings, knowledge procedure prose, index.html, e2e assertions) — batch, tested, committed.
- i18n architecture: add
i18next/react-i18next, language switcher, persistence,html lang,Intlformatting, namespaces, fail-fast missing-key check. - Translate all existing screens + new demo surfaces into nl-BE/en-GB/fr-BE.
- Backend message-code fields for data-quality reasons/recommended actions/return reasons/integration statuses/audit actions/errors; frontend localizes.
- Multilingual knowledge base (5 procedures × 3 locales) + locale-aware provider lookup.
- Adaptive Demo Guide: docked-rail / floating-sheet+chip / mobile-bottom-sheet behaviour, scroll-to-target + focus + highlight, reduced motion.
- Data Quality Workbench: choice cards everywhere, sticky action bar, de-emphasized defer/reject, contrast fixes.
- Central terminology mapping layer (nl/en/fr) used in Automation/Audit/Data-Quality.
- Automation ledger grouping/filtering + retry UX narration.
- Audit trail human action labels + correlation-grouped summary + labelled diffs.
- Fully clickable Attention Queue + Today's movements rows, with tests.
- Responsive pass across the 7 required breakpoints × 3 languages.
- Full test suite additions (i18n, branding, guide, quality, queue, automation/audit, trilingual guided demo).
- Clean-checkout drill.
- Deploy feature branch to Unraid for final validation.
- Safe merge to
master(the repository's actual main branch) + redeploy + final evidence atartifacts/fleet-ops-release/final-summary.md.