2026-03-31 00:18:07 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
refactor: namespace PostHog jobs + extract billing tracking, add tests
Reorganises PostHog plumbing under `App\Jobs\PostHog` and extracts the
Stripe billing capture out of `StripeEventListener` into its own job.
Adds the missing test coverage that was promised but not delivered in
the previous commit.
Code changes:
- Move `app/Jobs/SendPostHogEvent.php` → `app/Jobs/PostHog/SendEvent.php`
(low-level dispatcher).
- Move `app/Jobs/SyncUserToPostHog.php` → `app/Jobs/PostHog/SyncUser.php`
(high-level user/account/workspace sync).
- New `app/Jobs/PostHog/TrackBilling.php` that owns the
capture('subscription.*') + SyncUser re-dispatch flow. Receives
account id + event name + payload, runs on the `posthog` queue.
- `StripeEventListener` slims down to a switch table mapping Stripe
event types to PostHog event names and dispatches `TrackBilling`. No
more inline tracking logic in the listener.
- `resources/js/posthog.ts` now owns `syncPostHogContext(page)` and
`capturePageview()`. `resources/js/app.ts` imports them — no behaviour
inlined in the bootstrap.
- `app/Services/PostHogService.php` and `app/Actions/User/CreateUser.php`
updated to the new namespaces.
Tests added/updated:
- `tests/Feature/Jobs/PostHog/SyncUserTest.php` — identify/group payload
shape, account metrics, workspace skip when none, queue assignment,
no-op without api key.
- `tests/Feature/Jobs/PostHog/TrackBillingTest.php` — capture payload,
SyncUser re-dispatch, missing-account/owner handling, api key gate.
- `tests/Feature/Jobs/PostHog/SendEventTest.php` — moved from
`tests/Feature/SendPostHogEventTest.php` and updated to new namespace.
- `tests/Unit/PostHogServiceTest.php` — adds coverage for the
account-aware capture (auto-attached `\$groups.account`, `account_id`,
`plan`) and the no-account branch.
- `tests/Feature/Listeners/StripeEventListenerTest.php` — replaces the
old inline-PostHog assertions with `Bus::fake([TrackBilling::class])`
and verifies the listener dispatches TrackBilling with the right
account id + event name for each subscription type, and skips
non-subscription event types.
- `tests/Feature/Actions/User/CreateUserTest.php` — verifies signup
dispatches `SyncUser` with the new user id.
Suite: 1427 passed (+20 net new, including the previous round of
metrics-related tests).
2026-05-07 12:41:36 +00:00
|
|
|
namespace App\Jobs\PostHog;
|
2026-03-31 00:18:07 +00:00
|
|
|
|
2026-05-07 15:42:35 +00:00
|
|
|
use App\Services\PostHogService;
|
2026-03-31 00:18:07 +00:00
|
|
|
use Illuminate\Bus\Queueable;
|
|
|
|
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
|
|
|
|
use Illuminate\Foundation\Bus\Dispatchable;
|
|
|
|
|
use Illuminate\Queue\InteractsWithQueue;
|
|
|
|
|
use Illuminate\Queue\SerializesModels;
|
|
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
|
use PostHog\PostHog;
|
|
|
|
|
|
refactor: namespace PostHog jobs + extract billing tracking, add tests
Reorganises PostHog plumbing under `App\Jobs\PostHog` and extracts the
Stripe billing capture out of `StripeEventListener` into its own job.
Adds the missing test coverage that was promised but not delivered in
the previous commit.
Code changes:
- Move `app/Jobs/SendPostHogEvent.php` → `app/Jobs/PostHog/SendEvent.php`
(low-level dispatcher).
- Move `app/Jobs/SyncUserToPostHog.php` → `app/Jobs/PostHog/SyncUser.php`
(high-level user/account/workspace sync).
- New `app/Jobs/PostHog/TrackBilling.php` that owns the
capture('subscription.*') + SyncUser re-dispatch flow. Receives
account id + event name + payload, runs on the `posthog` queue.
- `StripeEventListener` slims down to a switch table mapping Stripe
event types to PostHog event names and dispatches `TrackBilling`. No
more inline tracking logic in the listener.
- `resources/js/posthog.ts` now owns `syncPostHogContext(page)` and
`capturePageview()`. `resources/js/app.ts` imports them — no behaviour
inlined in the bootstrap.
- `app/Services/PostHogService.php` and `app/Actions/User/CreateUser.php`
updated to the new namespaces.
Tests added/updated:
- `tests/Feature/Jobs/PostHog/SyncUserTest.php` — identify/group payload
shape, account metrics, workspace skip when none, queue assignment,
no-op without api key.
- `tests/Feature/Jobs/PostHog/TrackBillingTest.php` — capture payload,
SyncUser re-dispatch, missing-account/owner handling, api key gate.
- `tests/Feature/Jobs/PostHog/SendEventTest.php` — moved from
`tests/Feature/SendPostHogEventTest.php` and updated to new namespace.
- `tests/Unit/PostHogServiceTest.php` — adds coverage for the
account-aware capture (auto-attached `\$groups.account`, `account_id`,
`plan`) and the no-account branch.
- `tests/Feature/Listeners/StripeEventListenerTest.php` — replaces the
old inline-PostHog assertions with `Bus::fake([TrackBilling::class])`
and verifies the listener dispatches TrackBilling with the right
account id + event name for each subscription type, and skips
non-subscription event types.
- `tests/Feature/Actions/User/CreateUserTest.php` — verifies signup
dispatches `SyncUser` with the new user id.
Suite: 1427 passed (+20 net new, including the previous round of
metrics-related tests).
2026-05-07 12:41:36 +00:00
|
|
|
class SendEvent implements ShouldQueue
|
2026-03-31 00:18:07 +00:00
|
|
|
{
|
|
|
|
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
|
|
|
|
|
|
|
|
|
public int $tries = 3;
|
|
|
|
|
|
|
|
|
|
public int $timeout = 15;
|
|
|
|
|
|
|
|
|
|
/**
|
2026-05-07 13:41:53 +00:00
|
|
|
* @param array<string, mixed> $payload
|
2026-03-31 00:18:07 +00:00
|
|
|
*/
|
|
|
|
|
public function __construct(
|
2026-05-07 13:41:53 +00:00
|
|
|
public string $method,
|
|
|
|
|
public array $payload,
|
2026-03-31 00:18:07 +00:00
|
|
|
) {
|
|
|
|
|
$this->onQueue('posthog');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function handle(): void
|
|
|
|
|
{
|
2026-05-07 15:42:35 +00:00
|
|
|
if (! PostHogService::isEnabled()) {
|
2026-03-31 00:18:07 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-07 13:41:53 +00:00
|
|
|
match ($this->method) {
|
|
|
|
|
'capture' => PostHog::capture($this->payload),
|
|
|
|
|
'identify' => PostHog::identify($this->payload),
|
|
|
|
|
'groupIdentify' => PostHog::groupIdentify($this->payload),
|
|
|
|
|
default => Log::warning('PostHog SendEvent: unknown method', ['method' => $this->method]),
|
|
|
|
|
};
|
2026-03-31 00:18:07 +00:00
|
|
|
|
|
|
|
|
PostHog::flush();
|
|
|
|
|
}
|
|
|
|
|
}
|