perf(resend): default sync-leads to last 24h window (#354)

## Why

`resend:sync-leads` was syncing every verified lead on each run, taking
4+ minutes.

## Change

- New `--since=N` option (hours). Default `24`.
- `--since=0` syncs all leads (manual backfill).
- Scheduler unchanged: runs daily at 03:00 → 24h window covers it.

## Tests

- Default 24h window excludes older leads.
- `--since=0` syncs everything.
This commit is contained in:
Víctor Falcón 2026-05-05 09:57:25 +01:00 committed by GitHub
parent b1709b714e
commit e387c038ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 7 deletions

View File

@ -8,12 +8,14 @@ use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
#[Signature('resend:sync-leads')]
#[Description('Sync all user leads to the Resend leads segment')]
#[Signature('resend:sync-leads {--since=24 : Sync leads created within the last N hours. Use 0 to sync all.}')]
#[Description('Sync user leads to the Resend leads segment (last 24h by default)')]
class ResendSyncLeadsCommand extends Command
{
public function handle(ResendService $resendService): int
{
$since = (int) $this->option('since');
if (! config('services.resend.key')) {
$this->error('Resend API key not configured.');
@ -28,6 +30,7 @@ class ResendSyncLeadsCommand extends Command
$leads = UserLead::query()
->whereNotNull('email_verified_at')
->when($since > 0, fn ($query) => $query->where('created_at', '>=', now()->subHours($since)))
->get();
if ($leads->isEmpty()) {

View File

@ -9,20 +9,39 @@ use function Pest\Laravel\mock;
const TEST_RESEND_LEADS_SEGMENT_ID = 'test-segment-id';
test('resend:sync-leads syncs all user leads to resend', function () {
test('resend:sync-leads syncs leads created in the last 24h by default', function () {
config([
'services.resend.key' => 'test-api-key',
'services.resend.leads_segment_id' => TEST_RESEND_LEADS_SEGMENT_ID,
]);
UserLead::factory()->count(3)->create();
UserLead::factory()->count(2)->create();
UserLead::factory()->count(3)->create(['created_at' => now()->subDays(2)]);
$resendService = mock(ResendService::class);
$resendService->shouldReceive('syncLead')->times(3);
$resendService->shouldReceive('syncLead')->times(2);
artisan('resend:sync-leads')
->expectsOutputToContain('Syncing 3 user leads to Resend...')
->expectsOutputToContain('Synced 3 user leads to Resend.')
->expectsOutputToContain('Syncing 2 user leads to Resend...')
->expectsOutputToContain('Synced 2 user leads to Resend.')
->assertSuccessful();
});
test('resend:sync-leads syncs all leads when --since=0', function () {
config([
'services.resend.key' => 'test-api-key',
'services.resend.leads_segment_id' => TEST_RESEND_LEADS_SEGMENT_ID,
]);
UserLead::factory()->count(2)->create();
UserLead::factory()->count(3)->create(['created_at' => now()->subDays(2)]);
$resendService = mock(ResendService::class);
$resendService->shouldReceive('syncLead')->times(5);
artisan('resend:sync-leads', ['--since' => 0])
->expectsOutputToContain('Syncing 5 user leads to Resend...')
->expectsOutputToContain('Synced 5 user leads to Resend.')
->assertSuccessful();
});