Pular para o conteúdo

Tabelas de Apoio

Tabelas de Apoio são tabelas relacionais gerenciadas pelo TunnelHub para guardar dados operacionais que precisam ser consultados ou alterados por automações.

Use esse recurso quando o dado tem estrutura própria, chave primária, colunas tipadas e precisa ir além de um simples de/para.

Tabelas de Apoio fazem sentido para cenários como:

  • cache operacional compartilhado por execuções;
  • controle de processamento por entidade de negócio;
  • tabelas auxiliares com várias colunas;
  • dados importados por CSV e consumidos por automações;
  • estado de integração que precisa ser visível e administrado no produto.

Se o caso for apenas traduzir um valor de origem para um valor de destino, prefira Tabelas De/Para.

Cada Tabela de Apoio possui:

  • externalCode, usado por automações e SDK;
  • descrição funcional;
  • pacote associado;
  • lista opcional de usuários limitados;
  • schemaDefinition, com colunas e tipos;
  • primaryKey, com uma ou mais colunas;
  • indexesDefinition, para índices adicionais.

Tipos de coluna suportados:

  • TEXT;
  • INTEGER;
  • REAL;
  • NUMERIC;
  • BOOLEAN;
  • DATETIME.

Além da chave primária definida no schema, o TunnelHub mantém um rowId técnico para operações sobre linhas.

No produto, Tabelas de Apoio permitem:

  • criar e editar a definição da tabela;
  • listar linhas com paginação, filtros e ordenação;
  • inserir, editar e remover linhas;
  • importar dados por CSV;
  • exportar dados por CSV;
  • controlar visibilidade para usuários limitados.

Alterações de schema são tratadas pela plataforma. Mudanças destrutivas ou troca de chave primária podem exigir recriação planejada da tabela.

Para usar Tabelas de Apoio em uma automação, associe a tabela à automação no produto e habilite o runtime compatível no tunnelhub.yml.

Exemplo:

configuration:
runtimeEngine: LAMBDA
entrypoint: index.handler
runtime: nodejs24.x
memorySize: 1024
timeout: 60
runInVpc: true
sqlTables:
enabled: true

Requisitos quando sqlTables.enabled é true:

  • runtime deve ser nodejs24.x;
  • runInVpc deve ser true;
  • runtimeEngine deve ser LAMBDA ou ECS_FARGATE.

O SDK expõe o helper SqlTables para operar linhas durante a execução.

Exemplo conceitual:

const sqlTables = new SqlTables(event);
const inserted = await sqlTables.insertRow('customer-cache', {
document: '12345678900',
name: 'Cliente exemplo',
active: true,
});
const page = await sqlTables.queryRows('customer-cache', {
current: 1,
pageSize: 20,
filter: {
document: ['12345678900'],
},
});
await sqlTables.updateRow('customer-cache', inserted.rowId, {
name: 'Cliente atualizado',
});

O helper acessa o arquivo SQLite montado pela plataforma durante a execução. Ele não deve ser usado fora do runtime gerenciado do TunnelHub.

Para testes unitários com Jest, defina SDK.testMode = true antes de construir a integração. Nesse modo, o construtor de SqlTables não valida os requisitos do runtime gerenciado. As operações continuam precisando de mock explícito.

testMode não fornece persistência local e não simula SQLite, EFS ou DynamoDB. O exemplo a seguir usa fixtures por externalCode e mantém as inserções apenas em memória durante o processo do Jest:

import fs from 'node:fs';
import path from 'node:path';
import {ProcessorPayload, SDK, SqlTables} from '@tunnelhub/sdk';
type CustomerCacheRow = {
document: string;
name: string;
active: boolean;
};
type MockRow = {
rowId: string;
values: CustomerCacheRow;
};
const rowsByTable = new Map<string, MockRow[]>();
let nextRowId = 1;
const testEvent = {
tenantId: 'test-tenant',
environmentId: 'test-environment',
automationId: 'test-automation',
executionId: 'test-execution',
systems: [],
parameters: {},
} as ProcessorPayload;
function getRows(externalCode: string): MockRow[] {
const rows = rowsByTable.get(externalCode);
if (rows) return rows;
const fixturePath = path.join(__dirname, 'data', `${externalCode}.json`);
const fixture = JSON.parse(fs.readFileSync(fixturePath, 'utf8')) as MockRow[];
const clonedRows = structuredClone(fixture);
rowsByTable.set(externalCode, clonedRows);
return clonedRows;
}
describe('CustomerCacheIntegration', () => {
beforeAll(() => {
SDK.testMode = true;
});
beforeEach(() => {
jest.spyOn(SqlTables.prototype, 'queryRows').mockImplementation(async (externalCode, request = {}) => {
const current = request.current ?? 1;
const pageSize = request.pageSize ?? 20;
const rows = getRows(externalCode);
return {
success: true,
current,
pageSize,
total: rows.length,
data: rows.slice((current - 1) * pageSize, current * pageSize),
};
});
jest.spyOn(SqlTables.prototype, 'insertRow').mockImplementation(async (externalCode, values) => {
const row = {rowId: `test-row-${nextRowId++}`, values};
getRows(externalCode).push(row as MockRow);
return row;
});
});
afterEach(() => {
jest.restoreAllMocks();
rowsByTable.clear();
nextRowId = 1;
});
afterAll(() => {
SDK.testMode = false;
});
test('insere cliente ausente do cache', async () => {
const sqlTables = new SqlTables(testEvent);
await sqlTables.insertRow('customer-cache', {document: '12345678900', name: 'Ana', active: true});
expect(await sqlTables.queryRows('customer-cache')).toEqual({
success: true,
current: 1,
pageSize: 20,
total: 1,
data: [
{
rowId: 'test-row-1',
values: {document: '12345678900', name: 'Ana', active: true},
},
],
});
});
});

Organize as fixtures em __tests__/data/<externalCode>.json. Cada arquivo deve conter uma lista de linhas no formato retornado por queryRows. Por exemplo, o arquivo __tests__/data/customer-cache.json usado no teste de inserção pode conter apenas:

[]

Uma fixture vazia representa uma tabela existente sem registros.

O mock é apropriado para testar o fluxo da automação. Ele não reproduz schema, constraints, normalização de tipos nem o comportamento do SQLite. Teste esses cenários com SqlTables real, usando um arquivo SQLite preparado ou o runtime gerenciado do TunnelHub.

  • escolha externalCode estável e orientado ao domínio;
  • defina uma chave primária natural quando possível;
  • modele colunas com tipos claros;
  • use índices somente para consultas recorrentes;
  • evite armazenar segredos ou credenciais;
  • prefira Tabelas de Apoio para dados estruturados e Tabelas De/Para para mapeamentos simples.