feat: ship creator journey v2 and profile updates
This commit is contained in:
@@ -49,7 +49,7 @@ Route::middleware(['web', 'auth', 'normalize.username'])->prefix('profile/cover'
|
||||
|
||||
// ── Per-artwork signal tracking (public) ────────────────────────────────────
|
||||
// GET /api/art/{id}/similar → up to 12 similar artworks (Meilisearch)
|
||||
// POST /api/art/{id}/view → record a view (session-deduped, 5 per 10 min)
|
||||
// POST /api/art/{id}/view → record a page visit as a view
|
||||
// POST /api/art/{id}/download → record a download, returns file URL (10/min)
|
||||
Route::middleware(['web', 'throttle:300,1'])
|
||||
->get('art/{id}/similar', \App\Http\Controllers\Api\SimilarArtworksController::class)
|
||||
@@ -61,7 +61,7 @@ Route::middleware(['web', 'throttle:120,1'])
|
||||
->whereNumber('id')
|
||||
->name('api.art.similar-ai');
|
||||
|
||||
Route::middleware(['web', 'throttle:5,10'])
|
||||
Route::middleware(['web', 'throttle:120,1'])
|
||||
->post('art/{id}/view', \App\Http\Controllers\Api\ArtworkViewController::class)
|
||||
->middleware('forum.bot.protection:api_write')
|
||||
->whereNumber('id')
|
||||
@@ -86,6 +86,11 @@ Route::middleware(['web', 'throttle:social-read'])
|
||||
->where('username', '[A-Za-z0-9_-]{3,20}')
|
||||
->name('api.profile.activity');
|
||||
|
||||
Route::middleware(['web', 'throttle:social-read'])
|
||||
->get('profile/{username}/journey', \App\Http\Controllers\Api\ProfileJourneyController::class)
|
||||
->where('username', '[A-Za-z0-9_-]{3,20}')
|
||||
->name('api.profile.journey');
|
||||
|
||||
Route::middleware(['web', 'throttle:social-read'])
|
||||
->get('comments', [\App\Http\Controllers\Api\SocialCompatibilityController::class, 'comments'])
|
||||
->name('api.social.comments.index');
|
||||
@@ -130,6 +135,7 @@ Route::middleware(['web', 'auth'])->prefix('studio')->name('api.studio.')->group
|
||||
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}/evolution-options', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'evolutionOptions'])->whereNumber('id')->name('artworks.evolution-options');
|
||||
Route::get('artworks/{id}/analytics', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'analytics'])->whereNumber('id')->name('artworks.analytics');
|
||||
Route::get('artworks/{id}/ai', [\App\Http\Controllers\Studio\StudioArtworkAiAssistApiController::class, 'show'])->whereNumber('id')->name('artworks.ai.show');
|
||||
Route::post('artworks/{id}/ai/analyze', [\App\Http\Controllers\Studio\StudioArtworkAiAssistApiController::class, 'analyze'])->whereNumber('id')->name('artworks.ai.analyze');
|
||||
@@ -585,6 +591,14 @@ Route::middleware(['web', 'auth', 'normalize.username', 'throttle:artwork-awards
|
||||
Route::delete('{id}/award', [\App\Http\Controllers\Api\ArtworkAwardController::class, 'destroy']) ->whereNumber('id')->name('destroy');
|
||||
});
|
||||
|
||||
Route::middleware(['web', 'auth', 'normalize.username', 'throttle:artwork-awards'])
|
||||
->prefix('artworks')
|
||||
->name('api.artworks.medals.')
|
||||
->group(function () {
|
||||
Route::post('{id}/medal', [\App\Http\Controllers\Api\ArtworkAwardController::class, 'upsert'])->whereNumber('id')->name('store');
|
||||
Route::delete('{id}/medal', [\App\Http\Controllers\Api\ArtworkAwardController::class, 'destroyMedal'])->whereNumber('id')->name('destroy');
|
||||
});
|
||||
|
||||
// ── Latest Comments feed ──────────────────────────────────────────────────────
|
||||
// GET /api/comments/latest?type=all|following|mine&page=N
|
||||
Route::middleware(['web', 'throttle:60,1'])
|
||||
@@ -598,6 +612,13 @@ Route::middleware(['web'])
|
||||
Route::get('{id}/awards', [\App\Http\Controllers\Api\ArtworkAwardController::class, 'show'])->whereNumber('id')->name('show');
|
||||
});
|
||||
|
||||
Route::middleware(['web'])
|
||||
->prefix('artworks')
|
||||
->name('api.artworks.medals.show.')
|
||||
->group(function () {
|
||||
Route::get('{id}/medal', [\App\Http\Controllers\Api\ArtworkAwardController::class, 'show'])->whereNumber('id')->name('show');
|
||||
});
|
||||
|
||||
Route::middleware(['web', 'auth', 'normalize.username'])->group(function () {
|
||||
Route::match(['post', 'delete'], 'like', [\App\Http\Controllers\Api\SocialCompatibilityController::class, 'like'])
|
||||
->name('api.social.like');
|
||||
|
||||
@@ -121,6 +121,12 @@ Schedule::command('collections:sync-lifecycle')
|
||||
->withoutOverlapping()
|
||||
->runInBackground();
|
||||
|
||||
Schedule::command('homepage:warm-guest-cache')
|
||||
->everyTenMinutes()
|
||||
->name('warm-homepage-guest-cache')
|
||||
->withoutOverlapping()
|
||||
->runInBackground();
|
||||
|
||||
// ── Feed 2.0: Trending Cache Warm-up ─────────────────────────────────────────
|
||||
// Warm the post trending cache every 2 minutes (complements the 2-min TTL).
|
||||
Schedule::command('posts:warm-trending')
|
||||
|
||||
@@ -89,10 +89,10 @@ Route::prefix('explore')->name('explore.')->group(function () {
|
||||
Route::get('/members', fn () => redirect()->route('creators.top', request()->query(), 301))->name('members.redirect');
|
||||
Route::get('/memebers', fn () => redirect()->route('creators.top', request()->query(), 301))->name('memebers.redirect');
|
||||
Route::get('/{type}', [ExploreController::class, 'byType'])
|
||||
->where('type', 'artworks|wallpapers|skins|photography|digital-art|other')
|
||||
->where('type', '[a-z0-9][a-z0-9\-]*')
|
||||
->name('type');
|
||||
Route::get('/{type}/{mode}', [ExploreController::class, 'byTypeMode'])
|
||||
->where('type', 'artworks|wallpapers|skins|photography|digital-art|other')
|
||||
->where('type', '[a-z0-9][a-z0-9\-]*')
|
||||
->where('mode', 'trending|new-hot|best|latest')
|
||||
->name('type.mode');
|
||||
});
|
||||
@@ -160,10 +160,10 @@ Route::middleware('throttle:60,1')->group(function () {
|
||||
|
||||
Route::prefix('rss/explore')->name('rss.explore.')->group(function () {
|
||||
Route::get('/{type}', [ExploreFeedController::class, 'byType'])
|
||||
->where('type', 'artworks|wallpapers|skins|photography|digital-art|other')
|
||||
->where('type', '[a-z0-9][a-z0-9\-]*')
|
||||
->name('type');
|
||||
Route::get('/{type}/{mode}', [ExploreFeedController::class, 'byTypeMode'])
|
||||
->where('type', 'artworks|wallpapers|skins|photography|digital-art|other')
|
||||
->where('type', '[a-z0-9][a-z0-9\-]*')
|
||||
->where('mode', 'trending|latest|best')
|
||||
->name('type.mode');
|
||||
});
|
||||
@@ -623,6 +623,12 @@ Route::middleware(['auth', 'admin.moderation'])->prefix('cp/cards')->name('cp.ca
|
||||
Route::patch('/categories/{category}', [\App\Http\Controllers\Settings\NovaCardAdminController::class, 'updateCategory'])->whereNumber('category')->name('categories.update');
|
||||
});
|
||||
|
||||
Route::middleware(['artwork.maturity.access'])->prefix('cp/maturity')->name('cp.maturity.')->group(function () {
|
||||
Route::get('/', [\App\Http\Controllers\Settings\ArtworkMaturityAdminController::class, 'index'])->name('index');
|
||||
Route::get('/queue', [\App\Http\Controllers\Settings\ArtworkMaturityAdminController::class, 'list'])->name('list');
|
||||
Route::post('/{artwork:id}/review', [\App\Http\Controllers\Settings\ArtworkMaturityAdminController::class, 'review'])->whereNumber('artwork')->name('review');
|
||||
});
|
||||
|
||||
// ── SETTINGS / PROFILE EDIT ───────────────────────────────────────────────────
|
||||
Route::middleware(['auth', 'normalize.username', 'ensure.onboarding.complete'])->group(function () {
|
||||
Route::get('/profile', fn () => redirect()->route('dashboard.profile', [], 301))->name('legacy.profile.redirect');
|
||||
@@ -644,6 +650,7 @@ Route::middleware(['auth', 'normalize.username', 'ensure.onboarding.complete'])-
|
||||
->name('settings.email.verify');
|
||||
Route::post('/settings/personal/update', [ProfileController::class, 'updatePersonalSection'])->middleware('forum.bot.protection:profile_update')->name('settings.personal.update');
|
||||
Route::post('/settings/notifications/update', [ProfileController::class, 'updateNotificationsSection'])->middleware('forum.bot.protection:profile_update')->name('settings.notifications.update');
|
||||
Route::post('/settings/content/update', [ProfileController::class, 'updateContentPreferencesSection'])->middleware('forum.bot.protection:profile_update')->name('settings.content.update');
|
||||
Route::post('/settings/security/password', [ProfileController::class, 'updateSecurityPassword'])->middleware('forum.bot.protection:profile_update')->name('settings.security.password');
|
||||
|
||||
Route::get('/settings/collections/create', [CollectionManageController::class, 'create'])->name('settings.collections.create');
|
||||
@@ -730,6 +737,9 @@ Route::middleware(['auth', 'ensure.onboarding.complete'])->group(function () {
|
||||
return [
|
||||
'id' => $ct->id,
|
||||
'name' => $ct->name,
|
||||
'slug' => $ct->slug,
|
||||
'mascot_url' => $ct->mascot_url,
|
||||
'cover_art_url' => $ct->cover_art_url,
|
||||
'categories' => $ct->rootCategories->map(function ($c) {
|
||||
return [
|
||||
'id' => $c->id,
|
||||
@@ -786,6 +796,9 @@ Route::middleware(['auth', 'ensure.onboarding.complete'])->group(function () {
|
||||
return [
|
||||
'id' => $ct->id,
|
||||
'name' => $ct->name,
|
||||
'slug' => $ct->slug,
|
||||
'mascot_url' => $ct->mascot_url,
|
||||
'cover_art_url' => $ct->cover_art_url,
|
||||
'categories' => $ct->rootCategories->map(function ($c) {
|
||||
return [
|
||||
'id' => $c->id,
|
||||
@@ -892,12 +905,12 @@ Route::bind('artwork', function ($value) {
|
||||
});
|
||||
|
||||
Route::get('/{contentTypeSlug}/{categoryPath}/{artwork}', [BrowseGalleryController::class, 'showArtwork'])
|
||||
->where('contentTypeSlug', 'photography|wallpapers|skins|other|digital-art')
|
||||
->where('contentTypeSlug', '[a-z0-9][a-z0-9\-]*')
|
||||
->where('categoryPath', '[^/]+(?:/[^/]+)*')
|
||||
->name('artworks.show');
|
||||
|
||||
Route::get('/{contentTypeSlug}/{path?}', [BrowseGalleryController::class, 'content'])
|
||||
->where('contentTypeSlug', 'photography|wallpapers|skins|other|digital-art')
|
||||
->where('contentTypeSlug', '[a-z0-9][a-z0-9\-]*')
|
||||
->where('path', '.*')
|
||||
->name('content.route');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user