middleware(['auth:sanctum'])->group(function () { // Store-specific opportunities (with scoring) Route::get('/stores/{store}/opportunities', [BrandPlacementController::class, 'storeOpportunities']) ->name('api.internal.store.opportunities'); // Ranked stores by opportunity score Route::get('/opportunities', [BrandPlacementController::class, 'topOpportunities']) ->name('api.internal.opportunities'); // Multiple ranking views (opportunity, cross-sell, declines, portfolio gaps) Route::get('/opportunities/top', [BrandPlacementController::class, 'topOpportunitiesRanked']) ->name('api.internal.opportunities.top'); // Coverage overview Route::get('/coverage', [BrandPlacementController::class, 'coverageOverview']) ->name('api.internal.coverage'); // Low coverage stores (high opportunity) Route::get('/coverage/low', [BrandPlacementController::class, 'lowCoverageStores']) ->name('api.internal.coverage.low'); // Alerts from the alerts engine Route::get('/alerts', [BrandPlacementController::class, 'getAlerts']) ->name('api.internal.alerts'); // Weekly digest summary Route::get('/digest', [BrandPlacementController::class, 'getWeeklyDigest']) ->name('api.internal.digest'); // Trigger signal computation (manual refresh) Route::post('/signals/compute', [BrandPlacementController::class, 'computeSignals']) ->name('api.internal.signals.compute'); }); /* |-------------------------------------------------------------------------- | Push Notifications |-------------------------------------------------------------------------- */ Route::middleware(['auth:sanctum'])->group(function () { Route::post('/push-subscriptions', [PushSubscriptionController::class, 'store']) ->name('api.push-subscriptions.store'); Route::delete('/push-subscriptions', [PushSubscriptionController::class, 'destroy']) ->name('api.push-subscriptions.destroy'); }); /* |-------------------------------------------------------------------------- | Marketplace Chat |-------------------------------------------------------------------------- | | Real-time B2B chat between buyers and sellers. | Uses web middleware for session auth (called from same-origin frontend). | */ Route::prefix('marketplace/chat')->middleware(['web', 'auth'])->group(function () { Route::get('/threads', [MarketplaceChatController::class, 'index']) ->name('api.marketplace.chat.threads'); Route::post('/threads', [MarketplaceChatController::class, 'store']) ->name('api.marketplace.chat.threads.store'); Route::get('/threads/{thread}', [MarketplaceChatController::class, 'show']) ->name('api.marketplace.chat.threads.show'); Route::post('/threads/{thread}/messages', [MarketplaceChatController::class, 'sendMessage']) ->name('api.marketplace.chat.messages.send'); Route::post('/threads/{thread}/read', [MarketplaceChatController::class, 'markAsRead']) ->name('api.marketplace.chat.threads.read'); Route::get('/unread-count', [MarketplaceChatController::class, 'unreadCount']) ->name('api.marketplace.chat.unread'); });