@praxisui/dynamic-form 10.0.0-rc.40 → 10.0.0-rc.41
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.
- package/README.md +74 -0
- package/ai/component-registry.json +17 -5
- package/docs/custom-fields-enterprise-review.md +229 -0
- package/fesm2022/praxisui-dynamic-form.mjs +648 -199
- package/package.json +8 -8
- package/src/lib/praxis-dynamic-form.json-api.md +16 -3
- package/types/praxisui-dynamic-form.d.ts +27 -8
package/README.md
CHANGED
|
@@ -757,3 +757,77 @@ suportada, ocupa a linha seguinte. Nenhum documento ou protocolo de Save é alte
|
|
|
757
757
|
### Filhos de páginas governadas
|
|
758
758
|
|
|
759
759
|
Consulte [o adapter nativo de página](docs/governed-page-widget-adapter.md) para reconstrução sem defaults, presença exata, identidade derivada e execução sem preferências concorrentes.
|
|
760
|
+
|
|
761
|
+
### Schema-backed custom fields
|
|
762
|
+
|
|
763
|
+
Core expands an object marked `x-ui.customFieldsContainer: true` (or the inline
|
|
764
|
+
`customFields` object) into fields named `customFields.<key>`. Dynamic Form uses
|
|
765
|
+
those names as nested reactive-form paths and keeps the wire payload nested:
|
|
766
|
+
`{ "customFields": { "numero_calcado": 38, "data_exame": "2026-10-27" } }`.
|
|
767
|
+
The `customField`, `customFieldKey` and `customFieldScope` metadata identifies
|
|
768
|
+
schema-backed fields; it does not make them local/transient authoring fields.
|
|
769
|
+
Saved containers colliding with the server's expanded namespace are replaced by
|
|
770
|
+
its direct children, including a container previously marked `source: 'local'`.
|
|
771
|
+
Noncolliding local fields and existing child placement remain. Restrictive parent
|
|
772
|
+
flags remain restrictive in children; they do not create a submit omission policy.
|
|
773
|
+
|
|
774
|
+
Date controls hydrate nested API values without mutating the input. Submit applies
|
|
775
|
+
the same date/lookup serialization, required/dirty handling and omission policies
|
|
776
|
+
to flat and dotted names. Missing nested values do not create containers. Filter
|
|
777
|
+
Form preserves supported nested values during same-context metadata rebuilds,
|
|
778
|
+
unless the new field has an explicit default (reset). A removed server field can
|
|
779
|
+
remain as metadata for layout continuity, but becomes disabled and omitted from
|
|
780
|
+
applicable payloads. Hidden alone is not omission: explicit local and legitimate
|
|
781
|
+
hidden fields keep their published semantics. No host adapter is needed for the
|
|
782
|
+
supported nested value paths.
|
|
783
|
+
|
|
784
|
+
Temporal normalization is metadata-aware: legacy date tuples and local datetime
|
|
785
|
+
strings are transformed only on declared temporal fields, including collection
|
|
786
|
+
item schemas. Numeric/unknown arrays such as `[2026, 10, 27]` remain arrays;
|
|
787
|
+
ordinary/unknown strings retain their spaces and date-like text. The `DateInput`
|
|
788
|
+
control follows date-only serialization. A same-context metadata rebuild can
|
|
789
|
+
restore nested dirty/touched control paths, including collection items, without
|
|
790
|
+
marking unrelated controls touched. This does not preserve a draft across every
|
|
791
|
+
reset, identity switch or retry.
|
|
792
|
+
|
|
793
|
+
Scalar arrays use the operation schema's `fieldMetadata[].items`, separately
|
|
794
|
+
from object collections' `array.itemSchema.fields`. Core's shared normalizer turns
|
|
795
|
+
valid UI tokens into declared strings, safe integers, finite numbers or exact
|
|
796
|
+
booleans and enforces the item enum after conversion. Date/date-time item formats
|
|
797
|
+
use that same contract. An invalid/null item rejects the entire projection rather
|
|
798
|
+
than silently dropping it; an optional null container and an empty array remain
|
|
799
|
+
distinct valid inputs. Form validation and prepared submit must agree, so a token
|
|
800
|
+
such as `12.5` cannot be submitted as an integer. This subset does not promise
|
|
801
|
+
integer precision beyond JavaScript's safe range or an object-array editor.
|
|
802
|
+
|
|
803
|
+
Record paths do not traverse array intermediates in computed-rule contexts;
|
|
804
|
+
collection submit uses its own item-schema pipeline. The canonical Metadata key
|
|
805
|
+
policy rejects reserved control names such as `constructor`, `toString` and
|
|
806
|
+
`hasOwnProperty`; payload helper support does not relax that policy. Existing
|
|
807
|
+
stored definitions with such keys require a backend migration.
|
|
808
|
+
|
|
809
|
+
Read-only/disabled does not automatically mean omission from `getRawValue()`.
|
|
810
|
+
The canonical backend command request projection excludes read-only custom fields
|
|
811
|
+
from properties and required, while response schemas retain them for display.
|
|
812
|
+
Use the exact operation request schema; merging response fields into commands or
|
|
813
|
+
adding an unimplemented `x-ui.submitPolicy` adapter would break that boundary.
|
|
814
|
+
Reconciliation treats a successful empty schema as authoritative. Removed
|
|
815
|
+
server-backed fields become hidden, disabled and `submitPolicy: 'omit'`, including
|
|
816
|
+
manual sync and Filter; explicit local fields remain local. Reappearance restores
|
|
817
|
+
the current server constraints rather than stale saved required/type/enum/items.
|
|
818
|
+
|
|
819
|
+
Each fresh schema-loading cycle revalidates HTTP and normalizes its body; compiled
|
|
820
|
+
L1 is not a readiness shortcut. A matching 304 can reuse the cached representation.
|
|
821
|
+
Status 0, denied access, malformed schema and failed saved-config reconciliation
|
|
822
|
+
cannot make the old form ready. Authorization errors show access feedback without
|
|
823
|
+
a generic retry action; timeout/transport failures retain their retry surface.
|
|
824
|
+
Schema loading/error or a known unconfirmed enterprise context blocks submit.
|
|
825
|
+
Context changes cancel obsolete reads, revalidate metadata and invalidate the old
|
|
826
|
+
initial-value seed; retry is not a general cross-context autosave guarantee.
|
|
827
|
+
|
|
828
|
+
The confirmed enterprise context supplies effective tenant/locale and context
|
|
829
|
+
version. Explicit schema URLs conflicting with that context are rejected. Identity
|
|
830
|
+
visible only to cookies/interceptors still requires a captured context version or
|
|
831
|
+
complete cache/session invalidation by the host; backend authorization is always
|
|
832
|
+
required. See the [enterprise review](https://github.com/codexrodrigues/praxis-ui-angular/pull/658)
|
|
833
|
+
for source, candidate gates, host proof and remaining adoption limits.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-10-
|
|
3
|
+
"generatedAt": "2026-10-27T22:14:23.237Z",
|
|
4
4
|
"packageName": "@praxisui/dynamic-form",
|
|
5
|
-
"packageVersion": "10.0.0-rc.
|
|
5
|
+
"packageVersion": "10.0.0-rc.41",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 2,
|
|
@@ -71,11 +71,23 @@
|
|
|
71
71
|
},
|
|
72
72
|
{
|
|
73
73
|
"name": "schemaSource",
|
|
74
|
-
"type": "'resource' | 'filter'",
|
|
74
|
+
"type": "'resource' | 'filter' | 'action'",
|
|
75
75
|
"required": false,
|
|
76
76
|
"description": "Fonte do schema de campos",
|
|
77
77
|
"default": "resource"
|
|
78
78
|
},
|
|
79
|
+
{
|
|
80
|
+
"name": "actionId",
|
|
81
|
+
"type": "string | null",
|
|
82
|
+
"required": false,
|
|
83
|
+
"description": "Identificador canônico da ação de workflow ou comando governado associado ao formulário"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"name": "operationId",
|
|
87
|
+
"type": "string | null",
|
|
88
|
+
"required": false,
|
|
89
|
+
"description": "OperationId canônico publicado pelo catálogo de ações ou surfaces para execução do comando"
|
|
90
|
+
},
|
|
79
91
|
{
|
|
80
92
|
"name": "schemaUrl",
|
|
81
93
|
"type": "string | null",
|
|
@@ -9418,9 +9430,9 @@
|
|
|
9418
9430
|
{
|
|
9419
9431
|
"chunkIndex": 0,
|
|
9420
9432
|
"chunkKind": "summary",
|
|
9421
|
-
"content": "Component ID: praxis-dynamic-form\nSelector: praxis-dynamic-form\nFriendly Name: Praxis Dynamic Form\nDescription: Formulario dinamico com layout por secoes/linhas/colunas e campos renderizados por metadados.\nCategory: form\nLib/Package: @praxisui/dynamic-form\nTags: widget, form, configurable, hasWizard, stable\nInputs:\n - resourcePath (string)\n - resourceId (string | number | null)\n - initialValue (Record<string, unknown> | null)\n - emptyState (PraxisDynamicFormEmptyState | null)\n - editorialContext (Record<string, unknown> | null)\n - mode ('create' | 'edit' | 'view' | 'presentation' | 'dossier')\n - config (FormConfig)\n - actions (FormConfig['actions'] | null)\n - schemaSource ('resource' | 'filter')\n - schemaUrl (string | null)\n - readUrl (string | null)\n - apiEndpointKey (ApiEndpoint | string | null)\n - apiUrlEntry (ApiUrlEntry | null)\n - submitUrl (string | null)\n - submitMethod ('post' | 'put' | 'patch' | null)\n - submitIdempotencyKey (string | null)\n - submitCorrelationId (string | null)\n - submitResourceVersion (string | number | null)\n - submitResourceVersionTargetResourceKey (string | null)\n - submitResourceVersionTargetIdField (string | null)\n - responseSchemaUrl (string | null)\n - enableCustomization (boolean)\n - showAiAssistant (boolean)\n - formId (string)\n - componentInstanceId (string)\n - configPersistenceStrategy ('local-first' | 'input-first' | 'volatile')\n - layout (FormLayout)\n - generatedLayoutPreset ('default' | 'compactPresentation')\n - layoutPolicy (DynamicFormLayoutPolicy | null)\n - backConfig (BackConfig)\n - hooks (FormHooksLayout)\n - removeEmptyContainersOnSave (boolean)\n - reactiveValidation (boolean | null)\n - reactiveValidationDebounceMs (number | null)\n - notifyIfOutdated ('inline' | 'snackbar' | 'both' | 'none')\n - snoozeMs (number)\n - autoOpenSettingsOnOutdated (boolean)\n - readonlyModeGlobal (boolean | null)\n - disabledModeGlobal (boolean | null)\n - presentation (DynamicFormPresentationSnapshot | null)\n - presentationPreset (FormPresentationPreset)\n - presentationModeGlobal (boolean | null)\n - fieldIconPolicy ('all' | 'presentation-only' | 'none')\n - visibleGlobal (boolean | null)\n - customEndpoints (EndpointConfig)\nOutputs:\n - formSubmit (FormSubmitEvent)\n - formCancel (void)\n - formReset (void)\n - configChange (FormConfig)\n - configPatchChange (DynamicFormConfigPatchChangeEvent)\n - formReady (FormReadyEvent)\n - valueChange (FormValueChangeEvent)\n - payloadPreviewChange (FormPayloadPreviewEvent)\n - syncCompleted (SyncResult)\n - initializationError (FormInitializationError)\n - enableCustomizationChange (boolean)\n - customAction (FormCustomActionEvent)\n - actionConfirmation (FormActionConfirmationEvent)\n - schemaStatusChange ({ outdated: boolean; serverHash?: string; lastVerifiedAt?: string; formId?: string })\n - reactiveDeterminationExecuted (ReactiveDeterminationExecutionEvent)\n - reactiveDeterminationPendingChange (boolean)\n",
|
|
9433
|
+
"content": "Component ID: praxis-dynamic-form\nSelector: praxis-dynamic-form\nFriendly Name: Praxis Dynamic Form\nDescription: Formulario dinamico com layout por secoes/linhas/colunas e campos renderizados por metadados.\nCategory: form\nLib/Package: @praxisui/dynamic-form\nTags: widget, form, configurable, hasWizard, stable\nInputs:\n - resourcePath (string)\n - resourceId (string | number | null)\n - initialValue (Record<string, unknown> | null)\n - emptyState (PraxisDynamicFormEmptyState | null)\n - editorialContext (Record<string, unknown> | null)\n - mode ('create' | 'edit' | 'view' | 'presentation' | 'dossier')\n - config (FormConfig)\n - actions (FormConfig['actions'] | null)\n - schemaSource ('resource' | 'filter' | 'action')\n - actionId (string | null)\n - operationId (string | null)\n - schemaUrl (string | null)\n - readUrl (string | null)\n - apiEndpointKey (ApiEndpoint | string | null)\n - apiUrlEntry (ApiUrlEntry | null)\n - submitUrl (string | null)\n - submitMethod ('post' | 'put' | 'patch' | null)\n - submitIdempotencyKey (string | null)\n - submitCorrelationId (string | null)\n - submitResourceVersion (string | number | null)\n - submitResourceVersionTargetResourceKey (string | null)\n - submitResourceVersionTargetIdField (string | null)\n - responseSchemaUrl (string | null)\n - enableCustomization (boolean)\n - showAiAssistant (boolean)\n - formId (string)\n - componentInstanceId (string)\n - configPersistenceStrategy ('local-first' | 'input-first' | 'volatile')\n - layout (FormLayout)\n - generatedLayoutPreset ('default' | 'compactPresentation')\n - layoutPolicy (DynamicFormLayoutPolicy | null)\n - backConfig (BackConfig)\n - hooks (FormHooksLayout)\n - removeEmptyContainersOnSave (boolean)\n - reactiveValidation (boolean | null)\n - reactiveValidationDebounceMs (number | null)\n - notifyIfOutdated ('inline' | 'snackbar' | 'both' | 'none')\n - snoozeMs (number)\n - autoOpenSettingsOnOutdated (boolean)\n - readonlyModeGlobal (boolean | null)\n - disabledModeGlobal (boolean | null)\n - presentation (DynamicFormPresentationSnapshot | null)\n - presentationPreset (FormPresentationPreset)\n - presentationModeGlobal (boolean | null)\n - fieldIconPolicy ('all' | 'presentation-only' | 'none')\n - visibleGlobal (boolean | null)\n - customEndpoints (EndpointConfig)\nOutputs:\n - formSubmit (FormSubmitEvent)\n - formCancel (void)\n - formReset (void)\n - configChange (FormConfig)\n - configPatchChange (DynamicFormConfigPatchChangeEvent)\n - formReady (FormReadyEvent)\n - valueChange (FormValueChangeEvent)\n - payloadPreviewChange (FormPayloadPreviewEvent)\n - syncCompleted (SyncResult)\n - initializationError (FormInitializationError)\n - enableCustomizationChange (boolean)\n - customAction (FormCustomActionEvent)\n - actionConfirmation (FormActionConfirmationEvent)\n - schemaStatusChange ({ outdated: boolean; serverHash?: string; lastVerifiedAt?: string; formId?: string })\n - reactiveDeterminationExecuted (ReactiveDeterminationExecutionEvent)\n - reactiveDeterminationPendingChange (boolean)\n",
|
|
9422
9434
|
"sourcePointer": "projects/praxis-dynamic-form/src/lib/praxis-dynamic-form.metadata.ts",
|
|
9423
|
-
"contentHash": "
|
|
9435
|
+
"contentHash": "97e0c3da46840798955442e4cb38ad5e4946c2fa4f5eb841b85182993a83a59e",
|
|
9424
9436
|
"sourceKind": "component_definition",
|
|
9425
9437
|
"sourceId": "praxis-dynamic-form",
|
|
9426
9438
|
"corpusVersion": "1.0.0"
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Custom fields: revisão de adoção corporativa"
|
|
3
|
+
slug: "dynamic-form-custom-fields-enterprise-review"
|
|
4
|
+
description: "Registro de achados, fontes, provas e pendências da adoção de custom fields no Core e Dynamic Form."
|
|
5
|
+
doc_type: "reference"
|
|
6
|
+
document_kind: "governance-reference"
|
|
7
|
+
component: "dynamic-form"
|
|
8
|
+
category: "architecture"
|
|
9
|
+
audience:
|
|
10
|
+
- "frontend"
|
|
11
|
+
- "host"
|
|
12
|
+
- "architect"
|
|
13
|
+
- "platform-team"
|
|
14
|
+
level: "advanced"
|
|
15
|
+
status: "active"
|
|
16
|
+
owner: "praxis-ui"
|
|
17
|
+
last_updated: "2026-10-27"
|
|
18
|
+
toc: true
|
|
19
|
+
sidebar: false
|
|
20
|
+
source_of_truth:
|
|
21
|
+
- "projects/praxis-core/src/lib/services/schema-normalization-kernel.ts"
|
|
22
|
+
- "projects/praxis-core/src/lib/models/form/materialize-custom-fields-layout.ts"
|
|
23
|
+
- "projects/praxis-core/src/lib/services/dynamic-form.service.ts"
|
|
24
|
+
- "projects/praxis-core/src/lib/schema/schema-metadata-client.ts"
|
|
25
|
+
- "projects/praxis-core/src/lib/services/generic-crud.service.ts"
|
|
26
|
+
- "projects/praxis-dynamic-form/src/lib/praxis-dynamic-form.ts"
|
|
27
|
+
- "projects/praxis-dynamic-form/src/lib/utils/prepare-submit-payload.ts"
|
|
28
|
+
- "projects/praxis-dynamic-form/src/lib/services/form-rules.service.ts"
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
# Custom fields: revisão de adoção corporativa
|
|
32
|
+
|
|
33
|
+
## Escopo e baseline
|
|
34
|
+
|
|
35
|
+
A [Issue 657](https://github.com/codexrodrigues/praxis-ui-angular/issues/657) e o
|
|
36
|
+
[PR 658](https://github.com/codexrodrigues/praxis-ui-angular/pull/658) materializam
|
|
37
|
+
custom fields no runtime oficial. A revisão atual parte de Angular `48b004c9e` e
|
|
38
|
+
Metadata `368d96266b`. Os PRs 658/304 permanecem sem merge. A revisão da fonte e os gates focais desta rodada estão concluídos, com as
|
|
39
|
+
exceções preexistentes e pendências downstream registradas abaixo. Fonte candidata e provas
|
|
40
|
+
não certificam publicação, deploy, release ou adoção corporativa irrestrita.
|
|
41
|
+
|
|
42
|
+
A revisão anterior partiu de Angular `6598ef221f0708c6628b02380c0e27110fa4a1ae`
|
|
43
|
+
e skills `59c64169fe062de69c83b886c75b681d4e7ee967`; seus achados motivaram esta
|
|
44
|
+
rodada. O backend é dono da definição, autorização e validação. Core projeta,
|
|
45
|
+
reconcilia e transporta; Form/Table materializam controles e payloads. A landing
|
|
46
|
+
publica essa fonte, e não uma semântica alternativa.
|
|
47
|
+
|
|
48
|
+
Classificação: `contrato-publico`, com correções de semântica já suportada e mal
|
|
49
|
+
materializada em Core/Form/Table e alinhamento canônico backend. Consumidores:
|
|
50
|
+
Form schema-driven/salvo, Filter standalone/integrado/avançado, discovery e
|
|
51
|
+
GenericCrud. Derivados: READMEs, JSON API, dois guias Table, vendor docs da landing
|
|
52
|
+
e skills existentes. Não há nova rota pública para este relatório, nem alteração
|
|
53
|
+
de endpoint, corpus HTTP ou recipe pela documentação.
|
|
54
|
+
|
|
55
|
+
## Achados, tratamento e fontes
|
|
56
|
+
|
|
57
|
+
| Cenário / origem | Correção na fonte candidata | Gate / limite |
|
|
58
|
+
| --- | --- | --- |
|
|
59
|
+
| Container salvo ou local colidente substituía filhos e podia perder a subárvore no payload. | `materialize-custom-fields-layout`, reconciliadores e sync migram pai direto para filhos schema-backed, preservando posições, rich content e locais não colidentes; diagnostics persistem a correção. | Integração normalizer/reconcile/FormGroup/submit nos três caminhos; não transferir omit/defaults/validadores escalares do pai. |
|
|
60
|
+
| Restrições e identidade eram relaxadas por metadata antiga. | Pisos disabled/readOnly/formHidden do container; identidade customField/key/scope e constraints items/enum server-owned. FieldAccess ausente é herdado; policies equivalentes por sets são aceitas, conflito exige policy leaf efetiva do backend. | Conflito de normalização bloqueia inicialização, incluindo configuração salva; listas OR não implementam AND arbitrário. |
|
|
61
|
+
| Cache/deduplicação/replay e getters podiam cruzar tenant, autenticação ou recurso por chamada. | `schema-request-key`, `schema-request-context`, `schema-fetch`, SchemaMetadataClient, GenericCrud e Discovery capturam contexto/headers, isolam representação e deduplicam só trabalho em andamento. GenericCrud só publica derivados do recurso configurado; callbacks obsoletos não publicam. | Snapshot antes de await/subscription e retry304 igual; provider/hook/aliases inválidos falham antes do request. Getters singleton não são mapa de resultados por chamada. |
|
|
62
|
+
| L1, cache status0 ou configuração salva podiam parecer schema autorizado atual. | Novo ciclo HTTP revalida e normaliza; L1 compilado não estabelece readiness. Corpo cacheado só após 304 correspondente; status0/401/403/normalização inválida não recuperam silenciosamente o form. | Sem modo offline. Discovery não usa resumo do catálogo ou schema response para substituir request vazio/negado. Fallback de indisponibilidade conhecido só nas trilhas equivalentes já suportadas. |
|
|
63
|
+
| Remover o último campo gerava defs=[] ignorado; sync/filter conservavam órfãos aplicáveis/required. | Schema vazio bem-sucedido é autoritativo. Reconcile Form/Filter e sync manual marcam órfãos não locais hidden+disabled+omit; reaparecimento usa required/type/items/enum atuais. | Hidden legítimo e `source: local` explícito conservam sua semântica; raw draft pode manter diagnóstico, mas não é payload aplicável. |
|
|
64
|
+
| Request publicava read-only que o backend recusava; nomes admitidos colidiam com controles. | Metadata PR304 exclui read-only de comando properties/required e mantém leitura/filtro apropriados; política de chaves rejeita nomes reservados exatos. | Consumir schema da operação; não mesclar response em comando nem inventar x-ui.submitPolicy local. Definições antigas exigem migração explícita. |
|
|
65
|
+
| Arrays IN/enum perdiam tipo e diferentes fronteiras emitiam valores incompatíveis. | FieldDefinition/Metadata `items: FieldScalarItemsSchema`; parser Core único `normalizeScalarArrayValue`, validators e projeção Form/Table. Modal Apply/Save usa payload do child; merge de shortcut reprojeta omit. | Rejeição inteira de item inválido/null, sem descarte parcial; bloqueio pending/invalid inclui debounce anterior. Zero filtros ativos DISABLED permite limpar. |
|
|
66
|
+
| Regras computed liam alias pontuado antigo. | Contexto JSON Logic aninhado via helper interno; `fieldValues` continua mapa plano de target IDs. | Cadeia em ordem inversa, condições true/false e imutabilidade. Arrays intermediários não são record paths suportados. |
|
|
67
|
+
| Heurística temporal alterava strings e arrays numéricos; rebuild perdia estado aninhado. | Normalização metadata-aware de datas e item schemas, DateInput date-only e snapshot dirty/touched por leaf/FormArray. Campos planos escrevem draft privado, sem clone raiz por campo. | Arrays numéricos/unknown e strings não temporais preservados; não é autosave entre contextos/resets. |
|
|
68
|
+
| Erro de acesso parecia conexão/retry e submit podia usar estado não pronto. | Form distingue acesso, contexto não confirmado, projeção inválida e transporte. Loading/erro/known nonready bloqueiam submit; preview scalar inválido emite formData:null/isValid:false com raw intacto. | 401/403 não oferecem retry genérico. Troca confirmada invalida seed anterior e revalida; não restaura draft de outro tenant. |
|
|
69
|
+
|
|
70
|
+
## Contratos e limites ainda exigidos do host
|
|
71
|
+
|
|
72
|
+
A fonte backend inspecionada é o candidato PR304, docs em `99b75a2dde`:
|
|
73
|
+
[spec canônica](https://github.com/codexrodrigues/praxis-metadata-starter/blob/99b75a2dde/docs/spec/custom-fields-and-resource-facts.md).
|
|
74
|
+
A política rejeita exatamente `constructor`, `prototype`, `hasOwnProperty`,
|
|
75
|
+
`isPrototypeOf`, `propertyIsEnumerable`, `toLocaleString`, `toString` e `valueOf`,
|
|
76
|
+
com comparação sensível a maiúsculas. `__proto__` já é inválido pelo formato da
|
|
77
|
+
chave. Não corrigir dados antigos com aliases silenciosos de frontend.
|
|
78
|
+
|
|
79
|
+
Read-only/disabled/hidden não significam omissão universal. Na escrita, a projeção
|
|
80
|
+
canônica exclui custom fields read-only; filtros podem mantê-los como operandos de
|
|
81
|
+
busca e respostas como leitura. Campos contextuais legítimos continuam sujeitos
|
|
82
|
+
ao contrato da operação. `rawFormData`/`getRawValue()` são diagnósticos, não uma
|
|
83
|
+
instrução para ignorar o payload projetado.
|
|
84
|
+
|
|
85
|
+
A chave de representação usa URL real, identidade semântica e tenant/locale
|
|
86
|
+
capturados; headers adicionais selecionam um token opaco por sessão/página.
|
|
87
|
+
O lookup de headers é limitado e fica só em memória: credenciais/fingerprints não
|
|
88
|
+
são persistidos em chaves ou metadata. Isso não redige corpos arbitrários do
|
|
89
|
+
servidor. Contexto enterprise confirmado fornece tenant/locale/version; GenericCrud,
|
|
90
|
+
Discovery e Form bloqueiam um snapshot conhecido não pronto. O cliente standalone
|
|
91
|
+
SchemaMetadataClient captura o hook e não descobre o serviço DI por conta própria. Parâmetros explícitos conflitantes falham.
|
|
92
|
+
|
|
93
|
+
Cookies/interceptors que alterem identidade depois do snapshot não são observáveis
|
|
94
|
+
pelo cache. O host precisa materializar a versão confirmada nos headers capturados
|
|
95
|
+
ou invalidar todo o escopo de cache/sessão; recriar somente um cliente sobre o
|
|
96
|
+
mesmo armazenamento não basta. Tenant nunca substitui autorização por principal.
|
|
97
|
+
GenericCrud mantém getters do recurso configurado: overrides por chamada devolvem
|
|
98
|
+
seus resultados, sem transformar esses getters em uma API multiscope.
|
|
99
|
+
|
|
100
|
+
Scalar `items` cobre string/integer/number/boolean e formatos date/date-time
|
|
101
|
+
suportados. Inteiros precisam ser seguros no JavaScript; números finitos seguem
|
|
102
|
+
sintaxe JSON e booleans são exatos. Enum é aplicado depois da conversão. `null`
|
|
103
|
+
container/ausente e `[]` não equivalem a item null; required continua independente.
|
|
104
|
+
Não anunciar arbitrary JSON Schema items, editor object-array, precisão int64 ou
|
|
105
|
+
record paths de regras através de arrays intermediários.
|
|
106
|
+
|
|
107
|
+
## UX e progresso
|
|
108
|
+
|
|
109
|
+
| Situação | Comportamento / limite comunicável |
|
|
110
|
+
| --- | --- |
|
|
111
|
+
| Schema loading, timeout e transporte | SchemaMetadataClient aplica deadline; leituras supersedidas são canceladas. Falha recuperável oferece retry. Não é modo offline ou promessa de recuperar todo rascunho. |
|
|
112
|
+
| Acesso negado ou contexto não confirmado | Form não monta controles cacheados como prontos nem permite submit; acesso tem feedback próprio sem retry genérico. Recuperação depende de contexto/autorização do host. |
|
|
113
|
+
| Config salva, defs vazias ou projeção inválida | Vazio bem-sucedido reconcilia; erro não mantém configuração antiga pronta. FieldAccess conflitante é erro de metadata, não autorização alternativa de host. |
|
|
114
|
+
| Troca de tenant/registro | Cancela geração antiga, invalida seed anterior e revalida. Não comunica continuidade de dados entre identidades. |
|
|
115
|
+
| Campo removido/reaparecido | Órfão server-backed pode manter metadata/layout/raw diagnóstico, mas fica disabled/omit. Ao voltar usa constraints do schema atual. |
|
|
116
|
+
| Rebuild do filtro | Valores suportados do mesmo contexto podem ser restaurados; default explícito pode resetar. Hidden/local legítimo não é removido por uma política genérica. |
|
|
117
|
+
| Valor scalar inválido | Permanece corrigível no raw/control com feedback; nenhuma emissão aplicável/submit/shortcut ou preview com formData utilizável. |
|
|
118
|
+
| Narrow viewport | Ações/labels devem permanecer acessíveis por scroll sem overflow horizontal. Densidade da toolbar não prova campo acima da dobra ou conformidade de teclado/AXE. |
|
|
119
|
+
|
|
120
|
+
## Evidências da rodada atual
|
|
121
|
+
|
|
122
|
+
- Core: 471 casos distintos na campanha atual. Quatro falhas de fixture/guard foram
|
|
123
|
+
corrigidas; rerun focal de contexto/discovery 61/61 aprovado. Não somar 471+61.
|
|
124
|
+
- Comandos de build Core e Form com closure de 13 libs aprovados. Core precedeu
|
|
125
|
+
o último guard; a closure final Form recompilou Core/Form/Table e cobre a fonte
|
|
126
|
+
final de produção. Pureza e MatSelect zero-debt também passaram.
|
|
127
|
+
- Form: 406 casos distintos aprovados, com rerun focal das três fixtures
|
|
128
|
+
corrigidas. Deltas posteriores ao build são apenas testes.
|
|
129
|
+
- Browser: seis casos distintos aprovados (quatro Form e dois Table). Os quatro
|
|
130
|
+
Form cobrem editor desktop/resize, abertura narrow inicial, warm-cache seguido
|
|
131
|
+
de403 e formulário público scalar/enum. O último caso passou em rerun após
|
|
132
|
+
corrigir uma corrida do teste ao observar a ação ficar disabled. Table cobre
|
|
133
|
+
toolbar/gerenciador de campos/avançado/modal, sem prova de query IN por browser.
|
|
134
|
+
- Table: **224/224 aprovados** após o alinhamento das quatro fixtures year/month
|
|
135
|
+
ao contrato introduzido em `6de618805`. O runtime e o registry preservam
|
|
136
|
+
inlineYearRange/inlineMonthRange como wrappers numéricos; não são aliases de
|
|
137
|
+
inlinePeriodRange. Os testes agora verificam IDs, modo range, imutabilidade,
|
|
138
|
+
hidratação em controle real e payload numérico no submit. O resultado anterior
|
|
139
|
+
220/224 é histórico e foi substituído pela execução focal completa aprovada.
|
|
140
|
+
- Dynamic Fields: **10/10 aprovados** nos componentes inline-year-range,
|
|
141
|
+
inline-month-range e inline-period-range. A prova distingue limites numéricos
|
|
142
|
+
de identificadores de períodos, sem alterar a semântica de produção.
|
|
143
|
+
- Quickstart: revisão cruzada confirmou 25 casos distintos sem falha no candidato
|
|
144
|
+
backend e a prova HTTP Neon coordenada no trabalho backend. Três pilotos
|
|
145
|
+
históricos (EventosFolha, MetadataMigration e OpenApiGroupResolution), além do
|
|
146
|
+
verify integral e do pin de artefato público, permanecem pendentes no Draft482;
|
|
147
|
+
não inferir adoção completa a partir do piloto. Fontes brutas e fingerprint estão no registro
|
|
148
|
+
backend `docs/technical/ISSUE-303-EXECUTION.md` e no PR304.
|
|
149
|
+
- Frontmatter incremental dos documentos desta rodada validado. Skills867
|
|
150
|
+
publicado em `d351c44`; landing docs no PR270 em `cfc0212`. Validação canônica
|
|
151
|
+
de skills e gates documentais aprovados. O fechamento documental corrigiu também as
|
|
152
|
+
cinco cópias vendor antigas: List, Metadata Editor, Page Builder, Table API e
|
|
153
|
+
Visual Builder. Os dois guias Dynamic Fields foram alinhados ao contrato de
|
|
154
|
+
ranges; o link prospectivo do Page Builder aponta à fonte GitHub existente.
|
|
155
|
+
Full vendor freshness passou para os 75 documentos, assim como docs25,
|
|
156
|
+
published-guides146 e sitemap. Nenhuma sincronização instalada ou merge.
|
|
157
|
+
|
|
158
|
+
A E2E ampliada `surface-open-form-demo.playwright.spec.ts` cobre o editor,
|
|
159
|
+
abertura narrow inicial, leitura autorizada seguida de403 sem reaproveitar
|
|
160
|
+
campos prontos, e formulário público com items/enum, bloqueio de token inválido e
|
|
161
|
+
submit nested tipado. Esses casos passaram na execução final e usam
|
|
162
|
+
schema/HTTP mockado; não substituem prova backend Neon. Não há prova AXE,
|
|
163
|
+
teclado completo, tema claro, filtro IN por browser ou persistência real pelo E2E.
|
|
164
|
+
|
|
165
|
+
A coordenação inspecionou screenshots desktop e narrow estabilizados: labels e
|
|
166
|
+
quadros acessíveis, sem overflow horizontal; a toolbar estreita continua densa e
|
|
167
|
+
o campo pode exigir scroll. O rerun Playwright pode limpar `test-results`, então
|
|
168
|
+
este registro não publica links para screenshots transitórios. Logs em
|
|
169
|
+
`/tmp/praxis-658-e2e-form-final.log`, `praxis-658-e2e-scalar-rerun.log` e
|
|
170
|
+
`praxis-658-e2e-table-final.log` pertencem à campanha local coordenada.
|
|
171
|
+
|
|
172
|
+
O receipt `/tmp/praxis-658-source-freeze.json` vincula as provas à árvore de
|
|
173
|
+
44 arquivos fonte/teste alterados contra48b004, fingerprint SHA256
|
|
174
|
+
`f99a2bdde6f3fa9f05cd56025e1d375c24c6bcffa2fef5e541e155d6c2650bda`.
|
|
175
|
+
O lockfile não mudou. O commit Angular final é registrado no PR658 após o freeze
|
|
176
|
+
documental; o fingerprint distingue a fonte validada das edições de relatório.
|
|
177
|
+
|
|
178
|
+
## Evidência histórica anterior
|
|
179
|
+
|
|
180
|
+
A rodada anterior passou 313 casos Core distintos (311+duas novas em rerun70),
|
|
181
|
+
324 Form e build closure13. Um E2E mockado passou em1280×720 e após resize390×844,
|
|
182
|
+
com screenshots finais inspecionados pela coordenação: sem overflow, tabs para
|
|
183
|
+
select, ações sticky e campo narrow atingível por scroll, abaixo da dobra. Essa
|
|
184
|
+
execução não cobria abertura narrow inicial nem submit real. Capturas ignoradas
|
|
185
|
+
pelo Git em `test-results/surface-open-form-demo.pla-6e87b-the-employee-drawer-surface-chromium/`.
|
|
186
|
+
Esses resultados não são somados aos gates da árvore atual.
|
|
187
|
+
|
|
188
|
+
## Publicação e guidance
|
|
189
|
+
|
|
190
|
+
O [PR skills867](https://github.com/codexrodrigues/praxis-codex-skills/pull/867)
|
|
191
|
+
pertence ao incremento Angular Core/Form/Table; o
|
|
192
|
+
[PR skills868](https://github.com/codexrodrigues/praxis-codex-skills/pull/868)
|
|
193
|
+
pertence ao backend e tem escritor próprio. Integração canônica e sincronização
|
|
194
|
+
instalada são estados separados e permanecem pendentes enquanto os PRs não forem
|
|
195
|
+
integrados. O [PR270 da landing](https://github.com/codexrodrigues/praxis-ui-landing-page/pull/270)
|
|
196
|
+
usa o fluxo vendor oficial em worktree isolado. Este registro
|
|
197
|
+
não cria nova rota, manifesto, endpoint, corpus ou assets públicos.
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
## Fechamento Table e documentação — 27/10/2026
|
|
201
|
+
|
|
202
|
+
Escopo autorizado: corrigir as quatro falhas preexistentes da Table e as cinco
|
|
203
|
+
cópias documentais divergentes enquanto a campanha financeira Quickstart segue
|
|
204
|
+
em outro chat. Classificação transversal: testes e documentação, sem modificação
|
|
205
|
+
de runtime, API, dependências, rotas ou configuração de build. Inventário
|
|
206
|
+
`ja-suportado-mal-nomeado-ou-mal-materializado`: contrato e implementação já
|
|
207
|
+
concordavam; expectativas e guias ainda ensinavam a conversão antiga.
|
|
208
|
+
|
|
209
|
+
A auditoria das cinco cópias vendor encontrou versões históricas exatas das fontes
|
|
210
|
+
Angular, sem conteúdo exclusivo novo a preservar. A correção usa o sync oficial
|
|
211
|
+
com `PRAXIS_UI_ANGULAR_ROOT` apontando ao worktree revisado. O ajuste dos dois guias
|
|
212
|
+
Dynamic Fields é derivado do mesmo diagnóstico; não cria controles ou DTOs.
|
|
213
|
+
|
|
214
|
+
A revisão independente confrontou o patch dos quatro testes, os wrappers e
|
|
215
|
+
registry, o contrato runtime e o histórico. O coordenador revisou os guias e a
|
|
216
|
+
projeção vendor. Evidências locais: `/tmp/praxis-658-table-alignment.log` (224),
|
|
217
|
+
`/tmp/praxis-658-range-contracts.log` (10) e
|
|
218
|
+
`/tmp/praxis-658-alignment-docs.log`. A bateria Table inclui componente, host e projeção; Dynamic Fields cobre os três
|
|
219
|
+
componentes de range, com `tools/karma/karma.headless.conf.cjs`. Não foi repetido build
|
|
220
|
+
ou E2E porque este incremento altera somente specs/documentação. Os builds e E2E
|
|
221
|
+
da fonte de produção `f5880172f` continuam válidos.
|
|
222
|
+
|
|
223
|
+
Skills: `atualizar-existente` para `praxis-fields-inline-overlay-runtime`, com a
|
|
224
|
+
distinção de valores numéricos/períodos e provas de promoção; `existente-adequada`
|
|
225
|
+
para publicação na landing, que já determina owner-first, sync oficial e gates
|
|
226
|
+
completos. A atualização canônica segue no PR867; integração e sync instalado
|
|
227
|
+
aguardam a revisão sem merge. Os commits finais deste fechamento estão nos PRs
|
|
228
|
+
658/270/867. Pilotos financeiros, verify integral e pin público do Quickstart
|
|
229
|
+
continuam sob coordenação exclusiva do outro chat; este incremento não os aprova.
|