group(function (): void { Route::get('/auth/captcha', [AuthController::class, 'captcha']); Route::post('/auth/register', [AuthController::class, 'register'])->middleware('throttle:10,1'); Route::post('/auth/login', [AuthController::class, 'login'])->middleware('throttle:10,1'); }); Route::get('/legal/documents', [LegalController::class, 'index']); // --------------------------------------------------------------------------- // Authenticated endpoints // --------------------------------------------------------------------------- Route::middleware(['auth:sanctum', EnsureUserIsActive::class])->group(function (): void { Route::get('/auth/me', [AuthController::class, 'me']); Route::post('/auth/logout', [AuthController::class, 'logout']); // Legal consent (accessible before terms are accepted, by design). Route::get('/legal/status', [LegalController::class, 'status']); Route::post('/legal/accept', [LegalController::class, 'accept']); Route::get('/legal/history', [LegalController::class, 'history']); // World snapshot for the 3D renderer. Route::get('/city/world', [CityController::class, 'world']); // Stores: users manage their own, admins manage all. Route::apiResource('stores', StoreController::class); Route::get('/stores-world/seed', [StoreController::class, 'world']); // Profile. Route::patch('/auth/profile', [AuthController::class, 'updateProfile']); }); // --------------------------------------------------------------------------- // Admin-only endpoints // --------------------------------------------------------------------------- Route::middleware(['auth:sanctum', EnsureUserIsActive::class, EnsureUserIsAdmin::class]) ->prefix('admin') ->group(function (): void { Route::apiResource('users', UserController::class); Route::delete('users/{user}/deactivate', [UserController::class, 'destroy']); Route::apiResource('agents', AiAgentController::class)->except(['show']); Route::get('/agents-meta/models', [AiAgentController::class, 'models']); Route::get('/agents-world/seed', [AiAgentController::class, 'world']); });