From cf187f97214f0de330f4482c1f9ee09c55fd965b Mon Sep 17 00:00:00 2001 From: Ovidiu U Date: Sat, 4 Apr 2026 13:59:55 +0100 Subject: [PATCH] feat: add HasFactory and factories for ApiLog, BrentPrice, PricePrediction Co-Authored-By: Claude Sonnet 4.6 --- app/Models/ApiLog.php | 5 +++ app/Models/BrentPrice.php | 5 +++ app/Models/PricePrediction.php | 5 +++ database/factories/ApiLogFactory.php | 31 +++++++++++++++++ database/factories/BrentPriceFactory.php | 27 +++++++++++++++ database/factories/PricePredictionFactory.php | 34 +++++++++++++++++++ 6 files changed, 107 insertions(+) create mode 100644 database/factories/ApiLogFactory.php create mode 100644 database/factories/BrentPriceFactory.php create mode 100644 database/factories/PricePredictionFactory.php diff --git a/app/Models/ApiLog.php b/app/Models/ApiLog.php index b002ae8..b92e3ef 100644 --- a/app/Models/ApiLog.php +++ b/app/Models/ApiLog.php @@ -2,12 +2,17 @@ namespace App\Models; +use Database\Factories\ApiLogFactory; use Illuminate\Database\Eloquent\Attributes\Fillable; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; #[Fillable(['service', 'method', 'url', 'status_code', 'duration_ms', 'error'])] class ApiLog extends Model { + /** @use HasFactory */ + use HasFactory; + const null UPDATED_AT = null; protected function casts(): array diff --git a/app/Models/BrentPrice.php b/app/Models/BrentPrice.php index 412ebb1..0039e62 100644 --- a/app/Models/BrentPrice.php +++ b/app/Models/BrentPrice.php @@ -2,7 +2,9 @@ namespace App\Models; +use Database\Factories\BrentPriceFactory; use Illuminate\Database\Eloquent\Attributes\Fillable; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Carbon; @@ -13,6 +15,9 @@ use Illuminate\Support\Carbon; #[Fillable(['date', 'price_usd'])] class BrentPrice extends Model { + /** @use HasFactory */ + use HasFactory; + public $timestamps = false; protected $primaryKey = 'date'; diff --git a/app/Models/PricePrediction.php b/app/Models/PricePrediction.php index fb0c94f..e2d3102 100644 --- a/app/Models/PricePrediction.php +++ b/app/Models/PricePrediction.php @@ -4,7 +4,9 @@ namespace App\Models; use App\Enums\PredictionSource; use App\Enums\TrendDirection; +use Database\Factories\PricePredictionFactory; use Illuminate\Database\Eloquent\Attributes\Fillable; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Carbon; @@ -20,6 +22,9 @@ use Illuminate\Support\Carbon; #[Fillable(['predicted_for', 'source', 'direction', 'confidence', 'reasoning', 'generated_at'])] class PricePrediction extends Model { + /** @use HasFactory */ + use HasFactory; + public $timestamps = false; protected function casts(): array diff --git a/database/factories/ApiLogFactory.php b/database/factories/ApiLogFactory.php new file mode 100644 index 0000000..a418332 --- /dev/null +++ b/database/factories/ApiLogFactory.php @@ -0,0 +1,31 @@ + */ +class ApiLogFactory extends Factory +{ + public function definition(): array + { + return [ + 'service' => fake()->randomElement(['fuel_finder', 'fred', 'anthropic', 'postcodes_io']), + 'method' => fake()->randomElement(['GET', 'POST']), + 'url' => fake()->url(), + 'status_code' => fake()->randomElement([200, 200, 200, 401, 429, 500]), + 'duration_ms' => fake()->numberBetween(50, 2000), + 'error' => null, + 'created_at' => fake()->dateTimeBetween('-7 days'), + ]; + } + + public function failed(): static + { + return $this->state([ + 'status_code' => fake()->randomElement([400, 401, 403, 429, 500, 503]), + 'error' => fake()->sentence(), + ]); + } +} diff --git a/database/factories/BrentPriceFactory.php b/database/factories/BrentPriceFactory.php new file mode 100644 index 0000000..6101f43 --- /dev/null +++ b/database/factories/BrentPriceFactory.php @@ -0,0 +1,27 @@ + */ +class BrentPriceFactory extends Factory +{ + /** @var array */ + private static array $usedDates = []; + + public function definition(): array + { + do { + $date = fake()->dateTimeBetween('-60 days')->format('Y-m-d'); + } while (in_array($date, self::$usedDates, true)); + + self::$usedDates[] = $date; + + return [ + 'date' => $date, + 'price_usd' => fake()->randomFloat(2, 65, 95), + ]; + } +} diff --git a/database/factories/PricePredictionFactory.php b/database/factories/PricePredictionFactory.php new file mode 100644 index 0000000..5e70eba --- /dev/null +++ b/database/factories/PricePredictionFactory.php @@ -0,0 +1,34 @@ + */ +class PricePredictionFactory extends Factory +{ + public function definition(): array + { + return [ + 'predicted_for' => fake()->dateTimeBetween('-30 days')->format('Y-m-d'), + 'source' => fake()->randomElement(PredictionSource::cases()), + 'direction' => fake()->randomElement(TrendDirection::cases()), + 'confidence' => fake()->numberBetween(40, 85), + 'reasoning' => fake()->sentence(12), + 'generated_at' => now(), + ]; + } + + public function llm(): static + { + return $this->state(['source' => PredictionSource::Llm]); + } + + public function ewma(): static + { + return $this->state(['source' => PredictionSource::Ewma]); + } +}