*/ use HasFactory, HasUuids; protected $fillable = [ 'workspace_id', 'platform', 'platform_user_id', 'username', 'display_name', 'avatar_url', 'access_token', 'refresh_token', 'token_expires_at', 'scopes', 'meta', 'status', 'error_message', 'disconnected_at', ]; protected $hidden = [ 'access_token', 'refresh_token', ]; protected function casts(): array { return [ 'platform' => SocialPlatform::class, 'status' => Status::class, 'access_token' => 'encrypted', 'refresh_token' => 'encrypted', 'token_expires_at' => 'datetime', 'disconnected_at' => 'datetime', 'scopes' => 'array', 'meta' => 'array', ]; } public function workspace(): BelongsTo { return $this->belongsTo(Workspace::class); } public function postPlatforms(): HasMany { return $this->hasMany(PostPlatform::class); } protected function isTokenExpired(): Attribute { return Attribute::make( get: fn () => $this->token_expires_at && $this->token_expires_at->isPast(), ); } protected function isTokenExpiringSoon(): Attribute { return Attribute::make( get: fn () => $this->token_expires_at && $this->token_expires_at->isBefore(now()->addHour()), ); } protected function avatarUrl(): Attribute { return Attribute::make( get: fn (?string $value) => $value ? Storage::url($value) : null, ); } public function markAsDisconnected(string $errorMessage): void { $lock = Cache::lock("social_account_disconnect:{$this->id}", 10); if ($lock->get()) { try { $this->refresh(); $wasConnected = $this->status !== Status::Disconnected; $this->update([ 'status' => Status::Disconnected, 'error_message' => $errorMessage, 'disconnected_at' => now(), ]); if ($wasConnected) { Mail::to($this->workspace->owner)->send(new AccountDisconnected($this)); } } finally { $lock->release(); } } } public function markAsConnected(): void { $this->update([ 'status' => Status::Connected, 'error_message' => null, 'disconnected_at' => null, ]); } public function isDisconnected(): bool { return $this->status === Status::Disconnected || $this->status === Status::TokenExpired; } }