> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Conexões

> Registre, teste, atualize e exclua uma conexão do Fetcher — a referência nomeada, com credencial criptografada, a um banco de dados externo que todo job endereça.

Uma **conexão** é uma referência nomeada e armazenada a um banco de dados externo. Ela carrega o tipo de fonte de dados, o host e a porta, o nome do banco, as credenciais e as configurações TLS. Todo job de extração e toda chamada de esquema endereçam uma fonte de dados pelo `configName` da conexão, nunca pelo host dela.

O Fetcher é dono da credencial desde o momento em que ela chega. Ele criptografa a senha antes do armazenamento e nunca a devolve.

## O que uma conexão guarda

***

| Campo                   | Observações                                                                                                                                                                                     |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `configName`            | A identidade que um job usa. De 3 a 100 caracteres, apenas letras, dígitos, sublinhados e hifens.                                                                                               |
| `type`                  | Um entre `POSTGRESQL`, `MYSQL`, `ORACLE`, `SQL_SERVER`, `MONGODB`, em maiúsculas. A validação da requisição compara exatamente essas cinco cadeias, então qualquer outra caixa falha com `400`. |
| `host` e `port`         | A porta precisa ficar entre 1 e 65535.                                                                                                                                                          |
| `databaseName`          | Obrigatório.                                                                                                                                                                                    |
| `schema`                | Opcional. Restringe a descoberta e a extração a um namespace.                                                                                                                                   |
| `userName` e `password` | Ambos obrigatórios. O Manager criptografa a senha com sua chave de credenciais e registra a versão da chave junto ao registro armazenado.                                                       |
| `ssl`                   | Bloco opcional. Quando você o define, um modo e uma CA passam a ser obrigatórios.                                                                                                               |
| `metadata`              | Dados livres de chave-valor. Você pode filtrar a lista de conexões por eles.                                                                                                                    |

O Manager rejeita um modo TLS inválido para o tipo declarado. Cada driver de banco aceita um conjunto diferente de modos, e o Fetcher valida o modo contra o tipo antes de armazenar o registro.

## Ciclo de vida

***

<Steps>
  <Step title="Criar">
    `POST /v1/management/connections` com o corpo da conexão e um cabeçalho `X-Product-Name`. O cabeçalho nomeia o produto dono da conexão. Uma criação bem-sucedida responde `201 Created`.
  </Step>

  <Step title="Testar">
    `POST /v1/management/connections/{id}/test` abre uma conexão real com a fonte de dados e reporta a latência de ida e volta. Rode isso antes de qualquer job depender da conexão.
  </Step>

  <Step title="Descobrir">
    `GET /v1/management/connections/{id}/schema` retorna as tabelas e os campos que o Fetcher encontra na fonte de dados ao vivo. Veja [Descoberta de esquema](/pt/fetcher/fetcher-schema-discovery).
  </Step>

  <Step title="Usar">
    Referencie a conexão pelo `configName` dela no mapa `mappedFields` de um job de extração.
  </Step>

  <Step title="Atualizar ou excluir">
    `PATCH` aplica uma atualização parcial e deixa intocados os campos omitidos. `DELETE` é uma exclusão lógica: o registro guarda um carimbo de data e hora de exclusão. As duas operações respondem `409 Conflict` enquanto ainda há jobs em execução contra a conexão.
  </Step>
</Steps>

## Credenciais criptografadas

***

O Fetcher deriva quatro chaves independentes da única chave-mestra `APP_ENC_KEY`, por HKDF-SHA256. Uma dessas chaves protege as credenciais das fontes de dados.

A senha chega ao armazenamento criptografada com AES-256-GCM, e o registro armazenado guarda a `APP_ENC_KEY_VERSION` que a protegeu. Essa versão é o que torna a rotação de chaves tratável: um registro declara qual chave o abre.

A versão de chave vazia carrega significado. Ela marca uma fonte de dados **interna** — uma que um operador declara por variáveis de ambiente `DATASOURCE_{NAME}_*` em vez da API. O Fetcher monta essas conexões em memória na inicialização e não guarda registro algum delas em repouso. O gerenciador de segredos do próprio operador é o dono da credencial. Veja [Configuração](/pt/fetcher/fetcher-configuration).

