From 7f64c42a23128290cfa39cfc29ae09bbcc74a07f Mon Sep 17 00:00:00 2001 From: Ovidiu U Date: Wed, 29 Apr 2026 20:00:01 +0100 Subject: [PATCH] refactor: extract DbDialect helper, inline ProfileValidationRules trait MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audit items #17 and #21. #17 — DayOfWeekSignal and StickinessSignal each had their own isSqlite ternary picking between SQLite (strftime/julianday) and MySQL (DAYOFWEEK/DATEDIFF) date expressions. Centralised in App\Services\Prediction\Signals\DbDialect. #21 — ProfileValidationRules was a trait with one consumer (CreateNewUser); inlined the rules into the action and deleted the trait. Also dropped PasswordValidationRules::currentPasswordRules() which was unused. PasswordValidationRules trait stays (two consumers). Co-Authored-By: Claude Opus 4.7 (1M context) --- app/Actions/Fortify/CreateNewUser.php | 7 +-- app/Concerns/PasswordValidationRules.php | 10 ---- app/Concerns/ProfileValidationRules.php | 50 ------------------- .../Prediction/Signals/DayOfWeekSignal.php | 5 +- app/Services/Prediction/Signals/DbDialect.php | 40 +++++++++++++++ .../Prediction/Signals/StickinessSignal.php | 5 +- 6 files changed, 46 insertions(+), 71 deletions(-) delete mode 100644 app/Concerns/ProfileValidationRules.php create mode 100644 app/Services/Prediction/Signals/DbDialect.php diff --git a/app/Actions/Fortify/CreateNewUser.php b/app/Actions/Fortify/CreateNewUser.php index 3c7c00c..d7e1a36 100644 --- a/app/Actions/Fortify/CreateNewUser.php +++ b/app/Actions/Fortify/CreateNewUser.php @@ -3,14 +3,14 @@ namespace App\Actions\Fortify; use App\Concerns\PasswordValidationRules; -use App\Concerns\ProfileValidationRules; use App\Models\User; use Illuminate\Support\Facades\Validator; +use Illuminate\Validation\Rule; use Laravel\Fortify\Contracts\CreatesNewUsers; class CreateNewUser implements CreatesNewUsers { - use PasswordValidationRules, ProfileValidationRules; + use PasswordValidationRules; /** * Validate and create a newly registered user. @@ -20,7 +20,8 @@ class CreateNewUser implements CreatesNewUsers public function create(array $input): User { Validator::make($input, [ - ...$this->profileRules(), + 'name' => ['required', 'string', 'max:255'], + 'email' => ['required', 'string', 'email', 'max:255', Rule::unique(User::class)], 'password' => $this->passwordRules(), ])->validate(); diff --git a/app/Concerns/PasswordValidationRules.php b/app/Concerns/PasswordValidationRules.php index e858302..1d6c887 100644 --- a/app/Concerns/PasswordValidationRules.php +++ b/app/Concerns/PasswordValidationRules.php @@ -16,14 +16,4 @@ trait PasswordValidationRules { return ['required', 'string', Password::default(), 'confirmed']; } - - /** - * Get the validation rules used to validate the current password. - * - * @return array|string> - */ - protected function currentPasswordRules(): array - { - return ['required', 'string', 'current_password']; - } } diff --git a/app/Concerns/ProfileValidationRules.php b/app/Concerns/ProfileValidationRules.php deleted file mode 100644 index 46e19ba..0000000 --- a/app/Concerns/ProfileValidationRules.php +++ /dev/null @@ -1,50 +0,0 @@ -|string>> - */ - protected function profileRules(?int $userId = null): array - { - return [ - 'name' => $this->nameRules(), - 'email' => $this->emailRules($userId), - ]; - } - - /** - * Get the validation rules used to validate user names. - * - * @return array|string> - */ - protected function nameRules(): array - { - return ['required', 'string', 'max:255']; - } - - /** - * Get the validation rules used to validate user emails. - * - * @return array|string> - */ - protected function emailRules(?int $userId = null): array - { - return [ - 'required', - 'string', - 'email', - 'max:255', - $userId === null - ? Rule::unique(User::class) - : Rule::unique(User::class)->ignore($userId), - ]; - } -} diff --git a/app/Services/Prediction/Signals/DayOfWeekSignal.php b/app/Services/Prediction/Signals/DayOfWeekSignal.php index 8149c51..f3b464e 100644 --- a/app/Services/Prediction/Signals/DayOfWeekSignal.php +++ b/app/Services/Prediction/Signals/DayOfWeekSignal.php @@ -10,10 +10,7 @@ final class DayOfWeekSignal extends AbstractSignal public function compute(SignalContext $context): array { - $isSqlite = DB::connection()->getDriverName() === 'sqlite'; - $dowExpr = $isSqlite - ? "(CAST(strftime('%w', price_effective_at) AS INTEGER) + 1)" - : 'DAYOFWEEK(price_effective_at)'; + $dowExpr = DbDialect::dayOfWeekExpr('price_effective_at'); $rows = DB::table('station_prices') ->where('fuel_type', $context->fuelType->value) diff --git a/app/Services/Prediction/Signals/DbDialect.php b/app/Services/Prediction/Signals/DbDialect.php new file mode 100644 index 0000000..40cd53c --- /dev/null +++ b/app/Services/Prediction/Signals/DbDialect.php @@ -0,0 +1,40 @@ +getDriverName() === 'sqlite'; + } + + /** + * Day-of-week expression returning 1=Sun..7=Sat (MySQL DAYOFWEEK convention). + * Targets a column on the queried table. + */ + public static function dayOfWeekExpr(string $column): string + { + return self::isSqlite() + ? "(CAST(strftime('%w', {$column}) AS INTEGER) + 1)" + : "DAYOFWEEK({$column})"; + } + + /** + * Whole-day difference between MAX and MIN of a datetime column, suitable + * for use in an aggregate selectRaw. + */ + public static function maxMinDayDiffExpr(string $column): string + { + return self::isSqlite() + ? "CAST((julianday(MAX({$column})) - julianday(MIN({$column}))) AS INTEGER)" + : "DATEDIFF(MAX({$column}), MIN({$column}))"; + } +} diff --git a/app/Services/Prediction/Signals/StickinessSignal.php b/app/Services/Prediction/Signals/StickinessSignal.php index 89af42a..e463d84 100644 --- a/app/Services/Prediction/Signals/StickinessSignal.php +++ b/app/Services/Prediction/Signals/StickinessSignal.php @@ -8,10 +8,7 @@ final class StickinessSignal extends AbstractSignal { public function compute(SignalContext $context): array { - $isSqlite = DB::connection()->getDriverName() === 'sqlite'; - $diffExpr = $isSqlite - ? 'CAST((julianday(MAX(price_effective_at)) - julianday(MIN(price_effective_at))) AS INTEGER)' - : 'DATEDIFF(MAX(price_effective_at), MIN(price_effective_at))'; + $diffExpr = DbDialect::maxMinDayDiffExpr('price_effective_at'); $rows = DB::table('station_prices') ->where('fuel_type', $context->fuelType->value)