refactor: extract Brent price sources into dedicated classes
OilPriceService no longer inlines per-provider fetch/transform/error logic. EIA and FRED are now their own classes with a common shape; the service just iterates and upserts the first successful result.
This commit is contained in:
58
app/Services/BrentPriceSources/FredBrentPriceSource.php
Normal file
58
app/Services/BrentPriceSources/FredBrentPriceSource.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\BrentPriceSources;
|
||||
|
||||
use App\Services\ApiLogger;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Throwable;
|
||||
|
||||
final class FredBrentPriceSource
|
||||
{
|
||||
private const string URL = 'https://api.stlouisfed.org/fred/series/observations';
|
||||
|
||||
public function __construct(private readonly ApiLogger $apiLogger) {}
|
||||
|
||||
/**
|
||||
* @return array{date: string, price_usd: float}[]|null
|
||||
*/
|
||||
public function fetch(): ?array
|
||||
{
|
||||
try {
|
||||
$response = $this->apiLogger->send('fred', 'GET', self::URL, fn () => Http::timeout(10)
|
||||
->get(self::URL, [
|
||||
'series_id' => 'DCOILBRENTEU',
|
||||
'api_key' => config('services.fred.api_key'),
|
||||
'sort_order' => 'desc',
|
||||
'limit' => 30,
|
||||
'file_type' => 'json',
|
||||
]));
|
||||
|
||||
if (! $response->successful()) {
|
||||
Log::error('FredBrentPriceSource: request failed', ['status' => $response->status()]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$rows = collect($response->json('observations') ?? [])
|
||||
->filter(fn (array $obs) => $obs['value'] !== '.')
|
||||
->map(fn (array $obs) => [
|
||||
'date' => $obs['date'],
|
||||
'price_usd' => (float) $obs['value'],
|
||||
])
|
||||
->all();
|
||||
|
||||
if ($rows === []) {
|
||||
Log::warning('FredBrentPriceSource: no valid observations returned');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $rows;
|
||||
} catch (Throwable $e) {
|
||||
Log::error('FredBrentPriceSource: fetch failed', ['error' => $e->getMessage()]);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user