fix: localize dashboard evidence, explain blocked vehicles, clarify pending odometers

Three content defects found by a live reviewer:

- Dashboard attention subtext was raw, untranslated evidence.summary text, and for
  11 of 15 seeded issues that text was literally "Synthetic deterministic seed
  issue". AttentionItem now exposes evidence_signals (stable code + params, same
  shape as the issue detail page) instead of a detail string; the frontend renders
  them through a shared describeEvidenceSignal() used by both the dashboard and the
  issue detail page. Every previously-placeholder seed row now cites a real,
  per-rule-type fact (a genuinely crossed service threshold, a genuinely blank
  field, or a real pair of booking odometer readings) instead of invented prose.

- 5 of 7 blocked vehicles had no quality issue at all and one had only a resolved
  one, so "needs attention" led nowhere. Each now has a real open
  missing_required_field issue backed by a genuinely blank field (no schema change,
  no migration -- reuses the existing data-quality pipeline).

- Booking odometer fields showing a bare "-" for 25 reserved + 1 active booking now
  show a localized explanation ("trip hasn't started yet" / "not yet closed").
  MO-024's rented-but-service-overdue contradiction was already caught by the
  vehicle-status evaluator (DQ-SCAN, vehicle.manual_review_required) -- added a
  regression test rather than new logic.

