autentica e popula "user_role" a partir do banco; * 2) RoleMiddleware -> autoriza conforme os papéis permitidos. */ final class Dispatcher { public static function register(App $app): void { $auth = new JwtAuthMiddleware(); // ---- Público (sem autenticação) ------------------------------------- // Login é protegido contra brute-force via RateLimiter no controller. $app->post('/v1/login', \Controllers\LoginController::class); $app->post('/v1/webhooks/unipile', \Controllers\UnipileWebhookController::class); $app->post('/v1/webhooks/unipile/hosted-auth', \Controllers\UnipileHostedAuthWebhookController::class); // Ingestão de CRM: autenticada por HMAC próprio da empresa (sem JWT). // O {companyId} resolve a empresa; o segredo valida o corpo. $app->post('/v1/webhooks/crm/{companyId}', \Controllers\CrmWebhookController::class); // Provisionamento de empresa + admin: operação de plataforma, protegida // pelo header X-Provision-Secret (PROVISION_SECRET). Sem JWT porque cria // o primeiro tenant/usuário, que ainda não tem token. $app->post('/v1/companies', \Controllers\RegisterCompanyController::class); $app->get('/v1/integrations/unipile/whatsapp/success', new \Controllers\UnipileRedirectController('success')); $app->get('/v1/integrations/unipile/whatsapp/failure', new \Controllers\UnipileRedirectController('failure')); // ---- Somente admin -------------------------------------------------- // Cadastro de usuários: o novo usuário herda o company_id do solicitante. $app->post('/v1/register', $auth, new RoleMiddleware(Roles::ADMIN), \Controllers\RegisterController::class); // ---- Autenticado (qualquer papel válido) ---------------------------- self::registerAuthenticated($app, $auth); } /** * Rotas que exigem apenas um usuário autenticado, sem restrição de papel. * Para restringir uma destas no futuro, basta inserir um RoleMiddleware * entre $auth e o controller (ex.: new RoleMiddleware(Roles::ADMIN, Roles::MANAGER)). */ private static function registerAuthenticated(App $app, JwtAuthMiddleware $auth): void { // Perfil do usuário autenticado. $app->get('/v1/me', $auth, \Controllers\MeController::class); $app->post('/v1/me/change-password', $auth, \Controllers\MeChangePasswordController::class); // Dashboards e analytics (leitura). $app->get('/v1/dashboard/overview', $auth, \Controllers\DashboardOverviewController::class); $app->get('/v1/interactions', $auth, \Controllers\InteractionsController::class); $app->get('/v1/interactions/details', $auth, \Controllers\InteractionDetailsController::class); $app->post('/v1/interactions/messages', $auth, new RoleMiddleware(Roles::ADMIN, Roles::MANAGER, Roles::OPERATOR), \Controllers\InteractionSendMessageController::class); $app->get('/v1/analytics/sentiment/dashboard', $auth, \Controllers\AnalyticsSentimentDashboardController::class); $app->get('/v1/personas/overview', $auth, \Controllers\PersonasOverviewController::class); $app->get('/v1/evolution/overview', $auth, \Controllers\EvolutionOverviewController::class); $app->get('/v1/executive/dashboard', $auth, new RoleMiddleware(Roles::ADMIN), \Controllers\ExecutiveDashboardController::class); // SLA. $app->get('/v1/sla/configs', $auth, \Controllers\SlaConfigsController::class); $app->get('/v1/sla/live-status', $auth, \Controllers\SlaLiveStatusController::class); $app->post('/v1/sla/configs', $auth, \Controllers\SlaSaveConfigController::class); // Agentes. $app->get('/v1/agents', $auth, \Controllers\AgentsController::class); $app->post('/v1/agents', $auth, \Controllers\AgentSaveController::class); $app->post('/v1/agents/status', $auth, \Controllers\AgentStatusController::class); $app->post('/v1/agents/escalation', $auth, \Controllers\AgentEscalationController::class); $app->get('/v1/integrations/unipile/whatsapp/accounts', $auth, new RoleMiddleware(Roles::ADMIN, Roles::MANAGER, Roles::OPERATOR), \Controllers\UnipileAccountsController::class); $app->post('/v1/integrations/unipile/whatsapp/hosted-link', $auth, new RoleMiddleware(Roles::ADMIN, Roles::MANAGER, Roles::OPERATOR), \Controllers\UnipileHostedLinkController::class); } }