- Delete unused Livewire Search test and fuel type select Blade component
- Move subscription webhook listener from EventServiceProvider to AppServiceProvider
- Add FUEL_TYPES global config to app layout for client-side use
- Add Billable trait to User model and include email_verified_at in fillable
- Implement monthly/annual cadence toggle with pricing display and smart CTA routing on homepage
- Update VerifyApiKeyMiddlewareTest to use e10 instead of petrol
- Refactor PollFuelPrices to auto-refresh stale stations based on last_seen_at
- Add incremental polling with cached timestamp and effective-start-timestamp param to FuelPriceService
- Normalize amenities/fuel_types from API objects to flat arrays, skip stations missing required fields
- Log response body on API failures in ApiLogger
- Default homepage sort to 'reliable' instead of 'price'
Adds authenticated endpoints for reading/updating fuel type preferences and managing saved stations, backed by new migrations and a SavedStation model.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Enables stateful API via Sanctum so the Vue SPA can call /api/* routes
using cookie auth, without requiring an X-Api-Key header.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extends NearbyStationsRequest to accept `postcode` (full or outcode) as an alternative to lat/lng. PostcodeService resolves it via postcodes.io and falls through to coordinates. Also adds SearchResource to the Filament admin panel for viewing logged search activity with fuel type filter and price/distance stats columns. Includes SQLite GREATEST/LEAST function polyfills in AppServiceProvider for test compatibility.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Four-stat overview widget (users, stations, oil prediction, API errors)
with 30s polling registered on the admin panel dashboard.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Runs is_admin migration, adds AdminSeeder for the admin user, registers
it in DatabaseSeeder, adds admin() factory state to UserFactory, and
adds AdminAccessTest covering both forbidden and ok cases.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>