Untitled
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
matchMode | SQL | Tipo do value |
|---|---|---|
contains | LIKE '%value%' | string |
startsWith | LIKE 'value%' | string |
endsWith | LIKE '%value' | string |
equals | = value | string | number |
notEquals | != value | string | number |
in | IN (values) | array |
notIn | NOT IN (values) | array |
gt | > value | number |
gte | >= value | number |
lt | < value | number |
lte | <= value | number |
between | BETWEEN a AND b | [min, max] |
dateIs | = date | string (ISO date) |
dateIsNot | != date | string (ISO date) |
dateBefore | < date | string (ISO date) |
dateAfter | > date | string (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 tabelaconsignee, filtrar pornamedates.ata→ acessar sub-objeto/tabeladates, colunaata
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