fix: model audit cleanups (primaryKey, fuel_type cast, cadence cache)

- StationPriceCurrent: $primaryKey was null; set to 'station_id' + keyType
  string so Eloquent has a sensible default for save() / find() paths.
- UserNotificationPreference: add FuelType enum cast on fuel_type so it
  hydrates as an enum like every other price model.
- Plan::resolveCadenceForUser: cache for 1h under the same plans tag as
  resolveForUser; HandleStripeWebhook busts both keys on subscription
  events.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ovidiu U
2026-04-29 18:32:55 +01:00
parent 775e076bb7
commit 783297694c
4 changed files with 36 additions and 22 deletions

View File

@@ -129,6 +129,8 @@ final class HandleStripeWebhook
private function bustPlanCache(User $user): void private function bustPlanCache(User $user): void
{ {
Cache::tags(['plans'])->forget("plan_for_user_{$user->id}"); $tag = Cache::tags(['plans']);
$tag->forget("plan_for_user_{$user->id}");
$tag->forget("plan_cadence_for_user_{$user->id}");
} }
} }

View File

@@ -77,33 +77,41 @@ class Plan extends Model
*/ */
public static function resolveCadenceForUser(User $user): ?string public static function resolveCadenceForUser(User $user): ?string
{ {
if (! method_exists($user, 'subscriptions')) { $cache = Cache::supportsTags() ? Cache::tags(['plans']) : Cache::store();
return null;
}
$priceId = $user->subscriptions()->active()->value('stripe_price'); return $cache->remember(
"plan_cadence_for_user_{$user->id}",
3600,
function () use ($user): ?string {
if (! method_exists($user, 'subscriptions')) {
return null;
}
if ($priceId === null) { $priceId = $user->subscriptions()->active()->value('stripe_price');
return null;
}
$plan = static::where('stripe_price_id_monthly', $priceId) if ($priceId === null) {
->orWhere('stripe_price_id_annual', $priceId) return null;
->first(); }
if ($plan === null) { $plan = static::where('stripe_price_id_monthly', $priceId)
return null; ->orWhere('stripe_price_id_annual', $priceId)
} ->first();
if ($plan->stripe_price_id_monthly === $priceId) { if ($plan === null) {
return 'monthly'; return null;
} }
if ($plan->stripe_price_id_annual === $priceId) { if ($plan->stripe_price_id_monthly === $priceId) {
return 'annual'; return 'monthly';
} }
return null; if ($plan->stripe_price_id_annual === $priceId) {
return 'annual';
}
return null;
}
);
} }
protected static function booted(): void protected static function booted(): void

View File

@@ -19,7 +19,9 @@ class StationPriceCurrent extends Model
public $timestamps = false; public $timestamps = false;
protected $primaryKey = null; protected $primaryKey = 'station_id';
protected $keyType = 'string';
public $incrementing = false; public $incrementing = false;

View File

@@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Enums\FuelType;
use Database\Factories\UserNotificationPreferenceFactory; use Database\Factories\UserNotificationPreferenceFactory;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -44,6 +45,7 @@ class UserNotificationPreference extends Model
{ {
return [ return [
'enabled' => 'boolean', 'enabled' => 'boolean',
'fuel_type' => FuelType::class,
]; ];
} }
} }