optimizations
This commit is contained in:
261
routes/api.php
261
routes/api.php
@@ -55,6 +55,11 @@ Route::middleware(['web', 'throttle:300,1'])
|
||||
->whereNumber('id')
|
||||
->name('api.art.similar');
|
||||
|
||||
Route::middleware(['web', 'throttle:120,1'])
|
||||
->get('art/{id}/similar-ai', \App\Http\Controllers\Api\SimilarAiArtworksController::class)
|
||||
->whereNumber('id')
|
||||
->name('api.art.similar-ai');
|
||||
|
||||
Route::middleware(['web', 'throttle:5,10'])
|
||||
->post('art/{id}/view', \App\Http\Controllers\Api\ArtworkViewController::class)
|
||||
->middleware('forum.bot.protection:api_write')
|
||||
@@ -75,6 +80,11 @@ Route::middleware(['web', 'throttle:social-read'])
|
||||
->get('activity', [\App\Http\Controllers\Api\SocialActivityController::class, 'index'])
|
||||
->name('api.activity');
|
||||
|
||||
Route::middleware(['web', 'throttle:social-read'])
|
||||
->get('profile/{username}/activity', \App\Http\Controllers\Api\ProfileActivityController::class)
|
||||
->where('username', '[A-Za-z0-9_-]{3,20}')
|
||||
->name('api.profile.activity');
|
||||
|
||||
Route::middleware(['web', 'throttle:social-read'])
|
||||
->get('comments', [\App\Http\Controllers\Api\SocialCompatibilityController::class, 'comments'])
|
||||
->name('api.social.comments.index');
|
||||
@@ -110,6 +120,11 @@ Route::middleware(['web', 'auth'])->prefix('studio')->name('api.studio.')->group
|
||||
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::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');
|
||||
Route::post('artworks/{id}/ai/apply', [\App\Http\Controllers\Studio\StudioArtworkAiAssistApiController::class, 'apply'])->whereNumber('id')->name('artworks.ai.apply');
|
||||
Route::post('artworks/{id}/ai/events', [\App\Http\Controllers\Studio\StudioArtworkAiAssistApiController::class, 'event'])->whereNumber('id')->name('artworks.ai.events');
|
||||
Route::post('artworks/{id}/ai/regenerate', [\App\Http\Controllers\Studio\StudioArtworkAiAssistApiController::class, 'regenerate'])->whereNumber('id')->name('artworks.ai.regenerate');
|
||||
Route::post('artworks/{id}/replace-file', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'replaceFile'])->whereNumber('id')->name('artworks.replaceFile');
|
||||
// Versioning
|
||||
Route::get('artworks/{id}/versions', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'versions'])->whereNumber('id')->name('artworks.versions');
|
||||
@@ -117,6 +132,192 @@ Route::middleware(['web', 'auth'])->prefix('studio')->name('api.studio.')->group
|
||||
Route::get('tags/search', [\App\Http\Controllers\Studio\StudioArtworksApiController::class, 'searchTags'])->name('tags.search');
|
||||
});
|
||||
|
||||
Route::middleware(['web', 'auth'])->prefix('cards')->name('api.cards.')->group(function () {
|
||||
Route::post('{id}/like', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'like'])
|
||||
->middleware(['throttle:nova-cards-render', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('like.alias.store');
|
||||
Route::delete('{id}/like', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'unlike'])
|
||||
->whereNumber('id')
|
||||
->name('like.alias.destroy');
|
||||
Route::post('{id}/save', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'save'])
|
||||
->middleware(['throttle:nova-cards-render', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('save.alias.store');
|
||||
Route::post('{id}/remix', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'remix'])
|
||||
->middleware(['throttle:nova-cards-publish', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('remix.alias.store');
|
||||
Route::post('drafts', [\App\Http\Controllers\Api\NovaCards\NovaCardDraftController::class, 'store'])
|
||||
->middleware(['throttle:nova-cards-drafts', 'forum.bot.protection:api_write'])
|
||||
->name('drafts.store');
|
||||
Route::get('drafts/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardDraftController::class, 'show'])
|
||||
->whereNumber('id')
|
||||
->name('drafts.show');
|
||||
Route::patch('drafts/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardDraftController::class, 'update'])
|
||||
->middleware(['throttle:nova-cards-autosave', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('drafts.update');
|
||||
Route::post('drafts/{id}/autosave', [\App\Http\Controllers\Api\NovaCards\NovaCardDraftController::class, 'autosave'])
|
||||
->middleware(['throttle:nova-cards-autosave', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('drafts.autosave');
|
||||
Route::post('drafts/{id}/background', [\App\Http\Controllers\Api\NovaCards\NovaCardDraftController::class, 'background'])
|
||||
->middleware(['throttle:nova-cards-background-upload', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('drafts.background');
|
||||
Route::post('drafts/{id}/render', [\App\Http\Controllers\Api\NovaCards\NovaCardDraftController::class, 'render'])
|
||||
->middleware(['throttle:nova-cards-render', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('drafts.render');
|
||||
Route::post('drafts/{id}/publish', [\App\Http\Controllers\Api\NovaCards\NovaCardDraftController::class, 'publish'])
|
||||
->middleware(['throttle:nova-cards-publish', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('drafts.publish');
|
||||
Route::delete('drafts/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardDraftController::class, 'destroy'])
|
||||
->whereNumber('id')
|
||||
->name('drafts.destroy');
|
||||
Route::get('collections', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'collections'])
|
||||
->name('collections.index');
|
||||
Route::post('collections', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'storeCollection'])
|
||||
->middleware(['throttle:nova-cards-drafts', 'forum.bot.protection:api_write'])
|
||||
->name('collections.store');
|
||||
Route::patch('collections/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'updateCollection'])
|
||||
->middleware(['throttle:nova-cards-drafts', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('collections.update');
|
||||
Route::post('collections/{id}/items', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'storeCollectionItem'])
|
||||
->middleware(['throttle:nova-cards-drafts', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('collections.items.store');
|
||||
Route::delete('collections/{id}/items/{cardId}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'destroyCollectionItem'])
|
||||
->whereNumber('id')
|
||||
->whereNumber('cardId')
|
||||
->name('collections.items.destroy');
|
||||
Route::get('challenges', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'challenges'])
|
||||
->name('challenges.index');
|
||||
Route::get('assets', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'assets'])
|
||||
->name('assets.index');
|
||||
Route::get('templates', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'templates'])
|
||||
->name('templates.index');
|
||||
Route::post('like/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'like'])
|
||||
->middleware(['throttle:nova-cards-render', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('like');
|
||||
Route::delete('like/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'unlike'])
|
||||
->whereNumber('id')
|
||||
->name('unlike');
|
||||
Route::post('favorite/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'favorite'])
|
||||
->middleware(['throttle:nova-cards-render', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('favorite');
|
||||
Route::delete('favorite/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'unfavorite'])
|
||||
->whereNumber('id')
|
||||
->name('unfavorite');
|
||||
Route::post('save/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'save'])
|
||||
->middleware(['throttle:nova-cards-render', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('save');
|
||||
Route::delete('save/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'unsave'])
|
||||
->whereNumber('id')
|
||||
->name('unsave');
|
||||
Route::post('remix/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'remix'])
|
||||
->middleware(['throttle:nova-cards-publish', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('remix');
|
||||
Route::post('duplicate/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'duplicate'])
|
||||
->middleware(['throttle:nova-cards-drafts', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('duplicate');
|
||||
Route::get('drafts/{id}/versions', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'versions'])
|
||||
->whereNumber('id')
|
||||
->name('drafts.versions');
|
||||
Route::post('drafts/{id}/restore/{versionId}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'restoreVersion'])
|
||||
->middleware(['throttle:nova-cards-autosave', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->whereNumber('versionId')
|
||||
->name('drafts.restore');
|
||||
Route::post('drafts/{id}/restore-version/{versionId}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'restoreVersion'])
|
||||
->middleware(['throttle:nova-cards-autosave', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->whereNumber('versionId')
|
||||
->name('drafts.restore-version');
|
||||
Route::post('challenges/{challengeId}/submit/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'submitChallenge'])
|
||||
->middleware(['throttle:nova-cards-publish', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('challengeId')
|
||||
->whereNumber('id')
|
||||
->name('challenges.submit');
|
||||
Route::post('challenges/{id}/submit', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'submitChallengeByChallenge'])
|
||||
->middleware(['throttle:nova-cards-publish', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('challenges.submit.alias');
|
||||
Route::post('challenges/{id}/submit-card', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'submitChallengeByChallenge'])
|
||||
->middleware(['throttle:nova-cards-publish', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('challenges.submit-card');
|
||||
|
||||
// v3: Creator presets
|
||||
Route::get('presets', [\App\Http\Controllers\Api\NovaCards\NovaCardPresetController::class, 'index'])
|
||||
->name('presets.index');
|
||||
Route::post('presets', [\App\Http\Controllers\Api\NovaCards\NovaCardPresetController::class, 'store'])
|
||||
->middleware(['throttle:nova-cards-drafts', 'forum.bot.protection:api_write'])
|
||||
->name('presets.store');
|
||||
Route::patch('presets/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardPresetController::class, 'update'])
|
||||
->middleware(['throttle:nova-cards-drafts', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('presets.update');
|
||||
Route::delete('presets/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardPresetController::class, 'destroy'])
|
||||
->whereNumber('id')
|
||||
->name('presets.destroy');
|
||||
Route::post('presets/capture/{cardId}', [\App\Http\Controllers\Api\NovaCards\NovaCardPresetController::class, 'captureFromCard'])
|
||||
->middleware(['throttle:nova-cards-drafts', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('cardId')
|
||||
->name('presets.capture');
|
||||
Route::get('presets/{presetId}/apply/{cardId}', [\App\Http\Controllers\Api\NovaCards\NovaCardPresetController::class, 'applyToCard'])
|
||||
->whereNumber('presetId')
|
||||
->whereNumber('cardId')
|
||||
->name('presets.apply');
|
||||
|
||||
// v3: Export requests
|
||||
Route::post('{id}/export', [\App\Http\Controllers\Api\NovaCards\NovaCardExportController::class, 'store'])
|
||||
->middleware(['throttle:nova-cards-render', 'forum.bot.protection:api_write'])
|
||||
->whereNumber('id')
|
||||
->name('export.store');
|
||||
Route::get('exports/{exportId}', [\App\Http\Controllers\Api\NovaCards\NovaCardExportController::class, 'show'])
|
||||
->whereNumber('exportId')
|
||||
->name('exports.show');
|
||||
|
||||
// v3: AI-assist suggestions
|
||||
Route::get('{id}/ai-suggest', [\App\Http\Controllers\Api\NovaCards\NovaCardDiscoveryController::class, 'suggest'])
|
||||
->middleware(['throttle:nova-cards-render'])
|
||||
->whereNumber('id')
|
||||
->name('ai-suggest');
|
||||
});
|
||||
|
||||
Route::middleware(['web', 'throttle:60,1'])->prefix('cards')->name('api.cards.')->group(function () {
|
||||
Route::get('{id}/lineage', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'lineage'])
|
||||
->whereNumber('id')
|
||||
->name('lineage.alias');
|
||||
Route::get('lineage/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardInteractionController::class, 'lineage'])
|
||||
->whereNumber('id')
|
||||
->name('lineage');
|
||||
Route::post('share/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardEngagementController::class, 'share'])
|
||||
->middleware('forum.bot.protection:api_write')
|
||||
->whereNumber('id')
|
||||
->name('share');
|
||||
Route::post('download/{id}', [\App\Http\Controllers\Api\NovaCards\NovaCardEngagementController::class, 'download'])
|
||||
->middleware('forum.bot.protection:api_write')
|
||||
->whereNumber('id')
|
||||
->name('download');
|
||||
|
||||
// v3: Discovery feeds (public, cached)
|
||||
Route::get('rising', [\App\Http\Controllers\Api\NovaCards\NovaCardDiscoveryController::class, 'rising'])
|
||||
->name('rising');
|
||||
Route::get('{id}/related', [\App\Http\Controllers\Api\NovaCards\NovaCardDiscoveryController::class, 'related'])
|
||||
->whereNumber('id')
|
||||
->name('related');
|
||||
});
|
||||
|
||||
Route::prefix('v1')->name('api.v1.')->group(function () {
|
||||
// Public browse feed (authoritative tables only)
|
||||
Route::get('browse', [\App\Http\Controllers\Api\BrowseController::class, 'index'])
|
||||
@@ -216,6 +417,12 @@ Route::middleware(['web', 'auth', 'normalize.username'])->prefix('uploads')->nam
|
||||
->name('vision-suggest');
|
||||
});
|
||||
|
||||
Route::middleware(['web', 'auth'])->prefix('search')->name('api.search.')->group(function () {
|
||||
Route::post('image', \App\Http\Controllers\Api\ImageSearchController::class)
|
||||
->middleware(['throttle:20,1', 'forum.bot.protection:api_write'])
|
||||
->name('image');
|
||||
});
|
||||
|
||||
Route::middleware(['web', 'auth', 'admin.moderation'])->prefix('admin/uploads')->name('api.admin.uploads.')->group(function () {
|
||||
Route::get('pending', [\App\Http\Controllers\Api\Admin\UploadModerationController::class, 'pending'])
|
||||
->name('pending');
|
||||
@@ -233,9 +440,23 @@ Route::middleware(['web', 'auth', 'admin.moderation'])->prefix('admin/reports')-
|
||||
Route::get('queue', [\App\Http\Controllers\Api\Admin\ModerationReportQueueController::class, 'index'])
|
||||
->name('queue');
|
||||
|
||||
Route::patch('{report}', [\App\Http\Controllers\Api\Admin\ModerationReportQueueController::class, 'update'])
|
||||
->whereNumber('report')
|
||||
->name('update');
|
||||
|
||||
Route::post('{report}/moderate-target', [\App\Http\Controllers\Api\Admin\ModerationReportQueueController::class, 'moderateTarget'])
|
||||
->whereNumber('report')
|
||||
->name('moderate-target');
|
||||
|
||||
Route::get('feed-engine-decision', [\App\Http\Controllers\Api\Admin\FeedEngineDecisionController::class, 'index'])
|
||||
->name('feed-engine-decision');
|
||||
|
||||
Route::get('similar-artworks', [\App\Http\Controllers\Api\Admin\SimilarArtworkReportController::class, 'index'])
|
||||
->name('similar-artworks');
|
||||
|
||||
Route::get('discovery-feedback', [\App\Http\Controllers\Api\Admin\DiscoveryFeedbackReportController::class, 'index'])
|
||||
->name('discovery-feedback');
|
||||
|
||||
Route::get('feed-performance', [\App\Http\Controllers\Api\Admin\FeedPerformanceReportController::class, 'index'])
|
||||
->name('feed-performance');
|
||||
|
||||
@@ -256,6 +477,20 @@ Route::middleware(['web', 'auth', 'admin.moderation'])->prefix('admin/usernames'
|
||||
->name('reject');
|
||||
});
|
||||
|
||||
Route::middleware(['web', 'auth', 'admin.moderation'])->prefix('admin/collections')->name('api.admin.collections.')->group(function () {
|
||||
Route::patch('{collection}/moderation', [\App\Http\Controllers\Api\Admin\CollectionModerationController::class, 'updateModeration'])
|
||||
->name('moderation.update');
|
||||
|
||||
Route::patch('{collection}/interactions', [\App\Http\Controllers\Api\Admin\CollectionModerationController::class, 'updateInteractions'])
|
||||
->name('interactions.update');
|
||||
|
||||
Route::post('{collection}/unfeature', [\App\Http\Controllers\Api\Admin\CollectionModerationController::class, 'unfeature'])
|
||||
->name('unfeature');
|
||||
|
||||
Route::delete('{collection}/members/{member}', [\App\Http\Controllers\Api\Admin\CollectionModerationController::class, 'destroyMember'])
|
||||
->name('members.destroy');
|
||||
});
|
||||
|
||||
Route::post('analytics/similar-artworks', [\App\Http\Controllers\Api\SimilarArtworkAnalyticsController::class, 'store'])
|
||||
->middleware('throttle:uploads-status')
|
||||
->name('api.analytics.similar-artworks.store');
|
||||
@@ -272,6 +507,22 @@ Route::middleware(['web', 'auth', 'normalize.username'])->prefix('discovery')->n
|
||||
Route::post('events', [\App\Http\Controllers\Api\DiscoveryEventController::class, 'store'])
|
||||
->middleware(['throttle:uploads-status', 'forum.bot.protection:api_write'])
|
||||
->name('events.store');
|
||||
|
||||
Route::post('feedback/hide-artwork', [\App\Http\Controllers\Api\DiscoveryNegativeSignalController::class, 'hideArtwork'])
|
||||
->middleware(['throttle:uploads-status', 'forum.bot.protection:api_write'])
|
||||
->name('feedback.hide-artwork');
|
||||
|
||||
Route::delete('feedback/hide-artwork', [\App\Http\Controllers\Api\DiscoveryNegativeSignalController::class, 'unhideArtwork'])
|
||||
->middleware(['throttle:uploads-status', 'forum.bot.protection:api_write'])
|
||||
->name('feedback.unhide-artwork');
|
||||
|
||||
Route::post('feedback/dislike-tag', [\App\Http\Controllers\Api\DiscoveryNegativeSignalController::class, 'dislikeTag'])
|
||||
->middleware(['throttle:uploads-status', 'forum.bot.protection:api_write'])
|
||||
->name('feedback.dislike-tag');
|
||||
|
||||
Route::delete('feedback/dislike-tag', [\App\Http\Controllers\Api\DiscoveryNegativeSignalController::class, 'undislikeTag'])
|
||||
->middleware(['throttle:uploads-status', 'forum.bot.protection:api_write'])
|
||||
->name('feedback.undislike-tag');
|
||||
});
|
||||
|
||||
// ─── Artwork Search (Meilisearch-powered, public) ────────────────────────────
|
||||
@@ -440,26 +691,32 @@ Route::middleware(['web', 'auth', 'normalize.username', 'throttle:30,1'])
|
||||
->name('tags');
|
||||
});
|
||||
|
||||
Route::middleware(['web', 'auth', 'throttle:social-read'])
|
||||
->get('users/suggestions', \App\Http\Controllers\Api\UserSuggestionsController::class)
|
||||
->name('api.users.suggestions');
|
||||
|
||||
// ── Follow system ─────────────────────────────────────────────────────────────
|
||||
// POST /api/user/{username}/follow → follow a user
|
||||
// DELETE /api/user/{username}/follow → unfollow a user
|
||||
// GET /api/user/{username}/followers → paginated followers (public)
|
||||
// GET /api/user/{username}/following → paginated following (public)
|
||||
Route::middleware(['web', 'throttle:60,1'])
|
||||
Route::middleware(['web'])
|
||||
->prefix('user')
|
||||
->name('api.user.follow.')
|
||||
->group(function () {
|
||||
// Public: list followers / following
|
||||
Route::get('{username}/followers', [\App\Http\Controllers\Api\FollowController::class, 'followers'])
|
||||
->middleware('throttle:social-read')
|
||||
->where('username', '[A-Za-z0-9_-]{3,20}')
|
||||
->name('followers');
|
||||
|
||||
Route::get('{username}/following', [\App\Http\Controllers\Api\FollowController::class, 'following'])
|
||||
->middleware('throttle:social-read')
|
||||
->where('username', '[A-Za-z0-9_-]{3,20}')
|
||||
->name('following');
|
||||
|
||||
// Auth-required: follow / unfollow
|
||||
Route::middleware(['auth', 'normalize.username'])->group(function () {
|
||||
Route::middleware(['auth', 'normalize.username', 'throttle:follow-write', 'forum.security.firewall:follow', 'forum.bot.protection:follow'])->group(function () {
|
||||
Route::post('{username}/follow', [\App\Http\Controllers\Api\FollowController::class, 'follow'])
|
||||
->where('username', '[A-Za-z0-9_-]{3,20}')
|
||||
->name('follow');
|
||||
|
||||
Reference in New Issue
Block a user