---
title: "Dynamic Filter Architecture Overview"
slug: "dynamic-filter-architecture-overview"
description: "Visao arquitetural do filtro dinamico no ecossistema Praxis, cobrindo runtime Angular, campos inline, payload enviado e normalizacao no metadata-starter."
doc_type: "concept"
document_kind: "host-guide"
component: "table"
category: "architecture"
audience:
  - "host"
  - "frontend"
  - "backend"
  - "architect"
level: "advanced"
status: "active"
owner: "praxis-ui"
tags:
  - "table"
  - "dynamic-filter"
  - "dynamic-fields"
  - "metadata-starter"
  - "range"
order: 26
icon: "account_tree"
toc: true
sidebar: true
search_boost: 1.15
reading_time: 16
estimated_setup_time: 35
version: "1.0"
related_docs:
  - "praxis-table-json-api"
  - "dynamic-filter-payload-contract"
  - "dynamic-filter-range-filters-guide"
  - "dynamic-fields-inline-components-guide"
keywords:
  - "praxis-filter"
  - "GenericFilterDTO"
  - "RangePayloadNormalizer"
  - "filter settings"
source_of_truth:
  - "projects/praxis-table/src/lib/components/praxis-filter/praxis-filter.component.ts"
  - "projects/praxis-table/src/lib/services/filter-config.service.ts"
  - "projects/praxis-table/src/lib/filter-settings/filter-settings.component.ts"
  - "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/filter/web/FilterRequestBodyAdvice.java"
  - "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/filter/range/RangePayloadNormalizer.java"
  - "../praxis-metadata-starter/src/main/java/org/praxisplatform/uischema/filter/specification/GenericSpecificationsBuilder.java"
last_updated: "2026-03-07"
---

# Dynamic Filter Architecture Overview

## Objetivo

Explicar o filtro dinâmico como uma feature transversal do ecossistema Praxis, não como um componente isolado, deixando claro como metadata, UI inline, editor/configuração, payload HTTP e interpretação backend trabalham juntos.

## Pré-requisitos

- Conhecimento básico de `@praxisui/table`, `@praxisui/dynamic-fields` e contratos de `FilterDTO`.
- Host Angular já integrado com `praxis-filter` e endpoints resource-oriented de filtro do backend.
- Familiaridade com metadados `controlType`, `@Filterable` e `@UISchema`.

## Quando usar

Use este documento quando precisar:

- entender o fluxo completo do filtro da tabela;
- planejar documentação funcional para hosts e squads backend;
- decidir onde documentar variantes inline, settings editor e contratos de range;
- investigar por que um payload válido na UI vira filtro inválido no backend.

## Visão geral da feature

No Praxis, o filtro dinâmico é uma pipeline de seis etapas:

1. O backend publica um `FilterDTO` anotado com `@Filterable` e `@UISchema`.
2. O host ou a tabela obtém schema/metadata para montar os campos do filtro.
3. O `PraxisFilter` decide o layout visível, a variante inline e o modo avançado.
4. O usuário interage com os campos, e o runtime emite `change`, `submit`, `clear`, `tagsChange` e eventos auxiliares.
5. O host envia o payload para endpoints como `POST /filter`, `POST /filter/cursor`, `POST /locate` ou `POST /options/filter`.
6. O `praxis-metadata-starter` normaliza ranges e constrói as predicates JPA a partir do `GenericFilterDTO`.

## Mapa de responsabilidades

### 1. `praxis-table`: runtime de orquestração

`PraxisFilter` é o núcleo do runtime na UI. Ele concentra:

- inputs de configuração e layout, como `alwaysVisibleFields`, `selectedFieldIds`, `allowSaveTags`, `changeDebounceMs` e variantes `useInline*Variant`;
- outputs que materializam o contrato com o host, principalmente `submit` e `change`;
- persistência local do estado do DTO e das preferências de exibição com chaves `filter-dto:<key>` e `filter-config:<key>`;
- heurísticas que convertem `controlType` genérico para inline canônico quando a feature pede experiência compacta.

Na toolbar da tabela, essa responsabilidade é materializada em quatro regiões
semânticas governadas pela largura do próprio container:

- `identity`: identidade e contexto da coleção;
- `scope`: quick filters mutuamente exclusivos e removíveis;
- `query`: campos de filtro e atalhos projetados;
- `commands`: ações de negócio, utilidades e authoring.

Dentro de `PraxisFilter`, `query` se divide em `criteria` e
`query-auxiliary`. A primeira região contém os campos selecionados e sempre
visíveis. A segunda mantém tags/atalhos e comandos de gerenciamento como um
cluster único. O reflow move regiões completas e preserva ordem visual, ordem de
teclado e paridade de comandos; hosts não devem reconstruir essa composição com
breakpoints locais.

Esse acoplamento existe em `projects/praxis-table/src/lib/components/praxis-filter/praxis-filter.component.ts` e `projects/praxis-table/src/lib/services/filter-config.service.ts`.

### 2. `praxis-dynamic-fields`: superfície dos controles

