Files
fuel-price/api-data.md
Ovidiu U 02d4c9d888
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
Add comprehensive project documentation and architecture guidelines
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.
2026-04-03 16:49:19 +01:00

69 lines
2.8 KiB
Markdown

# 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
1. Fetch OAuth token (cache it)
2. GET all station prices
3. Upsert `stations` table with metadata
4. Insert new rows into `station_prices` only when price has changed for that station+fuel combo
5. Call StationTaggingService to set `is_supermarket` and `brand`
6. Dispatch `PricesUpdatedEvent` for 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` + `lng` on `users` table
- 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_KEY` in .env
- Fetched once daily via scheduler at 7am
- Stored in `brent_prices` table: `(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 in `users.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-core` via Composer
- Credentials: `VONAGE_KEY`, `VONAGE_SECRET`, `VONAGE_WHATSAPP_FROM` in .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.