docs: record the three-defect fix, gates, and live verification evidence

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
NuklearRabbit
2026-08-05 17:52:13 +02:00
co-authored by Claude Sonnet 5
parent 4faac24b5a
commit 9e9dd8e0e3
+75
View File
@@ -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`).