From 9e9dd8e0e32e2a511c9cad2b9d766e147da1d128 Mon Sep 17 00:00:00 2001 From: NuklearRabbit <145918611+NuklearRabbit@users.noreply.github.com> Date: Wed, 5 Aug 2026 17:52:13 +0200 Subject: [PATCH] docs: record the three-defect fix, gates, and live verification evidence Co-Authored-By: Claude Sonnet 5 --- PROJECT_STATE.md | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/PROJECT_STATE.md b/PROJECT_STATE.md index 4ace1e9..9c209da 100644 --- a/PROJECT_STATE.md +++ b/PROJECT_STATE.md @@ -1934,3 +1934,78 @@ deployed them live. - **Next action**: none required by this task. Longer-term open items remain as recorded above — RAGcore reranker gap, n8n workflow 3 publication decision, no PR yet opened from `feat/fleet-ops-final-integrations` to `master`. + +## Merged to master (2026-08-05) + +`feat/fleet-ops-final-integrations` fast-forward merged into `master` (29 commits, 0 +conflicts — `master` was a clean ancestor). Pushed and verified; both branches now sit at +`3808bbe`. The already-deployed Unraid instance needed no redeploy (it was already running +this exact revision). + +## Three live-reviewer content defects fixed (2026-08-05) + +A reviewer testing the live instance found three defects. Fixed all three; no redesign, no +new pages. + +- **Dashboard subtext was raw and untranslated, and mostly meaningless.** 11 of 15 seeded + data-quality issues carried the evidence text "Synthetic deterministic seed issue", and + `AttentionItem.detail` piped `evidence_json["summary"]` straight to the page, bypassing + i18n entirely. Fixed both sides: `AttentionItem` now exposes `evidence_signals` (stable + `code` + `params`, the same shape the issue detail page already used for its four + scripted demo rows) instead of a raw string; a new `frontend/src/data/evidenceSignals.ts` + shares one `describeEvidenceSignal()` between the dashboard and + `DataQualityIssueDetail.tsx`. Every previously-placeholder seed row now cites a real + per-rule-type fact instead of invented prose: `seed_loader.py`'s `_seed_signals` was + extended with `_SEED_SIGNALS_BY_REF`, and three vehicles' data were adjusted so the facts + are genuinely true — MO-036/MO-028's `next_service_km` lowered to a value their real + odometer already exceeds (`vehicle.service_threshold_reached`), MO-007 already showed + "rented" with no active booking so `vehicle.rental_ended` needed no data change, + MO-043/MO-014 have a genuinely blank `location`, and MO-050/MO-021 have a real + odometer-regression pair engineered into `seed/bookings.csv` (one booking's + `end_odometer_km` lowered below the prior booking's, both still internally consistent + with their own `start_odometer_km`). Learned the hard way that a *resolved* row must + never carry a currently-true live-detectable fact — the post-seed scan + (`app.services.data_quality.run_scan`, called on every `seed --reset`) independently + re-finds any real regression/conflict regardless of an existing resolved CSV row (only + `status == "open"` blocks a duplicate), so DQ-0013 (originally planned as a resolved + `odometer_regression` for MO-042) was switched to `missing_required_field` instead once a + real engineered regression there produced a duplicate `DQ-SCAN-0003`. +- **5 of 7 blocked vehicles had no quality issue at all; one (MO-049) had only a resolved + one.** Presented the two architecture options to the user before building (per their + explicit request): (a) a new coded+localized blocking-reason field on `Vehicle` with a + migration, or (b) link each blocked vehicle to a real open issue via the existing + data-quality pipeline. User chose **(b)** — no schema change, no migration, and the + vehicle-status evaluator already structurally can't explain "blocked" on its own (it + treats `blocked` as a valid terminal state requiring no further fact-check, by design). + Gave MO-009/025/026/041/045/049 a real open `missing_required_field` issue each, backed + by a genuinely blank `location` or `registration_number` (varied to avoid a uniqueness + collision on `registration_number` and to avoid breaking the vehicle-detail page + title/subtitle, which read `make`+`model` and `registration_number`+`location`). +- **Booking odometer showed a bare "—" for 25 reserved + 1 active booking.** Replaced with + localized explanations (`bookings:detail.startOdometerPending` / + `endOdometerPending`) in `BookingDetail.tsx`. **MO-024's "rented but 14,820 km past + service" contradiction was already fixed** — verified live that the vehicle-status + evaluator already produces `DQ-SCAN-*`/`vehicle.manual_review_required` for it; added a + regression test instead of new logic, per the instruction not to invent a third status. +- **Found and fixed a related bug while verifying live**: the vehicle `entity_snapshot` + (`backend/app/api/routers/data_quality.py::_snapshot`) omitted `registration_number` + entirely, so the "provide missing fields" form always showed Kenteken/Registration blank + — even for a vehicle whose plate was genuinely on file, and even when a *different* + field was the one actually missing. Added the field; added a regression test. +- **Gates**: `docker compose build api` (stale-image trap avoided each time), `pytest -q` + — **186 passed** (181 + 5 new: blocked-vehicle-has-open-issue, MO-024 regression lock-in, + no-placeholder-summary, dashboard-signals-not-raw-text, vehicle-snapshot-has-registration); + `ruff check .` clean; `mypy app` clean (50 files); `npm run build` clean. Full i18n key + parity re-verified across all 14 namespaces (manual script, not the Playwright + i18n-coverage spec — that suite needs a browser/server this session didn't spin up for + it). +- **Browser-verified in all three languages (nl-BE/en-GB/fr-BE), both locally and on the + live Unraid instance after deploy**: dashboard attention subtext, a blocked vehicle's + Quality tab (MO-009 and MO-041), and a reserved booking's odometer fields all render + correctly with no placeholder/raw text and no bare dashes. +- **Pushed** `feat/fleet-ops-final-integrations` → `4faac24` (verified via fresh fetch). + **Deployed** to Unraid (`.deploy/source-revision` = `4faac24b5aabf6cfaecff71ffecf132b03c417f1`), + `db`/`api`/`web` rebuilt and healthy, `seed --reset` run, live count confirmed at + **33 data-quality issues** (21 CSV + 12 scan-found, unchanged from before this fix). +- **Not done**: no PR opened from this branch to `master` this session (master was merged + once, earlier, at `3808bbe` — this new commit is not yet on `master`).