subDay()->toDateString(); DB::table('feed_daily_metrics')->insert([ [ 'metric_date' => $metricDate, 'algo_version' => 'clip-cosine-v1', 'source' => 'personalized', 'impressions' => 100, 'clicks' => 20, 'saves' => 6, 'ctr' => 0.2, 'save_rate' => 0.3, 'dwell_0_5' => 4, 'dwell_5_30' => 8, 'dwell_30_120' => 5, 'dwell_120_plus' => 3, 'created_at' => now(), 'updated_at' => now(), ], [ 'metric_date' => $metricDate, 'algo_version' => 'clip-cosine-v2', 'source' => 'personalized', 'impressions' => 100, 'clicks' => 22, 'saves' => 8, 'ctr' => 0.22, 'save_rate' => 0.36, 'dwell_0_5' => 3, 'dwell_5_30' => 9, 'dwell_30_120' => 6, 'dwell_120_plus' => 4, 'created_at' => now(), 'updated_at' => now(), ], ]); $this->artisan('analytics:evaluate-feed-weights', ['--from' => $metricDate, '--to' => $metricDate]) ->assertSuccessful(); }); it('compares baseline and candidate feed algos', function () { $metricDate = now()->subDay()->toDateString(); DB::table('feed_daily_metrics')->insert([ [ 'metric_date' => $metricDate, 'algo_version' => 'clip-cosine-v1', 'source' => 'personalized', 'impressions' => 100, 'clicks' => 20, 'saves' => 6, 'ctr' => 0.2, 'save_rate' => 0.3, 'dwell_0_5' => 4, 'dwell_5_30' => 8, 'dwell_30_120' => 5, 'dwell_120_plus' => 3, 'created_at' => now(), 'updated_at' => now(), ], [ 'metric_date' => $metricDate, 'algo_version' => 'clip-cosine-v2', 'source' => 'personalized', 'impressions' => 100, 'clicks' => 24, 'saves' => 10, 'ctr' => 0.24, 'save_rate' => 0.416, 'dwell_0_5' => 3, 'dwell_5_30' => 8, 'dwell_30_120' => 7, 'dwell_120_plus' => 6, 'created_at' => now(), 'updated_at' => now(), ], ]); $this->artisan('analytics:compare-feed-ab', [ 'baseline' => 'clip-cosine-v1', 'candidate' => 'clip-cosine-v2', '--from' => $metricDate, '--to' => $metricDate, ])->assertSuccessful(); });