Best Value: baseline on the closest eligible price and gate on freshness
- Add FuelPriceFreshness: selected-fuel-aware eligibility plus a shared comparison confidence, so a saving is presented as verified only when both the candidate and the baseline pass the gate for the fuel on screen. - Rank against the closest station with an eligible selected-fuel price instead of the physically closest station, so a single stale neighbour can no longer invalidate every comparison in the list. Ordinary Closest sorting still includes every priced station. - Keep ineligible prices visible, fall back to pump-price order, and label Best Value unavailable when no comparison qualifies. - Widget: same baseline and confidence path as the app. - Tests: stale-closest baseline, alert baseline, eligibility policy, boundary and missing-timestamp regressions.
This commit is contained in:
@@ -203,6 +203,8 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
// 3) Load + order stations per widget mode.
|
||||
let ordered: [FuelStation]
|
||||
var bestValueResult: FuelSavingsResult?
|
||||
var bestValuePriceConfidence: FuelPriceFreshness.ComparisonConfidence = .ineligible
|
||||
var bestValuePriceWarning: String?
|
||||
if isFavourites {
|
||||
let favourites = FuelStore.loadFavourites()
|
||||
.filter { $0.station.prices[$0.fuel] != nil }
|
||||
@@ -306,7 +308,8 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
break
|
||||
}
|
||||
let amount = settings.preferredAmount
|
||||
let baseline = FuelSavingsEstimator.baselineStation(filtered, fuel: fuel, journeyMiles: journey)
|
||||
let baseline = FuelSavingsEstimator.bestValueBaselineStation(filtered, fuel: fuel,
|
||||
journeyMiles: journey)
|
||||
let ranked = FuelSavingsEstimator.ranked(
|
||||
filtered,
|
||||
fuel: fuel,
|
||||
@@ -317,6 +320,13 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
)
|
||||
ordered = ranked
|
||||
if let first = ranked.first, let baseline {
|
||||
bestValuePriceConfidence = FuelPriceFreshness.comparisonConfidence(
|
||||
station: first, fuel: fuel, baseline: baseline)
|
||||
bestValuePriceWarning = FuelPriceFreshness.comparisonWarning(
|
||||
station: first, fuel: fuel, baseline: baseline)
|
||||
}
|
||||
if let first = ranked.first, let baseline,
|
||||
bestValuePriceConfidence != .ineligible {
|
||||
let baselineJourney = journey(baseline)
|
||||
let result = FuelSavingsEstimator.availability(
|
||||
station: first,
|
||||
@@ -348,7 +358,9 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
date: Date(), stations: Array(ordered.prefix(8)),
|
||||
fuel: fuel, sort: sort, isFavourites: isFavourites,
|
||||
location: origin, locationSource: source,
|
||||
unit: unit, bestValueResult: bestValueResult
|
||||
unit: unit, bestValueResult: bestValueResult,
|
||||
bestValuePriceConfidence: bestValuePriceConfidence,
|
||||
bestValuePriceWarning: bestValuePriceWarning
|
||||
)
|
||||
), originSource)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user