Saltar al contenido principal

Gestionando Tablas Managed

Esta guia muestra los flujos completos de la API de Managed Tables: provisionamiento del banco, creacion manual, upload de archivos con inferencia de schema, y CRUD de filas.

Cuando usar: cuando tu aplicacion necesita almacenar datos estructurados propios de la company (planillas, datos de calculo, listas operacionales) sin depender de un banco externo. Cuando no usar: si quieres exponer una visualizacion guardada como API (usa Data API).

Pre-requisitos

  • JWT del console (login normal — no usa API key).
  • Permisos IAM asignados:
    • managed-tables:list, managed-tables:create, managed-tables:update, managed-tables:delete
    • managed-tables:upload, managed-tables:data-read, managed-tables:data-write
  • Roles managed que ya agregan todo: ConnectionManager, DataEngineer.

Vision general de los flujos

Workflow 1: Provisionamiento

Cada company debe provisionar su area de almacenamiento una unica vez. Idempotente — llamadas subsiguientes devuelven el estado existente.

export TOKEN="eyJ..."
export API_BASE_URL="http://localhost:3100"

# 1. Verifica estado
curl "$API_BASE_URL/api/v1/managed-tables/status" \
-H "Authorization: Bearer $TOKEN"
# → { "provisioned": false, "connection_id": null }

# 2. Provisiona (idempotente)
curl -X POST "$API_BASE_URL/api/v1/managed-tables/provision" \
-H "Authorization: Bearer $TOKEN"
# → { "provisioned": true, "connection_id": "507f..." }

Workflow 2: Creacion manual de tabla

Usalo cuando ya conoces el schema. No requiere archivo.

# 1. Crear tabla
curl -X POST "$API_BASE_URL/api/v1/managed-tables" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "ventas_mensuales",
"columns": [
{ "name": "producto", "display_name": "Producto", "type": "text", "nullable": false },
{ "name": "valor", "display_name": "Valor", "type": "decimal", "nullable": true },
{ "name": "fecha_venta", "display_name": "Fecha", "type": "date", "nullable": false }
]
}'

# Respuesta:
# { "_id": "507f...", "display_name": "ventas_mensuales", "columns": [...], ... }

# 2. Insertar filas
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../data" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"rows": [
{ "producto": "Camisa", "valor": 89.90, "fecha_venta": "2026-01-15" },
{ "producto": "Pantalon", "valor": 159.90, "fecha_venta": "2026-01-15" }
]
}'
# → 201 { "inserted": 2 }
Reglas de nombre
  • display_name y nombre de columna coinciden con ^[a-z_][a-z0-9_]*$.
  • display_name es unico por company entre tablas activas.
  • Conflicto devuelve 400 con error_code: MANAGED_TABLE_DUPLICATE_NAME.

Workflow 3: Upload de archivo (CSV/Excel/ZIP)

Flujo de 2 pasos con inferencia de schema. La API procesa el archivo de forma asincrona y el cliente confirma el schema antes de la insercion final.

Etapa 1 — upload

curl -X POST "$API_BASE_URL/api/v1/managed-tables/upload" \
-H "Authorization: Bearer $TOKEN" \
-F "files=@ventas_2026.csv"
# → 201 { "job_id": "abc123", "status": "queued" }

Limites: hasta 10 archivos por llamada, 100MB total. Acepta .csv, .xlsx, .xls, .zip (zip es descomprimido automaticamente).

Etapa 2 — polling del estado

curl "$API_BASE_URL/api/v1/managed-tables/upload-jobs/abc123" \
-H "Authorization: Bearer $TOKEN"

Estados que vas a observar (en orden):

EstadoSignificadoAccion del cliente
queuedEsperando procesamientoContinuar polling
analisandoAPI procesando archivoMostrar spinner
waiting_confirmSchema inferido listoRenderizar UI de confirmacion con inferred_schema
insertingInsercion en cursoMostrar progreso (progress.processed_rows)
doneTabla creada/actualizadaRedirigir a user_table_id
failedErrorMostrar error

Cuando status === "waiting_confirm", el body contiene:

{
"status": "waiting_confirm",
"inferred_schema": {
"suggested_table_name": "ventas_2026",
"columns": [
{ "name": "producto", "display_name": "Producto", "type": "text", "nullable": false },
{ "name": "valor", "display_name": "Valor", "type": "decimal", "nullable": true }
],
"sample_rows": [{ "producto": "Camisa", "valor": "89.90" }],
"total_row_count_estimate": 1500
}
}

Etapa 3 — confirmar schema