Os componentes `filter-*-inline` pertencem ao catálogo de `dynamic-fields`. Eles não definem sozinhos a jornada do filtro; eles implementam o comportamento visual e semântico de cada campo compacto:

- selects inline;
- async/searchable/entity lookup;
- intervalos numéricos, monetários, data e hora;
- controles especializados como rating, radius, pipeline status e score priority.

O contrato corporativo desses campos está em `projects/praxis-dynamic-fields/docs/dynamic-fields-inline-components-guide.md` (slug publicado: `dynamic-fields-inline-components-guide`).

### 3. `filter-settings`: governança editorial e operacional

`filter-settings.component.ts` é a ponte entre metadata, seleção de campos e overrides de UX. É onde o ecossistema define:

- quais campos ficam sempre visíveis;
- que `controlType` efetivo será usado na toolbar compacta;
- se a fonte da metadata vem do `filter-dto` ou de `columns`;
- quais conversões são aceitas para `rangeSlider`, `priceRange`, `dateRange`, `timeRange` e afins.

Em termos de documentação, isso significa que o editor do filtro precisa ser tratado como parte da feature, não como “extra”.

### 4. `praxis-metadata-starter`: normalização e interpretação

No backend, o payload recebido pelo controller não vai direto para a specification.

Antes disso:

- `FilterRequestBodyAdvice` intercepta qualquer request body compatível com `GenericFilterDTO`;
- `RangePayloadNormalizer` converte objetos e aliases em formato canônico de lista;
- `GenericSpecificationsBuilder` transforma o valor normalizado em predicates como `BETWEEN`, `BETWEEN_EXCLUSIVE`, `NOT_BETWEEN` e `OUTSIDE_RANGE`.

Isso é o motivo de a documentação do filtro precisar citar explicitamente o `praxis-metadata-starter`.

## Fluxo ponta a ponta

### Etapa 1. Schema e metadata

O backend descreve o filtro com:

- `@Filterable` para a operação semântica;
- `@UISchema` para `label`, `controlType`, `endpoint`, `numericFormat`, ordem e outras pistas visuais.

### Etapa 2. Resolução da UI

O `PraxisFilter` e o catálogo `dynamic-fields` decidem:

- se o campo vai para a barra compacta ou para a grade;
- se a variante será inline, dedicada ou avançada;
- se haverá clear button corporativo, tooltip contextual e presets rápidos.

### Etapa 3. Estado local

O runtime persiste:

- o DTO de filtro em `filter-dto:<key>`;
- a configuração de layout do filtro em `filter-config:<key>`.

Isso permite restaurar seleção de campos, preferências visuais e estado operacional do filtro.

Tags fornecidas por `tags` são presets governados e não pertencem ao conjunto
editável de atalhos salvos pelo usuário. O runtime permite aplicá-las e removê-las,
mas não renomeá-las ou excluí-las. O `patch` de cada tag deve usar os nomes e
shapes canônicos do `FilterDTO`; um campo desconhecido não ganha semântica apenas
por estar presente no JSON do host.

### Etapa 4. Emissão de payload

No modo avançado, `onAdvancedChange(event)` trabalha sobre `event.formData`. Os eventos `change` e `submit` são o contrato que o host normalmente observa para disparar integração com a API.

Há uma nuance importante já coberta em teste: objeto de range vazio deve ser limpo antes de poluir o payload emitido.

### Etapa 5. Request HTTP

O host envia o DTO para endpoints como:

- `POST /filter`
- `POST /filter/cursor`
- `POST /locate`
- `POST /options/filter`

Todos eles fazem parte da superfície resource-oriented de filtro do metadata-starter.

### Etapa 6. Normalização backend

O backend aceita mais de um shape para intervalos, mas canonicaliza tudo para a lista esperada pelo `FilterDTO` tipado.

Exemplos:

- `{ minPrice: 10, maxPrice: 20 }` vira `[10, 20]`;
- `{ startDate: "2026-03-01", endDate: "2026-03-31" }` vira `["2026-03-01", "2026-03-31"]`;
- `[null, 100]` continua representando “somente teto superior”.

## Regras arquiteturais que a doc precisa preservar

1. O filtro é metadata-driven, mas não schema-only.
   Runtime Angular, overrides do host e normalização backend influenciam o comportamento final.

2. O payload não é só responsabilidade do frontend.
   O backend canonicaliza ranges aceitos pela plataforma e rejeita payloads inválidos.

3. O editor/configuração faz parte do contrato da feature.
   Sempre documente `alwaysVisibleFields`, metadata overrides e variantes inline quando o componente depender deles.

4. A documentação deve separar duas perspectivas:
   - experiência de uso do filtro no contexto da tabela;
   - contrato técnico dos campos inline e do payload.

## Escopo da trilha documental recomendada

Para documentação extensa e didática, a feature deve ser desdobrada em pelo menos quatro documentos:

- arquitetura geral;
- contrato de payload;
- ranges e normalização;
- catálogo de campos inline e settings editor.

Os três primeiros já passam a existir nesta trilha. O quarto permanece ancorado no guia canônico de inline em `dynamic-fields`.
