Some checks failed
ci/woodpecker/push/ci Pipeline failed
Backend:
- Add MarketplaceChatParticipant model for tracking thread participants
- Extend CrmThread with marketplace relationships (buyerBusiness, sellerBusiness, order)
- Add marketplace scopes to CrmThread for filtering B2B threads
- Create MarketplaceChatService for thread/message operations
- Create NewMarketplaceMessage broadcast event for real-time updates
- Create MarketplaceChatController API with thread/message endpoints
API Routes:
- GET /api/marketplace/chat/threads - List threads
- POST /api/marketplace/chat/threads - Create thread
- GET /api/marketplace/chat/threads/{id} - Get thread with messages
- POST /api/marketplace/chat/threads/{id}/messages - Send message
- POST /api/marketplace/chat/threads/{id}/read - Mark as read
- GET /api/marketplace/chat/unread-count - Get unread count
Frontend:
- Create marketplace-chat-widget component with Alpine.js
- Add floating chat button with unread badge
- Implement thread list and message views
- Add real-time message updates via Reverb/Echo
- Include widget in seller and buyer layouts
Broadcasting:
- Add marketplace-chat.{businessId} private channel
99 lines
4.1 KiB
PHP
99 lines
4.1 KiB
PHP
<?php
|
|
|
|
use App\Http\Controllers\Api\Internal\BrandPlacementController;
|
|
use App\Http\Controllers\Api\MarketplaceChatController;
|
|
use App\Http\Controllers\Api\PushSubscriptionController;
|
|
use Illuminate\Support\Facades\Route;
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| API Routes
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Here is where you can register API routes for your application. These
|
|
| routes are loaded by the RouteServiceProvider and all of them will
|
|
| be assigned to the "api" middleware group.
|
|
|
|
|
*/
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Internal API Routes - Sales Intelligence
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| These routes provide internal sales intelligence data for the
|
|
| Head of Sales Orchestrator and internal dashboards.
|
|
|
|
|
| All routes require authentication via Sanctum token or session.
|
|
|
|
|
*/
|
|
Route::prefix('internal')->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');
|
|
});
|