Studio: make grid checkbox rectangular and commit table changes
This commit is contained in:
@@ -44,6 +44,18 @@ Route::prefix('rank')->name('api.rank.')->middleware(['throttle:60,1'])->group(f
|
||||
* GET /api/v1/artworks/{slug}
|
||||
* GET /api/v1/categories/{slug}/artworks
|
||||
*/
|
||||
|
||||
// ── Studio Pro API (authenticated) ─────────────────────────────────────────────
|
||||
Route::middleware(['web', 'auth'])->prefix('studio')->name('api.studio.')->group(function () {
|
||||
Route::get('artworks', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'index'])->name('artworks.index');
|
||||
Route::post('artworks/bulk', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'bulk'])->name('artworks.bulk');
|
||||
Route::put('artworks/{id}', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'update'])->whereNumber('id')->name('artworks.update');
|
||||
Route::post('artworks/{id}/toggle', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'toggle'])->whereNumber('id')->name('artworks.toggle');
|
||||
Route::get('artworks/{id}/analytics', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'analytics'])->whereNumber('id')->name('artworks.analytics');
|
||||
Route::post('artworks/{id}/replace-file', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'replaceFile'])->whereNumber('id')->name('artworks.replaceFile');
|
||||
Route::get('tags/search', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'searchTags'])->name('tags.search');
|
||||
});
|
||||
|
||||
Route::prefix('v1')->name('api.v1.')->group(function () {
|
||||
// Public browse feed (authoritative tables only)
|
||||
Route::get('browse', [\App\Http\Controllers\Api\BrowseController::class, 'index'])
|
||||
|
||||
@@ -64,6 +64,29 @@ Schedule::command('skinbase:prune-view-events --days=90')
|
||||
->name('prune-view-events')
|
||||
->withoutOverlapping();
|
||||
|
||||
// ── Similar Artworks (Hybrid Recommender) ──────────────────────────────────────
|
||||
// Build co-occurrence pairs from favourites every 4 hours.
|
||||
Schedule::job(new \App\Jobs\RecBuildItemPairsFromFavouritesJob())
|
||||
->everyFourHours()
|
||||
->name('rec-build-item-pairs')
|
||||
->withoutOverlapping();
|
||||
|
||||
// Nightly: recompute tag, behavior, and hybrid similarity lists.
|
||||
Schedule::job(new \App\Jobs\RecComputeSimilarByTagsJob())
|
||||
->dailyAt('02:00')
|
||||
->name('rec-compute-tags')
|
||||
->withoutOverlapping();
|
||||
|
||||
Schedule::job(new \App\Jobs\RecComputeSimilarByBehaviorJob())
|
||||
->dailyAt('02:15')
|
||||
->name('rec-compute-behavior')
|
||||
->withoutOverlapping();
|
||||
|
||||
Schedule::job(new \App\Jobs\RecComputeSimilarHybridJob())
|
||||
->dailyAt('02:30')
|
||||
->name('rec-compute-hybrid')
|
||||
->withoutOverlapping();
|
||||
|
||||
// ── Ranking Engine V2 ──────────────────────────────────────────────────────────
|
||||
// Recalculate ranking_score + engagement_velocity every 30 minutes.
|
||||
// Also syncs V2 scores to rank_artwork_scores so list builds benefit.
|
||||
|
||||
@@ -38,6 +38,7 @@ use Inertia\Inertia;
|
||||
// ── DISCOVER routes (/discover/*) ─────────────────────────────────────────────
|
||||
Route::prefix('discover')->name('discover.')->group(function () {
|
||||
Route::get('/trending', [DiscoverController::class, 'trending'])->name('trending');
|
||||
Route::get('/rising', [DiscoverController::class, 'rising'])->name('rising');
|
||||
Route::get('/fresh', [DiscoverController::class, 'fresh'])->name('fresh');
|
||||
Route::get('/top-rated', [DiscoverController::class, 'topRated'])->name('top-rated');
|
||||
Route::get('/most-downloaded', [DiscoverController::class, 'mostDownloaded'])->name('most-downloaded');
|
||||
@@ -236,6 +237,18 @@ Route::middleware(['auth', \App\Http\Middleware\NoIndexDashboard::class])->prefi
|
||||
Route::get('/awards', [\App\Http\Controllers\Dashboard\DashboardAwardsController::class, 'index'])->name('awards');
|
||||
});
|
||||
|
||||
// ── Studio Pro (Creator Artwork Manager) ────────────────────────────────────
|
||||
use App\Http\Controllers\Studio\StudioController;
|
||||
Route::middleware(['auth', 'ensure.onboarding.complete'])->prefix('studio')->name('studio.')->group(function () {
|
||||
Route::get('/', [StudioController::class, 'index'])->name('index');
|
||||
Route::get('/artworks', [StudioController::class, 'artworks'])->name('artworks');
|
||||
Route::get('/artworks/drafts', [StudioController::class, 'drafts'])->name('drafts');
|
||||
Route::get('/artworks/archived', [StudioController::class, 'archived'])->name('archived');
|
||||
Route::get('/artworks/{id}/edit', [StudioController::class, 'edit'])->whereNumber('id')->name('artworks.edit');
|
||||
Route::get('/artworks/{id}/analytics', [StudioController::class, 'analytics'])->whereNumber('id')->name('artworks.analytics');
|
||||
Route::get('/analytics', [StudioController::class, 'analyticsOverview'])->name('analytics');
|
||||
});
|
||||
|
||||
Route::middleware(['auth', 'normalize.username', 'ensure.onboarding.complete'])->group(function () {
|
||||
// Redirect legacy `/profile` edit path to canonical dashboard profile route.
|
||||
Route::get('/profile', function () {
|
||||
|
||||
Reference in New Issue
Block a user