Files
Investidor-V2/docs/investmoz/suitecrm/client.md
T
nala 250ac35fd1
tests / ci (push) Canceled after 0s
first commit
2026-09-28 10:01:09 +02:00

76 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SuiteCrmClient — contrato implementado
Estado: cliente Laravel implementado e testado com HTTP simulado. Não há SuiteCRM instalado, credenciais criadas, tráfego real ou integração com as manifestações. Não activar apenas por estes testes passarem.
## Ficheiros desta entrega
| Ficheiro | Finalidade |
| ------------------------------------------------- | ------------------------------------------------- |
| `app/Integrations/SuiteCrm/SuiteCrmClient.php` | Cliente OAuth2/JSON:API |
| `app/Integrations/SuiteCrm/SuiteCrmException.php` | Erro sanitizado e metadados de recuperação |
| `config/suitecrm.php` | Desactivação por defeito, URLs, módulos e limites |
| `.env.example` | Variáveis backend sem credenciais reais |
| `tests/Feature/SuiteCrm/SuiteCrmClientTest.php` | Testes de contrato local, recuperação e segurança |
Sem novas dependências Composer, rotas, migrations ou chamadas desde o frontend. A configuração usa o cache database existente; os testes usam array e não precisam de uma base de dados. Em implantação com vários workers, todos devem partilhar o cache e os locks.
## Contrato HTTP
A base configurada é a URL HTTPS da aplicação legacy que contém `Api`; o prefixo real será confirmado na instalação. Todos os caminhos abaixo são relativos a essa base.
| Método Laravel | HTTP | Caminho | Contrato |
| -------------------- | ----- | -------------------------------------------------------- | ------------------------------------------------------------------------------- |
| Autenticação interna | POST | `/Api/access_token` | `grant_type=client_credentials`, client ID/secret; resposta Bearer com validade |
| `find` | GET | `/Api/V8/module/{module}/{id}` | Registo autorizado |
| `search` | GET | `/Api/V8/module/{module}` | Filtros exactos combinados por AND; página >=1; tamanho 1–100 |
| `create` | POST | `/Api/V8/module` | Envelope `data.type` e `data.attributes` |
| `update` | PATCH | `/Api/V8/module` | Envelope com tipo, ID e atributos |
| `relate` | POST | `/Api/V8/module/{module}/{id}/relationships/{linkField}` | Tipo e ID do registo relacionado |
| `fields` | GET | `/Api/V8/meta/fields/{module}` | Metadados para validar o mapeamento |
O cliente devolve o documento JSON, preservando paginação. Não segue links de paginação devolvidos pelo servidor; o consumidor pede explicitamente a página seguinte. Módulos são limitados à allowlist de configuração; nomes e IDs não aceitam separadores de caminho. Métodos não são endpoints públicos e não substituem autorização de negócio, validação dos atributos ou permissões da conta técnica.
Os formatos foram confrontados com `public/legacy/Api/V8/Config/routes.php` no pacote oficial SuiteCRM 8.10.2 de SHA-256 `ac4693d10ea2d6cd20b3256098781d134599d88878fb24e8dc127038d624f5a8`. Os testes são contratos do consumidor com respostas simuladas; ainda falta provar compatibilidade contra o servidor.
## Tokens e segredos
HTTPS e validação do certificado são obrigatórios; redirects são recusados. A URL não pode conter credenciais, query ou fragmento. Tokens são cifrados com a chave Laravel antes de entrar no cache e expiram antecipadamente. Obtenção e invalidação usam locks. Se outra chamada já renovou o token, um 401 atrasado não deve apagar o token novo.
Client credentials obtém novo token na expiração; não presume refresh token. Um 401 da API permite uma renovação e repetição. O segundo 401 termina a operação. Alterar o segredo muda o namespace do cache; reiniciar workers/reconstruir o cache de configuração durante rotação. Revogar o cliente antigo no CRM; a mudança local não o revoga remotamente.
O segredo deve ser injectado no ambiente do backend por mecanismo privado. Não usar variáveis `VITE_`. O `.env` actual não foi alterado. Não imprimir configuração, payloads ou respostas de autenticação no diagnóstico.
## Retries, circuit breaker e ambiguidade
- Consultas: até duas repetições para falhas de rede, 429 e 5xx, com backoff exponencial e jitter.
- Retry-After numérico/data é respeitado. Atrasos superiores a cinco segundos são devolvidos ao futuro job, sem bloquear o processo; valor limitado a um dia.
- Criação, actualização e relação: não repetir automaticamente após timeout ou 5xx. `outcomeUnknown=true` exige consultar a identidade externa/reconciliar antes de reenviar.
- 403, 404, 409 e 422 são erros permanentes neste nível; a lógica de negócio decide a recuperação.
- Cinco operações com falha transitória abrem o circuito durante 60 segundos. O contador usa lock. Após o intervalo, operações voltam a ser permitidas; ainda não há controlo de uma única sonda half-open.
- Sucesso com JSON inválido é rejeitado; numa escrita, é considerado ambíguo.
`retryable` indica natureza transitória, não autorização para repetir uma escrita. O futuro processador da outbox deve respeitar também `outcomeUnknown` e `retryAfter`. O cliente isolado não implementa idempotência distribuída nem fusão de contactos.
## Observabilidade
Cada tentativa produz `suitecrm.http` com operação, código HTTP e duração em milissegundos. Não inclui URL, IDs, corpos, atributos ou cabeçalhos. Excepções usam razões enumeradas e não encadeiam a excepção HTTP original. Há atributos SensitiveParameter nos argumentos com dados pessoais/segredos.
Esses eventos permitem agregar taxa de falhas/latência; ainda não há exporter, dashboard ou alertas instalados. Instrumentação externa que capture HTTP (debuggers/APM) deve ser configurada para excluir tokens e payloads antes de activar a integração.
## Verificação e limites
15 testes, 62 asserções, sem rede real: desactivação, HTTPS, tokens cifrados, reutilização, expiração, rotação, 401 limitado, formato JSON:API, retry de leitura, escrita ambígua, Retry-After, circuito, módulos/IDs/paginação, sanitização e resposta inválida. PHPStan passou sem erros.
A suite completa também passou: 85 testes e 612 asserções. Pint, formatação e lint passaram. Não foi necessário alterar ou testar o frontend visual, pois esta entrega não o modifica.
Ainda faltam: testes reais e concorrência entre processos; configuração OAuth; RBAC no CRM; documentos binários; outbox/inbox e jobs; reconciliação; métricas/alertas; relação com consentimento e domínios do portal. Metadados de Documents podem ser enviados por `create` após validação do esquema; não existe upload binário genérico implementado.
## Rollback
Manter `SUITECRM_ENABLED=false`. Como nenhum fluxo do portal chama o cliente, esta entrega não altera dados comerciais. Ao remover os ficheiros, retirar também a configuração e variáveis de exemplo. Se o cliente tiver sido activado numa instalação futura, desactivar envios e revogar o OAuth; não considerar isso reversão de registos já escritos no CRM.
## Referências
- [Endpoints oficiais](https://docs.suitecrm.com/developer/integration-api/v8/endpoints/)
- [Autenticação oficial](https://docs.suitecrm.com/developer/integration-api/v8/authentication/)