@praxisui/table 8.0.0-beta.2 → 8.0.0-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +81 -8
  2. package/docs/DSL-Extensions-Guide.md +23 -0
  3. package/docs/adr/2026-03-dynamic-filter-cross-lib-coupling.md +107 -0
  4. package/docs/adr/2026-03-filter-drawer-adapter-light-entrypoint.md +105 -0
  5. package/docs/adr/2026-03-table-editor-idfield-decision.md +85 -0
  6. package/docs/column-resize-reorder-implementation-plan.md +338 -0
  7. package/docs/column-resize-reorder-review-prompt.md +34 -0
  8. package/docs/dynamic-filter-architecture-overview.md +207 -0
  9. package/docs/dynamic-filter-backend-contract-cheatsheet.md +167 -0
  10. package/docs/dynamic-filter-editor-settings-guide.md +229 -0
  11. package/docs/dynamic-filter-host-integration-guide.md +217 -0
  12. package/docs/dynamic-filter-payload-contract.md +331 -0
  13. package/docs/dynamic-filter-range-filters-guide.md +289 -0
  14. package/docs/dynamic-filter-troubleshooting-guide.md +220 -0
  15. package/docs/dynamic-inline-filter-catalog.md +147 -0
  16. package/docs/e2e-column-drag-playwright.md +62 -0
  17. package/docs/expandable-rows-enterprise-big-leagues-plan.md +1080 -0
  18. package/docs/json-logic-operators-and-helpers.md +57 -0
  19. package/docs/local-data-mode-precedence.md +12 -0
  20. package/docs/local-data-pre-implementation-baseline.md +22 -0
  21. package/docs/local-data-preimplementation-go-no-go.md +39 -0
  22. package/docs/local-data-support-implementation-plan.md +524 -0
  23. package/docs/local-data-support-pr-package.md +66 -0
  24. package/docs/localization-persistence-merge.md +22 -0
  25. package/docs/performance-hardening-v2-implementation-plan.md +479 -0
  26. package/docs/playground-scenario-curation-plan.md +482 -0
  27. package/docs/playground-scenario-second-opinion-prompt.md +121 -0
  28. package/docs/playground-scenario-second-opinion-review.md +234 -0
  29. package/docs/release-notes-p1-hardening.md +76 -0
  30. package/docs/table-authoring-document-completeness-checklist.md +120 -0
  31. package/docs/table-editor-capability-review-prompt.md +349 -0
  32. package/docs/visual-rules-editor-transition.md +29 -0
  33. package/fesm2022/{praxisui-table-table-ai.adapter-DxjDaQqy.mjs → praxisui-table-table-ai.adapter-fS74fZ7o.mjs} +14 -5
  34. package/fesm2022/praxisui-table.mjs +3650 -324
  35. package/index.d.ts +120 -51
  36. package/package.json +15 -9
  37. package/src/lib/praxis-table.json-api.md +1315 -0
