feat: add GET /api/prediction endpoint

Implements PredictionRequest (fuel_type validation with ValueError→ValidationException), PredictionController delegating to NationalFuelPredictionService, and 5 feature tests. Also fixes LEAST() MySQL-only function to a CASE WHEN expression for SQLite test compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ovidiu U
2026-04-04 19:26:48 +01:00
parent 1c548eae87
commit cf6a1369d4
4 changed files with 119 additions and 1 deletions

View File

@@ -344,7 +344,7 @@ class NationalFuelPredictionService
->join('stations', 'station_prices.station_id', '=', 'stations.node_id')
->where('station_prices.fuel_type', $fuelType->value)
->where('station_prices.price_effective_at', '>=', now()->subDays(14))
->whereRaw('(6371 * acos(LEAST(1.0, cos(radians(?)) * cos(radians(lat)) * cos(radians(lng) - radians(?)) + sin(radians(?)) * sin(radians(lat))))) <= 50', [$lat, $lng, $lat])
->whereRaw('(6371 * acos(CASE WHEN (cos(radians(?)) * cos(radians(lat)) * cos(radians(lng) - radians(?)) + sin(radians(?)) * sin(radians(lat))) > 1.0 THEN 1.0 ELSE (cos(radians(?)) * cos(radians(lat)) * cos(radians(lng) - radians(?)) + sin(radians(?)) * sin(radians(lat))) END)) <= 50', [$lat, $lng, $lat, $lat, $lng, $lat])
->selectRaw('DATE(station_prices.price_effective_at) as day, AVG(station_prices.price_pence) as avg_price')
->groupBy('day')
->orderBy('day')