feat: motor de resolucao estrutural TXT-XML via XSD NF-e (issue #140) - #205
Merged
elson-vinicius-lopes merged 4 commits intoAug 28, 2026
Merged
Conversation
…(issue #140, itens 1/3/4/5) Implementa XmlLayoutStructureParser (le XSD real da SEFAZ NF-e via XmlSchemaSet, mirror nfephp-org/sped-nfe PL_009_V4 - fonte de verdade decidida pelo dono 2026-08-27), XmlLayoutCatalog (resolução por caminho/leaf-name + XPath absoluto com namespace), MappingKindClassifier (direct/transformed/concatenated/static sobre StructuredRule, sem regex ad-hoc) e OccurrenceResolver + FieldToXmlMappingComposer (lineOccurrence->xmlOccurrence e critério objetivo authoritative/best-effort do design, §5). 25 testes novos: 8 contra o XSD real da NF-e, 6 do classificador, 11 do composer cobrindo direct/static/concatenated/N->1/1->N/grupo repetido/mismatch de repetição/loop dinâmico/função desconhecida/FunctionCatalog indisponível/ fallback por nome de folha. Sem regressão (36/36 verdes no projeto). Escopo: só NF-e por ora, extensível por tipo de documento (fonte é XSD+elemento raiz passados pelo chamador). Não implementa endpoint HTTP nem validação comportamental contra LowCodeRunner real - fica para #140 itens 6-8.
…>XML ao pipeline real (issue #140, itens 2/6-9) Conecta o motor ja implementado (ai/XslSynth.Contracts/Core/StructuralResolution/, commit 36ae5cb) a dados reais: Layout/ParsedField do parse posicional real (ILayoutParserService) + MapperVo real via RealMapperParser sobre mapper decifrado (MapperDatabaseService) + catalogo XML de destino (XSD NF-e) cacheado por TargetLayoutGuid via IMemoryCache. - Services/Transformation/StructuralResolution/StructuralXmlCatalogCacheService.cs: cache do XmlLayoutCatalog (parse de XSD e caro), chave "structural-xml-catalog:{docType}:{targetGuid}", degrada para null (sem lancar) quando StructuralResolution:NfeSchemaPath nao configurado. - Services/Transformation/StructuralResolution/FieldMappingCompositionService.cs: crosswalk GUID/nome do Layout de origem, resolve sources (LinkMappingItem por GUID, MapperRule via StructuredRule.AllSources por nome), usa ParsedField.Occurrence fisico real (nunca sintetico) e compoe via FieldToXmlMappingComposer ja existente. - Controllers/TransformationExecutionController.cs: novo endpoint dedicado POST api/TransformationExecution/field-mappings — deliberadamente SEPARADO do contrato de execute-candidates (issue #141 decide se/como fieldMappings entra la). - Program.cs/appsettings.json: AddMemoryCache, secao StructuralResolution, registro dos 2 servicos novos (Singleton para o cache, Scoped para a composicao). - Testes de integracao (fixtures/XSD real da NF-e) validando o wiring ponta-a-ponta e a degradacao sem XSD configurado; ajuste de 2 testes existentes do controller (novos parametros do construtor). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ssue #140) 23 testes deterministicos cobrindo a matriz do design §6.1 (TXT/MQSeries/IDOC, grupo repetido/aninhado, atributo, concatenação, estático, condicional, função de transformação, loop dinâmico, N:1/1:N, namespace não-default, mismatch de repetição, função desconhecida). Documenta 2 gaps reais no composer (IsDeclaredEmpty/PositionalAlignmentFailed não chegam ao motor) e confirma que o critério authoritative/best-effort é conservador quando FunctionCatalog está indisponível. Validação comportamental contra o LowCodeRunner.exe real fica pendente (Windows-only, não roda neste ambiente) — registrado em .claude/agent-memory/lp-qa/issue140-resolucao-estrutural-qa-gate.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… é linha vazia/degradada Achado do @lp-qa (issue140-resolucao-estrutural-qa-gate.md, gap 2): LineInfo.IsDeclaredEmpty e LineInfo.PositionalAlignmentFailed (contrato de degradacao posicional de 2026-08-27) nao chegavam ao FieldMappingCompositionService, permitindo que um mapeamento vindo de linha vazia/degradada saisse Authoritative. Adiciona uma 6a condicao de pos-processamento (FieldMappingCompositionService. DegradeForUnhealthySourceLines) que so pode degradar Authoritative->BestEffort, nunca promover o contrario - sem reescrever o criterio objetivo ja existente em FieldToXmlMappingComposer. ParsingResult.LineInfos ja era populado internamente mas nao chegava ao composer; agora e passado via TransformationExecutionController -> FieldMappingCompositionService.Compose(..., lineInfos).
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
elson-vinicius-lopes
added a commit
that referenced
this pull request
Aug 28, 2026
…andidates-141 Reconcilia PR #207 (issue #141) com develop, que já absorveu as PRs irmãs #200 (issue #86), #201 (issue #139), #203 (issue #138) e #205 (issue #140) da mesma cadeia de trabalho. Conflitos eram todos overlap real entre PRs desta cadeia tocando os mesmos arquivos, não clash semântico: - LowCodeCandidateResult.cs: DecryptedMapperContent (#141) e MapperDecryptedContent (#138) eram o mesmo dado (mapper.DecryptedContent) sob nomes diferentes — unificado em DecryptedMapperContent, único campo, usado tanto por SysmiddleSectionMappingResolver (#138) quanto por TryComposeFieldMappings (#141). - LowCodeAutoTransformationService.cs: mesma duplicação de atribuição nos dois pontos de criação de LowCodeCandidateResult. - TransformationExecutionController.cs: TransformationCandidate agora preenche FieldMappings (#141) E SectionMappings/XmlNamespaces (#138) no mesmo objeto — funcionalidades complementares, ambas preservadas. - README.md: seções de documentação de fieldMappings (#141) e sectionMappings (#138) são independentes, mantidas as duas em sequência. - security-code-scan-baseline.json: entradas de linha para LowCodeAutoTransformationService.cs reconciliadas para 371/415 (linhas atuais pós-merge) — mesmos 2 achados de sempre (File.WriteAllTextAsync em inPath/metaPath), não vulnerabilidades novas. Nota adicionada ao _readme documentando o ajuste. dotnet build: 0 erros. dotnet test: 413/417 passando — as 4 falhas (SafePathResolverTests, LowCodeRunnerArgsTests) são pré-existentes, específicas de ambiente (assumem paths Windows, falham sob WSL/Linux), não relacionadas aos arquivos deste merge. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resumo
Implementa o motor de resolução estrutural TXT↔XML para NF-e (issue #140), permitindo
mapear campos de origem TXT/IDOC/MQSeries para o XPath correto no XML de destino usando
o XSD oficial da SEFAZ como fonte de verdade — em vez de heurísticas de regex/nome.
TargetElementGuid → XPathconstruído a partir do XSD SEFAZ NF-e (decisão dodono: escopo NF-e por ora, extensível por tipo de documento depois).
mappingKindsem regex — resolução estrutural via schema.para best-effort quando a origem TXT vem de linha vazia/degradada (
LineInfo).POST /api/TransformationExecution/field-mappings— não foiadicionado ao contrato de
execute-candidates(isso fica para a issue feature: adicionar fieldMappings opcional em execute-candidates, alimentado pelo parser de runtime #141).TargetLayoutGuid.Commits principais:
36ae5cb— motor de resolução estrutural TXT→XML NF-e9b2d0d0— wiring do motor ao pipeline real (@lp-backend-dev)110c998— matriz de 20 cenários sintéticos de teste (@lp-qa)1992ed4— fix: degradação para best-effort porLineInfoDesign:
docs/architecture/design-resolucao-estrutural-txt-xml-issue-140.mdQA gate:
.claude/agent-memory/lp-qa/issue140-resolucao-estrutural-qa-gate.mdO critério de aceite original da issue #140 previa validar 20 execuções reais contra o
LowCodeRunner(executável Windows-only, net481, interop nativo Sysmiddle). Issonão foi possível neste ambiente (WSL/Linux não roda o runner). Em substituição, foram
criados 20+ testes determinísticos contra fixtures sintéticas que validam a resolução
estrutural (catálogo XSD, classificação, ocorrência física, authoritative/best-effort) —
mas isso é uma aproximação, não a validação comportamental real.
Ação pendente: rodar a validação comportamental completa contra o
LowCodeRunnerrealem ambiente Windows — do dono do projeto ou de um agente com acesso a esse ambiente.
Test plan
dotnet build— 0 errosdotnet test— 461 passando, 4 falhas pré-existentes de path Windows×Linux (nãorelacionadas a esta mudança)
LowCodeRunner(Windows) — pendente, ver acimaCo-Authored-By: Claude Sonnet 5 noreply@anthropic.com