5.4 KiB
Task 3 Report: Final Mileage Election Projector
Outcome
Implemented ProjectDailyMileage in go/vehicle-gateway/internal/stats/source_mileage.go and added focused projector coverage in go/vehicle-gateway/internal/stats/source_mileage_test.go.
RED
Before implementation, the new projector test failed as expected because the function did not exist yet:
internal/stats/source_mileage_test.go:87:9: undefined: ProjectDailyMileage
That confirmed the test was exercising the missing task-3 surface rather than passing accidentally.
GREEN
After implementation:
go test ./internal/stats -run TestProjectDailyMileageSelectsCandidateAndMarksSource -count=1go test ./internal/stats -count=1
Both passed.
What Changed
- Added
maxSelectedDailyMileageKM = 1000. - Added
ProjectDailyMileage(...)with three SQL steps:- clear
is_selectedfor the VIN/date/protocol slice, - project the elected row from
vehicle_daily_mileage_sourceintovehicle_daily_mileage, - mark the winning source row as selected.
- clear
- Kept the candidate identity intact:
source_keystill carries protocol + phone/device + source IP, while the data-source join uses protocol + source IP. - Added a focused test that asserts the clear/project/mark sequence and the key SQL fragments.
Files Changed
go/vehicle-gateway/internal/stats/source_mileage.gogo/vehicle-gateway/internal/stats/source_mileage_test.go
Self-Review
- The projector stays aligned with the existing stats schema and helper conventions.
- The SQL ordering and join logic preserve the intended source identity split; there is no IP-only simplification.
- I did not add an unrelated schema migration because the current repository state already contained the needed
vehicle_daily_mileage_sourceandvehicle_daily_mileagecolumns/indexes for this projector. - The only notable follow-up risk is that the final selection query relies on MySQL-style
INSERT ... SELECT ... LIMIT 1 ON DUPLICATE KEY UPDATEbehavior, which matches the rest of the stats package but should still be exercised against the target DB in an integration run.
Commit
aa12317b5 - feat(stats): project elected mileage source
Fix (reviewer findings)
Applied the reviewer correction for the trusted source endpoint contract:
- In
go/vehicle-gateway/internal/stats/source_mileage.go,projectDailyMileageSQLnow writestrusted_source_endpointfromvehicle_data_source.latest_source_endpointviaCOALESCE(NULLIF(ds.latest_source_endpoint, ''), s.source_endpoint)so latest connection metadata is authoritative with a simple fallback. - Replaced hardcoded quality predicate with the existing constant using
s.quality_status = '+ QualityOK +'inprojectDailyMileageSQL. - Updated
go/vehicle-gateway/internal/stats/source_mileage_test.goto assert both the endpoint expression and constant-based quality predicate.
Validation commands:
cd go/vehicle-gateway && go test ./internal/stats -run TestProjectDailyMileageSelectsCandidateAndMarksSource -count=1
# PASS: lingniu-vehicle-ingest/go/vehicle-gateway/internal/stats
cd go/vehicle-gateway && go test ./internal/stats -count=1
# PASS: lingniu-vehicle-ingest/go/vehicle-gateway/internal/stats
Fix (reviewer findings #2)
Corrected the remaining projectDailyMileageSQL contract issue so trusted_source_endpoint uses only vehicle_data_source.latest_source_endpoint:
- In
go/vehicle-gateway/internal/stats/source_mileage.go, changed the projection from:COALESCE(NULLIF(ds.latest_source_endpoint, ''), s.source_endpoint)to:ds.latest_source_endpoint. - In
go/vehicle-gateway/internal/stats/source_mileage_test.go, extendedTestProjectDailyMileageSelectsCandidateAndMarksSourceassertions to:- require
ds.latest_source_endpointis selected, and - explicitly verify no fallback expression using
s.source_endpointremains.
- require
This enforces the strict source-of-truth rule that endpoint data for final projection must come from latest connection metadata only, even when it is null/empty.
Fix (reviewer findings #3)
Addressed stale candidate selection re-flagging by narrowing source marking to the same eligibility rules used by projection:
- In
go/vehicle-gateway/internal/stats/source_mileage.go,markSelectedSourceSQLnow:- No longer joins
vehicle_daily_mileageto discover the selected source. - Selects the same single winning candidate directly from
vehicle_daily_mileage_source, constrained by:- VIN/date/protocol
quality_status = QualityOK- mileage bounds (
0..maxSelectedDailyMileageKM) - enabled source metadata
- same trust/sample/time ordering
- Marks only that candidate as
is_selected = 1.
- No longer joins
- In
go/vehicle-gateway/internal/stats/source_mileage_test.go,TestProjectDailyMileageSelectsCandidateAndMarksSourcenow verifies:- the mark query includes candidate filters and ordering, including
s2.quality_status,s2.daily_mileage_km, andCOALESCE(ds.enabled, 1) = 1. - it no longer references
vehicle_daily_mileageas a join source. - it passes the selection window arg through to marking (
maxSelectedDailyMileageKM) and uses seven bind args.
- the mark query includes candidate filters and ordering, including
Validation commands:
cd go/vehicle-gateway && go test ./internal/stats -run TestProjectDailyMileage -count=1
# PASS: lingniu-vehicle-ingest/go/vehicle-gateway/internal/stats
cd go/vehicle-gateway && go test ./internal/stats -count=1
# PASS: lingniu-vehicle-ingest/go/vehicle-gateway/internal/stats