chore: commit mileage updates and accumulated project artifacts

This commit is contained in:
lingniu
2026-09-21 09:15:54 +08:00
parent 6cc872ceb6
commit 8b32ae2988
767 changed files with 572885 additions and 17 deletions
@@ -9,8 +9,8 @@ import (
"time"
)
// ReconciledMileageRange uses terminal odometers, including one preceding
// observation per protocol. The same function serves single days and every
// ReconciledMileageRange uses verified platform daily mileage when available,
// with terminal odometers and one preceding observation per protocol as fallback. The same function serves single days and every
// range page: neither the requested start date nor page size changes a result.
func (r *MySQLRepository) ReconciledMileageRange(ctx context.Context, vins []string, start, end string, protocols []string) (map[string]DailyMileage, error) {
if len(vins) == 0 {
@@ -42,9 +42,16 @@ func (r *MySQLRepository) ReconciledMileageRange(ctx context.Context, vins []str
DATE_FORMAT(s.latest_event_time,'%Y-%m-%dT%H:%i:%s+08:00'),
DATE_FORMAT(s.updated_at,'%Y-%m-%dT%H:%i:%s+08:00'),
COALESCE(DATE_FORMAT(s.first_event_time,'%Y-%m-%dT%H:%i:%s+08:00'),''),
CASE WHEN s.quality_status='INVALID_DELTA' THEN COALESCE(s.quality_reason,'INVALID_DELTA') ELSE '' END
CASE WHEN s.quality_status='INVALID_DELTA' THEN COALESCE(NULLIF(s.quality_reason,''),'INVALID_DELTA') ELSE '' END,
CASE WHEN s.quality_status='OK' AND s.is_selected=1 AND m.vin IS NOT NULL
AND m.daily_mileage_km>=0 AND m.daily_mileage_km<=s.latest_total_mileage_km
THEN 1 ELSE 0 END
FROM wanted w JOIN vehicle_daily_mileage_source s
ON s.vin=w.vin AND s.protocol=w.protocol AND s.stat_date=w.stat_date
LEFT JOIN vehicle_daily_mileage m
ON m.vin=s.vin AND m.protocol=s.protocol AND m.stat_date=s.stat_date
AND m.daily_mileage_km=s.daily_mileage_km
AND COALESCE(m.day_end_total_mileage_km,m.latest_total_mileage_km)=s.latest_total_mileage_km
WHERE ` + eligible("s") + `
ORDER BY s.stat_date,s.vin,s.protocol,s.is_selected DESC,
CASE WHEN s.quality_status='OK' THEN 0 ELSE 1 END,s.latest_event_time DESC,s.sample_count DESC,s.source_key`
@@ -72,7 +79,7 @@ func (r *MySQLRepository) ReconciledMileageRange(ctx context.Context, vins []str
seen := map[string]bool{}
for rows.Next() {
var v DailyMileage
if err := rows.Scan(&v.VIN, &v.Date, &v.Protocol, &v.SourceKey, &v.MileageKm, &v.TotalMileageKm, &v.DataTime, &v.UpdatedAt, &v.StatisticsStartTime, &v.DataQuality); err != nil {
if err := rows.Scan(&v.VIN, &v.Date, &v.Protocol, &v.SourceKey, &v.MileageKm, &v.TotalMileageKm, &v.DataTime, &v.UpdatedAt, &v.StatisticsStartTime, &v.DataQuality, &v.PlatformMileage); err != nil {
return nil, err
}
key := v.VIN + "|" + v.Date + "|" + v.Protocol
@@ -152,6 +159,10 @@ func reconcileMileage(points []DailyMileage, vins []string, start, end string, p
}
} else if current.DataQuality != "" {
result.MileageKm = 0
} else if current.PlatformMileage {
// The daily projection already used this source's own baseline.
// Recomputing against yesterday's selected source can mix odometers
// or discard valid recovery mileage after a source switch.
} else if !hasPrevious {
result.DataQuality = "NO_PREVIOUS_BASELINE"
} else if current.Protocol != previous.Protocol || current.SourceKey != previous.SourceKey {