feat: add Laravel Fortify skill, condense API data rules, add homepage mockup
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

This commit is contained in:
Ovidiu U
2026-04-09 14:19:04 +01:00
parent 1848c070da
commit 19d5c6eb0b
7 changed files with 753 additions and 394 deletions

View File

@@ -34,344 +34,25 @@ Content-Type: application/json
- Use the `refresh_token` to regenerate before expiry if needed
- Include token in every API request: `Authorization: Bearer {token}`
Fuel Finder REST API
The Fuel Finder API is a REST API that gives a simple, consistent way to request, create and update data. REST stands for Representational State Transfer which is an architectural software style in which standard HTTP request methods are used to retrieve and modify representations of data. This is identical to the process of retrieving a web page or submitting a web form.
Representational State Transfer (REST) web services
In a RESTful API, each data resource has a unique URL and is manipulated using standard HTTP verbs such as:
GET to request a resource
POST to create a resource (not used for read-only endpoints)
PUT to change a resource (not used for read-only endpoints)
DELETE to remove a resource (not used for read-only endpoints)
Example: request a price resource
GET: https://api.fuelfinder.service.gov.uk/v1/prices/GB-12345 HTTP/1.1
The request uses GET and does not include a request body.
In a RESTful API, a resource is modified by POSTing a revised resource representation, in this case JSON, to the same resource URL:
POST: https://api.fuelfinder.service.gov.uk/v1/<endpoint>
Content-Type: text/json
{
"CustomerName": "Joe Bloggs",
"Address": "",
"etc": etc
}
REST builds on the features of HTTP. Because each resource has a globally unique URL and can be fetched with GET, REST APIs can benefit from existing network components such as caches and proxies.
The JSON data format
Responses use JSON (JavaScript Object Notation). JSON is a compact, widely used format for storing and exchanging data. Most programming languages support JSON, which makes it well suited to HTTP-based API services.
#### Endpoints
- Endpoints
- Method Endpoint
- GET Fetch all PFS fuel prices
- GET Fetch incremental PFS fuel prices
- GET Fetch PFS information
- GET Fetch incremental PFS information
- `GET /api/v1/pfs/fuel-prices?batch-number` — all/incremental station prices
- `GET /api/v1/pfs?batch-number` — all/incremental station metadata
**Fuel prices response fields** (array of stations):
- `node_id` — station identifier
- `trading_name` — station name
- `fuel_prices[]` — array of `{fuel_type, price, price_last_updated, price_change_effective_timestamp}`
- Fuel types: `E5`, `E10`, `B7_STANDARD`, `B7_PREMIUM`, `B10`, `HVO`
- Price is a float (e.g. `159.9` = 159.9p) — multiply × 100 and store as integer pence
```
https://www.fuel-finder.service.gov.uk/api/v1/pfs/fuel-prices?batch-number
[
{
"node_id": "0028acef5f3afc41c7e7d56fb285a940dfb64d6fea01cb4accd79c148321112d",
"public_phone_number": null,
"trading_name": "Alex Fuel Station",
"fuel_prices": [
{
"fuel_type": "E5",
"price": 159.9,
"price_last_updated": "2026-02-17T16:03:04.938Z",
"price_change_effective_timestamp": "2026-02-17T16:00:00.000Z"
},
{
"fuel_type": "E10",
"price": 132.9,
"price_last_updated": "2026-02-17T16:03:04.938Z",
"price_change_effective_timestamp": "2026-02-17T16:00:00.000Z"
},
{
"fuel_type": "B7_STANDARD",
"price": 141.9,
"price_last_updated": "2026-02-17T16:03:04.938Z",
"price_change_effective_timestamp": "2026-02-17T16:00:00.000Z"
}
]
},
{
"node_id": "01da92125c3751767044d06b202f45da5933f0e16e256fa3e98a16af8386308d",
"public_phone_number": "",
"trading_name": "Star Garage",
"fuel_prices": [
{
"fuel_type": "E5",
"price": 159.9,
"price_last_updated": "2026-02-17T16:03:04.938Z",
"price_change_effective_timestamp": "2026-02-17T16:00:00.000Z"
}
]
},
{
"node_id": "020592cd81196efdb61ab2135f837ddf3d2bee4e64346810270f0b088b4c09d8",
"public_phone_number": null,
"trading_name": "Blue Hills Fuel Station",
"fuel_prices": [
{
"fuel_type": "E5",
"price": 159.9,
"price_last_updated": "2026-02-17T16:03:04.938Z",
"price_change_effective_timestamp": "2026-02-17T16:00:00.000Z"
},
{
"fuel_type": "B7_STANDARD",
"price": 141.9,
"price_last_updated": "2026-02-17T16:03:04.938Z",
"price_change_effective_timestamp": "2026-02-17T16:00:00.000Z"
}
]
}
]
```
```
https://www.fuel-finder.service.gov.uk/api/v1/pfs?batch-number=1
[
{
"node_id": "9b275ab576eeba3c6677984be15ee22a74e54fdfe8e5ea700e84a03178dc4ac1",
"public_phone_number": null,
"trading_name": "TEST",
"is_same_trading_and_brand_name": true,
"brand_name": "TEST",
"temporary_closure": false,
"permanent_closure": false,
"permanent_closure_date": null,
"is_motorway_service_station": false,
"is_supermarket_service_station": false,
"location": {
"address_line_1": "HALL & WOODHOUSE, TAPLOW BOATYARD, MILL LANE, TAPLOW, MAIDENHEAD, SL6 0AA",
"address_line_2": null,
"city": "MAIDENHEAD",
"country": "England",
"county": null,
"postcode": "SL6 0AA",
"latitude": 51.5268585,
"longitude": -0.700361
},
"amenities": [
"water_filling"
],
"opening_times": {
"usual_days": {
"monday": {
"open": "00:00:00",
"close": "00:00:00",
"is_24_hours": false
},
"tuesday": {
"open": "00:00:00",
"close": "00:00:00",
"is_24_hours": false
},
"wednesday": {
"open": "00:00:00",
"close": "00:00:00",
"is_24_hours": false
},
"thursday": {
"open": "00:00:00",
"close": "00:00:00",
"is_24_hours": false
},
"friday": {
"open": "00:00:00",
"close": "00:00:00",
"is_24_hours": false
},
"saturday": {
"open": "00:00:00",
"close": "00:00:00",
"is_24_hours": false
},
"sunday": {
"open": "00:00:00",
"close": "23:59:00",
"is_24_hours": true
}
},
"bank_holiday": {
"type": "bank holiday",
"open_time": "00:00:00",
"close_time": "00:00:00",
"is_24_hours": false
}
},
"fuel_types": [
"E10",
"E5",
"HVO",
"B10"
]
},
{
"node_id": "4fd9a4c6b48358b9b5c95989fba100fdcbb87c9e909ed4ce1ad96f64ffb8b56a",
"public_phone_number": "+44 7723608248",
"trading_name": "TEST FORECOURT 1",
"is_same_trading_and_brand_name": true,
"brand_name": "TEXACO ONE",
"temporary_closure": false,
"permanent_closure": null,
"permanent_closure_date": null,
"is_motorway_service_station": false,
"is_supermarket_service_station": false,
"location": {
"address_line_1": "NEWPORT",
"address_line_2": "",
"city": "BROUGH",
"country": "ENGLAND",
"county": "EAST YORKSHIRE",
"postcode": "HU15 2RD",
"latitude": 51.258503,
"longitude": -3.417567
},
"amenities": [
"adblue_packaged",
"adblue_pumps",
"car_wash",
"customer_toilets"
],
"opening_times": {
"usual_days": {
"monday": {
"open": "06:00:01",
"close": "23:00:01",
"is_24_hours": false
},
"tuesday": {
"open": "06:00:01",
"close": "23:00:01",
"is_24_hours": false
},
"wednesday": {
"open": "06:00:01",
"close": "23:00:01",
"is_24_hours": false
},
"thursday": {
"open": "06:00:01",
"close": "23:00:01",
"is_24_hours": false
},
"friday": {
"open": "06:00:01",
"close": "23:00:01",
"is_24_hours": false
},
"saturday": {
"open": "06:00:01",
"close": "23:00:01",
"is_24_hours": false
},
"sunday": {
"open": "06:00:01",
"close": "23:00:01",
"is_24_hours": false
}
},
"bank_holiday": {
"type": "standard",
"open_time": "06:00:01",
"close_time": "23:00:01",
"is_24_hours": false
}
},
"fuel_types": [
"B10"
]
},
{
"node_id": "91bdda1c07fa05110a31639cc66932f9ed8bd388d4f6be542a423365bcfd53e1",
"public_phone_number": "+442071930000",
"trading_name": "SUPERFUEL LOUGHBOROUGH 12",
"is_same_trading_and_brand_name": true,
"brand_name": "SUPERFUEL STATION 4",
"temporary_closure": false,
"permanent_closure": null,
"permanent_closure_date": null,
"is_motorway_service_station": false,
"is_supermarket_service_station": false,
"location": {
"address_line_1": "14 LONDON ROAD",
"address_line_2": "FUELVILLE",
"city": "LOUGHBOROUGH",
"country": "ENGLAND",
"county": "LEICESTERSHIRE",
"postcode": "LE11 9AA",
"latitude": 50.503343,
"longitude": -2.12444
},
"amenities": [
"adblue_packaged",
"adblue_pumps",
"car_wash",
"customer_toilets",
"water_filling"
],
"opening_times": {
"usual_days": {
"monday": {
"open": "06:00:00",
"close": "22:00:00",
"is_24_hours": false
},
"tuesday": {
"open": "06:00:00",
"close": "22:00:00",
"is_24_hours": false
},
"wednesday": {
"open": "06:00:00",
"close": "22:00:00",
"is_24_hours": false
},
"thursday": {
"open": "06:00:00",
"close": "22:00:00",
"is_24_hours": false
},
"friday": {
"open": "06:00:00",
"close": "22:00:00",
"is_24_hours": false
},
"saturday": {
"open": "06:00:00",
"close": "22:00:00",
"is_24_hours": false
},
"sunday": {
"open": "06:00:00",
"close": "22:00:00",
"is_24_hours": false
}
},
"bank_holiday": {
"type": "standard",
"open_time": "08:00:00",
"close_time": "20:00:00",
"is_24_hours": false
}
},
"fuel_types": [
"E5",
"HVO",
"B10",
"B7_PREMIUM",
"B7_STANDARD"
]
}
]
```
**Station metadata response fields** (array of stations):
- `node_id`, `trading_name`, `brand_name`
- `is_supermarket_service_station`, `is_motorway_service_station`
- `temporary_closure`, `permanent_closure`
- `location``{address_line_1, city, postcode, latitude, longitude}`
- `amenities` — string array (e.g. `car_wash`, `adblue_pumps`)
- `fuel_types` — string array of available fuel types
- `opening_times` — per-day open/close times (not used in scoring)
### FuelPriceService responsibilities
1. Fetch OAuth token (cache it)