Dispatch PostCreated from PostObserver on every create.

Centralize provenance/broadcast/PostHog triggers so CreatePost and DuplicatePost no longer fire the event by hand.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Paulo Castellano 2026-07-24 12:01:01 -03:00
parent 8b1ce057c3
commit d1d38865ef
6 changed files with 54 additions and 15 deletions

View file

@ -6,7 +6,6 @@
use App\Enums\Post\CreatedVia;
use App\Enums\Post\Status as PostStatus;
use App\Events\PostCreated;
use App\Models\Post;
use App\Models\User;
use App\Models\Workspace;
@ -91,8 +90,6 @@ public static function execute(Workspace $workspace, User $user, array $data): P
return $post;
});
PostCreated::dispatch($post);
return $post;
}

View file

@ -7,7 +7,6 @@
use App\Enums\Post\CreatedVia;
use App\Enums\Post\Status as PostStatus;
use App\Enums\PostPlatform\Status as PostPlatformStatus;
use App\Events\PostCreated;
use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Facades\DB;
@ -21,7 +20,7 @@ class DuplicatePost
{
public static function execute(Post $original, User $user): Post
{
$copy = DB::transaction(function () use ($original, $user): Post {
return DB::transaction(function () use ($original, $user): Post {
$copy = $original->workspace->posts()->create([
'user_id' => $user->id,
'content' => $original->content,
@ -57,9 +56,5 @@ public static function execute(Post $original, User $user): Post
return $copy;
});
PostCreated::dispatch($copy);
return $copy;
}
}

View file

@ -6,11 +6,18 @@
use App\Enums\Automation\Trigger\Type as TriggerType;
use App\Enums\Post\Status as PostStatus;
use App\Events\PostCreated;
use App\Jobs\Automation\DispatchPostTriggerAutomationsJob;
use App\Models\Post;
use Illuminate\Contracts\Events\ShouldHandleEventsAfterCommit;
class PostObserver
class PostObserver implements ShouldHandleEventsAfterCommit
{
public function created(Post $post): void
{
PostCreated::dispatch($post);
}
public function saved(Post $post): void
{
if (! $post->wasChanged('status')) {
@ -27,6 +34,6 @@ public function saved(Post $post): void
return;
}
DispatchPostTriggerAutomationsJob::dispatch($post, $triggerType)->afterCommit();
DispatchPostTriggerAutomationsJob::dispatch($post, $triggerType);
}
}

View file

@ -9,7 +9,7 @@
use App\Models\Workspace;
use Illuminate\Support\Facades\Event;
test('execute dispatches PostCreated with the persisted post', function () {
test('execute relies on the observer to dispatch PostCreated', function () {
Event::fake([PostCreated::class]);
$user = User::factory()->create();

View file

@ -32,9 +32,7 @@
->and($copy->published_at)->toBeNull();
});
test('execute dispatches PostCreated for the duplicated post', function () {
Event::fake([PostCreated::class]);
test('execute relies on the observer to dispatch PostCreated for the duplicate', function () {
$user = User::factory()->create();
$workspace = Workspace::factory()->create(['user_id' => $user->id]);
$original = Post::factory()->create([
@ -42,6 +40,8 @@
'user_id' => $user->id,
]);
Event::fake([PostCreated::class]);
$copy = DuplicatePost::execute($original, $user);
Event::assertDispatched(

View file

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
use App\Events\PostCreated;
use App\Models\Post;
use App\Models\User;
use App\Models\Workspace;
use Illuminate\Support\Facades\Event;
test('creating a post dispatches PostCreated via the observer', function () {
Event::fake([PostCreated::class]);
$user = User::factory()->create();
$workspace = Workspace::factory()->create(['user_id' => $user->id]);
$post = Post::factory()->create([
'workspace_id' => $workspace->id,
'user_id' => $user->id,
]);
Event::assertDispatched(
PostCreated::class,
fn (PostCreated $event) => $event->post->id === $post->id,
);
});
test('creating a post quietly does not dispatch PostCreated', function () {
Event::fake([PostCreated::class]);
$user = User::factory()->create();
$workspace = Workspace::factory()->create(['user_id' => $user->id]);
Post::factory()->createQuietly([
'workspace_id' => $workspace->id,
'user_id' => $user->id,
]);
Event::assertNotDispatched(PostCreated::class);
});