> ## 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.

# Conexiones

> Registra, prueba, actualiza y elimina una conexión de Fetcher — la referencia nombrada, con credenciales cifradas, a una base de datos externa que direcciona cada job.

Una **conexión** es una referencia nombrada y almacenada a una base de datos externa. Lleva el tipo de datasource, el host y el puerto, el nombre de la base, las credenciales y la configuración TLS que corresponda. Cada job de extracción y cada llamada de esquema direccionan un datasource por el `configName` de la conexión, nunca por su host.

Fetcher es dueño de la credencial desde el momento en que llega. Cifra la contraseña antes de almacenarla y nunca la devuelve.

## Qué guarda una conexión

***

| Campo                   | Notas                                                                                                                                                                                                        |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `configName`            | La identidad que usa un job. De 3 a 100 caracteres, solo letras, dígitos, guiones bajos y guiones.                                                                                                           |
| `type`                  | Uno de `POSTGRESQL`, `MYSQL`, `ORACLE`, `SQL_SERVER`, `MONGODB`, en mayúsculas. La validación de la solicitud compara exactamente esas cinco cadenas, así que cualquier otra capitalización falla con `400`. |
| `host` y `port`         | El puerto debe estar entre 1 y 65535.                                                                                                                                                                        |
| `databaseName`          | Obligatorio.                                                                                                                                                                                                 |
| `schema`                | Opcional. Limita el descubrimiento y la extracción a un solo espacio de nombres.                                                                                                                             |
| `userName` y `password` | Ambos obligatorios. El Manager cifra la contraseña con su clave de credenciales y registra la versión de clave junto al registro almacenado.                                                                 |
| `ssl`                   | Bloque opcional. Cuando lo defines, un modo y una CA se vuelven obligatorios.                                                                                                                                |
| `metadata`              | Datos libres de clave-valor. Puedes filtrar la lista de conexiones por ellos.                                                                                                                                |

El Manager rechaza un modo TLS inválido para el tipo declarado. Cada driver de base de datos acepta un conjunto distinto de modos, y Fetcher valida el modo contra el tipo antes de almacenar el registro.

## Ciclo de vida

***

<Steps>
  <Step title="Crear">
    `POST /v1/management/connections` con el cuerpo de la conexión y una cabecera `X-Product-Name`. La cabecera nombra el producto que es dueño de la conexión. Una creación exitosa responde `201 Created`.
  </Step>

  <Step title="Probar">
    `POST /v1/management/connections/{id}/test` abre una conexión real al datasource y reporta la latencia de ida y vuelta. Ejecútalo antes de que cualquier job dependa de la conexión.
  </Step>

  <Step title="Descubrir">
    `GET /v1/management/connections/{id}/schema` devuelve las tablas y los campos que Fetcher encuentra en el datasource en vivo. Consulta [Descubrimiento de esquemas](/es/fetcher/fetcher-schema-discovery).
  </Step>

  <Step title="Usar">
    Referencia la conexión por su `configName` en el mapa `mappedFields` de un job de extracción.
  </Step>

  <Step title="Actualizar o eliminar">
    `PATCH` aplica una actualización parcial y deja intactos los campos omitidos. `DELETE` es una eliminación lógica: el registro conserva una marca de tiempo de eliminación. Ambas operaciones responden `409 Conflict` mientras aún corren jobs contra la conexión.
  </Step>
</Steps>

## Credenciales cifradas

***

Fetcher deriva cuatro claves independientes de la única clave maestra `APP_ENC_KEY`, mediante HKDF-SHA256. Una de esas claves protege las credenciales de datasource.

La contraseña llega al almacenamiento cifrada con AES-256-GCM, y el registro almacenado conserva el `APP_ENC_KEY_VERSION` que la protegió. Esa versión es lo que hace tratable la rotación de claves: un registro declara qué clave lo abre.

La versión de clave vacía tiene significado. Marca un datasource **interno** — uno que un operador declara mediante variables de entorno `DATASOURCE_{NAME}_*` en lugar de la API. Fetcher construye esas conexiones en memoria al arrancar y no guarda ningún registro de ellas en reposo. El gestor de secretos del propio operador es el dueño de la credencial. Consulta [Configuración](/es/fetcher/fetcher-configuration).