Also fixed a related bug the above exposed: the vehicle entity_snapshot omitted
registration_number entirely, so the "provide missing fields" form always showed
it blank regardless of the real value.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
NuklearRabbit
2026-08-05 17:44:32 +02:00
co-authored by Claude Sonnet 5
parent 3808bbe132
commit 4faac24b5a
21 changed files with 349 additions and 132 deletions
+2 -2
View File
@@ -5,10 +5,10 @@ BK-H-0003,CUS-0034,MO-022,2026-07-22T06:00:00Z,2026-07-27T06:00:00Z,returned,314
BK-H-0004,CUS-0045,MO-029,2026-07-20T05:00:00Z,2026-07-26T05:00:00Z,returned,36708,36912,true
BK-H-0005,CUS-0056,MO-036,2026-07-18T04:00:00Z,2026-07-25T04:00:00Z,returned,41655,41860,true
BK-H-0006,CUS-0067,MO-043,2026-07-16T03:00:00Z,2026-07-24T03:00:00Z,returned,46513,46719,true
BK-H-0007,CUS-0078,MO-050,2026-07-14T02:00:00Z,2026-07-23T02:00:00Z,returned,51685,51892,true
BK-H-0007,CUS-0078,MO-050,2026-07-14T02:00:00Z,2026-07-23T02:00:00Z,returned,51685,51700,true
BK-H-0008,CUS-0089,MO-007,2026-07-12T09:00:00Z,2026-07-22T09:00:00Z,returned,20681,20889,true
BK-H-0009,CUS-0100,MO-014,2026-07-10T08:00:00Z,2026-07-21T08:00:00Z,returned,25419,25628,true
BK-H-0010,CUS-0111,MO-021,2026-07-18T07:00:00Z,2026-07-20T07:00:00Z,returned,31088,31298,true
BK-H-0010,CUS-0111,MO-021,2026-07-18T07:00:00Z,2026-07-20T07:00:00Z,returned,31088,31150,true
BK-H-0011,CUS-0122,MO-028,2026-07-16T06:00:00Z,2026-07-19T06:00:00Z,returned,35948,36159,true
BK-H-0012,CUS-0133,MO-035,2026-07-14T05:00:00Z,2026-07-18T05:00:00Z,returned,41022,41234,true
BK-H-0013,CUS-0144,MO-042,2026-07-12T04:00:00Z,2026-07-17T04:00:00Z,returned,46535,46748,true
1 public_ref customer_ref vehicle_ref starts_at ends_at status start_odometer_km end_odometer_km requirements_complete
5 BK-H-0004 CUS-0045 MO-029 2026-07-20T05:00:00Z 2026-07-26T05:00:00Z returned 36708 36912 true
6 BK-H-0005 CUS-0056 MO-036 2026-07-18T04:00:00Z 2026-07-25T04:00:00Z returned 41655 41860 true
7 BK-H-0006 CUS-0067 MO-043 2026-07-16T03:00:00Z 2026-07-24T03:00:00Z returned 46513 46719 true
8 BK-H-0007 CUS-0078 MO-050 2026-07-14T02:00:00Z 2026-07-23T02:00:00Z returned 51685 51892 51700 true
9 BK-H-0008 CUS-0089 MO-007 2026-07-12T09:00:00Z 2026-07-22T09:00:00Z returned 20681 20889 true
10 BK-H-0009 CUS-0100 MO-014 2026-07-10T08:00:00Z 2026-07-21T08:00:00Z returned 25419 25628 true
11 BK-H-0010 CUS-0111 MO-021 2026-07-18T07:00:00Z 2026-07-20T07:00:00Z returned 31088 31298 31150 true
12 BK-H-0011 CUS-0122 MO-028 2026-07-16T06:00:00Z 2026-07-19T06:00:00Z returned 35948 36159 true
13 BK-H-0012 CUS-0133 MO-035 2026-07-14T05:00:00Z 2026-07-18T05:00:00Z returned 41022 41234 true
14 BK-H-0013 CUS-0144 MO-042 2026-07-12T04:00:00Z 2026-07-17T04:00:00Z returned 46535 46748 true
+17 -11
View File
@@ -3,14 +3,20 @@ DQ-DEMO-DUPLICATE,possible_duplicate_customer,CUS-0012,CUS-0178,high,open,exact
DQ-DEMO-OVERLAP,booking_overlap,MO-016,BK-DEMO-OVERLAP-A|BK-DEMO-OVERLAP-B,high,open,controlled legacy import overlap
DQ-DEMO-STATUS,vehicle_status_conflict,MO-016,,high,open,vehicle marked available while reserved bookings conflict
DQ-DEMO-ATTENTION,missing_required_field,MO-031,BK-DEMO-NEXT,high,open,near-future booking; required operational inspection missing
DQ-0005,vehicle_status_conflict,MO-036,,high,open,Synthetic deterministic seed issue
DQ-0006,missing_required_field,MO-043,,low,open,Synthetic deterministic seed issue
DQ-0007,odometer_regression,MO-050,,medium,open,Synthetic deterministic seed issue
DQ-0008,vehicle_status_conflict,MO-007,,high,open,Synthetic deterministic seed issue
DQ-0009,missing_required_field,MO-014,,low,open,Synthetic deterministic seed issue
DQ-0010,odometer_regression,MO-021,,medium,open,Synthetic deterministic seed issue
DQ-0011,vehicle_status_conflict,MO-028,,high,open,Synthetic deterministic seed issue
DQ-0012,missing_required_field,MO-035,,low,resolved,Synthetic deterministic seed issue
DQ-0013,odometer_regression,MO-042,,medium,resolved,Synthetic deterministic seed issue
DQ-0014,vehicle_status_conflict,MO-049,,high,resolved,Synthetic deterministic seed issue
DQ-0015,missing_required_field,MO-006,,low,resolved,Synthetic deterministic seed issue
DQ-0005,vehicle_status_conflict,MO-036,,high,open,Recommended status: maintenance (44660 km reported against a 44000 km service threshold)
DQ-0006,missing_required_field,MO-043,,low,open,Missing: location
DQ-0007,odometer_regression,MO-050,,medium,open,Booking BK-H-0007 recorded 51700 km, below the 51892 km recorded by earlier booking BK-H-0057.
DQ-0008,vehicle_status_conflict,MO-007,,high,open,Recommended status: available (marked rented with no active booking)
DQ-0009,missing_required_field,MO-014,,low,open,Missing: location
DQ-0010,odometer_regression,MO-021,,medium,open,Booking BK-H-0010 recorded 31150 km, below the 31298 km recorded by earlier booking BK-H-0060.
DQ-0011,vehicle_status_conflict,MO-028,,high,open,Recommended status: maintenance (38959 km reported against a 38000 km service threshold)
DQ-0012,missing_required_field,MO-035,,low,resolved,Missing: registration_number
DQ-0013,missing_required_field,MO-042,,low,resolved,Missing: location
DQ-0014,missing_required_field,MO-049,,low,resolved,Missing: registration_number
DQ-0015,missing_required_field,MO-006,,low,resolved,Missing: location
DQ-0016,missing_required_field,MO-009,,medium,open,Missing: location
DQ-0017,missing_required_field,MO-025,,medium,open,Missing: location
DQ-0018,missing_required_field,MO-026,,medium,open,Missing: registration_number
DQ-0019,missing_required_field,MO-041,,medium,open,Missing: location
DQ-0020,missing_required_field,MO-045,,medium,open,Missing: location
DQ-0021,missing_required_field,MO-049,,medium,open,Missing: location
1 public_ref public_ref,rule_type,entity_ref,related_ref,severity,status,evidence rule_type entity_ref related_ref severity status evidence
3 DQ-DEMO-OVERLAP DQ-DEMO-OVERLAP,booking_overlap,MO-016,BK-DEMO-OVERLAP-A|BK-DEMO-OVERLAP-B,high,open,controlled legacy import overlap booking_overlap MO-016 BK-DEMO-OVERLAP-A|BK-DEMO-OVERLAP-B high open controlled legacy import overlap
4 DQ-DEMO-STATUS DQ-DEMO-STATUS,vehicle_status_conflict,MO-016,,high,open,vehicle marked available while reserved bookings conflict vehicle_status_conflict MO-016 high open vehicle marked available while reserved bookings conflict
5 DQ-DEMO-ATTENTION DQ-DEMO-ATTENTION,missing_required_field,MO-031,BK-DEMO-NEXT,high,open,near-future booking; required operational inspection missing missing_required_field MO-031 BK-DEMO-NEXT high open near-future booking; required operational inspection missing
6 DQ-0005 DQ-0005,vehicle_status_conflict,MO-036,,high,open,Recommended status: maintenance (44660 km reported against a 44000 km service threshold) vehicle_status_conflict MO-036 high open Synthetic deterministic seed issue
7 DQ-0006 DQ-0006,missing_required_field,MO-043,,low,open,Missing: location missing_required_field MO-043 low open Synthetic deterministic seed issue
8 DQ-0007 DQ-0007,odometer_regression,MO-050,,medium,open,Booking BK-H-0007 recorded 51700 km, below the 51892 km recorded by earlier booking BK-H-0057. odometer_regression MO-050 medium open Synthetic deterministic seed issue
9 DQ-0008 DQ-0008,vehicle_status_conflict,MO-007,,high,open,Recommended status: available (marked rented with no active booking) vehicle_status_conflict MO-007 high open Synthetic deterministic seed issue
10 DQ-0009 DQ-0009,missing_required_field,MO-014,,low,open,Missing: location missing_required_field MO-014 low open Synthetic deterministic seed issue
11 DQ-0010 DQ-0010,odometer_regression,MO-021,,medium,open,Booking BK-H-0010 recorded 31150 km, below the 31298 km recorded by earlier booking BK-H-0060. odometer_regression MO-021 medium open Synthetic deterministic seed issue
12 DQ-0011 DQ-0011,vehicle_status_conflict,MO-028,,high,open,Recommended status: maintenance (38959 km reported against a 38000 km service threshold) vehicle_status_conflict MO-028 high open Synthetic deterministic seed issue
13 DQ-0012 DQ-0012,missing_required_field,MO-035,,low,resolved,Missing: registration_number missing_required_field MO-035 low resolved Synthetic deterministic seed issue
14 DQ-0013 DQ-0013,missing_required_field,MO-042,,low,resolved,Missing: location odometer_regression MO-042 medium resolved Synthetic deterministic seed issue
15 DQ-0014 DQ-0014,missing_required_field,MO-049,,low,resolved,Missing: registration_number vehicle_status_conflict MO-049 high resolved Synthetic deterministic seed issue
16 DQ-0015 DQ-0015,missing_required_field,MO-006,,low,resolved,Missing: location missing_required_field MO-006 low resolved Synthetic deterministic seed issue
17 DQ-0016,missing_required_field,MO-009,,medium,open,Missing: location
18 DQ-0017,missing_required_field,MO-025,,medium,open,Missing: location
19 DQ-0018,missing_required_field,MO-026,,medium,open,Missing: registration_number
20 DQ-0019,missing_required_field,MO-041,,medium,open,Missing: location
21 DQ-0020,missing_required_field,MO-045,,medium,open,Missing: location
22 DQ-0021,missing_required_field,MO-049,,medium,open,Missing: location
+10 -10
View File
@@ -7,12 +7,12 @@ MO-005,Bürstner,Lyseo,2024,2-MOB-005,Geel,available,22213,30000,true
MO-006,Sunlight,Cliff,2025,2-MOB-006,Geel,cleaning,23163,30000,true
MO-007,Adria,Matrix,2019,2-MOB-007,Geel,rented,23689,30000,true
MO-008,Dethleffs,Trend,2020,2-MOB-008,Geel,available,23933,30000,true
MO-009,Carado,T-Series,2021,2-MOB-009,Geel,blocked,25203,30000,true
MO-009,Carado,T-Series,2021,2-MOB-009,,blocked,25203,30000,true
MO-010,Hymer,Exsis,2022,2-MOB-010,Geel,available,25333,30000,true
MO-011,Bürstner,Lyseo,2023,2-MOB-011,Geel,available,26160,30000,true
MO-012,Sunlight,Cliff,2024,2-MOB-012,Geel,available,26859,30000,true
MO-013,Adria,Matrix,2025,2-MOB-013,Geel,rented,27750,30000,true
MO-014,Dethleffs,Trend,2019,2-MOB-014,Geel,rented,28428,30000,true
MO-014,Dethleffs,Trend,2019,2-MOB-014,,rented,28428,30000,true
MO-015,Carado,T-Series,2020,2-MOB-015,Geel,available,29661,30000,true
MO-016,Hymer,Exsis,2021,2-MOB-016,Geel,available,30497,40000,true
MO-017,Bürstner,Lyseo,2022,2-MOB-017,Geel,available,30596,40000,true
@@ -23,10 +23,10 @@ MO-021,Carado,T-Series,2019,2-MOB-021,Geel,cleaning,34098,40000,true
MO-022,Hymer,Exsis,2020,2-MOB-022,Geel,available,34410,40000,true
MO-023,Bürstner,Lyseo,2021,2-MOB-023,Geel,rented,35624,40000,true
MO-024,Sunlight,Cliff,2022,2-MOB-024,Geel,rented,54820,40000,true
MO-025,Adria,Matrix,2023,2-MOB-025,Geel,blocked,36429,40000,true
MO-026,Dethleffs,Trend,2024,2-MOB-026,Geel,blocked,37273,40000,true
MO-025,Adria,Matrix,2023,2-MOB-025,,blocked,36429,40000,true
MO-026,Dethleffs,Trend,2024,,Geel,blocked,37273,40000,true
MO-027,Carado,T-Series,2025,2-MOB-027,Geel,available,38502,40000,true
MO-028,Hymer,Exsis,2019,2-MOB-028,Geel,cleaning,38959,40000,true
MO-028,Hymer,Exsis,2019,2-MOB-028,Geel,cleaning,38959,38000,true
MO-029,Bürstner,Lyseo,2020,2-MOB-029,Geel,rented,39712,40000,true
MO-030,Sunlight,Cliff,2021,2-MOB-030,Geel,maintenance,40213,50000,true
MO-031,Adria,Matrix,2022,2-MOB-031,Geel,blocked,41149,50000,true
@@ -34,18 +34,18 @@ MO-032,Dethleffs,Trend,2023,2-MOB-032,Geel,rented,41791,50000,true
MO-033,Carado,T-Series,2024,2-MOB-033,Geel,available,42561,50000,true
MO-034,Hymer,Exsis,2025,2-MOB-034,Geel,available,43057,50000,true
MO-035,Bürstner,Lyseo,2019,2-MOB-035,Geel,rented,44034,50000,true
MO-036,Sunlight,Cliff,2020,2-MOB-036,Geel,available,44660,50000,true
MO-036,Sunlight,Cliff,2020,2-MOB-036,Geel,available,44660,44000,true
MO-037,Adria,Matrix,2021,2-MOB-037,Geel,available,45654,50000,true
MO-038,Dethleffs,Trend,2022,2-MOB-038,Geel,available,46630,50000,true
MO-039,Carado,T-Series,2023,2-MOB-039,Geel,rented,46657,50000,true
MO-040,Hymer,Exsis,2024,2-MOB-040,Geel,available,47909,50000,true
MO-041,Bürstner,Lyseo,2025,2-MOB-041,Geel,blocked,48443,50000,true
MO-041,Bürstner,Lyseo,2025,2-MOB-041,,blocked,48443,50000,true
MO-042,Sunlight,Cliff,2019,2-MOB-042,Geel,available,49548,50000,true
MO-043,Adria,Matrix,2020,2-MOB-043,Geel,available,49519,50000,true
MO-043,Adria,Matrix,2020,2-MOB-043,,available,49519,50000,true
MO-044,Dethleffs,Trend,2021,2-MOB-044,Geel,available,50611,60000,true
MO-045,Carado,T-Series,2022,2-MOB-045,Geel,blocked,51260,60000,true
MO-045,Carado,T-Series,2022,2-MOB-045,,blocked,51260,60000,true
MO-046,Hymer,Exsis,2023,2-MOB-046,Geel,cleaning,51957,60000,true
MO-047,Bürstner,Lyseo,2024,2-MOB-047,Geel,available,52452,60000,true
MO-048,Sunlight,Cliff,2025,2-MOB-048,Geel,maintenance,53693,60000,true
MO-049,Adria,Matrix,2019,2-MOB-049,Geel,blocked,53935,60000,true
MO-049,Adria,Matrix,2019,2-MOB-049,,blocked,53935,60000,true
MO-050,Dethleffs,Trend,2020,2-MOB-050,Geel,cleaning,54692,60000,true
1 public_ref make model model_year registration_number location operational_status odometer_km next_service_km active
7 MO-006 Sunlight Cliff 2025 2-MOB-006 Geel cleaning 23163 30000 true
8 MO-007 Adria Matrix 2019 2-MOB-007 Geel rented 23689 30000 true
9 MO-008 Dethleffs Trend 2020 2-MOB-008 Geel available 23933 30000 true
10 MO-009 Carado T-Series 2021 2-MOB-009 Geel blocked 25203 30000 true
11 MO-010 Hymer Exsis 2022 2-MOB-010 Geel available 25333 30000 true
12 MO-011 Bürstner Lyseo 2023 2-MOB-011 Geel available 26160 30000 true
13 MO-012 Sunlight Cliff 2024 2-MOB-012 Geel available 26859 30000 true
14 MO-013 Adria Matrix 2025 2-MOB-013 Geel rented 27750 30000 true
15 MO-014 Dethleffs Trend 2019 2-MOB-014 Geel rented 28428 30000 true
16 MO-015 Carado T-Series 2020 2-MOB-015 Geel available 29661 30000 true
17 MO-016 Hymer Exsis 2021 2-MOB-016 Geel available 30497 40000 true
18 MO-017 Bürstner Lyseo 2022 2-MOB-017 Geel available 30596 40000 true
23 MO-022 Hymer Exsis 2020 2-MOB-022 Geel available 34410 40000 true
24 MO-023 Bürstner Lyseo 2021 2-MOB-023 Geel rented 35624 40000 true
25 MO-024 Sunlight Cliff 2022 2-MOB-024 Geel rented 54820 40000 true
26 MO-025 Adria Matrix 2023 2-MOB-025 Geel blocked 36429 40000 true
27 MO-026 Dethleffs Trend 2024 2-MOB-026 Geel blocked 37273 40000 true
28 MO-027 Carado T-Series 2025 2-MOB-027 Geel available 38502 40000 true
29 MO-028 Hymer Exsis 2019 2-MOB-028 Geel cleaning 38959 40000 38000 true
30 MO-029 Bürstner Lyseo 2020 2-MOB-029 Geel rented 39712 40000 true
31 MO-030 Sunlight Cliff 2021 2-MOB-030 Geel maintenance 40213 50000 true
32 MO-031 Adria Matrix 2022 2-MOB-031 Geel blocked 41149 50000 true
34 MO-033 Carado T-Series 2024 2-MOB-033 Geel available 42561 50000 true
35 MO-034 Hymer Exsis 2025 2-MOB-034 Geel available 43057 50000 true
36 MO-035 Bürstner Lyseo 2019 2-MOB-035 Geel rented 44034 50000 true
37 MO-036 Sunlight Cliff 2020 2-MOB-036 Geel available 44660 50000 44000 true
38 MO-037 Adria Matrix 2021 2-MOB-037 Geel available 45654 50000 true
39 MO-038 Dethleffs Trend 2022 2-MOB-038 Geel available 46630 50000 true
40 MO-039 Carado T-Series 2023 2-MOB-039 Geel rented 46657 50000 true
41 MO-040 Hymer Exsis 2024 2-MOB-040 Geel available 47909 50000 true
42 MO-041 Bürstner Lyseo 2025 2-MOB-041 Geel blocked 48443 50000 true
43 MO-042 Sunlight Cliff 2019 2-MOB-042 Geel available 49548 50000 true
44 MO-043 Adria Matrix 2020 2-MOB-043 Geel available 49519 50000 true
45 MO-044 Dethleffs Trend 2021 2-MOB-044 Geel available 50611 60000 true
46 MO-045 Carado T-Series 2022 2-MOB-045 Geel blocked 51260 60000 true
47 MO-046 Hymer Exsis 2023 2-MOB-046 Geel cleaning 51957 60000 true
48 MO-047 Bürstner Lyseo 2024 2-MOB-047 Geel available 52452 60000 true
49 MO-048 Sunlight Cliff 2025 2-MOB-048 Geel maintenance 53693 60000 true
50 MO-049 Adria Matrix 2019 2-MOB-049 Geel blocked 53935 60000 true
51 MO-050 Dethleffs Trend 2020 2-MOB-050 Geel cleaning 54692 60000 true