Forum: - TipTap WYSIWYG editor with full toolbar - @emoji-mart/react emoji picker (consistent with tweets) - @mention autocomplete with user search API - Fix PHP 8.4 parse errors in Blade templates - Fix thread data display (paginator items) - Align forum page widths to max-w-5xl Discover: - Extract shared _nav.blade.php partial - Add missing nav links to for-you page - Add Following link for authenticated users Feed/Posts: - Post model, controllers, policies, migrations - Feed page components (PostComposer, FeedCard, etc) - Post reactions, comments, saves, reports, sharing - Scheduled publishing support - Link preview controller Profile: - Profile page components (ProfileHero, ProfileTabs) - Profile API controller Uploads: - Upload wizard enhancements - Scheduled publish picker - Studio status bar and readiness checklist
113 lines
4.7 KiB
PHP
113 lines
4.7 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\EvaluateFeedWeightsCommand;
|
|
use App\Console\Commands\AiTagArtworksCommand;
|
|
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\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\ResetAllUserPasswords::class,
|
|
CleanupUploadsCommand::class,
|
|
PublishScheduledArtworksCommand::class,
|
|
BackfillArtworkEmbeddingsCommand::class,
|
|
AggregateSimilarArtworkAnalyticsCommand::class,
|
|
AggregateFeedAnalyticsCommand::class,
|
|
EvaluateFeedWeightsCommand::class,
|
|
CompareFeedAbCommand::class,
|
|
AiTagArtworksCommand::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');
|
|
// 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();
|
|
|
|
// ── 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');
|
|
}
|
|
|
|
/**
|
|
* Register the commands for the application.
|
|
*/
|
|
protected function commands(): void
|
|
{
|
|
$this->load(__DIR__ . '/Commands');
|
|
|
|
require base_path('routes/console.php');
|
|
}
|
|
}
|