Ship production optimization M1-M12.5A: queues, metrics, HTTP observability, and vector search reliability.
Keep similar-ai from tripping the global circuit on a lone URL 502, clamp Qdrant search to 100, and add Server-Timing plus slow-request logging. Studio shared props, Academy S3 exists caching, heat chunking, and Redis/scheduler hygiene stay in this rollout.
This commit is contained in:
@@ -135,7 +135,7 @@ function seedCreatorJourneyFixture(): User
|
||||
DB::table('artwork_metric_snapshots_hourly')->insert([
|
||||
[
|
||||
'artwork_id' => $breakthroughArtwork->id,
|
||||
'bucket_hour' => Carbon::parse('2024-05-10 10:00:00'),
|
||||
'bucket_hour' => now()->subHours(5)->startOfHour(),
|
||||
'views_count' => 1200,
|
||||
'downloads_count' => 40,
|
||||
'favourites_count' => 60,
|
||||
@@ -145,7 +145,7 @@ function seedCreatorJourneyFixture(): User
|
||||
],
|
||||
[
|
||||
'artwork_id' => $breakthroughArtwork->id,
|
||||
'bucket_hour' => Carbon::parse('2024-05-10 11:00:00'),
|
||||
'bucket_hour' => now()->subHours(4)->startOfHour(),
|
||||
'views_count' => 1320,
|
||||
'downloads_count' => 64,
|
||||
'favourites_count' => 68,
|
||||
@@ -155,7 +155,7 @@ function seedCreatorJourneyFixture(): User
|
||||
],
|
||||
[
|
||||
'artwork_id' => $lateYearArtwork->id,
|
||||
'bucket_hour' => Carbon::parse('2024-11-20 19:00:00'),
|
||||
'bucket_hour' => now()->subHours(3)->startOfHour(),
|
||||
'views_count' => 300,
|
||||
'downloads_count' => 10,
|
||||
'favourites_count' => 12,
|
||||
@@ -165,7 +165,7 @@ function seedCreatorJourneyFixture(): User
|
||||
],
|
||||
[
|
||||
'artwork_id' => $lateYearArtwork->id,
|
||||
'bucket_hour' => Carbon::parse('2024-11-20 20:00:00'),
|
||||
'bucket_hour' => now()->subHours(2)->startOfHour(),
|
||||
'views_count' => 360,
|
||||
'downloads_count' => 14,
|
||||
'favourites_count' => 15,
|
||||
@@ -276,4 +276,45 @@ it('hydrates the public profile page with creator journey props', function () {
|
||||
->where('journey.timeline', fn ($timeline) => collect($timeline)->pluck('headline')->contains('First Spectrum Pack'))
|
||||
->where('journeyApiUrl', route('api.profile.journey', ['username' => strtolower((string) $creator->username)]))
|
||||
);
|
||||
});
|
||||
|
||||
it('ignores download spikes older than the snapshot retention window', function () {
|
||||
$creator = seedCreatorJourneyFixture();
|
||||
$oldArtwork = Artwork::query()->where('user_id', $creator->id)->where('slug', 'sky-one')->firstOrFail();
|
||||
|
||||
DB::table('artwork_metric_snapshots_hourly')->insert([
|
||||
[
|
||||
'artwork_id' => $oldArtwork->id,
|
||||
'bucket_hour' => now()->subDays(40)->startOfHour(),
|
||||
'views_count' => 10,
|
||||
'downloads_count' => 1,
|
||||
'favourites_count' => 0,
|
||||
'comments_count' => 0,
|
||||
'shares_count' => 0,
|
||||
'created_at' => now(),
|
||||
],
|
||||
[
|
||||
'artwork_id' => $oldArtwork->id,
|
||||
'bucket_hour' => now()->subDays(40)->addHour()->startOfHour(),
|
||||
'views_count' => 10,
|
||||
'downloads_count' => 900,
|
||||
'favourites_count' => 0,
|
||||
'comments_count' => 0,
|
||||
'shares_count' => 0,
|
||||
'created_at' => now(),
|
||||
],
|
||||
]);
|
||||
|
||||
app(CreatorJourneyService::class)->rebuildForUser($creator);
|
||||
|
||||
$spike = DB::table('creator_milestones')
|
||||
->where('user_id', $creator->id)
|
||||
->where('type', 'biggest_download_spike')
|
||||
->first();
|
||||
|
||||
$payload = json_decode((string) $spike->payload_json, true);
|
||||
|
||||
expect($spike)->not->toBeNull()
|
||||
->and((int) data_get($payload, 'metrics.downloads_in_hour'))->toBe(24)
|
||||
->and((int) data_get($payload, 'metrics.downloads_in_hour'))->not->toBe(899);
|
||||
});
|
||||
Reference in New Issue
Block a user