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

# Bases de datos

> Lee, crea, actualiza y elimina registros de tus bases de Datum desde el canvas

El nodo **Bases de datos** conecta tu workflow con tus bases de datos y ejecuta operaciones sobre los registros sin escribir código. Eliges la base, la colección y la operación, y el panel arma la petición por ti.

Piensa en este nodo como un intermediario entre tu workflow y la base de datos: tú le indicas qué quieres hacer con los registros y él se encarga de hablar con el servicio.

<Note>
  Para administrar tus bases, colecciones, campos y registros en Datum, consulta la [documentación completa de Datum](/guides/datum/introduccion). Este nodo asume que la base ya existe.
</Note>

***

## Concepto clave

Toda operación del nodo se resuelve contra **una base + una colección + una operación**. Los tres son obligatorios para que el nodo pueda construir la petición correcta.

| Concepto          | Qué significa                                                                               |
| :---------------- | :------------------------------------------------------------------------------------------ |
| **Base de datos** | El contenedor que tienes provisionado en Datum (equivale a "la base").                      |
| **Colección**     | La tabla dentro de la base: usuarios, pedidos, productos, etc.                              |
| **Operación**     | La acción que realizarás sobre la colección: listar, obtener, crear, actualizar o eliminar. |

Cambiar cualquiera de los tres limpia los campos dependientes de abajo. Si ya habías ingresado datos que se perderían, el panel te avisa con un modal antes de aplicar el cambio.

***

## Configuración

El panel se organiza de arriba hacia abajo, en el mismo orden en que debes configurarlo.

### Base de datos

Selector con las bases que tu cuenta tiene disponibles en Datum. Junto al label aparece un botón **Abrir** que abre la base en una pestaña nueva del app de Datum, útil para revisar colecciones y registros mientras configuras el nodo.

<Frame caption="Selector de base de datos con botón Abrir">
  <img src="https://mintcdn.com/jelouai/kALZm2QrUx5mUtt4/assets/images/nodos/bases-de-datos/selector-base-datos-es.png?fit=max&auto=format&n=kALZm2QrUx5mUtt4&q=85&s=0438a69f297ba14292e393268c4912fb" alt="Selector de base de datos con botón Abrir en la esquina superior derecha" width="1678" height="1335" data-path="assets/images/nodos/bases-de-datos/selector-base-datos-es.png" />
</Frame>

<Note>
  Si la lista aparece vacía o ves un error 401/403, tu usuario no tiene permiso sobre esa base. Contacta al administrador de Datum en tu cuenta.
</Note>

### Colección

Solo se habilita cuando hay una base seleccionada. Muestra las colecciones que creaste en la base (las colecciones internas de Datum no aparecen). Mientras cargan, el selector queda deshabilitado; si la carga falla, se mantiene deshabilitado hasta que la base cambie o se corrijan los permisos.

### Operación

Define qué hará el nodo sobre la colección:

| Operación               | Para qué sirve                                          |
| :---------------------- | :------------------------------------------------------ |
| **Listar registros**    | Traer varios registros con filtros, orden y paginación. |
| **Obtener registro**    | Traer un único registro por su `id`.                    |
| **Crear registro**      | Insertar un nuevo registro.                             |
| **Actualizar registro** | Modificar un registro existente por `id`.               |
| **Eliminar registro**   | Borrar un registro por `id`.                            |

### Campos según operación

El resto del panel cambia en función de la operación elegida.

#### ID del registro

Requerido por **Obtener**, **Actualizar** y **Eliminar**. Acepta un valor fijo o una variable:

```text theme={null}
{{$context.userRecordId}}
```

<Warning>
  Si eliges **Obtener**, **Actualizar** o **Eliminar** y dejas el ID vacío, el servicio responde con `404 Record not found`. Esto es intencional: protege de llamadas accidentales contra toda la colección cuando lo que pedías era un único registro.
</Warning>

#### Valores de los campos

Para **Crear** y **Actualizar**, el panel abre un editor con un control específico por tipo de campo declarado en la colección:

| Tipo del campo                   | Control                                             |
| :------------------------------- | :-------------------------------------------------- |
| `text`, `email`, `url`, `number` | Input con soporte de variables                      |
| `bool`                           | Interruptor `true`/`false` o entrada de variable    |
| `date`                           | Calendario + selector de hora o entrada de variable |
| `select` (simple o múltiple)     | Selector desplegable o entrada de variable          |
| `editor`                         | Editor de texto enriquecido                         |
| `json`                           | Área de texto con sintaxis JSON                     |

En los tipos que lo soportan, un selector junto al campo alterna entre **Valor fijo** (el control propio del tipo) y **Variable** (entrada libre para inyectar un `{{$memory.x}}` o `{{$context.y}}`).

<Frame caption="Editor de campos por tipo declarado en la colección">
  <img src="https://mintcdn.com/jelouai/kALZm2QrUx5mUtt4/assets/images/nodos/bases-de-datos/editor-campos-es.png?fit=max&auto=format&n=kALZm2QrUx5mUtt4&q=85&s=38d91d3a57ec69fa26645dfdb9ee939b" alt="Editor de campos mostrando controles según el tipo declarado en la colección" width="1693" height="723" data-path="assets/images/nodos/bases-de-datos/editor-campos-es.png" />
