PostCreated::dispatch($post)); $this->notifyOnboarding($post); } public function deleted(Post $post): void { $this->notifyOnboarding($post); } public function saved(Post $post): void { if (! $post->wasChanged('status')) { return; } $previousStatus = $this->previousStatus($post); DB::afterCommit(fn () => PostStatusChanged::dispatch($post, $previousStatus)); } private function previousStatus(Post $post): ?PostStatus { $previous = $post->getRawOriginal('status'); if ($previous instanceof PostStatus) { return $previous; } if (is_string($previous)) { return PostStatus::tryFrom($previous); } return null; } /** * Notify only on the account's first post create or last post delete — * later creates / partial deletes would spam Echo while activation is open. */ private function notifyOnboarding(Post $post): void { $account = $post->workspace?->account; if ($account?->isOnboardingOpen() && $this->otherPosts($account, $post)->doesntExist()) { OnboardingStatusUpdated::dispatchForWorkspace($post->workspace_id, $post->user); } } /** * @return Builder */ private function otherPosts(Account $account, Post $post): Builder { return Post::query() ->whereIn('workspace_id', $account->workspaces()->select('id')) ->whereKeyNot($post->id); } }