134 lines
5.6 KiB
PHP
134 lines
5.6 KiB
PHP
<?php
|
|
|
|
namespace App\Console;
|
|
|
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
|
use App\Console\Commands\ImportLegacyUsers;
|
|
use App\Console\Commands\ImportCategories;
|
|
use App\Console\Commands\MigrateFeaturedWorks;
|
|
use App\Console\Commands\BackfillArtworkEmbeddingsCommand;
|
|
use App\Console\Commands\AggregateSimilarArtworkAnalyticsCommand;
|
|
use App\Console\Commands\AggregateFeedAnalyticsCommand;
|
|
use App\Console\Commands\AggregateTagInteractionAnalyticsCommand;
|
|
use App\Console\Commands\SeedTagInteractionDemoCommand;
|
|
use App\Console\Commands\EvaluateFeedWeightsCommand;
|
|
use App\Console\Commands\AiTagArtworksCommand;
|
|
use App\Console\Commands\SyncCountriesCommand;
|
|
use App\Console\Commands\CompareFeedAbCommand;
|
|
use App\Console\Commands\RecalculateTrendingCommand;
|
|
use App\Console\Commands\RecalculateRankingsCommand;
|
|
use App\Console\Commands\MetricsSnapshotHourlyCommand;
|
|
use App\Console\Commands\RecalculateHeatCommand;
|
|
use App\Jobs\UpdateLeaderboardsJob;
|
|
use App\Jobs\RankComputeArtworkScoresJob;
|
|
use App\Jobs\RankBuildListsJob;
|
|
use App\Uploads\Commands\CleanupUploadsCommand;
|
|
use App\Console\Commands\PublishScheduledArtworksCommand;
|
|
|
|
class Kernel extends ConsoleKernel
|
|
{
|
|
/**
|
|
* The Artisan commands provided by your application.
|
|
*
|
|
* @var array<int, class-string>
|
|
*/
|
|
protected $commands = [
|
|
ImportLegacyUsers::class,
|
|
\App\Console\Commands\EnforceUsernamePolicy::class,
|
|
ImportCategories::class,
|
|
MigrateFeaturedWorks::class,
|
|
\App\Console\Commands\AvatarsMigrate::class,
|
|
\App\Console\Commands\AvatarsBulkUpdate::class,
|
|
\App\Console\Commands\ResetAllUserPasswords::class,
|
|
CleanupUploadsCommand::class,
|
|
PublishScheduledArtworksCommand::class,
|
|
BackfillArtworkEmbeddingsCommand::class,
|
|
AggregateSimilarArtworkAnalyticsCommand::class,
|
|
AggregateFeedAnalyticsCommand::class,
|
|
AggregateTagInteractionAnalyticsCommand::class,
|
|
SeedTagInteractionDemoCommand::class,
|
|
EvaluateFeedWeightsCommand::class,
|
|
CompareFeedAbCommand::class,
|
|
AiTagArtworksCommand::class,
|
|
SyncCountriesCommand::class,
|
|
\App\Console\Commands\MigrateFollows::class,
|
|
RecalculateTrendingCommand::class,
|
|
RecalculateRankingsCommand::class,
|
|
MetricsSnapshotHourlyCommand::class,
|
|
RecalculateHeatCommand::class,
|
|
];
|
|
|
|
/**
|
|
* Define the application's command schedule.
|
|
*/
|
|
protected function schedule(\Illuminate\Console\Scheduling\Schedule $schedule): void
|
|
{
|
|
$schedule->command('uploads:cleanup')->dailyAt('03:00');
|
|
|
|
// Publish artworks whose scheduled publish_at has passed
|
|
$schedule->command('artworks:publish-scheduled')
|
|
->everyMinute()
|
|
->name('publish-scheduled-artworks')
|
|
->withoutOverlapping(2) // prevent overlap up to 2 minutes
|
|
->runInBackground();
|
|
$schedule->command('analytics:aggregate-similar-artworks')->dailyAt('03:10');
|
|
$schedule->command('analytics:aggregate-feed')->dailyAt('03:20');
|
|
$schedule->command('analytics:aggregate-tag-interactions')->dailyAt('03:30');
|
|
// Recalculate trending scores every 30 minutes (staggered to reduce peak load)
|
|
$schedule->command('skinbase:recalculate-trending --period=24h')->everyThirtyMinutes();
|
|
$schedule->command('skinbase:recalculate-trending --period=7d --skip-index')->everyThirtyMinutes()->runInBackground();
|
|
|
|
// ── Ranking system (rank_v1) ────────────────────────────────────────
|
|
// Step 1: compute per-artwork scores every hour at :05
|
|
$schedule->job(new RankComputeArtworkScoresJob)->hourlyAt(5)->runInBackground();
|
|
// Step 2: build ranked lists every hour at :15 (after scores are ready)
|
|
$schedule->job(new RankBuildListsJob)->hourlyAt(15)->runInBackground();
|
|
|
|
// ── Ranking Engine V2 — runs every 30 min ──────────────────────────
|
|
$schedule->command('nova:recalculate-rankings --sync-rank-scores')
|
|
->everyThirtyMinutes()
|
|
->name('ranking-v2')
|
|
->withoutOverlapping()
|
|
->runInBackground();
|
|
|
|
$schedule->job(new UpdateLeaderboardsJob)
|
|
->hourlyAt(20)
|
|
->name('leaderboards-refresh')
|
|
->withoutOverlapping()
|
|
->runInBackground();
|
|
|
|
// ── Rising Engine (Heat / Momentum) ─────────────────────────────────
|
|
// Step 1: snapshot metric totals every hour at :00
|
|
$schedule->command('nova:metrics-snapshot-hourly')
|
|
->hourly()
|
|
->name('metrics-snapshot-hourly')
|
|
->withoutOverlapping()
|
|
->runInBackground();
|
|
// Step 2: recalculate heat scores every 15 minutes
|
|
$schedule->command('nova:recalculate-heat')
|
|
->everyFifteenMinutes()
|
|
->name('recalculate-heat')
|
|
->withoutOverlapping()
|
|
->runInBackground();
|
|
// Step 3: prune old snapshots daily at 04:00
|
|
$schedule->command('nova:prune-metric-snapshots --keep-days=7')
|
|
->dailyAt('04:00');
|
|
|
|
$schedule->command('skinbase:sync-countries')
|
|
->monthlyOn(1, '03:40')
|
|
->name('sync-countries')
|
|
->withoutOverlapping()
|
|
->runInBackground();
|
|
}
|
|
|
|
/**
|
|
* Register the commands for the application.
|
|
*/
|
|
protected function commands(): void
|
|
{
|
|
$this->load(__DIR__ . '/Commands');
|
|
|
|
require base_path('routes/console.php');
|
|
}
|
|
}
|