</Frame>

#### Filtros (solo Listar)

Constructor visual con uno o varios términos unidos por AND. Cada fila se compone de campo, operador y valor.

| Operador             | Significado                     |
| :------------------- | :------------------------------ |
| `=`, `!=`            | Igual / distinto                |
| `>`, `>=`, `<`, `<=` | Comparación numérica o de fecha |
| `~`                  | Contiene el texto               |
| `!~`                 | No contiene el texto            |

Los términos a los que les falta el campo o el valor se ignoran al ejecutar — no bloquean la petición ni generan error; simplemente no forman parte del filtro final.

<Frame caption="Constructor visual de filtros con reglas AND">
  <img src="https://mintcdn.com/jelouai/kALZm2QrUx5mUtt4/assets/images/nodos/bases-de-datos/constructor-filtros-es.png?fit=max&auto=format&n=kALZm2QrUx5mUtt4&q=85&s=0dcb11a19b05d66b38952fe4aae372aa" alt="Constructor visual de filtros con operadores y reglas AND" width="1701" height="632" data-path="assets/images/nodos/bases-de-datos/constructor-filtros-es.png" />
</Frame>

#### Ordenamiento (solo Listar)

Constructor con una fila por criterio. En cada fila eliges el campo y la dirección (ascendente o descendente). Los criterios se aplican en el orden en que están visibles.

#### Paginación (solo Listar)

Dos campos numéricos: **página** (por defecto `1`) y **por página** (por defecto `50`). Si dejas uno vacío o con un número inválido, el nodo usa el valor por defecto al ejecutar.

***

## Guardar la respuesta

Activa el toggle **Guardar respuesta** en el encabezado del panel y define un nombre de variable. La respuesta completa del servicio se almacena en esa variable y queda disponible en los nodos siguientes.

### Acceder a la respuesta sin manipulación

Usa la variable directamente en otros nodos:

```text theme={null}
{{$context.basesRespuesta}}
```

### Manipular la respuesta en un nodo Código

```javascript theme={null}
let respuesta = $context.getHttpResponse('basesRespuesta')
respuesta = respuesta.json()

const primerRegistro = respuesta.items?.[0]
$memory.set('primerRegistro', primerRegistro)
```

<Warning>
  La llave que uses en `$context.getHttpResponse('basesRespuesta')` debe coincidir exactamente con la que configuraste en "Guardar respuesta".
</Warning>

***

## Respuesta de prueba

El botón **Probar** del encabezado ejecuta la petición contra Datum y abre un popover con el resultado. El popover muestra:

* **Código de estado** (por ejemplo, `200` o `404`)
* **Pestaña Cuerpo** — respuesta formateada como JSON con botón de copiar
* **Pestaña Encabezados** — encabezados de respuesta del servicio

<Frame caption="Popover de respuesta de prueba con pestañas Cuerpo y Encabezados">
  <img src="https://mintcdn.com/jelouai/kALZm2QrUx5mUtt4/assets/images/nodos/bases-de-datos/respuesta-prueba-es.png?fit=max&auto=format&n=kALZm2QrUx5mUtt4&q=85&s=185e5aab6c428c66b748514275d992ae" alt="Popover de respuesta del botón Probar con pestañas Cuerpo y Encabezados" width="1321" height="834" data-path="assets/images/nodos/bases-de-datos/respuesta-prueba-es.png" />
</Frame>

<Tip>
  Si cierras el popover y lo vuelves a abrir sin tocar la configuración, el nodo muestra la última respuesta en lugar de hacer una nueva llamada al servicio. En cuanto modificas cualquier campo, esa respuesta se marca como desactualizada y la próxima apertura ejecuta de nuevo.
</Tip>

***

## Casos de uso

<AccordionGroup>
  <Accordion title="Captura de leads desde un workflow de WhatsApp">
    Un workflow de WhatsApp que captura leads necesita registrar el teléfono y el nombre del usuario sin pasar por un endpoint externo. Mapea `{{$user.phone}}` y `{{$memory.nombre}}` a los campos de la colección `leads`, elige la operación **Crear** y el registro queda guardado sin escribir una sola línea de código.
  </Accordion>

  <Accordion title="Atención al cliente con respuestas personalizadas">
    Un workflow de atención al cliente que personaliza respuestas consulta primero la colección `clientes` filtrando por el email del usuario. El resultado se guarda en una variable y los nodos siguientes lo usan para adaptar el mensaje. Antes esto requería un nodo API con URL construida a mano; ahora son tres dropdowns y un filtro visual.
  </Accordion>

  <Accordion title="Seguimiento de pedidos con actualización de estado">
    Un workflow de seguimiento de pedidos recibe un código, busca el registro con la operación **Obtener** y actualiza el campo `status` a `entregado` con la fecha tomada de `{{$context.now}}`. El mismo proceso que antes requería dos nodos API ahora se resuelve en uno solo.
  </Accordion>
</AccordionGroup>
