Files
MobilityOps/docs/final-product-polish/audit.md
T
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

174 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`, 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:24``ORGANIZATION_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`.