chore: retire legacy oil prediction pipeline
Removes everything that was made redundant by the new forecasting stack. Per docs/superpowers/specs/2026-05-01-prediction-rebuild-design.md, this was the cleanup planned at the end of Phase 4. Deleted services and code: - App\Services\Prediction\Signals\* (the old six-signal aggregator — trend, supermarket, day-of-week, brand-behaviour, stickiness, regional-momentum, oil — replaced by RidgeRegressionModel). - App\Services\NationalFuelPredictionService (the post-Phase-4 thin shim; StationSearchService now depends on WeeklyForecastService directly, set up in the previous commit). - App\Services\LlmPrediction\* (AbstractLlmPredictionProvider plus the four provider implementations — Anthropic, OpenAI, Gemini, and the OilPredictionProvider router. Replaced by LlmOverlayService). - App\Services\BrentPricePredictor and App\Services\Ewma. The Ewma helper had no callers left after BrentPricePredictor went. - App\Models\PricePrediction and its factory. - App\Console\Commands\PredictOilPrices (the oil:predict command). - App\Filament\Resources\OilPredictionResource and its Pages. Schema and dashboard: - Drop the price_predictions table via a new migration. - Repoint the Filament StatsOverviewWidget tile from PricePrediction to WeeklyForecast so the dashboard reflects the new pipeline. - Remove the OilPredictionProvider binding from AppServiceProvider. Test cleanup: - Delete tests for every retired service. - Update StatsOverviewWidgetTest to seed weekly_forecasts instead of price_predictions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Services\BrentPricePredictor;
|
||||
use Illuminate\Console\Command;
|
||||
use Throwable;
|
||||
|
||||
class PredictOilPrices extends Command
|
||||
{
|
||||
protected $signature = 'oil:predict {--force : Generate even if the latest price already has a prediction}';
|
||||
|
||||
protected $description = 'Generate a Brent crude oil price direction prediction';
|
||||
|
||||
public function handle(BrentPricePredictor $predictor): int
|
||||
{
|
||||
try {
|
||||
$latest = $predictor->latestPrice();
|
||||
|
||||
if ($latest?->prediction_generated_at !== null && ! $this->option('force')) {
|
||||
$message = sprintf(
|
||||
'Prediction already generated for %s at %s.',
|
||||
$latest->date->toDateString(),
|
||||
$latest->prediction_generated_at->toDateTimeString(),
|
||||
);
|
||||
|
||||
if (! $this->confirm($message.' Run again anyway?', default: false)) {
|
||||
$this->info('Skipped.');
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('Generating prediction...');
|
||||
$prediction = $predictor->generatePrediction();
|
||||
|
||||
if ($prediction === null) {
|
||||
$this->error('Could not generate a prediction — not enough price data.');
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
$this->info(sprintf(
|
||||
'Done. [%s] direction=%s confidence=%d%% — %s',
|
||||
strtoupper($prediction->source->value),
|
||||
$prediction->direction->value,
|
||||
$prediction->confidence,
|
||||
$prediction->reasoning,
|
||||
));
|
||||
} catch (Throwable $e) {
|
||||
$this->error("Prediction failed: {$e->getMessage()}");
|
||||
|
||||
return self::FAILURE;
|
||||
}
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user