@praxisui/dynamic-form 8.0.0-beta.2 → 8.0.0-beta.21

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.
@@ -0,0 +1,379 @@
1
+ ---
2
+ title: "Dynamic Form Rules Authoring Plan"
3
+ slug: "dynamic-form-rules-authoring-plan"
4
+ description: "Plano canonico para evoluir a autoria de regras do Dynamic Form com builder visual, LLM, preview, validacao e visual blocks."
5
+ doc_type: "guide"
6
+ document_kind: "host-guide"
7
+ category: "architecture"
8
+ audience:
9
+ - "frontend"
10
+ - "host"
11
+ - "platform-team"
12
+ - "architect"
13
+ level: "advanced"
14
+ status: "active"
15
+ owner: "praxis-ui"
16
+ tags:
17
+ - "dynamic-form"
18
+ - "rules"
19
+ - "visual-builder"
20
+ - "llm"
21
+ - "visual-blocks"
22
+ toc: true
23
+ sidebar: true
24
+ reading_time: "16 min"
25
+ estimated_setup_time: "multi-phase"
26
+ last_updated: "2026-04-22"
27
+ source_of_truth:
28
+ - "projects/praxis-dynamic-form/src/lib/config-editor/praxis-dynamic-form-config-editor.ts"
29
+ - "projects/praxis-dynamic-form/src/lib/config-editor/praxis-dynamic-form-config-editor.html"
30
+ - "projects/praxis-dynamic-form/src/lib/utils/rule-converters.ts"
31
+ - "projects/praxis-dynamic-form/src/lib/utils/rule-property.utils.ts"
32
+ - "projects/praxis-dynamic-form/src/lib/services/form-rules.service.ts"
33
+ - "projects/praxis-core/src/lib/models/form/rule-property.schema.ts"
34
+ - "projects/praxis-dynamic-form/src/lib/ai/praxis-dynamic-form-authoring-manifest.ts"
35
+ - "projects/praxis-dynamic-form/docs/dynamic-form-llm-rule-authoring-guide.md"
36
+ ---
37
+
38
+ # Dynamic Form Rules Authoring Plan
39
+
40
+ Este plano define como a autoria de regras do Dynamic Form deve evoluir para suportar a complexidade real da funcionalidade: regras visuais, regras criadas por LLM, round-trip no builder, preview, alvos estruturais e blocos visuais.
41
+
42
+ ## Escopo deste documento
43
+
44
+ Este documento governa a evolucao da experiencia de autoria de regras no editor do `praxis-dynamic-form`. Ele nao substitui a referencia JSON API nem o contrato de visual blocks; ele amarra esses contratos em uma estrategia implementavel para UX, validacao, LLM e testes.
45
+
46
+ ## Pre-requisitos
47
+
48
+ - Conhecer `FormConfig`, `formRules` e `formRulesState`.
49
+ - Conhecer Json Logic canonico usado pelo runtime Praxis.
50
+ - Conhecer `FormColumn.items[]` para campos e blocos `richContent`.
51
+ - Consultar `RULE_PROPERTY_SCHEMA` antes de adicionar qualquer propriedade nova por regra.
52
+
53
+ ## Estado atual
54
+
55
+ O editor de configuracao do Dynamic Form usa um `mat-tab-group`. A aba `Regras` renderiza `praxis-visual-builder`:
56
+
57
+ ```html
58
+ <praxis-visual-builder
59
+ [config]="ruleBuilderConfig"
60
+ [initialRules]="ruleBuilderState"
61
+ (rulesChanged)="onRulesChanged($event)">
62
+ </praxis-visual-builder>
63
+ ```
64
+
65
+ Quando o builder muda, o editor persiste dois artefatos:
66
+
67
+ | Artefato | Papel | Quem deve escrever |
68
+ | --- | --- | --- |
69
+ | `formRules` | Contrato executavel pelo runtime. | Builder visual, LLM validada ou JSON editor. |
70
+ | `formRulesState` | Estado visual para reabrir o builder sem perda. | Apenas o builder/conversores internos. |
71
+
72
+ O runtime consome `formRules` via `FormRulesService`. `formRulesState` nao deve participar da execucao.
73
+
74
+ ## Partes da funcionalidade
75
+
76
+ A funcionalidade completa tem oito partes, que hoje estao espalhadas:
77
+
78
+ | Parte | Estado atual | Lacuna principal |
79
+ | --- | --- | --- |
80
+ | Descoberta de alvos | `createRuleBuilderConfig` mapeia campos, secoes, linhas, colunas, actions e visual blocks. | Falta mapa de impacto legivel para o usuario. |
81
+ | Condicao | Builder converte condicoes simples para Json Logic. | Condicoes complexas podem virar runtime-only. |
82
+ | Efeito | `RULE_PROPERTY_SCHEMA` define propriedades permitidas por alvo. | UI mostra propriedades por alvo, rejeicoes do sanitizer e oferece correcao assistida. |
83
+ | Conversao | `rule-converters.ts` faz round-trip `formRules` <-> `RuleBuilderState` e preserva metadados semanticos como `type: "visualBlockGuidance"` via `config.ruleType`. | Nao ha status explicito de compatibilidade visual. |
84
+ | Execucao | `FormRulesService` resolve valores calculados de campos em fase anterior, aplica propriedades saneadas e o editor oferece preview true/false para revisar o efeito antes de persistir. | Falta ampliar mensagens de diagnóstico para casos de sanitizer parcial. |
85
+ | LLM | Manifesto publica operacoes locais de component/form authoring e preserva `rule.visualBlockGuidance.add` apenas como projecao visual opcional. | Business-rule authoring deve entrar por `domain-rules`/`shared_rule_authoring` antes de virar `form_config`. |
86
+ | Visual blocks | Alvo `visualBlock` existe, entra em `targetSchemas.visualBlocks`, aceita `text`, `title` e `message` saneados e o painel de propriedades guia `textNodeId`, `titleNodeId` e `messageNodeId`. | Falta apenas ampliar biblioteca de exemplos visuais por domínio, sem mudar o contrato. |
87
+ | Governanca | Propriedades nao whitelisted sao descartadas, aparecem para o autor e podem ser corrigidas pelo painel de diagnosticos. | Expandir telemetria/curadoria conforme o catalogo publico amadurecer. |
88
+
89
+ ## Modelo mental alvo
90
+
91
+ A aba `Regras` deve virar uma experiencia guiada com cinco etapas internas:
92
+
93
+ ```mermaid
94
+ flowchart LR
95
+ target["1. Alvo"] --> condition["2. Condicao"]
96
+ condition --> effect["3. Efeito"]
97
+ effect --> preview["4. Preview"]
98
+ preview --> review["5. Revisao"]
99
+ review --> apply["Aplicar em formRules"]
100
+ ```
101
+
102
+ Isso nao exige trocar o editor inteiro para stepper. O editor geral pode continuar em abas. O fluxo guiado deve existir dentro da aba `Regras`.
103
+
104
+ ## Contrato de compatibilidade
105
+
106
+ Toda regra deve receber um status calculado:
107
+
108
+ | Status | Significado |
109
+ | --- | --- |
110
+ | `valid` | Executavel no runtime. |
111
+ | `invalid-target` | Um ou mais targets nao existem. |
112
+ | `invalid-condition` | Condicao nao e Json Logic valida. |
113
+ | `invalid-value-expression` | Valor calculado de campo usa Json Logic invalido ou envelope ambiguo. |
114
+ | `computed-value-iteration-limit` | Valores calculados encadeados nao estabilizaram dentro do limite do runtime. |
115
+ | `unsupported-property` | Efeito contem propriedade fora do whitelist. |
116
+ | `runtime-only` | Regra executa, mas nao reabre fielmente no builder visual. |
117
+ | `visual-builder-compatible` | Regra executa e reabre no builder visual. |
118
+ | `llm-generated-pending-review` | Sugestao da LLM ainda nao aprovada pelo usuario. |
119
+
120
+ O status deve ser exibido na lista de regras, no painel de revisao e no resumo de alteracoes.
121
+
122
+ ## Regras criadas por LLM
123
+
124
+ LLM pode sugerir materializacoes visuais derivadas, mas deve seguir estas politicas:
125
+
126
+ - LLM nao usa `formRules` ou `visualBlockGuidance` como fonte canonica da regra de negocio.
127
+ - Quando a decisao governada precisa aparecer na UI, a materializacao escreve apenas `formRules`.
128
+ - LLM nunca escreve `formRulesState`.
129
+ - Operacoes de IA `rule.visibility.add`, `rule.validation.add` e
130
+ `rule.visualBlockGuidance.add` exigem
131
+ `metadata.origin: "llm"` e `metadata.reviewStatus: "pending"` no manifesto.
132
+ - Para regra de negocio, politica, elegibilidade, validacao, compliance ou
133
+ decisao compartilhada, preferir `domain-rules`/`shared_rule_authoring`.
134
+ - Para materializacao visual derivada de uma decisao ja governada, aceitar
135
+ `rule.visualBlockGuidance.add` com `type: "visualBlockGuidance"`,
136
+ `targetType: "visualBlock"` e `context: "notification"`.
137
+ - Toda condicao deve ser Json Logic canonico.
138
+ - Valores calculados em `effect.properties.value` e
139
+ `effect.propertiesWhenFalse.value` devem usar envelope fechado e exclusivo:
140
+ exatamente `{ "expression": <JsonLogic> }` ou exatamente
141
+ `{ "literal": <valor> }`. Objetos literais estruturados precisam do envelope
142
+ `literal`; envelopes com chaves extras sao rejeitados.
143
+ - Valores calculados sao resolvidos antes das demais propriedades por iteracao
144
+ limitada ate estabilizacao, entao regras dependentes nao devem depender da
145
+ ordem no array de `formRules`.
146
+ - Toda propriedade deve existir em `RULE_PROPERTY_SCHEMA[targetType]`.
147
+ - Todo target deve existir no `ruleBuilderConfig.targetSchemas`.
148
+ - Remocao de regra exige confirmacao humana.
149
+ - Regra criada por LLM entra como `llm-generated-pending-review`.
150
+ - Ao aceitar, o editor tenta gerar `formRulesState` por `formLayoutRulesToBuilderState`.
151
+ - O round-trip deve preservar metadados semanticos. Quando o builder precisar
152
+ usar `config.type` para o tipo visual do node, o discriminador da regra deve
153
+ viajar como `config.ruleType` e voltar para `formRules[].type`.
154
+ - Se o round-trip perder semantica, a regra fica `runtime-only` e precisa aviso claro.
155
+
156
+ O guia operacional para prompts, contexto minimo, exemplos LGPD e correcao de
157
+ diagnostics fica em `./dynamic-form-llm-rule-authoring-guide.md`.
158
+
159
+ ## Visual blocks em regras
160
+
161
+ O alvo `visualBlock` ja existe no schema de propriedades. No estado atual, o whitelist permite:
162
+
163
+ | Propriedade | Uso |
164
+ | --- | --- |
165
+ | `visible` | Exibir quando a condicao e verdadeira. |
166
+ | `hidden` | Ocultar quando a condicao e verdadeira. |
167
+ | `text` | Sobrescrever texto apenas em documento simples ou node `text` identificado. |
168
+ | `textNodeId` | Escolher explicitamente o node que recebera `text`. |
169
+ | `title` | Sobrescrever titulo apenas em documento simples ou node `title` identificado. |
170
+ | `titleNodeId` | Escolher explicitamente o node que recebera `title`. |
171
+ | `message` | Sobrescrever mensagem apenas em documento simples ou node `message` identificado. |
172
+ | `messageNodeId` | Escolher explicitamente o node que recebera `message`. |
173
+ | `layout` | Alternar entre `block` e `inline`. |
174
+ | `rootClassName` | Classe no wrapper raiz. |
175
+ | `className` | Classe CSS do bloco. |
176
+ | `style` | Estilo inline saneado. |
177
+
178
+ O contrato seguro para `title`, `message` e `text` e:
179
+
180
+ - aplicar apenas em documentos simples ou nodes identificados;
181
+ - presets criados pelo layout usam ids convencionais: `text`, `title` e `message`;
182
+ - nodes identificados podem estar no primeiro nivel ou aninhados em `compose`/`card`;
183
+ - o painel de propriedades permite escolher um node identificado e persiste `textNodeId`, `titleNodeId` ou `messageNodeId`;
184
+ - rejeitar HTML arbitrario, handlers, URLs inseguras e documentos inteiros;
185
+ - preservar `RichContentDocument` original como fonte de verdade;
186
+ - aplicar override em runtime sem transformar bloco visual em campo;
187
+ - cobrir com testes unitarios de sanitizer, runtime e E2E visual.
188
+
189
+ ## Mapa de impacto
190
+
191
+ Cada regra deve exibir:
192
+
193
+ - alvos afetados;
194
+ - campos usados na condicao;
195
+ - propriedades alteradas em true/false;
196
+ - se afeta submit;
197
+ - se e visual-only;
198
+ - se depende de bloco visual, secao, linha ou coluna;
199
+ - se ha alvo inexistente;
200
+ - se alguma propriedade foi descartada pelo sanitizer.
201
+
202
+ Impacto esperado por alvo:
203
+
204
+ | Target type | Impacto no submit | Observacao |
205
+ | --- | --- | --- |
206
+ | `field` | Pode afetar payload indiretamente por `required`, `disabled`, `readonly` e `defaultValue`. | Exige cuidado maior. |
207
+ | `section` | Normalmente visual, mas pode ocultar varios campos. | Precisa listar campos descendentes. |
208
+ | `row` | Visual/layout. | Pode esconder grupo de campos. |
209
+ | `column` | Visual/layout. | Pode alterar alinhamento responsivo. |
210
+ | `action` | Pode bloquear fluxo operacional. | `disabled`, `loading` e `visible` devem ser revisados. |
211
+ | `visualBlock` | Visual-only. | Nunca entra em `fieldMetadata`, `FormControl` ou payload. |
212
+
213
+ ## Preview requerido
214
+
215
+ O editor deve ter preview true/false por regra:
216
+
217
+ 1. O usuario escolhe uma regra.
218
+ 2. O painel mostra os campos usados na condicao.
219
+ 3. O usuario edita valores de exemplo.
220
+ 4. O editor avalia Json Logic.
221
+ 5. O preview aplica `properties` ou `propertiesWhenFalse`.
222
+ 6. O diff mostra o que muda no formulario.
223
+
224
+ Esse preview deve funcionar sem backend. Para campos remotos/selects, usar valores de exemplo do metadata ou entrada manual.
225
+
226
+ ## Design e UX alvo
227
+
228
+ A aba `Regras` deve ter tres areas:
229
+
230
+ | Area | Conteudo |
231
+ | --- | --- |
232
+ | Lista | Regras, status, origem, alvo e busca/filtro. |
233
+ | Builder | Fluxo Alvo -> Condicao -> Efeito. |
234
+ | Preview | Estado true/false, impacto, JSON e diff. |
235
+
236
+ Filtros minimos:
237
+
238
+ - por alvo;
239
+ - por origem: manual, JSON, LLM;
240
+ - por status;
241
+ - por propriedade alterada.
242
+
243
+ Microcopy obrigatoria:
244
+
245
+ - explicar que `formRules` executa no runtime;
246
+ - explicar que `formRulesState` e somente para o builder visual;
247
+ - marcar `runtime-only` sem tom de erro fatal;
248
+ - marcar LLM como sugestao pendente de revisao.
249
+
250
+ ## Roadmap incremental
251
+
252
+ ### Fase 1 - Validador central
253
+
254
+ Status: implementado.
255
+
256
+ Criar um validador puro, sem UI, que recebe `FormConfig` e retorna status por regra.
257
+
258
+ Entradas:
259
+
260
+ - `formRules`;
261
+ - `formRulesState`;
262
+ - `fieldMetadata`;
263
+ - `sections`;
264
+ - `actions`;
265
+ - `RULE_PROPERTY_SCHEMA`.
266
+
267
+ Saida:
268
+
269
+ ```ts
270
+ interface FormRuleDiagnostics {
271
+ ruleId: string;
272
+ status: RuleAuthoringStatus[];
273
+ targetRefs: Array<{ type: string; id: string; exists: boolean }>;
274
+ conditionRefs: string[];
275
+ acceptedProperties: string[];
276
+ rejectedProperties: string[];
277
+ runtimeOnlyReason?: string;
278
+ }
279
+ ```
280
+
281
+ ### Fase 2 - Status na UI
282
+
283
+ Status: implementado com diagnostics acionaveis e correcao assistida.
284
+
285
+ Exibir diagnostics na aba `Regras`:
286
+
287
+ - badge por regra;
288
+ - resumo de problemas;
289
+ - link para abrir o alvo no layout;
290
+ - aviso quando o sanitizer descarta propriedade.
291
+ - acao `Corrigir` para aplicar whitelist/saneamento central e regenerar `formRulesState`.
292
+
293
+ ### Fase 3 - Preview true/false
294
+
295
+ Status: implementado como preview/diff de propriedades de regra; ainda cabe evolucao visual do formulario completo.
296
+
297
+ Adicionar painel de preview isolado:
298
+
299
+ - avaliar Json Logic com valores mockados;
300
+ - mostrar `properties` versus `propertiesWhenFalse`;
301
+ - aplicar preview visual sem persistir;
302
+ - exibir diff JSON.
303
+
304
+ ### Fase 4 - LLM review lane
305
+
306
+ Status: implementado para regras ja sugeridas/persistidas como pendentes; geracao de sugestao por LLM ainda e proxima evolucao.
307
+
308
+ Criar fluxo de aceite para sugestoes de LLM:
309
+
310
+ - `Generate suggestion`;
311
+ - validar;
312
+ - mostrar diff;
313
+ - permitir editar antes de aplicar;
314
+ - marcar origem `llm`;
315
+ - gerar `formRulesState` somente apos aceite.
316
+
317
+ ### Fase 5 - Visual block text seguro
318
+
319
+ Status: implementado como primeira versao segura.
320
+
321
+ O suporte a `title`, `message` e `text` em regras de `visualBlock` fica limitado a:
322
+
323
+ - nodes de texto simples;
324
+ - nodes com `id` estavel;
325
+ - ids convencionais gerados por presets do layout;
326
+ - escolha explicita de node pelo painel de propriedades da regra;
327
+ - overrides saneados em runtime;
328
+ - sem mutar o documento original durante preview.
329
+
330
+ ### Fase 6 - Testes E2E visuais
331
+
332
+ Status: cobertura implementada para os fluxos críticos; manter expansão incremental por domínio.
333
+
334
+ Cobrir:
335
+
336
+ - regra de field;
337
+ - regra de section;
338
+ - regra de action;
339
+ - regra de row/column;
340
+ - regra de visualBlock visible/style/text com node interno;
341
+ - regra LLM pendente e aceita;
342
+ - regra runtime-only;
343
+ - round-trip builder;
344
+ - formulario real de funcionarios.
345
+
346
+ ## Checklist de aceite
347
+
348
+ - [x] Regra invalida nunca e aplicada silenciosamente em todos os fluxos de entrada cobertos: editor, manifesto LLM, JSON authoring e runtime.
349
+ - [x] Propriedade descartada aparece na UI.
350
+ - [x] LLM nao escreve `formRulesState`.
351
+ - [x] Regra LLM so aplica apos revisao no fluxo de authoring do editor.
352
+ - [x] Regra runtime-only permanece editavel em JSON e visivel na lista.
353
+ - [x] Preview true/false funciona sem backend para propriedades de regra.
354
+ - [x] Visual block continua fora de `fieldMetadata`, `FormControl` e payload.
355
+ - [x] Text override de visual block e saneado e coberto por testes.
356
+ - [x] Abrir, salvar, reabrir e renderizar preserva `formRules`, `formRulesState` e metadata de revisao LLM no round-trip coberto.
357
+ - [x] A documentacao tecnica descreve limites do builder visual e da LLM.
358
+ - [x] Publicar/espelhar guia na landing publica em `/components/dynamic-form/docs/rules-authoring`.
359
+ - [x] Diagnostico diferencia propriedade fora do contrato, valor invalido e valor parcialmente saneado.
360
+ - [x] Painel de diagnostics oferece correcao assistida para propriedades rejeitadas/saneadas e regenera `formRulesState`.
361
+ - [x] Exemplos visuais por dominio demonstram `visualBlock` com regras de texto/estilo sem ampliar contrato.
362
+ - [x] Exemplos de dominio conectados ao catalogo de recipes em `examples/ai-recipes/praxis-dynamic-form.visual-block-domain-rules.json`.
363
+
364
+ ## Proximos incrementos recomendados
365
+
366
+ 1. Manter E2E visual em formularios reais para regressao de payload, node interno e round-trip do builder.
367
+ 2. Espelhar a referencia JSON API atualizada na landing publica quando a pipeline de docs rodar.
368
+ 3. Publicar/curar o novo recipe de regras `visualBlock` na landing publica quando a pipeline de docs rodar.
369
+ 4. Evoluir a correcao assistida para sugerir substituicoes semanticas, nao apenas aplicar sanitizer deterministico.
370
+
371
+ ## Evidencia publicada
372
+
373
+ - Guia tecnico canonico: `projects/praxis-dynamic-form/docs/dynamic-form-rules-authoring-plan.md`.
374
+ - Guia operacional LLM/analista: `projects/praxis-dynamic-form/docs/dynamic-form-llm-rule-authoring-guide.md`.
375
+ - Guia publico espelhado: `/components/dynamic-form/docs/rules-authoring`.
376
+ - Recipe publico de dominio: `examples/ai-recipes/praxis-dynamic-form.visual-block-domain-rules.json`.
377
+ - Cobertura focal de payload: `projects/praxis-dynamic-form/test-dev/e2e/funcionarios-form-demo-rules.playwright.spec.ts`.
378
+ - Cobertura focal de editor de node interno, revisao LLM e correcao assistida: `projects/praxis-dynamic-form/test-dev/e2e/form-config-editor-rules.playwright.spec.ts`.
379
+ - Cobertura focal de runtime fechado: `projects/praxis-dynamic-form/src/lib/services/form-rules.service.spec.ts`.
@@ -0,0 +1,141 @@
1
+ ---
2
+ title: "Dynamic Form Hot Metadata Updates"
3
+ slug: "dynamic-form-hot-metadata-updates"
4
+ description: "Guia operacional para aplicar patches de metadata em runtime no PraxisDynamicForm sem rebuild estrutural desnecessario."
5
+ doc_type: "guide"
6
+ document_kind: "host-guide"
7
+ component: "dynamic-form"
8
+ category: "integration"
9
+ audience:
10
+ - "frontend"
11
+ - "host"
12
+ - "architect"
13
+ - "platform-team"
14
+ level: "advanced"
15
+ status: "active"
16
+ owner: "praxis-ui"
17
+ tags:
18
+ - "dynamic-form"
19
+ - "hot-metadata"
20
+ - "runtime"
21
+ - "dynamic-fields"
22
+ last_updated: "2026-03-07"
23
+ toc: true
24
+ sidebar: true
25
+ related_docs:
26
+ - "dynamic-form-overview"
27
+ - "praxis-dynamic-form-json-api"
28
+ - "dynamic-fields-host-custom-field-guide"
29
+ keywords:
30
+ - "hot update"
31
+ - "field metadata patch"
32
+ - "dynamic field loader"
33
+ - "component metadata registry"
34
+ source_of_truth:
35
+ - "projects/praxis-dynamic-form/src/lib/praxis-dynamic-form.ts"
36
+ - "projects/praxis-dynamic-fields/src/lib/directives/dynamic-field-loader.directive.ts"
37
+ ---
38
+
39
+ # Dynamic Form Hot Metadata Updates
40
+
41
+ ## Objetivo
42
+
43
+ Explicar como o `PraxisDynamicForm` aplica patches de metadata em runtime sem reconstruir o formulario inteiro quando isso nao e necessario.
44
+
45
+ ```mermaid
46
+ flowchart LR
47
+ Patch["host aplica patch de metadata"] --> Runtime["PraxisDynamicForm"]
48
+ Runtime --> Hot["reaplica metadata no componente vivo"]
49
+ Runtime --> Refresh["refresh do loader afetado"]
50
+ Runtime --> Rebuild["buildFormFromConfig como fallback"]
51
+ ```
52
+
53
+ ## Pre-requisitos
54
+
55
+ - entendimento basico de `FormConfig`, `FieldMetadata` e `DynamicFieldLoaderDirective`
56
+ - familiaridade com o fluxo de configuracao de campos no `PraxisDynamicForm`
57
+
58
+ ## O que mudou no runtime
59
+
60
+ - `PraxisDynamicForm` mantem referencias para os `DynamicFieldLoaderDirective` ativos, um por coluna.
61
+ - Depois de aplicar um patch de metadata:
62
+ - atualiza o `FieldMetadata` canonico dentro da configuracao persistida;
63
+ - reusa o `FormControl` atual quando a mudanca e apenas de validacao/comportamento;
64
+ - reaplica metadata diretamente no componente vivo quando ele suporta hot metadata;
65
+ - faz `refresh()` apenas no loader afetado quando a mudanca exige rerender;
66
+ - cai em `buildFormFromConfig()` apenas como fallback seguro.
67
+
68
+ ## Quando o update continua hot
69
+
70
+ O caminho de hot update e usado quando a alteracao nao muda a estrutura do campo, por exemplo:
71
+
72
+ - `required`
73
+ - `readonly`
74
+ - `disabled`
75
+ - `hidden`
76
+ - `min`, `max`, `pattern`
77
+ - labels, hints e metadata de apresentacao que o componente consegue receber em runtime
78
+
79
+ Nesses casos o runtime:
80
+
81
+ 1. recalcula validators via `DynamicFormService.updateControlFromMetadata`;
82
+ 2. reaplica a metadata no componente por `setInputMetadata(...)` ou `WritableSignal`;
83
+ 3. evita rebuild completo do formulario.
84
+
85
+ ## Quando vira refresh estrutural
86
+
87
+ Mudancas estruturais ainda exigem rerender do loader para manter integridade:
88
+
89
+ - troca de `controlType`
90
+ - inclusao ou remocao de campos
91
+ - mudancas que alteram o conjunto de bindings esperados pelo componente
92
+
93
+ Regra operacional:
94
+
95
+ - se o loader da coluna for localizado, apenas ele e atualizado;
96
+ - se o loader nao puder ser localizado, o runtime usa fallback seguro de rebuild do form.
97
+
98
+ ## Melhorias no DynamicFieldLoader
99
+
100
+ O guard de rerender do loader passou a incluir no snapshot:
101
+
102
+ - `required`
103
+ - `readonly`
104
+ - `disabled`
105
+ - `hidden`
106
+
107
+ Isso reduz casos em que o host alterava metadata valida mas a UI nao refletia a mudanca imediatamente.
108
+
109
+ ## Limites e pre-requisitos
110
+
111
+ O hot update funciona melhor quando o field component:
112
+
113
+ - expõe metadata por `WritableSignal`; ou
114
+ - implementa `setInputMetadata(metadata)`; e
115
+ - trabalha ligado a um `FormControl`
116
+
117
+ Se o componente custom nao suporta isso, o runtime ainda funciona, mas cai no caminho de `loader.refresh()`.
118
+
119
+ ## Extensao no host
120
+
121
+ Para fields custom do host:
122
+
123
+ - registre o componente no `ComponentRegistryService`;
124
+ - registre metadados editoriais no `ComponentMetadataRegistry`;
125
+ - mantenha `controlType` e id de metadata alinhados;
126
+ - implemente `setInputMetadata(...)` ou sinal equivalente para aproveitar hot updates.
127
+
128
+ ## Por que isso importa
129
+
130
+ Em cenarios corporativos, esse fluxo reduz:
131
+
132
+ - flicker visual
133
+ - rebuilds desnecessarios
134
+ - perda de foco durante configuracao de campos
135
+ - custo de reconciliacao manual no host
136
+
137
+ ## Documentos relacionados
138
+
139
+ - Dynamic Form overview: `dynamic-form-overview`
140
+ - [Dynamic Form API](../src/lib/praxis-dynamic-form.json-api.md)
141
+ - [Dynamic Fields Host Custom Field Guide](../../praxis-dynamic-fields/docs/dynamic-fields-host-custom-field-guide.md)