Untitled

Anonymous
markdown
02/18/2026 2:09 PM
6.1 KB
14
Indexable

Plano: Filtros Genéricos por Coluna — Especificação para o Backend

Contexto

O frontend (PrimeNG) já gera metadados completos de filtro por coluna (campo, valor, modo de comparação). Hoje esses filtros são descartados antes de chegar ao backend. O objetivo é que o backend receba e aplique esses filtros de forma genérica.


Contrato: o que o frontend vai enviar

IListCriteria (estrutura completa)

interface IListCriteria { pagination: { index: number; // página (0-based) size: number; // itens por página }; sorts?: { column: string; direction: 'Ascendant' | 'Descendant'; }[]; filters?: IColumnFilter[]; // ← novo }

IColumnFilter

interface IColumnFilter { field: string; // nome do campo (ex: "name", "amount", "consignee.name") value: unknown; // valor digitado/selecionado pelo usuário matchMode: FilterMatchMode; } type FilterMatchMode = | 'contains' | 'startsWith' | 'endsWith' | 'equals' | 'notEquals' | 'in' | 'notIn' | 'gt' | 'gte' | 'lt' | 'lte' | 'between' | 'dateIs' | 'dateIsNot' | 'dateBefore' | 'dateAfter';

Exemplo de payload

{ "criteria": { "pagination": { "index": 0, "size": 25 }, "sorts": [ { "column": "name", "direction": "Ascendant" } ], "filters": [ { "field": "name", "value": "João", "matchMode": "contains" }, { "field": "userType", "value": ["Internal", "External"], "matchMode": "in" }, { "field": "amount", "value": 1000, "matchMode": "gte" }, { "field": "dates.ata", "value": "2026-01-15", "matchMode": "dateAfter" } ] }, "filters": { "search": { "term": "busca global" } } }

criteria.filters = filtros por coluna (novo). filters.search = busca global textual (já existe, mantido).


Mapeamento matchMode → SQL

matchModeSQLTipo do value
containsLIKE '%value%'string
startsWithLIKE 'value%'string
endsWithLIKE '%value'string
equals= valuestring | number
notEquals!= valuestring | number
inIN (values)array
notInNOT IN (values)array
gt> valuenumber
gte>= valuenumber
lt< valuenumber
lte<= valuenumber
betweenBETWEEN a AND b[min, max]
dateIs= datestring (ISO date)
dateIsNot!= datestring (ISO date)
dateBefore< datestring (ISO date)
dateAfter> datestring (ISO date)

Campos com notação de ponto

Campos como consignee.name, origin.name, dates.ata indicam acesso a propriedade aninhada (join/subquery no backend).

{ "field": "consignee.name", "value": ["id1", "id2"], "matchMode": "in" }

O backend deve interpretar o . como navegação de relacionamento:

  • consignee.name → JOIN na tabela consignee, filtrar por name
  • dates.ata → acessar sub-objeto/tabela dates, coluna ata

Múltiplos filtros no mesmo campo

O PrimeNG pode enviar mais de um filtro para o mesmo campo (ex: range numérico com gte e lte). Nesse caso, criteria.filters terá dois itens com o mesmo field:

[ { "field": "amount", "value": 100, "matchMode": "gte" }, { "field": "amount", "value": 5000, "matchMode": "lte" } ]

O backend deve aplicar todos como AND.


Retrocompatibilidade

  • criteria.filters é opcional. Se não vier (ou vier como []/null), o backend se comporta como hoje.
  • filters.search.term (busca global) continua funcionando como antes.
  • Filtros de domínio existentes (filters.userTypeList, etc.) continuam funcionando em paralelo durante a migração. Serão removidos gradualmente depois.
Leave a Comment