Skip to content

Commit d7a8cbb

Browse files
author
Sebastian BURGIN-FIX (ext)
committed
wip
1 parent 26fdbd4 commit d7a8cbb

2 files changed

Lines changed: 23 additions & 14 deletions

File tree

app/Console/Commands/FetchLlmAnalyticsCommand.php

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,24 @@
55
use App\Jobs\FetchLlmUsageJob;
66
use Carbon\CarbonImmutable;
77
use Carbon\CarbonPeriod;
8-
use Carbon\Exceptions\InvalidFormatException;
98
use Illuminate\Console\Command;
109

1110
class FetchLlmAnalyticsCommand extends Command
1211
{
12+
private const string INITIAL_SYNC_START = '2026-01-01';
13+
1314
protected $signature = 'llm:fetch-analytics
15+
{--full : Full sync from the very beginning ('.self::INITIAL_SYNC_START.')}
1416
{--from= : Start date (YYYY-MM-DD), defaults to 3 days ago}
1517
{--to= : End date (YYYY-MM-DD), defaults to today}';
1618

1719
protected $description = 'Fetch daily per-model LLM usage from the LiteLLM proxy and store it locally';
1820

1921
public function handle(): int
2022
{
21-
try {
22-
$to = $this->date($this->option('to')) ?? CarbonImmutable::today();
23-
$from = $this->date($this->option('from')) ?? $to->subDays(3);
24-
} catch (InvalidFormatException) {
25-
$this->error('Invalid date format, expected YYYY-MM-DD.');
26-
27-
return self::FAILURE;
28-
}
23+
$to = $this->date($this->option('to')) ?? CarbonImmutable::today();
24+
$from = $this->date($this->option('from'))
25+
?? ($this->option('full') ? $this->date(self::INITIAL_SYNC_START) : $to->subDays(3));
2926

3027
if ($from->greaterThan($to)) {
3128
$this->error('The --from date must not be after the --to date.');

tests/Feature/Commands/FetchLlmAnalyticsCommandTest.php

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22

33
use App\Jobs\FetchLlmUsageJob;
4+
use Carbon\CarbonImmutable;
5+
use Carbon\Exceptions\InvalidFormatException;
46
use Illuminate\Support\Facades\Queue;
57

68
it('dispatches one job per day for the default range', function () {
@@ -11,6 +13,18 @@
1113
Queue::assertPushed(FetchLlmUsageJob::class, 4);
1214
})->group('llm-analytics');
1315

16+
it('backfills from the initial sync start with the full flag', function () {
17+
Queue::fake();
18+
19+
$this->artisan('llm:fetch-analytics', ['--full' => true])->assertSuccessful();
20+
21+
$expectedDays = (int) CarbonImmutable::parse('2026-01-01')->diffInDays(CarbonImmutable::today()) + 1;
22+
23+
Queue::assertPushed(FetchLlmUsageJob::class, $expectedDays);
24+
25+
Queue::assertPushed(fn (FetchLlmUsageJob $job) => $job->date->toDateString() === '2026-01-01');
26+
})->group('llm-analytics');
27+
1428
it('dispatches one job per day for a custom range', function () {
1529
Queue::fake();
1630

@@ -23,13 +37,11 @@
2337
Queue::assertPushed(fn (FetchLlmUsageJob $job) => $job->date->toDateString() === '2026-01-05');
2438
})->group('llm-analytics');
2539

26-
it('fails on an invalid date', function () {
40+
it('throws on an invalid date', function () {
2741
Queue::fake();
2842

29-
$this->artisan('llm:fetch-analytics', ['--from' => 'not-a-date'])->assertFailed();
30-
31-
Queue::assertNothingPushed();
32-
})->group('llm-analytics');
43+
$this->artisan('llm:fetch-analytics', ['--from' => 'not-a-date']);
44+
})->throws(InvalidFormatException::class)->group('llm-analytics');
3345

3446
it('fails when from is after to', function () {
3547
Queue::fake();

0 commit comments

Comments
 (0)