<Warning>
  Os dois serviços precisam rodar com a mesma `APP_ENC_KEY`. O Worker precisa dela para abrir as credenciais que o Manager armazenou e para verificar a assinatura da mensagem que carregou o job. Nenhum dos serviços inicia sem uma chave válida de pelo menos 32 bytes.
</Warning>

## Testar uma conexão

***

A operação de teste faz trabalho real. Ela constrói o conector, abre a fonte de dados, roda a checagem de conectividade do próprio driver e fecha o conector em todo caminho — sucesso ou falha.

A resposta carrega `latencyMs`, a ida e volta observada em milissegundos. Use isso como sinal sobre o caminho de rede entre o Fetcher e a fonte de dados, não como um benchmark do banco de dados.

O endpoint tem limite de **10 testes por minuto por conexão**. Quem chama além desse orçamento recebe `429 Too Many Requests` com uma dica de espera. O limite vive no Manager, não no Engine, então um hospedeiro que incorpora o Engine define a própria política.

Um teste que falha diz a você que a conexão falhou. Ele não diz por quê em termos de driver. O Fetcher descarta o erro subjacente, porque esse texto pode carregar uma DSN ou uma credencial.

## O 409 em jobs ativos

***

<Warning>
  **O Fetcher bloqueia atualização e exclusão enquanto há jobs rodando contra a conexão.** `PATCH /v1/management/connections/{id}` e `DELETE /v1/management/connections/{id}` respondem `409 Conflict` quando pelo menos um job ainda roda contra o `configName` daquela conexão.

  Quem chama precisa tratar isso. Trate como "ainda não", não como "inválido". Espere os jobs chegarem a um estado terminal e tente de novo, ou cancele-os antes.
</Warning>

A regra existe para manter uma extração em curso consistente com a conexão contra a qual ela foi planejada. Uma troca de host ou uma mudança de credencial no meio da extração deixaria um job lendo de uma fonte de dados que ninguém pediu.

O Engine impõe essa trava por uma porta opcional, não por uma dependência dura do armazenamento de jobs. O Manager responde à pergunta a partir do repositório de jobs dele. Um hospedeiro que incorpora o Engine responde do jeito que rastreia trabalho — um conjunto em memória, um lock distribuído ou um "não" fixo. Um hospedeiro que não fornece nada não ganha trava, e as mutações seguem em frente.

## Segurança de host em modo multi-tenant

***

Com `MULTI_TENANT_ENABLED=true`, o Fetcher valida o host de toda conexão fornecida por um tenant antes de discar. A validação roda em duas camadas:

* Na análise da requisição, uma checagem sem DNS rejeita de imediato um literal de IP bloqueado.
* Na fábrica de fontes de dados, uma checagem com resolução rejeita hostnames bloqueados como `localhost` e nomes de metadados de nuvem, e em seguida rejeita todo endereço para o qual o hostname resolve.

Faixas privadas, loopback e endpoints de metadados de nuvem são bloqueados. Um host rejeitado retorna `400`.

<Note>
  Uma falha de resolução DNS deliberadamente **não** é um bloqueio. Transformar "não resolve" em rejeição construiria um oráculo de reconhecimento e faria conexões legítimas falharem durante um problema transitório de DNS. O driver expõe o próprio erro de conexão no lugar.
</Note>

A proteção nunca se aplica a fontes de dados internas. Um operador que configura uma fonte de dados por variáveis de ambiente já tomou essa decisão.

## Operações de migração

***

Duas operações existem apenas para conexões anteriores ao escopo por produto:

* `GET /v1/management/connections/unassigned` lista conexões sem produto.
* `POST /v1/management/connections/{id}/assign` vincula uma ao produto do cabeçalho `X-Product-Name`.

A atribuição é única e irreversível. Uma segunda tentativa em uma conexão já atribuída retorna um conflito.

## Próximos passos

***

<CardGroup cols={2}>
  <Card title="Descoberta de esquema" icon="table-list" href="/pt/fetcher/fetcher-schema-discovery">
    Leia o esquema de uma fonte de dados, mantenha-o em cache e valide um job contra ele.
  </Card>

  <Card title="Arquitetura" icon="sitemap" href="/pt/fetcher/fetcher-architecture">
    O Manager, o Worker e o Engine sobre o qual os dois rodam.
  </Card>
</CardGroup>