<Warning>
  Ambos servicios deben correr con la misma `APP_ENC_KEY`. El Worker la necesita para abrir las credenciales que almacenó el Manager y para verificar la firma del mensaje que llevó el job. Ninguno de los dos servicios arranca sin una clave válida de al menos 32 bytes.
</Warning>

## Probar una conexión

***

La operación de prueba hace trabajo real. Construye el conector, abre el datasource, ejecuta la verificación de conectividad propia del driver y cierra el conector en todos los casos — con éxito o con fallo.

La respuesta lleva `latencyMs`, la ida y vuelta observada en milisegundos. Úsalo como señal sobre el camino de red entre Fetcher y el datasource, no como benchmark de la base de datos.

El endpoint tiene un límite de tasa de **10 pruebas por minuto por conexión**. Un llamador que pasa ese presupuesto recibe `429 Too Many Requests` con una indicación de espera. El límite vive en el Manager, no en el Engine, así que un host embebido define su propia política.

Una prueba fallida te dice que la conexión falló. No te dice por qué en términos del driver. Fetcher descarta el error subyacente, porque ese texto puede llevar un DSN o una credencial.

## El 409 con jobs activos

***

<Warning>
  **Fetcher bloquea la actualización y la eliminación mientras corren jobs contra la conexión.** `PATCH /v1/management/connections/{id}` y `DELETE /v1/management/connections/{id}` responden `409 Conflict` cuando al menos un job todavía corre contra el `configName` de esa conexión.

  Un llamador debe manejarlo. Trátalo como "todavía no", no como "inválido". Espera a que los jobs lleguen a un estado terminal y reintenta, o cancélalos primero.
</Warning>

La regla existe para mantener una extracción en curso consistente con la conexión contra la que planificó. Un cambio de host o de credencial a mitad de la extracción dejaría a un job leyendo de un datasource que nadie pidió.

El Engine aplica la barrera mediante un puerto opcional, no mediante una dependencia dura del almacenamiento de jobs. El Manager responde la pregunta desde su repositorio de jobs. Un host embebido la responde como sea que lleve el registro del trabajo — un conjunto en memoria, un lock distribuido o un "no" fijo. Un host que no provee nada no obtiene barrera, y las mutaciones siguen adelante.

## Seguridad de host en modo multi-tenant

***

Con `MULTI_TENANT_ENABLED=true`, Fetcher valida el host de cada conexión provista por un tenant antes de marcar. La validación corre en dos capas:

* Al parsear la solicitud, una verificación sin DNS rechaza de plano una IP literal bloqueada.
* En la fábrica de datasources, una verificación con resolución rechaza los hostnames bloqueados como `localhost` y los nombres de metadatos de nube, y después rechaza toda dirección a la que resuelva el hostname.

Los rangos privados, el loopback y los endpoints de metadatos de nube están bloqueados. Un host rechazado devuelve `400`.

<Note>
  Un fallo de resolución DNS deliberadamente **no** es un bloqueo. Convertir "no resuelve" en un rechazo construiría un oráculo de reconocimiento y haría fallar conexiones legítimas durante un problema transitorio de DNS. En su lugar, el driver expone su propio error de conexión.
</Note>

La protección nunca se aplica a los datasources internos. Un operador que configura un datasource mediante variables de entorno ya tomó esa decisión.

## Operaciones de migración

***

Existen dos operaciones solo para conexiones anteriores al alcance por producto:

* `GET /v1/management/connections/unassigned` lista las conexiones sin producto.
* `POST /v1/management/connections/{id}/assign` asocia una al producto de la cabecera `X-Product-Name`.

La asignación es única e irreversible. Un segundo intento sobre una conexión ya asignada devuelve un conflicto.

## Próximos pasos

***

<CardGroup cols={2}>
  <Card title="Descubrimiento de esquemas" icon="table-list" href="/es/fetcher/fetcher-schema-discovery">
    Lee el esquema de un datasource, guárdalo en caché y valida un job contra él.
  </Card>

  <Card title="Arquitectura" icon="sitemap" href="/es/fetcher/fetcher-architecture">
    El Manager, el Worker y el Engine que ambos ejecutan.
  </Card>
</CardGroup>