@@ -0,0 +1,57 @@
1
+ # Operadores e Helpers de Json Logic
2
+
3
+ Estado canonico atual:
4
+
5
+ - Json Logic e o unico contrato ativo de regras condicionais em `@praxisui/table`.
6
+ - O editor de regras da tabela gera e valida AST Json Logic.
7
+ - O runtime da tabela avalia condicoes pelo `PraxisJsonLogicService` compartilhado em `@praxisui/core`.
8
+
9
+ ## Operadores executaveis
10
+
11
+ Operadores nativos aceitos pelo runtime:
12
+
13
+ - dados e fluxo: `var`, `if`
14
+ - comparacao: `==`, `===`, `!=`, `!==`, `>`, `>=`, `<`, `<=`
15
+ - logica: `!`, `!!`, `and`, `or`
16
+ - colecoes/texto nativos: `in`, `cat`, `substr`, `merge`
17
+ - colecoes funcionais: `map`, `filter`, `reduce`, `all`, `some`, `none`
18
+ - aritmetica: `+`, `-`, `*`, `/`, `%`, `min`, `max`
19
+
20
+ Operadores Praxis registrados por padrao:
21
+
22
+ - texto/valor: `contains`, `startsWith`, `endsWith`, `matches`, `isBlank`, `coalesce`, `stringify`
23
+ - tamanho e numeros: `len`, `round`, `ceil`, `floor`, `abs`, `toNumber`
24
+ - JSON/objeto: `jsonGet`, `hasKey`
25
+ - tempo: `now`, `date`, `yearsSince`, `monthsSince`, `daysSince`, `isToday`, `inLast`, `weekdayIn`
26
+
27
+ ## Conveniencias do editor
28
+
29
+ Algumas opcoes visuais do editor nao sao operadores runtime. Elas devem compilar para AST Json Logic canonica:
30
+
31
+ - `between` -> `and` com `>=` e `<=`
32
+ - `date between` -> `and` com limites de data
33
+ - `contains any` -> `or` com `contains`/`in`
34
+ - `contains all` -> `and` com `contains`/`in`
35
+ - `jsonEq` -> `===` combinado com `jsonGet`
36
+ - `jsonIn` -> `in` combinado com `jsonGet`
37
+ - `hasJsonKey` -> `hasKey`
38
+ - `not matches` -> `!` sobre `matches`
39
+
40
+ Esses nomes podem aparecer como labels, previews ou migracao de editor, mas nao devem ser persistidos como operador canonico se nao existirem no registry runtime.
41
+
42
+ ## Exemplos canonicos
43
+
44
+ ```json
45
+ { "===": [{ "jsonGet": [{ "var": "payload" }, "$.user.name"] }, "Alice"] }
46
+ { "in": [{ "jsonGet": [{ "var": "customer" }, "$.id"] }, [10, 20]] }
47
+ { "contains": [{ "var": "tags" }, "vip"] }
48
+ { "and": [{ ">=": [{ "var": "amount" }, 10] }, { "<=": [{ "var": "amount" }, 20] }] }
49
+ { "weekdayIn": [{ "var": "createdAt" }, [1, 5]] }
50
+ ```
51
+
52
+ ## Diretriz de uso
53
+
54
+ - Use Json Logic para visibilidade, styling, renderizacao condicional e comportamento declarativo.
55
+ - Mantenha a condicao como AST serializavel e validavel.
56
+ - Nao use strings DSL como `"status == 'Ativo'"` em regras novas.
57
+ - Nao espalhe logica condicional em componentes host quando ela pertence ao contrato metadata-driven da tabela.
@@ -0,0 +1,12 @@
1
+ # Precedência Oficial de Fonte de Dados
2
+
3
+ Contrato de resolução de origem para `praxis-table`:
4
+
5
+ 1. `resourcePath` explícito (input, quick-connect ou `document.bindings.resourcePath`) tem prioridade máxima.
6
+ 2. `data` (array local) define modo local quando não há `resourcePath` explícito.
7
+ 3. Conexão persistida só é usada como fallback quando não existe `resourcePath` explícito e o modo local não está ativo.
8
+
9
+ Regras de conflito:
10
+
11
+ - `resourcePath` + `data` ao mesmo tempo resolve para `remote`.
12
+ - Limpar `document.bindings.resourcePath` no documento autorado é a forma explícita de remover a conexão remota via editor.
@@ -0,0 +1,22 @@
1
+ # Baseline Remoto Protegido (PR-0)
2
+
3
+ Escopo congelado por testes de caracterização:
4
+
5
+ 1. Bootstrap remoto:
6
+ - `resourcePath` efetivo dispara `configure -> loadSchema -> fetchData`.
7
+
8
+ 2. Interações remotas que mantêm HTTP:
9
+ - `onSortChange` e `onPageChange` continuam disparando `fetchData`.
10
+ - `onAdvancedFilterSubmit` e `onAdvancedFilterClear` continuam disparando `fetchData`.
11
+
12
+ 3. Wrappers de recuperação:
13
+ - `retryData`, `reloadSchema`, `refetch` mantêm comportamento remoto.
14
+
15
+ 4. Precedência de modo:
16
+ - `resourcePath` explícito tem precedência sobre `data` para manter `remote`.
17
+
18
+ 5. Quick connect:
19
+ - Aplicação de conexão continua chamando `configure -> loadSchema/verify -> fetchData`.
20
+
21
+ Observação:
22
+ - Esta baseline é o gate inicial para evolução do modo local sem regressão no fluxo remoto existente.
@@ -0,0 +1,39 @@
1
+ # Go/No-Go (Pacote Pré-Implementação)
2
+
3
+ ## Gate remoto
4
+ - [x] Baseline remoto com testes de caracterização criada.
5
+ - [x] Guard rail de precedência `resourcePath > data` coberto.
6
+ - [x] Wrappers remotos (`retryData/reloadSchema/refetch`) preservados.
7
+ - [x] Test lane isolada criada para `praxis-table` (`npm run test:table:preimpl:lane`).
8
+
9
+ ## Última execução validada da lane (2026-02-23)
10
+ - [x] Execução da lane isolada concluída com Chrome do Windows (`cmd.exe` + `ChromeHeadless`).
11
+ - [x] Resultado final da suíte isolada: `TOTAL: 48 SUCCESS`.
12
+ - [x] Cobertura crítica confirmada na execução: preservação de `pageSize` local.
13
+ - [x] Cobertura crítica confirmada na execução: estabilidade de `fieldMetadata`.
14
+ - [x] Cobertura de transições confirmada na execução: `remote->local`, `local->remote`, `local->empty`, `empty->local`.
15
+ - [x] Ajustes de alinhamento do editor ao modo efetivo validados por testes.
16
+
17
+ ## Gate de contrato
18
+ - [x] `DataMode` formalizado no runtime (`remote|local|empty`).
19
+ - [x] Documento de precedência oficial adicionado.
20
+ - [x] Documento de autoria da tabela formalizado com `bindings.resourcePath` no envelope canônico do editor.
21
+
22
+ ## Gate de rollout
23
+ - [x] Feature flag `behavior.localDataMode.enabled` adicionada.
24
+ - [x] Default da flag definido como `false`.
25
+ - [x] Log de modo/flag por instância disponível em debug.
26
+
27
+ ## Gate de scaffolding local
28
+ - [x] Estruturas `localSource`, `localView`, `localTotal` criadas.
29
+ - [x] Stub de `recomputeLocalView()` implementado.
30
+ - [x] Renderização orientada a helper de modo no template (`shouldRenderDataSurface`, `shouldShowEmptyState`).
31
+
32
+ ## Gate de engine local
33
+ - [x] Engine pura criada (`matchesAdvancedCriteria` + comparadores por shape).
34
+ - [x] Testes unitários da engine cobrindo primitivo, array, range, dateRange, lookup e nested fields.
35
+
36
+ ## Bloqueios atuais de validação automática
37
+ - [x] Bloqueio operacional da lane isolada (browser headless) encerrado.
38
+ - [ ] Suíte Angular completa verde no workspace (fora do escopo da lane isolada da `praxis-table`).
39
+ Motivo: erros de tipagem preexistentes em múltiplos módulos fora de `praxis-table` (`@praxisui/ai`, `@praxisui/visual-builder`, etc.).
@@ -0,0 +1,524 @@
1
+ # Plano Tecnico Revisado: Suporte Oficial a Dados Locais (JSON) na `praxis-table`
2
+
3
+ ## 1. Objetivo
4
+ Implementar suporte oficial a dados locais via input `[data]` na `praxis-table`, mantendo regressao zero no fluxo remoto (`resourcePath`) e garantindo que o filtro dinamico funcione de forma real em modo local.
5
+
6
+ ## 2. Decisoes de Produto e Engenharia
7
+ - Mudanca aditiva, sem breaking change para consumidores atuais.
8
+ - `resourcePath` explicito continua soberano quando informado.
9
+ - `data` ativa modo local oficial quando nao houver `resourcePath` efetivo.
10
+ - Conexao persistida entra apenas como fallback quando nao houver `resourcePath` explicito nem modo local ativo.
11
+ - Runtime, editor e documentacao devem mostrar o mesmo modo efetivo.
12
+ - Filtro dinamico em local deve ser funcional (nao apenas visual), sem chamadas HTTP.
13
+
14
+ ## 3. Estado Atual Validado (snapshot em codigo)
15
+ ### 3.1 `praxis-table`
16
+ - Template principal esta acoplado a `resourcePath` para render de tabela e filtro.
17
+ - Empty state aparece quando `resourcePath` esta vazio, mesmo se existirem dados locais.
18
+ - `onAdvancedFilterSubmit/Clear` so dispara `fetchData()` quando existe `resourcePath`.
19
+ - Nao existe engine explicita de avaliacao de `advancedFilters` para dataset local.
20
+
21
+ ### 3.2 `praxis-filter`
22
+ - O componente aceita `fieldMetadata` estatico e, quando presente, evita carregamento de schema remoto.
23
+ - O payload emitido no `submit` eh um DTO dinamico limpo (`Record<string, any>`), removendo valores vazios.
24
+ - O formato dos valores varia por tipo de campo (range, dateRange, select com objeto, etc), o que exige avaliador local tipado.
25
+
26
+ ### 3.3 Editores
27
+ - Ja existe fallback de metadata por colunas em partes do editor.
28
+ - Ainda ha risco de UX contraditoria (configuracao server ativa quando runtime efetivo eh local).
29
+
30
+ ### 3.4 Drift de contrato
31
+ - README ja sinaliza uso com `[data]`.
32
+ - Runtime/metadata publica ainda nao garantem esse contrato de ponta a ponta.
33
+
34
+ ## 4. Contrato Final (API Publica + Runtime)
35
+ 1. Novo input no componente:
36
+ - `@Input() data: any[] | null = null;`
37
+ 2. Normalizacao:
38
+ - `resourcePathNormalized = (resourcePath ?? '').trim()`
39
+ - `hasExplicitResourcePath = resourcePathNormalized.length > 0`
40
+ - `hasLocalData = Array.isArray(data)`
41
+ 3. Modos efetivos:
42
+ - `remote`: existe `resourcePath` efetivo.
43
+ - `local`: `resourcePath` vazio e `data` eh array (inclui `[]`).
44
+ - `empty`: sem `resourcePath` efetivo e sem `data` valido.
45
+ 4. Precedencia por origem:
46
+ - `resourcePath` explicito (input/quick-connect/editor) > `data` > conexao persistida.
47
+ 5. Conflito `resourcePath + data`:
48
+ - Mantem `remote`, ignora `data`, logando warning apenas em debug.
49
+ 6. Metadata publica:
50
+ - Incluir `data` em `PRAXIS_TABLE_COMPONENT_METADATA.inputs`.
51
+
52
+ ## 5. Comportamento Alvo por Cenario
53
+ | Cenario | Modo efetivo | Comportamento alvo |
54
+ |---|---|---|
55
+ | Standalone com `resourcePath` | `remote` | Fluxo atual inalterado |
56
+ | Standalone com `[data]` sem `resourcePath` | `local` | Render + sort + paginacao + advanced filter client-side |
57
+ | Standalone com `resourcePath` + `[data]` | `remote` | `data` ignorado (warning debug) |
58
+ | Standalone sem `resourcePath` e sem `data` | `empty` | Empty state com CTA de conexao |
59
+ | `praxis-crud` com `metadata.resource.path` | `remote` | Sem regressao |
60
+ | `praxis-crud` sem `metadata.resource.path` | `empty` (no CRUD) | Mantem comportamento atual |
61
+
62
+ ## 6. Filtro Dinamico em Modo Local (requisito critico)
63
+ ### 6.1 Renderizacao do filtro no modo local
64
+ - O `praxis-filter` deve renderizar tambem em `local` (nao apenas em `remote`).
65
+ - Em `local`, passar `fieldMetadata` derivado das colunas da tabela.
66
+ - `resourcePath` deve ser passado como string (vazia ou virtual), apenas para contrato do componente; sem uso de backend.
67
+ - Definir `persistenceKey` estavel por tabela para evitar colisao de preferencias entre instancias locais.
68
+
69
+ ### 6.2 Fonte de metadata para o filtro local
70
+ - Base: `config.columns` com `filterable !== false`.
71
+ - Mapeamento minimo recomendado:
72
+ - `string/custom` -> input textual (contains).
73
+ - `number/currency/percentage` -> numero/range.
74
+ - `date` -> date ou dateRange.
75
+ - `boolean` -> toggle/select boolean.
76
+ - Aplicar overrides de metadata ja existentes em `advancedFilters.settings.alwaysVisibleFieldMetadataOverrides`.
77
+ - Se metadata estiver incompleta, cair para comportamento deterministico (input textual).
78
+
79
+ ### 6.3 Contrato de payload local (shape esperado)
80
+ O avaliador local deve suportar os formatos realmente emitidos pelo `praxis-filter`:
81
+ - Primitivos: `string | number | boolean | Date`.
82
+ - Arrays: `any[]` (multiselect, chips, etc).
83
+ - Faixa numerica/tempo: `{ start, end }`.
84
+ - Faixa numerica legado: `{ minPrice, maxPrice }`.
85
+ - Faixa de data: `{ startDate, endDate, preset?, label? }`.
86
+ - Select/lookup assinado por objeto: `OptionDTO` ou objeto equivalente (`id`, `value`, `label`, ...).
87
+
88
+ ### 6.4 Engine de avaliacao local
89
+ Implementar pipeline local explicito: `filtro -> ordenacao -> paginacao`.
90
+
91
+ Pseudo fluxo:
92
+
93
+ ```ts
94
+ function recomputeLocalView(): void {
95
+ const source = localDataSource;
96
+ const filtered = source.filter((row) => matchesAdvancedCriteria(row, filterCriteria));
97
+ const sorted = applyClientSort(filtered, sortState, visibleColumns);
98
+ const total = sorted.length;
99
+ const paged = applyClientPagination(sorted, pageIndex, pageSize);
100
+
101
+ dataSubject.next(paged);
102
+ syncLocalPaginationTotal(total);
103
+ }
104
+ ```
105
+
106
+ Contrato de matching (deterministico):
107
+ - `string` criterio: `contains` case-insensitive e accent-insensitive.
108
+ - `number/boolean/date`: igualdade semantica.
109
+ - `array` criterio: regra `IN` (qualquer valor valido).
110
+ - `{start,end}` ou `{minPrice,maxPrice}`: comparacao de faixa inclusiva.
111
+ - `{startDate,endDate}`: faixa de datas inclusiva (normalizada).
112
+ - `objeto select/lookup`: comparar por `id`; fallback para `value` e depois `label`.
113
+ - `null/undefined/empty`: ignorar criterio (defensivo, mesmo com payload limpo).
114
+
115
+ ### 6.5 UX e performance do filtro local
116
+ - Submit/Clear devem recalcular dataset local sem HTTP.
117
+ - `change` (debounce) pode ficar desabilitado na fase 1 para evitar recomputacao excessiva em datasets grandes.
118
+ - Atualizar contador de filtros ativos e chips com o mesmo contrato de remoto.
119
+ - Em local, esconder mensagens/CTAs de schema remoto no filtro/tabela.
120
+
121
+ ## 7. Matriz de Transicao de Modo (obrigatoria)
122
+ | De | Para | Acoes obrigatorias |
123
+ |---|---|---|
124
+ | `empty` | `remote` | `configure`, `loadSchema/verify`, `fetchData`, limpar erros |
125
+ | `empty` | `local` | hidratar dados locais, reset de pagina/sort/selecao, limpar erros remotos |
126
+ | `remote` | `local` | parar efeitos remotos, limpar `schemaError/dataError`, recomputar pipeline local |
127
+ | `remote` | `empty` | limpar datasource e estados remotos |
128
+ | `local` | `remote` | configurar service, carregar schema (se preciso), buscar remoto |
129
+ | `local` | `empty` | limpar datasource e manter empty state coerente |
130
+
131
+ ## 8. Plano de Implementacao Revisado
132
+ ### Fase 0: Camada central de modo e origem
133
+ 1. Adicionar `@Input() data`.
134
+ 2. Criar helpers centralizados:
135
+ - `getDataMode(): 'remote' | 'local' | 'empty'`
136
+ - `isRemoteMode()`, `isLocalMode()`, `isEmptyMode()`
137
+ - `hasUsableDataSource()`
138
+ 3. Resolver `resourcePath` efetivo por origem (explicito vs persistido).
139
+ 4. Logar modo/origem apenas em debug.
140
+
141
+ ### Fase 1: Ciclo de vida e transicoes
142
+ 1. `ngOnInit`: nao restaurar conexao persistida quando local ja estiver resolvido.
143
+ 2. `ngOnChanges`: tratar `data` e `resourcePath` pela matriz de transicao.
144
+ 3. Entrando em local: limpar erros remotos, resetar pagina/sort/selecao, popular fonte local.
145
+ 4. Entrando em remote: manter fluxo atual `configure -> loadSchema/verify -> fetchData`.
146
+
147
+ ### Fase 2: Template orientado a modo
148
+ 1. Trocar condicionais de `resourcePath` por helpers de modo.
149
+ 2. Exibir tabela em `remote` e `local`.
150
+ 3. Exibir empty state apenas em `empty`.
151
+ 4. Limitar quick-connect, disconnect, retry schema/data ao modo `remote`.
152
+
153
+ ### Fase 3: Filtro dinamico local (core)
154
+ 1. Renderizar `praxis-filter` em `local` com `fieldMetadata` de colunas.
155
+ 2. Implementar `buildLocalFilterMetadata(columns)`.
156
+ 3. Implementar `matchesAdvancedCriteria()` e comparadores por tipo/shape.
157
+ 4. Integrar recalculo local em `onAdvancedFilterSubmit/Clear`.
158
+ 5. Garantir `getPaginationLength()` refletindo total filtrado local.
159
+
160
+ ### Fase 4: Sort/paginacao locais consistentes
161
+ 1. Introduzir estrategia efetiva:
162
+ - em `local`: sempre `client`;
163
+ - em `remote`: respeitar config/default atual.
164
+ 2. `onPageChange/onSortChange`:
165
+ - local: recalcular pipeline local;
166
+ - remote: manter `fetchData()`.
167
+
168
+ ### Fase 5: Acoes backend-dependent
169
+ 1. `onRowAction` autoDelete:
170
+ - local: nao chamar API; emitir evento.
171
+ 2. `onToolbarAction` bulk autoDelete:
172
+ - local: nao chamar API; emitir evento.
173
+ 3. `retryData/reloadSchema/refetch`:
174
+ - no-op seguro fora de `remote`.
175
+
176
+ ### Fase 6: Editores alinhados
177
+ 1. Expor `dataMode` para editor.
178
+ 2. Bloquear/avisar contradicao `local + server` em strategy.
179
+ 3. Melhorar hints do `FilterSettings` quando metadata vier de colunas locais.
180
+ 4. Permitir limpar conexao explicitamente (remote -> local).
181
+
182
+ ### Fase 7: Docs, metadata e release notes
183
+ 1. Atualizar README com precedencia real (`resourcePath > data > persistido`).
184
+ 2. Incluir exemplo oficial de filtro dinamico em modo local.
185
+ 3. Atualizar metadata publica com input `data`.
186
+ 4. Remover drift entre docs, metadata e runtime antes do merge.
187
+
188
+ ## 9. Plano de Testes (minimo obrigatorio)
189
+ ### 9.1 `praxis-table` runtime
190
+ - Renderiza linhas em modo local com `[data]`.
191
+ - Atualiza reativamente ao trocar `data`.
192
+ - Precedencia `resourcePath > data`.
193
+ - Empty state apenas em `empty`.
194
+ - Transicoes: `remote->local`, `local->remote`, `local->empty`, `empty->local`.
195
+
196
+ ### 9.2 Filtro dinamico local
197
+ - Em local, `onAdvancedFilterSubmit` nao chama `crudService.filter()`.
198
+ - Em local, `onAdvancedFilterClear` recomputa dataset sem HTTP.
199
+ - Cobrir shapes de payload:
200
+ - primitivo (`string`, `number`, `boolean`),
201
+ - array,
202
+ - `{start,end}`,
203
+ - `{minPrice,maxPrice}`,
204
+ - `{startDate,endDate}`,
205
+ - objeto lookup (`id/value/label`).
206
+ - Validar compatibilidade com nested fields (`a.b.c`) usando `getNestedPropertyValue`.
207
+
208
+ ### 9.3 Sort/paginacao locais
209
+ - `onSortChange` em local nao chama HTTP e reordena dataset local.
210
+ - `onPageChange` em local nao chama HTTP e pagina localmente.
211
+ - `getPaginationLength()` reflete total filtrado local.
212
+
213
+ ### 9.4 Template/UX
214
+ - Quick connect nao aparece em local.
215
+ - Banner/erro remoto nao aparece em local.
216
+ - `praxis-filter` aparece em local quando advanced filter esta habilitado.
217
+
218
+ ### 9.5 Metadata publica e docs
219
+ - Input `data` presente na metadata.
220
+ - README alinhado ao contrato runtime.
221
+
222
+ ### 9.6 Regressao CRUD
223
+ - Fluxo remoto atual do `praxis-crud` permanece inalterado.
224
+ - Sem regressao em `refetch` apos save/delete.
225
+
226
+ ## 10. Riscos e Mitigacoes
227
+ 1. Risco: filtro local renderizar mas nao filtrar de fato.
228
+ - Mitigacao: engine local obrigatoria + testes de payload real.
229
+
230
+ 2. Risco: conexao persistida sobrescrever local.
231
+ - Mitigacao: precedencia por origem + gate no init.
232
+
233
+ 3. Risco: estrategia visual divergir da execucao.
234
+ - Mitigacao: estrategia efetiva centralizada (local sempre client).
235
+
236
+ 4. Risco: autoDelete chamar API em local.
237
+ - Mitigacao: bloqueio explicito + emissao de eventos.
238
+
239
+ 5. Risco: performance ruim com dataset grande.
240
+ - Mitigacao: debounce, recompute apenas em submit na fase 1, documentar limite recomendado.
241
+
242
+ ## 11. Checklist Final de PR
243
+ - [x] Input `data` implementado e documentado.
244
+ - [x] Resolucao central de modo (`remote|local|empty`) aplicada no runtime.
245
+ - [x] Matriz de transicao implementada sem estado residual.
246
+ - [x] Template orientado a modo (nao a `resourcePath` cru).
247
+ - [x] `praxis-filter` habilitado em local com metadata de colunas.
248
+ - [x] Engine local de `advancedFilters` implementada (shapes reais cobertos).
249
+ - [x] Sort/paginacao locais sem HTTP.
250
+ - [x] `getPaginationLength()` sincronizado com total local filtrado.
251
+ - [x] Bloqueio de autoDelete remoto no local.
252
+ - [x] Editores alinhados ao modo efetivo.
253
+ - [x] Metadata publica atualizada com `data`.
254
+ - [x] README e exemplos alinhados ao runtime.
255
+ - [x] Testes de regressao local/remote/empty + CRUD aprovados.
256
+
257
+ Status de execucao da lane (2026-02-23):
258
+ - Suite isolada da pre-implementacao executada com `ChromeHeadless` via `cmd.exe`.
259
+ - Resultado final: `TOTAL: 48 SUCCESS`.
260
+ - Coberturas criticas executadas: preservacao de `pageSize` local e estabilidade de `fieldMetadata`.
261
+ - Coberturas de transicao executadas: `remote->local`, `local->remote`, `local->empty`, `empty->local`.
262
+ - Revalidacao complementar de regressao em `praxis-crud` (`praxis-crud.component.spec.ts`) executada com `ChromeHeadless` + `zone.js`/`zone.js/testing`.
263
+ - Resultado final da suite alvo de CRUD: `TOTAL: 6 SUCCESS`.
264
+ - Coberturas de regressao confirmadas em CRUD: encaminhamento de `resourcePath` para `praxis-table` e refresh (`refetch`) apos `save/delete`.
265
+ - Evolucao da etapa seguinte (CRUD local sem `metadata.resource.path`) implementada e validada na suite alvo de CRUD.
266
+ - Resultado atualizado da suite alvo de CRUD: `TOTAL: 9 SUCCESS`.
267
+ - Coberturas adicionais confirmadas: renderizacao da tabela em modo local com `metadata.data`, empty state quando nao ha `resourcePath` nem dados locais e precedencia `resourcePath + data` mantendo fluxo remoto.
268
+
269
+ Status de validacao operacional (2026-02-24):
270
+ - Gate seguro revalidado com ChromeHeadless (Windows): `praxis-table` lane isolada + `praxis-crud` suite completa.
271
+ - Resultado da lane isolada `praxis-table`: `TOTAL: 48 SUCCESS`.
272
+ - Resultado da suite completa `praxis-crud`: `TOTAL: 30 SUCCESS`.
273
+ - Criterio atual de continuidade: manter este gate seguro verde em toda etapa incremental.
274
+ - Observacao: `ng test praxis-table` completo permanece fora do gate por drift de compilacao cross-lib no workspace, sem relacao direta com a implementacao local/remote da tabela.
275
+
276
+ ## 12. Fora de Escopo (fase 1)
277
+ - Virtualizacao local com garantia de consistencia.
278
+ - Otimizacoes avancadas para datasets muito grandes (chunking/worker).
279
+
280
+ ## 13. Pacote Pre-Implementacao (PR-0 a PR-6)
281
+ Objetivo: preparar base tecnica e cobertura de regressao para implementar modo local sem quebrar o uso normal remoto.
282
+
283
+ ### 13.1 PR-0 - Characterization Tests Remoto (gate inicial)
284
+ Escopo:
285
+ 1. Congelar comportamento remoto atual em testes.
286
+
287
+ Entregaveis:
288
+ 1. Casos cobrindo:
289
+ - bootstrap remoto (`resourcePath` -> `configure/loadSchema/fetchData`);
290
+ - `onSortChange` e `onPageChange` com HTTP em remoto;
291
+ - `onAdvancedFilterSubmit/Clear` com HTTP em remoto;
292
+ - `retryData/reloadSchema/refetch` em remoto;
293
+ - `praxis-crud` chamando `table.refetch()` apos save/delete.
294
+ 2. Documento curto de baseline com o que esta protegido por teste.
295
+
296
+ Criterios de aceite:
297
+ 1. Todos os testes novos verdes.
298
+ 2. Nenhum comportamento remoto critico sem cobertura.
299
+
300
+ ### 13.2 PR-1 - Contrato de Modo e Precedencia (sem alterar comportamento)
301
+ Escopo:
302
+ 1. Introduzir tipos e helpers de modo sem mudar output funcional.
303
+
304
+ Entregaveis:
305
+ 1. `type DataMode = 'remote' | 'local' | 'empty'`.
306
+ 2. Helpers centrais:
307
+ - `getDataMode()`;
308
+ - `hasExplicitResourcePath()`;
309
+ - `hasLocalDataInput()`.
310
+ 3. Documento de precedencia oficial:
311
+ - `resourcePath explicito > data > conexao persistida`.
312
+
313
+ Criterios de aceite:
314
+ 1. Snapshot de comportamento remoto permanece identico.
315
+ 2. Logs de debug de modo/origem disponiveis para diagnostico.
316
+
317
+ ### 13.3 PR-2 - Documento Canonico de `resourcePath` no Editor
318
+ Escopo:
319
+ 1. Remover ambiguidade de "string vazia" em apply/save do editor.
320
+
321
+ Entregaveis:
322
+ 1. Envelope canonico de autoria com:
323
+ - `bindings.resourcePath`.
324
+ 2. Handshake editor -> tabela sem side-channel implicito.
325
+ 3. Testes para:
326
+ - set remoto;
327
+ - clear remoto;
328
+ - round-trip do documento.
329
+
330
+ Criterios de aceite:
331
+ 1. Nao existe desconexao remota acidental em save.
332
+ 2. Limpar conexao e um ato explicito e rastreavel.
333
+
334
+ ### 13.4 PR-3 - Feature Flag de Rollout
335
+ Escopo:
336
+ 1. Isolar novas capacidades locais atras de flag.
337
+
338
+ Entregaveis:
339
+ 1. Flag ex.: `behavior.localDataMode.enabled`.
340
+ 2. Flag default `false`.
341
+ 3. Telemetria/log de flag ativa por instancia.
342
+
343
+ Criterios de aceite:
344
+ 1. Com flag `false`, fluxo remoto e identico ao baseline.
345
+ 2. Com flag `true`, habilita trilha de evolucao local sem impactar remoto por padrao.
346
+
347
+ ### 13.5 PR-4 - Scaffolding de Integracao Local (sem ligar feature final)
348
+ Escopo:
349
+ 1. Preparar pontos de extensao sem ativar pipeline local completo.
350
+
351
+ Entregaveis:
352
+ 1. Estrutura de dados local separada (`localSource`, `localView`, `localTotal`).
353
+ 2. Stub de `recomputeLocalView()` sem alterar caminho remoto.
354
+ 3. Ajustes de template por helper de modo, mantendo remoto equivalente.
355
+
356
+ Criterios de aceite:
357
+ 1. Delta funcional remoto zero.
358
+ 2. Codigo pronto para conectar engine local no PR seguinte.
359
+
360
+ ### 13.6 PR-5 - Engine Local em Modulo Puro (isolado)
361
+ Escopo:
362
+ 1. Construir avaliador local fora de `praxis-table` para facilitar teste.
363
+
364
+ Entregaveis:
365
+ 1. Modulo puro:
366
+ - `matchesAdvancedCriteria(row, criteria)`;
367
+ - comparadores por shape (`primitive`, `array`, `range`, `dateRange`, `lookupObject`).
368
+ 2. Suite de testes unitarios da engine.
369
+
370
+ Criterios de aceite:
371
+ 1. Cobertura de todos os shapes previstos no contrato.
372
+ 2. Sem acoplamento com `GenericCrudService` ou Angular component lifecycle.
373
+
374
+ ### 13.7 PR-6 - Guard Rails de Regressao Remota
375
+ Escopo:
376
+ 1. Adicionar protecoes para evitar regressao ao ligar modo local.
377
+
378
+ Entregaveis:
379
+ 1. Assertivas:
380
+ - em remoto, nao enviar `fieldMetadata` para `praxis-filter` por engano;
381
+ - em remoto, `onSortChange/onPageChange` continuam com fetch quando estrategia efetiva for server.
382
+ 2. Testes negativos de regressao:
383
+ - remoto nao usa pipeline local;
384
+ - remoto continua com schema/fetch/filter HTTP.
385
+ 3. Checklist de release go/no-go.
386
+
387
+ Criterios de aceite:
388
+ 1. Suite de regressao remota aprovada.
389
+ 2. Bloqueios automatizados impedem merge de regressao conhecida.
390
+
391
+ ### 13.8 Ordem de Execucao Recomendada
392
+ 1. PR-0.
393
+ 2. PR-1.
394
+ 3. PR-2.
395
+ 4. PR-3.
396
+ 5. PR-4.
397
+ 6. PR-5.
398
+ 7. PR-6.
399
+
400
+ ### 13.9 Go/No-Go para iniciar implementacao principal (Fases 0-7)
401
+ Todos os itens abaixo devem estar `true`:
402
+ 1. Baseline remoto protegido por testes (`PR-0`).
403
+ 2. Precedencia e modo formalizados (`PR-1`).
404
+ 3. Protocolo de `resourcePath` sem ambiguidade (`PR-2`).
405
+ 4. Rollout com feature flag pronto (`PR-3`).
406
+ 5. Scaffolding e engine local testavel disponiveis (`PR-4` e `PR-5`).
407
+ 6. Guard rails e testes negativos de remoto ativos (`PR-6`).
408
+
409
+ ### 13.10 Status de Execucao Atual (2026-02-24)
410
+ 1. Pacote pre-implementacao (PR-0 a PR-6) consolidado em codigo e testes da lane isolada.
411
+ 2. Bloqueio operacional de browser headless no ambiente Linux/sandbox foi contornado com execucao via Chrome do Windows.
412
+ 3. Trilha segura operacionalizada para regressao continua permanece verde:
413
+ - `praxis-table` lane isolada: `48 SUCCESS`;
414
+ - `praxis-crud` suite completa: `30 SUCCESS`.
415
+ 4. Revalidacao da suite completa `praxis-table` foi concluida no mesmo ambiente operacional:
416
+ - comando: `ng test praxis-table --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing`;
417
+ - resultado: `TOTAL: 372 SUCCESS`.
418
+ 5. Classificacao atual:
419
+ - gate local-data (lane isolada + CRUD full): verde;
420
+ - suite completa `praxis-table`: verde e apta para regressao continua.
421
+
422
+ ### 13.11 Proxima Frente Recomendada (hardening pos-estabilizacao)
423
+ 1. Concluido: remocao de `// @ts-nocheck` em `projects/praxis-table/src/test-dev/integration-tests/**`, com tipagem restaurada por arquivo.
424
+ 2. Concluido: setup compartilhado de `TestBed` consolidado em `projects/praxis-table/src/test-dev/integration-tests/testbed.providers.ts`, incluindo providers de `HttpClient`, `API_URL`, pipes e stub de `GlobalConfigService`.
425
+ 3. Concluido: specs migradas para o setup compartilhado:
426
+ - `advanced-filter-toggle.spec.ts`;
427
+ - `praxis-table-v2-integration.spec.ts`;
428
+ - `row-action-contract.spec.ts`;
429
+ - `end-to-end-workflow.spec.ts`;
430
+ - `auto-delete.spec.ts`;
431
+ - `row-actions-overflow.spec.ts`.
432
+ 4. Concluido: reexecucao incremental e full executadas apos a consolidacao, mantendo a suite verde.
433
+
434
+ ### 13.12 Status de Estabilizacao Full Suite (2026-02-24)
435
+ 1. Compilacao TypeScript da suite completa (`tsc -p projects/praxis-table/tsconfig.spec.json --noEmit`) voltou a verde.
436
+ 2. Imports quebrados em `projects/praxis-table/src/test-dev/integration-tests/**` foram normalizados para `../../lib/**`.
437
+ 3. Falhas de runtime de `TestBed` por providers ausentes (ex.: `NG0201: No provider found for _HttpClient`) foram eliminadas no fluxo de validacao atual.
438
+ 4. Expectativas defasadas em specs alvo foram alinhadas ao contrato vigente da `praxis-table`.
439
+ 5. Execucao full validada:
440
+ - `ng test praxis-table --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing`;
441
+ - `TOTAL: 372 SUCCESS`.
442
+ 6. Revalidacao dirigida das specs hardenizadas (sem `@ts-nocheck`) concluida:
443
+ - `migration-system.spec.ts` + `end-to-end-workflow.spec.ts` + `config-editors-integration.spec.ts`;
444
+ - `TOTAL: 62 SUCCESS`.
445
+ 7. Revalidacao full apos hardening dos integration tests:
446
+ - `ng test praxis-table --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing`;
447
+ - `TOTAL: 372 SUCCESS`.
448
+ 8. Consolidacao de setup compartilhado de providers concluida:
449
+ - helper criado em `projects/praxis-table/src/test-dev/integration-tests/testbed.providers.ts`;
450
+ - specs migradas: `advanced-filter-toggle.spec.ts`, `praxis-table-v2-integration.spec.ts`, `row-action-contract.spec.ts`, `end-to-end-workflow.spec.ts`.
451
+ 9. Revalidacao dirigida pos-consolidacao dos providers:
452
+ - `ng test praxis-table --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing --include projects/praxis-table/src/test-dev/integration-tests/advanced-filter-toggle.spec.ts --include projects/praxis-table/src/test-dev/integration-tests/praxis-table-v2-integration.spec.ts --include projects/praxis-table/src/test-dev/integration-tests/row-action-contract.spec.ts --include projects/praxis-table/src/test-dev/integration-tests/end-to-end-workflow.spec.ts`;
453
+ - `TOTAL: 24 SUCCESS`.
454
+ 10. Revalidacao full pos-consolidacao dos providers:
455
+ - `ng test praxis-table --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing`;
456
+ - `TOTAL: 372 SUCCESS`.
457
+ 11. Expansao da consolidacao de providers para os specs adicionais:
458
+ - `auto-delete.spec.ts`;
459
+ - `row-actions-overflow.spec.ts`.
460
+ 12. Revalidacao dirigida apos a expansao:
461
+ - `ng test praxis-table --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing --include projects/praxis-table/src/test-dev/integration-tests/advanced-filter-toggle.spec.ts --include projects/praxis-table/src/test-dev/integration-tests/praxis-table-v2-integration.spec.ts --include projects/praxis-table/src/test-dev/integration-tests/row-action-contract.spec.ts --include projects/praxis-table/src/test-dev/integration-tests/end-to-end-workflow.spec.ts --include projects/praxis-table/src/test-dev/integration-tests/auto-delete.spec.ts --include projects/praxis-table/src/test-dev/integration-tests/row-actions-overflow.spec.ts`;
462
+ - `TOTAL: 31 SUCCESS`.
463
+ 13. Revalidacao full apos a expansao:
464
+ - `ng test praxis-table --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing`;
465
+ - `TOTAL: 372 SUCCESS`.
466
+ 14. Revalidacao complementar do wrapper CRUD apos o hardening:
467
+ - `ng test praxis-crud --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing`;
468
+ - `TOTAL: 30 SUCCESS`.
469
+ 15. Validacao da lane dedicada no WSL:
470
+ - `bash ./scripts/test-table-preimpl-lane.sh`: bloqueada por infraestrutura (`No usable Chromium binary found for headless capture`).
471
+ - fallback operacional via Windows Chrome com os mesmos includes da lane:
472
+ `ng test praxis-table --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing --include ...`;
473
+ - resultado do fallback: `TOTAL: 48 SUCCESS`.
474
+ 16. Mitigacao operacional no WSL validada sem alterar o script da lane:
475
+ - wrapper: `tools/karma/chromium-bin-wrapper.sh` (contorna apenas probe `--dump-dom`);
476
+ - execucao:
477
+ `CHROMIUM_REAL_BIN=<puppeteer-executablePath> CHROMIUM_BIN=tools/karma/chromium-bin-wrapper.sh CHROME_BIN=tools/karma/chromium-bin-wrapper.sh bash ./scripts/test-table-preimpl-lane.sh`;
478
+ - resultado: `TOTAL: 48 SUCCESS`.
479
+ 17. Revalidacao integrada do gate seguro apos mitigacao WSL:
480
+ - `CHROMIUM_REAL_BIN=<puppeteer-executablePath> CHROMIUM_BIN=tools/karma/chromium-bin-wrapper.sh CHROME_BIN=tools/karma/chromium-bin-wrapper.sh bash tools/karma/run-safe-gate.sh`;
481
+ - `praxis-table lane`: `PASS` (`TOTAL: 48 SUCCESS`);
482
+ - `praxis-crud full`: `PASS` (`TOTAL: 30 SUCCESS`).
483
+ 18. Automacao do gate seguro no WSL concluida:
484
+ - `tools/karma/run-safe-gate.sh` agora auto-configura `chromium-bin-wrapper.sh` + Puppeteer Chromium quando `CHROMIUM_BIN/CHROME_BIN` nao sao informados;
485
+ - revalidacao sem env manual:
486
+ `env -u CHROMIUM_BIN -u CHROME_BIN -u CHROMIUM_REAL_BIN bash tools/karma/run-safe-gate.sh`;
487
+ - resultado: `praxis-table lane PASS (48 SUCCESS)` e `praxis-crud full PASS (30 SUCCESS)`.
488
+ 19. Cobertura adicional no wrapper `praxis-crud` para precedencia remoto > local concluida:
489
+ - novo teste para `metadata.table.resourcePath` prevalecer sobre `metadata.data`;
490
+ - novo teste para `metadata.table.resourcePath` em branco (apenas espacos) manter modo local com `metadata.data`;
491
+ - arquivo: `projects/praxis-crud/src/lib/praxis-crud.component.spec.ts`;
492
+ - validacao dirigida executada com tsconfig temporario isolado (evitando erro externo de compilacao em `praxis-dynamic-fields`):
493
+ `ng test praxis-crud --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing --ts-config .tmp-preimpl-lane/tsconfig.crud-isolated.json --include projects/praxis-crud/src/lib/praxis-crud.component.spec.ts`;
494
+ - resultado: `TOTAL: 11 SUCCESS`.
495
+ 20. Revalidacao do `safe-gate` apos ampliar cobertura do CRUD:
496
+ - comando: `bash tools/karma/run-safe-gate.sh`;
497
+ - tentativa WSL da lane `praxis-table` permaneceu bloqueada por deteccao de Chromium (`No usable Chromium binary found for headless capture`);
498
+ - fallback automatico via `cmd.exe + ChromeHeadless` executou com sucesso;
499
+ - resultado final:
500
+ - `praxis-table lane`: `PASS` (`TOTAL: 48 SUCCESS`);
501
+ - `praxis-crud full`: `PASS` (`TOTAL: 32 SUCCESS`).
502
+ 21. Revalidacao full da `praxis-table` apos a ampliacao de cobertura no CRUD:
503
+ - comando: `ng test praxis-table --watch=false --browsers=ChromeHeadless --polyfills=zone.js --polyfills=zone.js/testing`;
504
+ - resultado: `TOTAL: 372 SUCCESS`.
505
+ 22. Hardening da lane WSL no script dedicado concluido:
506
+ - `scripts/test-table-preimpl-lane.sh` agora aplica automaticamente `tools/karma/chromium-bin-wrapper.sh` quando o probe direto de Chromium falha no WSL;
507
+ - revalidacao direta da lane, sem env manual:
508
+ `bash ./scripts/test-table-preimpl-lane.sh`;
509
+ - resultado: `TOTAL: 48 SUCCESS`.
510
+ - revalidacao adicional com ambiente limpo de browser vars:
511
+ `env -u CHROMIUM_BIN -u CHROME_BIN -u CHROMIUM_REAL_BIN bash ./scripts/test-table-preimpl-lane.sh`;
512
+ - resultado: `TOTAL: 48 SUCCESS`.
513
+ 23. Revalidacao do gate seguro apos hardening da lane WSL:
514
+ - comando: `bash tools/karma/run-safe-gate.sh`;
515
+ - resultado final: `praxis-table lane PASS (48 SUCCESS)` e `praxis-crud full PASS (32 SUCCESS)`;
516
+ - nesta execucao, a lane WSL concluiu na trilha primaria (sem fallback para `cmd.exe`).
517
+ 24. Revalidacao completa do gate seguro em modo estrito + full suite:
518
+ - comando:
519
+ `SAFE_GATE_STRICT_WSL_PRIMARY=true SAFE_GATE_INCLUDE_TABLE_FULL=true bash tools/karma/run-safe-gate.sh`;
520
+ - resultado final:
521
+ - `praxis-table lane`: `PASS` (`TOTAL: 48 SUCCESS`);
522
+ - `praxis-table lane path`: `wsl-primary`;
523
+ - `praxis-crud full`: `PASS` (`TOTAL: 32 SUCCESS`);
524
+ - `praxis-table full`: `PASS` (`TOTAL: 372 SUCCESS`).