*/ use HasFactory, Notifiable, PasskeyAuthenticatable, TwoFactorAuthenticatable; /** * @var array */ protected $attributes = [ 'reminder_months_before' => 1, 'ocr_provider' => 'none', 'locale' => 'nl', ]; /** * Get the attributes that should be cast. * * @return array */ protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', 'reminder_months_before' => 'integer', 'ocr_api_key' => 'encrypted', ]; } /** * @return HasMany */ public function certificates(): HasMany { return $this->hasMany(Certificate::class); } /** * @return HasMany */ public function categories(): HasMany { return $this->hasMany(Category::class); } /** * @return HasOne */ public function subscription(): HasOne { return $this->hasOne(Subscription::class); } /** * The user's current plan. Falls back to Free for a user without a * subscription row yet (e.g. factory-created users in tests) rather * than requiring every call site to null-check. */ public function plan(): SubscriptionPlan { return $this->subscription?->plan ?? SubscriptionPlan::Free; } /** * Whether the user has already reached their plan's certificate limit, * so a new upload should be blocked. Always false for unlimited plans. */ public function certificateLimitReached(): bool { $limit = $this->plan()->certificateLimit(); return $limit !== null && $this->certificates()->count() >= $limit; } /** * Get the user's initials */ public function initials(): string { $initials = Str::initials($this->name, true); return Str::length($initials) > 1 ? Str::substr($initials, 0, 1).Str::substr($initials, -1) : $initials; } }