Reten Docs
Filtros de eventos

Catálogo de eventos

Tabelas, colunas, registros repetidos e semi-joins disponíveis para construir um filtro de eventos.

O catálogo responde o que pode ser filtrado. São duas rotas: uma lista as tabelas disponíveis e a outra, para uma tabela, tudo o que ela oferece —colunas escalares, colunas RECORD REPEATED e semi-joins contra tabelas relacionadas.

Sem o catálogo a definição não é construível: não há outra forma de saber que attributes é um registro repetido, que items[] tem sub-campos, ou que products alcança a tabela product_properties.

Auth: Obrigatória — permissão event-criteria:view em ambas as rotas


GET /api/event-criterias/tables

Lista as tabelas do catálogo sobre as quais um filtro de eventos pode ser construído. O catálogo é idêntico entre tenants: esta rota não consulta o dataset do tenant.

Exemplo

curl https://api.reten.ai/api/event-criterias/tables \
  -H "Authorization: Bearer <token>" \
  -H "x-tenant-id: <tenant-id>" \
  -H "x-project-id: <project-id>"
import axios from 'axios';

const response = await axios.get(
  'https://api.reten.ai/api/event-criterias/tables',
  { headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const tables = response.data;

Resposta 200 OK

Um array de IEventTable:

CampoTipoDescrição
tableNamestringNome da tabela; é o valor que vai em from.table e em ColumnRefDto.table.
defaultTimeReferenceColumnstringOpcional. Coluna TIMESTAMP sugerida como reference da janela temporal. Outra coluna TIMESTAMP pode ser escolhida.
requiresInnerJoinbooleantrue se a tabela só pode participar como tabela principal do from ou como destino de um INNER JOIN.
[
  {
    "tableName": "event_transactions",
    "defaultTimeReferenceColumn": "event_date",
    "requiresInnerJoin": false
  }
]

As tabelas deste catálogo não declaram identityColumn: um filtro de eventos projeta eventos, não sujeitos. O campo existe na forma da resposta por paridade com o catálogo de audiências, mas aqui vem sempre ausente.


GET /api/event-criterias/tables/:tableName/columns

Retorna tudo o que o catálogo oferece sobre uma tabela. Diferente de /tables, esta rota reconcilia o catálogo contra o schema real do dataset do tenant antes de responder.

Parâmetros de rota

ParâmetroTipoDescrição
tableNamestringNome da tabela, tal como retornado por GET /tables.

Exemplo

curl https://api.reten.ai/api/event-criterias/tables/event_transactions/columns \
  -H "Authorization: Bearer <token>" \
  -H "x-tenant-id: <tenant-id>" \
  -H "x-project-id: <project-id>"
import axios from 'axios';

const response = await axios.get(
  'https://api.reten.ai/api/event-criterias/tables/event_transactions/columns',
  { headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const entries = response.data;

Resposta 200 OK

Um array de IEventCatalogEntry: uma união discriminada por kind com três variantes.

Estreite por kind antes de ler type ou fields. Apenas a variante scalar traz type; apenas record e semiJoin trazem fields. Ler entry.type sem discriminar retorna undefined para as outras duas variantes.

  • kind: "scalar" — uma coluna que pode ser filtrada diretamente:

    CampoTipoDescrição
    columnNamestringNome da coluna. Para folhas de um STRUCT não repetido é o path com ponto (pricing.final_amount).
    kind"scalar"Discriminador.
    typeCatalogFieldTypeEnumTipo do catálogo; determina quais operadores de comparação ela admite.
  • kind: "record" — uma coluna RECORD REPEATED, filtrável apenas com um filtro de registro:

    CampoTipoDescrição
    columnNamestringNome da coluna repetida.
    kind"record"Discriminador.
    fieldsIEventColumn[]Sub-campos filtráveis, relativos ao registro. Pode conter outros record.
  • kind: "semiJoin" — uma tabela relacionada alcançável com um filtro de tabela relacionada:

    CampoTipoDescrição
    kind"semiJoin"Discriminador.
    semiJoinNamestringNome do semi-join; é o valor que vai em semiJoinPredicate.semiJoin.
    targetTablestringTabela relacionada contra a qual o filtro é resolvido.
    fieldsIEventColumn[]Campos filtráveis da tabela relacionada.

Os fields de um record e de um semiJoin usam a mesma união scalar | record, então a regra de estreitar por kind se aplica em cada nível.

Exemplo de resposta

GET /api/event-criterias/tables/event_transactions/columns (recortado nas colunas escalares por brevidade; os registros e o semi-join vão completos):

[
  { "columnName": "event_id", "kind": "scalar", "type": "STRING" },
  { "columnName": "event_date", "kind": "scalar", "type": "TIMESTAMP" },
  { "columnName": "user_id", "kind": "scalar", "type": "STRING" },
  { "columnName": "status", "kind": "scalar", "type": "STRING" },
  { "columnName": "coupon_code", "kind": "scalar", "type": "STRING" },
  { "columnName": "pricing.net_amount", "kind": "scalar", "type": "FLOAT64" },
  { "columnName": "pricing.final_amount", "kind": "scalar", "type": "FLOAT64" },
  { "columnName": "payment_details.method", "kind": "scalar", "type": "STRING" },
  { "columnName": "payment_details.date", "kind": "scalar", "type": "TIMESTAMP" },
  { "columnName": "shipping_address.region", "kind": "scalar", "type": "STRING" },
  {
    "columnName": "attributes",
    "kind": "record",
    "fields": [
      { "columnName": "key", "kind": "scalar", "type": "STRING" },
      { "columnName": "value", "kind": "scalar", "type": "STRING" }
    ]
  },
  {
    "columnName": "items",
    "kind": "record",
    "fields": [
      { "columnName": "item_id", "kind": "scalar", "type": "STRING" },
      { "columnName": "name", "kind": "scalar", "type": "STRING" },
      { "columnName": "price", "kind": "scalar", "type": "FLOAT64" },
      { "columnName": "quantity", "kind": "scalar", "type": "FLOAT64" },
      { "columnName": "category", "kind": "scalar", "type": "STRING" }
    ]
  },
  {
    "kind": "semiJoin",
    "semiJoinName": "products",
    "targetTable": "product_properties",
    "fields": [
      { "columnName": "sku", "kind": "scalar", "type": "STRING" },
      { "columnName": "name", "kind": "scalar", "type": "STRING" },
      { "columnName": "categorization.family_name", "kind": "scalar", "type": "STRING" },
      { "columnName": "categorization.subfamily_name", "kind": "scalar", "type": "STRING" },
      { "columnName": "categorization.category_name", "kind": "scalar", "type": "STRING" },
      { "columnName": "categorization.brand_name", "kind": "scalar", "type": "STRING" },
      { "columnName": "categorization.collection_name", "kind": "scalar", "type": "STRING" },
      { "columnName": "commercial.base_price", "kind": "scalar", "type": "FLOAT64" },
      { "columnName": "composition.is_pack", "kind": "scalar", "type": "BOOLEAN" },
      { "columnName": "composition.is_combo", "kind": "scalar", "type": "BOOLEAN" }
    ]
  }
]

Como cada variante é usada na definição

VarianteOnde vai
scalarColumnRefDto.column de uma folha predicate, do select, do groupBy, de um agregado ou da reference da janela temporal.
recordcolumn de uma folha recordPredicate; seus fields vão no field das folhas do subWhere.
semiJoinsemiJoin de uma folha semiJoinPredicate; seus fields vão no field das folhas do subWhere.

O targetTable de um semi-join não é uma tabela do catálogo: não aparece em GET /tables, não pode ir no from nem ser destino de um join. Só é alcançado com uma folha semiJoinPredicate.

Um semi-join é omitido da resposta se o dataset do tenant não tiver sua tabela relacionada: não é um erro, é que esse tenant não tem essa fonte de dados. A ausência do semiJoin no catálogo é o sinal de que o filtro não está disponível.

Respostas de erro

StatusDescrição
401Ausente ou inválido o Authorization: Bearer.
403O usuário não tem a permissão event-criteria:view, ou o x-tenant-id não está autorizado.
404Apenas em /tables/:tableName/columns: a tabela não está no catálogo (La tabla no existe o no está en el catálogo de eventos.), ou o tenant não tem dataset configurado (Dataset not configured for tenant <id>).
500Apenas em /tables/:tableName/columns: o schema real do dataset não satisfaz o catálogo (El schema de datos no satisface el catálogo de eventos.).

GET /api/event-criterias/tables não consulta o dataset do tenant, então só retorna 200, 401 ou 403.