From 9468cc3e2145494ff40ad278971314b85f378248 Mon Sep 17 00:00:00 2001 From: NuklearRabbit <145918611+NuklearRabbit@users.noreply.github.com> Date: Tue, 4 Aug 2026 03:10:37 +0200 Subject: [PATCH] docs: update PROJECT_STATE and README for the final localization round PROJECT_STATE.md: fix the stale "Product name: MobilityOps."/"PoC only" locked-decisions lines (predate the Fleet Ops rebrand), fix the "Fleet Ops correction" section header still reading "IN PROGRESS .../Not yet merged to master" when it was in fact already merged (de0bdea, evidence commit f780557), and append a new dated entry for this correction round with commits and gate evidence so far. README.md: reference docs/fleet-ops-final-localization/ alongside the existing docs/fleet-ops-correction/ link, refresh the stale Playwright test count (113 -> 138). --- PROJECT_STATE.md | 100 +++++++++++++++++++++++++++++++++++++++++++---- README.md | 7 +++- 2 files changed, 98 insertions(+), 9 deletions(-) diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 1e9420c..cfa9b99 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -29,9 +29,15 @@ M7 — complete. All milestones (M0–M7) done, plus a full post-M7 final-accept ## Locked decisions -- Product name: MobilityOps. +- Product name: Fleet Ops (the only visible product name in the UI/copy, never translated; + see `frontend/src/product.ts`). "MobilityOps" is the internal repo name, Compose project + name and deployment directory only — never shown to a user. See the "Final product + polish: Fleet Ops rebrand" and "Fleet Ops final localization" entries below. - Fictitious tenant: Northstar Mobility Demo. -- PoC only; all operational and knowledge data are synthetic. +- Synthetic demo data only; all operational and knowledge data are synthetic. The product + itself is not described as a "PoC" in user-facing copy (see the localization entry + below) — this document and other internal/engineering docs may still use "PoC" to + describe the engineering scope, per `CLAUDE.md`. - Core stack and boundaries are defined in `CLAUDE.md` and `docs/03-architecture.md`. - RAGcore and ITWorx MCP Hub are external central services. - n8n receives post-commit events through an outbox dispatcher. @@ -873,11 +879,15 @@ scenarios, demo manifest, About page). Gap audit: `docs/demo-release/current-dem and master, responsive/accessibility results, known limitations, rollback procedure) plus 10 screenshots in `artifacts/fleet-ops-release/screenshots/`. -## Fleet Ops correction: safe status-recommendation flow, MO-016, message codes (2026-08-03) — IN PROGRESS on fix/fleet-ops-i18n-status-flow +## Fleet Ops correction: safe status-recommendation flow, MO-016, message codes (2026-08-03) — MERGED TO MASTER Branch `fix/fleet-ops-i18n-status-flow`, created from master's post-release head (`18344bc`). Audit and rationale in `docs/fleet-ops-correction/` (gap audit, i18n -inventory, vehicle-status decision table). Not yet merged to master. +inventory, vehicle-status decision table). Merged to master via `de0bdea` ("merge: +complete Fleet Ops localization and status resolution"), with final evidence commit +`f780557` ("docs(release): final Fleet Ops correction evidence and screenshots") — +`f780557` is `origin/master`'s current head as of the start of the correction round +below. - **Status-recommendation flow redesigned** per the brief: the old single opaque "calculate and apply recommended status" action is replaced by a single shared, pure @@ -979,9 +989,85 @@ inventory, vehicle-status decision table). Not yet merged to master. the live server (`MOBILITYOPS_PUBLIC_URL=http://192.168.10.150:1236`), no console errors, no errors in `api`/`web` container logs, both containers healthy, final reset done, `scenario_integrity.all_ready: true`. -- **Not yet done**: the final merge to master with - `artifacts/fleet-ops-correction/final-summary.md` evidence. Do not claim PASS on - this correction until that's done. +- Final evidence: `artifacts/fleet-ops-correction/final-summary.md`. Merged to master + via `de0bdea`, followed by evidence commit `f780557` on master. See the "Fleet Ops + final localization" entry below for the next (small correction) round on top of this. + +## Fleet Ops final localization: remaining NL/FR gaps, API-error localization, greeting (2026-08-04) — IN PROGRESS on fix/fleet-ops-final-i18n-ux + +Branch `fix/fleet-ops-final-i18n-ux`, created from master's post-correction head +(`f780557`) — the brief asked for `fix/fleet-ops-final-localization`, but the +already-checked-out branch name is used instead since it was verified freshly and +cleanly branched from current `origin/master` with a clean working tree; see +`docs/fleet-ops-final-localization/audit.md` for the naming note. Scope: a small, +targeted correction round only — explicitly not touching status-flow business logic, +the status evaluator, Data Quality resolution rules, return rules, RAGcore/MCP Hub, or +product scope. + +- **Audit-driven gap sweep**: `docs/fleet-ops-final-localization/audit.md` documents + every remaining untranslated/incorrect string, raw-backend-error call site, + over-permissive allowlist entry, the static-greeting bug, and doc staleness found by + a dedicated Explore pass before any file was touched. +- **Remaining NL/FR translation gaps fixed**: role names actually translated (not just + labelled as translated) — `auth.json`/`demo.json` role keys, `audit.title` → + "Auditgeschiedenis"/"Piste d'audit", `columns.actor` → "Uitvoerder", `list.statusOpen` + → "Openstaand", `ledger.filterRecent` → "Recentste", `scenarios.startScenario` → + "Scenario starten". Also found and fixed (via the new embedded-substring test below) + 8 previously-missed mid-sentence "Audit trail" leaks across `demo.json`, + `quality.json`, `returns.json` that the old whole-string-identity test structurally + could not catch. +- **Central API-error localization**: new `frontend/src/api/errorMessages.ts` + (`describeApiError`) replaces the `err instanceof ApiError ? err.message : ...` + anti-pattern (which showed raw English for the common case) at all 13 call sites + across 7 files. Raw backend text is now only ever shown under a "Technical + details"/"Détails techniques" disclosure (new `ApiErrorNotice` component in + `PageChrome.tsx`); the primary message is always a localized title + explanation + + optional next step, keyed on the 32 known `AppError` codes, then known HTTP statuses + (401/403/404/409/422/500), then a fully generic fallback. `ApiError` was split out of + `client.ts` into a standalone `api/apiError.ts` (no `import.meta.env` dependency) so + `errorMessages.ts` is independently testable outside a Vite/browser context. +- **i18n allowlist tightened**: removed 7 now-stale `IDENTICAL_VALUE_ALLOWLIST` entries + in `i18n-coverage.spec.ts` (`audit.title`, `auth.roleOperationsManager`, + `auth.roleRentalEmployee`, `demo.scenarios.startScenario`, + `demo.scenarios.roles.operations_manager`, `demo.scenarios.roles.rental_employee`, + `navigation.items.audit`) now that they're genuinely translated. Added 2 new tests: + one closing the embedded-English/Dutch-substring blind spot (mid-sentence phrase + leaks the whole-string check misses), one asserting no locale file contains + "MobilityOps" or the word "PoC". +- **`describeApiError` test coverage**: new `frontend/e2e/error-messages.spec.ts` (10 + tests) — every known code/HTTP status has non-empty copy in all 3 locales, a known + code never surfaces raw backend text as the primary message (only via `.technical`), + unknown-code and unknown-status fallback chains behave correctly, and a drift guard + that greps the actual backend `AppError("CODE", ...)` call sites and fails if + `KNOWN_CODES` and the backend's real codes ever diverge (currently exactly in sync, + 32 codes). +- **Time-dependent Europe/Brussels dashboard greeting**: new + `frontend/src/i18n/greeting.ts` (`getGreetingPeriod`, DST-safe via + `Intl.DateTimeFormat({ timeZone: "Europe/Brussels", hourCycle: "h23" })`, clock + injectable) + `useGreetingPeriod.ts` hook (30s poll for period rollover while the app + stays open, no reload). Replaces the previously-always-"Goedemorgen" static + `dashboard.json` title with 4 periods × 3 languages for both the greeting word and a + varying accompanying sentence (never "Goedenacht"). Tests: `greeting.spec.ts` (pure + boundary/DST unit tests) + `greeting-live.spec.ts` (6 real-browser tests via + Playwright's `page.clock` — all 8 required boundary times in all 3 languages, live + rollover without reload, language-switch behaviour, the "never Goedenacht" guard). +- **Found and fixed one real CSS regression along the way**: correctly translating + `roleOperationsManager` to the single unbreakable Dutch compound word + "Operationsmanager" (vs. the old two-word "Operations Manager", which could wrap) + pushed the topbar's `.operator` block past 1024px width, caught by the existing + `responsive-i18n.spec.ts` overflow test. Fixed with `overflow-wrap: anywhere` on + `.operator strong`/`small` and `min-width: 0` on their flex-item wrapper, not by + reverting the correct translation. +- Gates green so far: backend `pytest` 151 passed, `ruff check .` clean, `mypy app` + clean (49 files, unchanged — no backend Python touched this round); frontend `tsc` + clean, production build clean, full local Playwright suite **138 passed** (rebuilt + and restarted the local `web` container from source before this run). +- **Not yet done**: clean-checkout drill, commit/push, Unraid deployment of this fix + branch with live 3-language validation, the master merge (with the mandatory + `git fetch origin` / unexpected-change check first), and + `artifacts/fleet-ops-final-localization/final-summary.md`. Do not claim PASS on this + correction round until all of those are done and `git rev-parse HEAD` exactly matches + `/mnt/user/appdata/mobilityops/.deploy/source-revision`. - Commits so far on this branch: `6deb955` (status flow + brand constant + message codes), `e6539d1` (knowledge fixes), `ac4b163` (Playwright spec updates for the new flow), `1fdd2b3` (new E2E coverage + 2 bug fixes), `1e40775` (accessibility test), diff --git a/README.md b/README.md index 0c1a8c9..f022810 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,10 @@ knowledge base, and this documentation. "MobilityOps" remains the technical identifier only — the repository name, local directory, package/module names, Docker Compose project, deployment directory, and database names. The UI is fully trilingual (nl-BE default, en-GB, fr-BE); see `docs/fleet-ops-correction/` for the localization -architecture, the vehicle-status decision table, and the correction evidence. +architecture, the vehicle-status decision table, and the correction evidence, and +`docs/fleet-ops-final-localization/` for the follow-up correction round (remaining +NL/FR translation gaps, centralized API-error localization, the time-dependent +Europe/Brussels dashboard greeting). The web application uses the premium responsive **Control Rail** interface: a compact operations-first workspace with persisted readiness metrics, evidence-led exceptions, @@ -123,7 +126,7 @@ All defaults are configurable via `.env` (see `.env.example`). ```bash make test # backend: pytest (151 tests) make lint # backend: ruff + mypy (strict, zero errors) -make e2e # frontend: Playwright end-to-end (113 tests, live stack required) +make e2e # frontend: Playwright end-to-end (138 tests, live stack required) ``` Frontend build/typecheck: `cd frontend && npm run build` (`tsc -b && vite build`).