Establishes core rules and conventions for the FuelAlert Laravel application: architecture patterns (fat services, thin controllers), database schema with partitioned station_prices table, multi-tier notification system with Vonage and OneSignal, 4-signal scoring engine for fuel price recommendations, Stripe subscription tiers, Livewire classic component structure, and Pest testing standards.
2.8 KiB
2.8 KiB
External API & Data Sources
UK Fuel Finder API (gov.uk) — PRIMARY SOURCE
- Base URL:
https://api.fuel-finder.service.gov.uk/ - Auth: OAuth 2.0 client credentials (client_id + client_secret → Bearer token)
- Token stored in cache with TTL matching expiry minus 60 seconds
- Returns: all UK station prices + station metadata
- Update frequency: stations report within 30 minutes of price change
- Our polling interval: every 15 minutes via scheduler
FuelPriceService responsibilities
- Fetch OAuth token (cache it)
- GET all station prices
- Upsert
stationstable with metadata - Insert new rows into
station_pricesonly when price has changed for that station+fuel combo - Call StationTaggingService to set
is_supermarketandbrand - Dispatch
PricesUpdatedEventfor downstream processing
Deduplication
Only insert a new station_prices row if price differs from the most recent stored price
for that (station_id, fuel_type) combination. Avoids row explosion on unchanged prices.
Credentials in .env
FUEL_FINDER_CLIENT_ID=
FUEL_FINDER_CLIENT_SECRET=
FUEL_FINDER_BASE_URL=https://api.fuel-finder.service.gov.uk
Postcodes.io — postcode → lat/lng
- URL:
https://api.postcodes.io/postcodes/{postcode} - Free, no API key required
- Called once on user registration / when postcode changes
- Store resolved
lat+lngonuserstable - Cache postcode lookups for 30 days (postcodes rarely change coordinates)
FRED API (St. Louis Fed) — Brent crude direction
- Series:
DCOILBRENTEU(daily Brent spot price) - URL:
https://api.stlouisfed.org/fred/series/observations?series_id=DCOILBRENTEU&api_key={key}&sort_order=desc&limit=10&file_type=json - Free API key required — stored as
FRED_API_KEYin .env - Fetched once daily via scheduler at 7am
- Stored in
brent_pricestable:(date DATE, price_usd DECIMAL(8,2)) - Only the 5-day trend direction is used by the scoring engine
OneSignal — push notifications
- REST API:
https://oapi.onesignal.com/notifications - App ID + REST API key stored in .env as
ONESIGNAL_APP_ID,ONESIGNAL_API_KEY - Target by
player_id(stored inusers.push_token) - No official Laravel package needed — use Laravel HTTP client (
Http::post(...)) - Free plan: 10,000 subscribers — sufficient for v1
Vonage — WhatsApp + SMS
- Package:
vonage/client-corevia Composer - Credentials:
VONAGE_KEY,VONAGE_SECRET,VONAGE_WHATSAPP_FROMin .env - WhatsApp: Messages API, utility template category (pre-approved)
- SMS: SMS API, alphanumeric sender ID "FuelAlert"
- All Vonage calls go through NotificationDispatchService — never call Vonage directly from components
HTTP client
Use Laravel's built-in Http facade for all external API calls.
Always set a timeout: Http::timeout(10)->get(...).
Wrap in try/catch — log failures, never let a failed API call crash the scheduler.