# API da aplicacao ## Arquitetura Web e API usam os mesmos servicos em `app/Services`, com as mesmas regras de negocio e acesso aos dados. A web mantem as vistas Blade e os redirecionamentos. A API devolve JSON, exceto a exportacao Excel e o diagnostico HTML `phpinfo`. Os controllers nao fazem chamadas HTTP a propria aplicacao. `APP_API_URL` ou `app.api_url` deixam de ser necessarios para o login e a sessao web. O bootstrap Laravel regista `routes/api.php` com o prefixo `/api`. ## Autenticacao `POST /api/login` recebe `email` e `password` e devolve `token` e `user`. Os tokens Sanctum expiram apos 20 minutos. Use estes cabecalhos nos pedidos: ```http Authorization: Bearer Accept: application/json Content-Type: application/json ``` `POST /api/refresh` prolonga um token ainda valido por 20 minutos. `POST /api/logout` revoga o token atual. A recuperacao de senha revoga todos os tokens do utilizador. Contas com `can_login=false` nao podem autenticar-se nem usar tokens existentes. O login web usa o mesmo servico, regenera a sessao e valida/renova o token localmente em cada pedido autenticado. Login e verificacao de PIN permitem 10 tentativas por minuto; pedidos publicos de recuperacao de senha e envio de email de teste permitem 5 por minuto. ## Endpoints Todos os caminhos abaixo sao relativos a `/api`. `CRUD /recurso` significa `GET /recurso`, `POST /recurso`, `GET /recurso/{id}`, `PUT` ou `PATCH /recurso/{id}` e `DELETE /recurso/{id}`. As rotas `/resources` aceitam `PUT`, nao `PATCH`. | Operacao | Endpoint | Acesso | | --- | --- | --- | | Login | `POST /login` | Publico | | Pedir recuperacao de senha | `POST /password/email` | Publico | | Redefinir senha | `POST /password/reset` | Publico | | Sair / renovar / verificar token | `POST /logout`, `POST /refresh`, `GET /check-token` | Autenticado | | Utilizador atual e permissoes | `GET /me` | Autenticado | | Dashboard | `GET /dashboard` | Autenticado | | Analises | `GET /analytics` | Role `administracao` | | Guardar / verificar PIN | `POST /user/pin`, `POST /user/check-pin` | Autenticado | | Clientes | CRUD `/clients` | Autenticado | | Opcoes de clientes | `GET /clients/options?type={client_type_id}` | Autenticado | | Detalhe e contratos de cliente | `GET /clients/{id}/detail` | Autenticado | | Pesquisa por nome | `GET /clients/search/name?term=...` | Autenticado | | Pesquisa por ID | `POST /clients/search/id`, corpo `{"id":1}` | Autenticado | | Leads | CRUD `/leads` | Autenticado | | Estados de leads | `GET /leads/options` | Autenticado | | Converter lead | `PUT /leads/{id}/convert` | Autenticado | | Contratos | CRUD `/contracts` | Autenticado | | Opcoes de contratos | `GET /contracts/options?client_id=...` | Autenticado | | Dados de edicao | `GET /contracts/{id}/edit` | Autenticado | | Opcoes / executar renovacao | `GET /contracts/{id}/renew`, `POST /contracts/{id}/renew` | Autenticado | | Historico | `GET /contracts/{id}/history` | Autenticado | | Ler / editar / eliminar historico | `GET`, `PUT`, `DELETE /contracts/{id}/history/{historyId}` | Autenticado | | Eliminar contratos em lote | `DELETE /contracts/bulk`, corpo `{"ids":[1,2]}` | Autenticado | | Exportar contratos | `GET /contracts/export` | Permissao `view_contract_summary` | | Utilizadores | CRUD `/users` | Role `admin` | | Roles para criar utilizador | `GET /users/options` | Role `admin` | | Enviar recuperacao de senha a utilizador | `POST /users/{user}/password-reset` | Role `admin` | | Roles e permissoes | `GET /admin/access/roles-permissions` | Role `admin` | | Atualizar permissoes de role | `POST /admin/access/roles/{role}/permissions` | Role `admin` | | Utilizadores e roles | `GET /admin/access/users` | Role `admin` | | Atualizar roles de utilizador | `POST /admin/access/users/{user}/roles` | Role `admin` | | Recursos auxiliares | CRUD `/resources/{resource}` | Permissao `manage_resources` | | Informacao do sistema | `GET /admin/info` | Role `admin` | | Diagnostico PHP (HTML) | `GET /admin/phpinfo` | Role `admin` | | Executar migrations | `POST /admin/runMigrations` | Role `admin` | | Email de teste | `POST /admin/testEmail`, corpo `{"email":"destino@example.com"}` | Role `admin` | Recursos permitidos: `power_tiers`, `contract_types`, `payment_methods`, `typologies`, `cui_tiers`, `suppliers`, `contract-statuses`. Roles e permissoes sao enviadas como listas de nomes nos campos `roles` e `permissions`. Os campos de negocio e datas seguem os FormRequests existentes, incluindo o formato `d/m/Y` nos formularios de contratos. As operacoes de senha recebem `email`; a redefinicao tambem recebe `token`, `password` e `password_confirmation`. ## Respostas e compatibilidade Criacao: `201`; operacao concluida: `200`; nao autenticado: `401`; acesso negado: `403`; registo inexistente: `404`; validacao: `422`; limite de tentativas: `429`. Erros de validacao incluem `message` e `errors`. Os erros API sao JSON mesmo sem o cabecalho `Accept`. Clientes mantem a listagem antiga `{"clients":[...]}` quando `per_page` nao e enviado. Com `per_page`, devolvem um paginador em `clients`, com `data`, `current_page`, `last_page`, `per_page`, `total` e links. Clientes e contratos limitam `per_page` ao intervalo 1-100. A listagem paginada de clientes filtra `type=client`, tal como a web; a listagem antiga conserva o comportamento anterior de devolver os registos ativos. Filtros de nome, NIF, email, tipo e codigo de contrato sao partilhados. Contratos incluem os totais da pagina atual. IDs de clientes passam a ser incluidos nas respostas. Passwords, hashes de PIN e remember tokens nao sao serializados. Dados financeiros e snapshots de contratos sao omitidos das respostas de negocio sem `view_contract_summary`. Atualizacoes sem essa permissao preservam os valores financeiros e parcelas. Exportacoes exigem essa permissao, tambem na web. As antigas operacoes administrativas `GET /admin/runMigrations` e `GET /admin/testEmail` passam a `POST`, exigem a role `admin`, e o email de destino passa a ser obrigatorio. Nenhuma migration foi executada durante esta refatoracao. Estes endpoints devem ser restritos tambem ao nivel de rede em producao, especialmente `phpinfo` e a execucao de migrations. ## Verificacao Os testes unitarios de regras ficam em `tests/Unit`. Os testes HTTP da API ficam em `tests/Api`, e os fluxos web destinados ao browser ficam em `tests/Browser`. Ambos usam uma base SQLite em memoria, com o esquema oficial de permissoes do Spatie e tabelas minimas; nao usam nem alteram a base de dados da aplicacao. Os testes Browser verificam a resposta HTTP, vistas, CSRF, redirecionamentos e sessoes Laravel; nao executam JavaScript num Chromium real. ```bash APP_ENV=testing DB_CONNECTION=sqlite DB_DATABASE=:memory: CACHE_STORE=array SESSION_DRIVER=array \ vendor/bin/phpunit tests/Unit tests/Api tests/Browser ``` Cada grupo tambem pode ser executado isoladamente com `vendor/bin/phpunit --testsuite API` ou `vendor/bin/phpunit --testsuite Browser`. O PHP CLI necessita da extensao `pdo_sqlite`. Os testes Feature legados que dependem de dados preexistentes nao estao incluidos no comando acima.