El usuario puede editar nombres de columna, tipos y display_name de la tabla antes de confirmar:

curl -X POST "$API_BASE_URL/api/v1/managed-tables/upload-jobs/abc123/confirm" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"display_name": "ventas_2026",
"columns": [
{ "name": "producto", "display_name": "Producto", "type": "text", "nullable": false },
{ "name": "valor", "display_name": "Valor", "type": "decimal", "nullable": true }
]
}'
# → 200 { "status": "inserting" }

Continua polling hasta status === "done". El user_table_id en el job apunta a la tabla creada.

Workflow 4: Append/Replace en tabla existente

Anexa nuevas filas a una tabla ya creada (o sustituye todo el contenido).

# Append en tabla existente
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../upload" \
-H "Authorization: Bearer $TOKEN" \
-F "files=@ventas_febrero.csv" \
-F "mode=append"

# Replace (sustituye todo)
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../upload" \
-H "Authorization: Bearer $TOKEN" \
-F "files=@ventas_completo.csv" \
-F "mode=replace"
Diferencias en append/replace
  • display_name de la tabla existente es reusado — el regex ^[a-z_][a-z0-9_]*$ no se aplica (soporta tablas legacy).
  • Schema confirmado debe coincidir con el schema de la tabla existente — columnas extras causan falla en el insert.
  • replace es atomico — todo el contenido es sustituido en una unica operacion (sin estado parcial visible).

Workflow 5: CRUD de filas

Operaciones punto-a-punto sobre las filas de una tabla.

# Listar (paginado)
curl "$API_BASE_URL/api/v1/managed-tables/507f.../data?page=1&per_page=50&sort_by=-fecha_venta" \
-H "Authorization: Bearer $TOKEN"
# → { "total": 1500, "quantity": 50, "records": [{ "id": "uuid", "producto": "X", ... }] }

# Insertar
curl -X POST "$API_BASE_URL/api/v1/managed-tables/507f.../data" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "rows": [{ "producto": "Z", "valor": 50 }] }'

# Actualizar fila
curl -X PUT "$API_BASE_URL/api/v1/managed-tables/507f.../data/<rowId>" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{ "valor": 99.90 }'

# Eliminar
curl -X DELETE "$API_BASE_URL/api/v1/managed-tables/507f.../data/<rowId>" \
-H "Authorization: Bearer $TOKEN"
# → 204 No Content

rowId es el identificador interno de la fila (generalmente UUID generado en el insert). Aparece como id en cada item de records.

Workflow 6: Soft-delete de la tabla

Listados (GET /v1/managed-tables) ya excluyen tablas archivadas, asi que la tabla desaparece inmediatamente. Restauracion no es expuesta por la API — abre un ticket de soporte si necesitas revertir.

Tipos de columna soportados

TipoPostgreSQL DDLEjemplo
textTEXT"abc"
integerBIGINT42
decimalNUMERIC89.90
booleanBOOLEANtrue
dateDATE"2026-01-15"
datetimeTIMESTAMPTZ"2026-01-15T10:30:00Z"

Tratamiento de errores

HTTPCodigoCausa comunAccion
400MANAGED_TABLE_DUPLICATE_NAMEdisplay_name ya existe activoPedir otro nombre al usuario
400-Banco no provisionadoLlamar POST /provision antes
400-Job no esta en waiting_confirmContinuar polling antes de confirmar
401-JWT ausente/expiradoRefresh token
403-Sin permiso IAMVerificar el role del usuario
404-Tabla/fila/job inexistenteReleer estado del recurso
422-Schema invalido (regex, tipo, campo obligatorio)Mostrar error especifico al usuario
500-Error internoRetry con backoff; loguear request_id

Buenas practicas

  • No llames POST /provision en loop — es idempotente, pero cada llamada es mas costosa. Verifica GET /status primero.
  • Polling con backoff exponencial — empieza en 1s, duplica hasta 10s. Job de upload puede llevar segundos a minutos dependiendo del tamano.
  • Muestra progress.processed_rows / progress.total_rows durante inserting para feedback al usuario en archivos grandes.
  • Valida el tamano de los archivos en el frontend antes del upload — backend rechaza >100MB total.
  • Reusa mode=append para uploads incrementales; no crees nueva tabla cada vez.
  • Para queries customizadas sobre las tablas managed, exponlas como Visualization y publicalas via Data API. Managed Tables no expone SQL libre.

Referencia completa

Para el contrato detallado de cada endpoint (todos los campos, status codes, ejemplos de error), ve Managed Tables API Reference.