group(function () { // External Sign In - For external backoffice systems Route::post('/agents/signin', [AgentController::class, 'externalSignin']); Route::post('/agents/validate-session', [AgentController::class, 'validateSession']); }); Route::prefix('mobile')->group(function () { Route::post('/login', [GeoTrackController::class, 'mobileLogin']); // Mobile Login }); // All other routes require CheckAgentSecret middleware Route::middleware([CheckAgentSecret::class])->group(function () { // ============ Merchants Routes ============ Route::get('/merchants', [MerchantController::class, 'index']); // ============ Grid Routes ============ Route::get('/grids', [GridController::class, 'index']); Route::get('/grids/generate', [GridController::class, 'generate']); Route::get('/grids/stats', [GridController::class, 'stats']); Route::post('/grids/{gridId}/download', [GridController::class, 'download']); // ============ GeoTrack Routes ============ Route::get('/sales-routes', [GeoTrackController::class, 'index']); Route::get('/sales-routes/dates', [GeoTrackController::class, 'dates']); Route::get('/sales-routes/sales', [GeoTrackController::class, 'sales']); Route::get('/sales-routes/{id}', [GeoTrackController::class, 'show']); Route::post('/sales-routes/waypoints', [GeoTrackController::class, 'storeWaypoint']); // ============ GeoPlan Routes ============ Route::get('/sales-plans', [GeoPlanController::class, 'index']); Route::get('/sales-plans/dates', [GeoPlanController::class, 'dates']); Route::get('/sales-plans/sales', [GeoPlanController::class, 'sales']); Route::get('/sales-plans/{id}', [GeoPlanController::class, 'show']); Route::post('/sales-plans', [GeoPlanController::class, 'store']); Route::put('/sales-plans/{id}', [GeoPlanController::class, 'update']); Route::delete('/sales-plans/{id}', [GeoPlanController::class, 'destroy']); Route::post('/sales-plans/{id}/optimize', [GeoPlanController::class, 'optimize']); Route::post('/sales-plans/{id}/add-target', [GeoPlanController::class, 'addTarget']); Route::put('/sales-plans/{id}/target/{targetId}', [GeoPlanController::class, 'updateTarget']); Route::delete('/sales-plans/{id}/target/{targetId}', [GeoPlanController::class, 'removeTarget']); Route::post('/sales-plans/assign-target', [GeoPlanController::class, 'autoAssignTarget']); // ============ GeoTrack Mobile API (Flutter) ============ Route::prefix('mobile')->group(function () { Route::post('/checkin', [GeoTrackController::class, 'mobileCheckin']); Route::post('/checkout', [GeoTrackController::class, 'mobileCheckout']); Route::post('/waypoints/batch', [GeoTrackController::class, 'storeBatchWaypoints']); Route::get('/route/today', [GeoTrackController::class, 'getTodayRoute']); Route::get('/status', [GeoTrackController::class, 'getTrackingStatus']); // New endpoints Route::get('/schedules', [GeoPlanController::class, 'getMobileSchedule']); Route::post('/schedules/{id}/target', [GeoPlanController::class, 'addTarget']); Route::post('/schedules/{id}/target/{targetId}/checkin', [GeoPlanController::class, 'checkinTarget']); Route::delete('/schedules/{id}/target/{targetId}', [GeoPlanController::class, 'removeTarget']); Route::post('/prospects', [\App\Http\Controllers\CustomerController::class, 'store']); Route::post('/profile', [GeoTrackController::class, 'updateProfile']); Route::post('/change-password', [GeoTrackController::class, 'changePassword']); }); // ============ Master Data: Staff ============ Route::apiResource('staff', StaffController::class); Route::apiResource('customers', \App\Http\Controllers\CustomerController::class); // ============ Agent Management ============ Route::get('/agents', [AgentController::class, 'index']); Route::get('/agents/{id}', [AgentController::class, 'show']); Route::put('/agents/{id}', [AgentController::class, 'update']); Route::delete('/agents/{id}', [AgentController::class, 'destroy']); Route::post('/agents/{id}/regenerate-key', [AgentController::class, 'regenerateKey']); // ============ RBAC (Role & Menu) ============ Route::apiResource('menus', \App\Http\Controllers\MenuController::class); Route::apiResource('user-groups', \App\Http\Controllers\UserGroupController::class); }); // ============ EXTERNAL AGENT INTEGRATION API (V1) ============ Route::prefix('v1')->middleware([CheckAgentSecret::class])->group(function () { // These are the Clean APIs for external Agents (Sandbox) // Tracking Route::get('/routes', [\App\Http\Controllers\Api\V1\TrackingController::class, 'index']); Route::post('/routes/waypoints', [\App\Http\Controllers\Api\V1\TrackingController::class, 'storeWaypoint']); // Planning Route::get('/plans', [\App\Http\Controllers\Api\V1\PlanningController::class, 'index']); Route::post('/plans', [\App\Http\Controllers\Api\V1\PlanningController::class, 'store']); // Visit (Customers/Merchants) - Reusing main controller for now as logic is same Route::post('/customers', [\App\Http\Controllers\CustomerController::class, 'store']); Route::get('/merchants', [MerchantController::class, 'index']); }); // ============ Health Check ============ Route::get('/health', function () { return response()->json([ 'status' => 'ok', 'timestamp' => now()->toISOString(), ]); });