docs: cross-check gate LayoutParserReact#200 / epic #368 vs estado atual - #412
Merged
Merged
Conversation
…ual da API 6 dos 8 itens originais ja estao implementados (workspaces/me, pacote fiscal, MappingDraft, contrato de saida TCL/XSL/XSLT, MappingExplanation, Test Lab diff+cobertura), 1 esta parcial (OpenAPI gerado mas sem contract-check em CI) e 1 revela gap pequeno nao previsto (capability como payload consultavel). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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
Sep 16, 2026
* feat(xml-analysis): endpoint de reconstrução reversa + validação contra TXT original (issue #151) (#407) * feat(xml-analysis): fecha issue #151 — endpoint de reconstrução reversa + validação contra TXT original ReverseReconstructionService (best-effort XML->TXT) já existia mas não estava plugado em nenhum controller/DI. Adiciona POST api/xml-analysis/reverse-reconstruct, que recebe LayoutXml + o crosswalk FieldToXmlMapping[] já resolvido + TargetXml, e devolve o TXT reconstruído. Fecha o gap real da issue (item 3 do critério de aceite): quando OriginalTxt é informado, ReverseReconstructionValidator compara campo a campo o valor escrito (via XML) contra o valor real parseado do TXT original (mesmo ILayoutParserService do pathway direto) — sem ele, a resposta não finge validação nenhuma. ReconstructionResult ganha ReconstructedFields (issue #151) para dar a granularidade por campo que a validação precisa, sem reparsear ReconstructedText. Layout com WithBreakLines=false (MQSeries/IDOC) vira scopeWarning, não erro — mantém o escopo MVP já declarado no serviço. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * chore(security): baseline do SCS0003 no reverse-reconstruct (issue #151) O gate de CI (Security Code Scan - gate por severidade) bloqueou o PR #407 por um achado novo: SCS0003 (XPath injection) em Services/XmlAnalysis/ReverseReconstructionService.cs:158 (navigator.SelectSingleNode(target.Xpath)). target.Xpath vem do corpo do POST api/xml-analysis/reverse-reconstruct, mas tanto ele quanto o TargetXml contra o qual roda vem da MESMA request do MESMO chamador autenticado - sem cenario de vazamento cross-documento. E leitura pura, ja dentro de try/catch(XPathException). Aceito conscientemente como debito de baixo risco, documentado no proprio finding. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(ai): preferências de usuário além do prompt customizado (issue #322) (#409) * feat(ai): preferências de usuário além do prompt customizado (issue #322) Adiciona idioma de exibição, nível de detalhe da explicação e engine padrão (TCL/XSLT) como preferências persistentes em tbLpAiUserSession (colunas novas via ALTER idempotente), com upsert parcial (SetPreferencesAsync) e leitura com defaults (GetPreferencesAsync). Endpoint dedicado PUT/GET api/transformation/ ai-preferences, [Authorize] + fail-closed 404 sem identidade, 422 para engine/ nível de detalhe fora dos valores aceitos. O prompt customizado (ai-prompt-adicional, issue #98) continua no AiUserInstructionStore em memória — não migrado para o SQL nesta issue, só exposto junto na leitura de GetAiPreferences para consulta única. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(memory): registra decisão dos dois stores de sessão de IA (issue #322) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * docs(architecture): cross-check gate React#200/epic #368 vs estado atual da API (#412) 6 dos 8 itens originais ja estao implementados (workspaces/me, pacote fiscal, MappingDraft, contrato de saida TCL/XSL/XSLT, MappingExplanation, Test Lab diff+cobertura), 1 esta parcial (OpenAPI gerado mas sem contract-check em CI) e 1 revela gap pequeno nao previsto (capability como payload consultavel). Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * docs: fechar gate React#200/epic #368 — documentar 6 contratos já implementados (issue #413) (#419) Cross-check de 2026-09-15 confirmou que 6 dos 8 itens da tabela original do gate #200 já estão implementados sem código novo: GET /api/workspaces/me, pacote fiscal versionado, MappingDraft (FiscalProfile, editor manual de artefato, filtros de release, arquivamento), contrato de saída TCL/XSL/XSLT (hash/status/imutabilidade), MappingExplanation e o Fiscal Test Lab (diff por regra, diff release×release, cobertura de obrigatórios). Documenta o gap real que sobra (capability Sysmiddle como payload consultável, issue #415) sem tratá-lo como resolvido. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(mapping-drafts): endpoint de listagem por workspace (issue #416) (#420) Front reportou gap: Mapping Studio exigia digitar o GUID do draft manualmente, sem forma de descobrir/listar. Adiciona GET .../mapping-drafts espelhando o padrão de descoberta já usado em mapping-releases (issue #377): paginação, RBAC de leitura (qualquer papel de membro) e filtro opcional por engine. Draft não tem "status" próprio (só as regras têm), então não há filtro de status neste endpoint. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
elson-vinicius-lopes
added a commit
that referenced
this pull request
Sep 16, 2026
* feat(xml-analysis): endpoint de reconstrução reversa + validação contra TXT original (issue #151) (#407) * feat(xml-analysis): fecha issue #151 — endpoint de reconstrução reversa + validação contra TXT original ReverseReconstructionService (best-effort XML->TXT) já existia mas não estava plugado em nenhum controller/DI. Adiciona POST api/xml-analysis/reverse-reconstruct, que recebe LayoutXml + o crosswalk FieldToXmlMapping[] já resolvido + TargetXml, e devolve o TXT reconstruído. Fecha o gap real da issue (item 3 do critério de aceite): quando OriginalTxt é informado, ReverseReconstructionValidator compara campo a campo o valor escrito (via XML) contra o valor real parseado do TXT original (mesmo ILayoutParserService do pathway direto) — sem ele, a resposta não finge validação nenhuma. ReconstructionResult ganha ReconstructedFields (issue #151) para dar a granularidade por campo que a validação precisa, sem reparsear ReconstructedText. Layout com WithBreakLines=false (MQSeries/IDOC) vira scopeWarning, não erro — mantém o escopo MVP já declarado no serviço. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * chore(security): baseline do SCS0003 no reverse-reconstruct (issue #151) O gate de CI (Security Code Scan - gate por severidade) bloqueou o PR #407 por um achado novo: SCS0003 (XPath injection) em Services/XmlAnalysis/ReverseReconstructionService.cs:158 (navigator.SelectSingleNode(target.Xpath)). target.Xpath vem do corpo do POST api/xml-analysis/reverse-reconstruct, mas tanto ele quanto o TargetXml contra o qual roda vem da MESMA request do MESMO chamador autenticado - sem cenario de vazamento cross-documento. E leitura pura, ja dentro de try/catch(XPathException). Aceito conscientemente como debito de baixo risco, documentado no proprio finding. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(ai): preferências de usuário além do prompt customizado (issue #322) (#409) * feat(ai): preferências de usuário além do prompt customizado (issue #322) Adiciona idioma de exibição, nível de detalhe da explicação e engine padrão (TCL/XSLT) como preferências persistentes em tbLpAiUserSession (colunas novas via ALTER idempotente), com upsert parcial (SetPreferencesAsync) e leitura com defaults (GetPreferencesAsync). Endpoint dedicado PUT/GET api/transformation/ ai-preferences, [Authorize] + fail-closed 404 sem identidade, 422 para engine/ nível de detalhe fora dos valores aceitos. O prompt customizado (ai-prompt-adicional, issue #98) continua no AiUserInstructionStore em memória — não migrado para o SQL nesta issue, só exposto junto na leitura de GetAiPreferences para consulta única. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(memory): registra decisão dos dois stores de sessão de IA (issue #322) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * docs(architecture): cross-check gate React#200/epic #368 vs estado atual da API (#412) 6 dos 8 itens originais ja estao implementados (workspaces/me, pacote fiscal, MappingDraft, contrato de saida TCL/XSL/XSLT, MappingExplanation, Test Lab diff+cobertura), 1 esta parcial (OpenAPI gerado mas sem contract-check em CI) e 1 revela gap pequeno nao previsto (capability como payload consultavel). Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * docs: fechar gate React#200/epic #368 — documentar 6 contratos já implementados (issue #413) (#419) Cross-check de 2026-09-15 confirmou que 6 dos 8 itens da tabela original do gate #200 já estão implementados sem código novo: GET /api/workspaces/me, pacote fiscal versionado, MappingDraft (FiscalProfile, editor manual de artefato, filtros de release, arquivamento), contrato de saída TCL/XSL/XSLT (hash/status/imutabilidade), MappingExplanation e o Fiscal Test Lab (diff por regra, diff release×release, cobertura de obrigatórios). Documenta o gap real que sobra (capability Sysmiddle como payload consultável, issue #415) sem tratá-lo como resolvido. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(mapping-drafts): endpoint de listagem por workspace (issue #416) (#420) Front reportou gap: Mapping Studio exigia digitar o GUID do draft manualmente, sem forma de descobrir/listar. Adiciona GET .../mapping-drafts espelhando o padrão de descoberta já usado em mapping-releases (issue #377): paginação, RBAC de leitura (qualquer papel de membro) e filtro opcional por engine. Draft não tem "status" próprio (só as regras têm), então não há filtro de status neste endpoint. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * fix(deploy): portar migracao NSSM -> servico nativo para producao (#426) deploy.yml nunca teve a logica de deteccao/migracao do servico legado NSSM (C:\Users\Administrator\Downloads\nssm-2.24) que o ci-dev.yml ja usa a cada deploy de dev - producao so fazia Stop-Service/Start-Service genericos, sem checar o ImagePath do registro nem recriar como servico Windows nativo (Program.cs usa UseWindowsService() ha tempo). Porta a mesma logica do ci-dev.yml: no stop, checa se o ImagePath contem "nssm" e, se sim, remove o registro (sc.exe delete); no restart, recria o servico nativo (sc.exe create/description/failure) caso ele nao exista - cobrindo tanto a migracao quanto o primeiro deploy num host novo. Como sc.exe delete apaga a chave Environment que o step "Configurar ambiente do servico" ja tinha escrito antes nesse mesmo registro NSSM, captura o Environment antes do delete e restaura apos criar o servico nativo, para nao perder Database__Password/ IdentityDatabase__*/etc. na primeira subida. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(fiscal): endpoint de arvore de layout dupla origem/destino (issue #425) (#427) Implementa GET /api/workspaces/{workspaceId}/mappings/{mappingId}/layout-tree conforme o ADR "adr-layout-tree-endpoint-425": generaliza GuidXPathCatalog (ai/XslSynth.Contracts) com extracao de cardinalidade (MinimalOccurrence/ MaximumOccurrence) e um novo BuildTree recursivo (achatando wrappers Choice/ Sequence como irmaos, mesma convencao do XPath ja existente), troca a fonte de arquivo local por lookup via ICachedLayoutService/ICachedMapperService ja registrados em producao, e expoe o contrato source/target/rules para o React replicar a UI de dupla-arvore do Connect Us. Regras[] reaproveitam apenas LinkMappingItemVO (unico ponto do MapperVO real onde origem e destino sao GUIDs de no, nao path de DSL) - decisao explicita do ADR pra nao inventar GUID de origem para as regras DSL (MapperRule). Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
elson-vinicius-lopes
added a commit
that referenced
this pull request
Sep 16, 2026
* feat(xml-analysis): endpoint de reconstrução reversa + validação contra TXT original (issue #151) (#407) * feat(xml-analysis): fecha issue #151 — endpoint de reconstrução reversa + validação contra TXT original ReverseReconstructionService (best-effort XML->TXT) já existia mas não estava plugado em nenhum controller/DI. Adiciona POST api/xml-analysis/reverse-reconstruct, que recebe LayoutXml + o crosswalk FieldToXmlMapping[] já resolvido + TargetXml, e devolve o TXT reconstruído. Fecha o gap real da issue (item 3 do critério de aceite): quando OriginalTxt é informado, ReverseReconstructionValidator compara campo a campo o valor escrito (via XML) contra o valor real parseado do TXT original (mesmo ILayoutParserService do pathway direto) — sem ele, a resposta não finge validação nenhuma. ReconstructionResult ganha ReconstructedFields (issue #151) para dar a granularidade por campo que a validação precisa, sem reparsear ReconstructedText. Layout com WithBreakLines=false (MQSeries/IDOC) vira scopeWarning, não erro — mantém o escopo MVP já declarado no serviço. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * chore(security): baseline do SCS0003 no reverse-reconstruct (issue #151) O gate de CI (Security Code Scan - gate por severidade) bloqueou o PR #407 por um achado novo: SCS0003 (XPath injection) em Services/XmlAnalysis/ReverseReconstructionService.cs:158 (navigator.SelectSingleNode(target.Xpath)). target.Xpath vem do corpo do POST api/xml-analysis/reverse-reconstruct, mas tanto ele quanto o TargetXml contra o qual roda vem da MESMA request do MESMO chamador autenticado - sem cenario de vazamento cross-documento. E leitura pura, ja dentro de try/catch(XPathException). Aceito conscientemente como debito de baixo risco, documentado no proprio finding. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(ai): preferências de usuário além do prompt customizado (issue #322) (#409) * feat(ai): preferências de usuário além do prompt customizado (issue #322) Adiciona idioma de exibição, nível de detalhe da explicação e engine padrão (TCL/XSLT) como preferências persistentes em tbLpAiUserSession (colunas novas via ALTER idempotente), com upsert parcial (SetPreferencesAsync) e leitura com defaults (GetPreferencesAsync). Endpoint dedicado PUT/GET api/transformation/ ai-preferences, [Authorize] + fail-closed 404 sem identidade, 422 para engine/ nível de detalhe fora dos valores aceitos. O prompt customizado (ai-prompt-adicional, issue #98) continua no AiUserInstructionStore em memória — não migrado para o SQL nesta issue, só exposto junto na leitura de GetAiPreferences para consulta única. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(memory): registra decisão dos dois stores de sessão de IA (issue #322) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * docs(architecture): cross-check gate React#200/epic #368 vs estado atual da API (#412) 6 dos 8 itens originais ja estao implementados (workspaces/me, pacote fiscal, MappingDraft, contrato de saida TCL/XSL/XSLT, MappingExplanation, Test Lab diff+cobertura), 1 esta parcial (OpenAPI gerado mas sem contract-check em CI) e 1 revela gap pequeno nao previsto (capability como payload consultavel). Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * docs: fechar gate React#200/epic #368 — documentar 6 contratos já implementados (issue #413) (#419) Cross-check de 2026-09-15 confirmou que 6 dos 8 itens da tabela original do gate #200 já estão implementados sem código novo: GET /api/workspaces/me, pacote fiscal versionado, MappingDraft (FiscalProfile, editor manual de artefato, filtros de release, arquivamento), contrato de saída TCL/XSL/XSLT (hash/status/imutabilidade), MappingExplanation e o Fiscal Test Lab (diff por regra, diff release×release, cobertura de obrigatórios). Documenta o gap real que sobra (capability Sysmiddle como payload consultável, issue #415) sem tratá-lo como resolvido. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(mapping-drafts): endpoint de listagem por workspace (issue #416) (#420) Front reportou gap: Mapping Studio exigia digitar o GUID do draft manualmente, sem forma de descobrir/listar. Adiciona GET .../mapping-drafts espelhando o padrão de descoberta já usado em mapping-releases (issue #377): paginação, RBAC de leitura (qualquer papel de membro) e filtro opcional por engine. Draft não tem "status" próprio (só as regras têm), então não há filtro de status neste endpoint. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * fix(deploy): portar migracao NSSM -> servico nativo para producao (#426) deploy.yml nunca teve a logica de deteccao/migracao do servico legado NSSM (C:\Users\Administrator\Downloads\nssm-2.24) que o ci-dev.yml ja usa a cada deploy de dev - producao so fazia Stop-Service/Start-Service genericos, sem checar o ImagePath do registro nem recriar como servico Windows nativo (Program.cs usa UseWindowsService() ha tempo). Porta a mesma logica do ci-dev.yml: no stop, checa se o ImagePath contem "nssm" e, se sim, remove o registro (sc.exe delete); no restart, recria o servico nativo (sc.exe create/description/failure) caso ele nao exista - cobrindo tanto a migracao quanto o primeiro deploy num host novo. Como sc.exe delete apaga a chave Environment que o step "Configurar ambiente do servico" ja tinha escrito antes nesse mesmo registro NSSM, captura o Environment antes do delete e restaura apos criar o servico nativo, para nao perder Database__Password/ IdentityDatabase__*/etc. na primeira subida. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(fiscal): endpoint de arvore de layout dupla origem/destino (issue #425) (#427) Implementa GET /api/workspaces/{workspaceId}/mappings/{mappingId}/layout-tree conforme o ADR "adr-layout-tree-endpoint-425": generaliza GuidXPathCatalog (ai/XslSynth.Contracts) com extracao de cardinalidade (MinimalOccurrence/ MaximumOccurrence) e um novo BuildTree recursivo (achatando wrappers Choice/ Sequence como irmaos, mesma convencao do XPath ja existente), troca a fonte de arquivo local por lookup via ICachedLayoutService/ICachedMapperService ja registrados em producao, e expoe o contrato source/target/rules para o React replicar a UI de dupla-arvore do Connect Us. Regras[] reaproveitam apenas LinkMappingItemVO (unico ponto do MapperVO real onde origem e destino sao GUIDs de no, nao path de DSL) - decisao explicita do ADR pra nao inventar GUID de origem para as regras DSL (MapperRule). Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * fix(fiscal): alinhar identidade de nó entre layout-tree e explanation (#430) (#431) * fix(fiscal): alinhar identidade de nó entre layout-tree e explanation (#430) Problema 1: SysmiddleExplanationAdapter.ToExplainedRule priorizava TargetLeafName (nome legível) sobre TargetGuid em SourceRefs/TargetRefs, enquanto LayoutTreeService.ResolveRules sempre usa InputGuid/TargetGuid — o cruzamento regra<->nó no front quebrava quando TargetLeafName estava preenchido. Agora ambos usam sempre InputGuid/TargetGuid; o nome legível continua disponível via HumanDescription. Problema 2: regras DSL (MapperRule/branches condicionais) aparecem em explanation.rules com sourceRefs/targetRefs prefixados I./T. (texto da DSL, não GUID de nó), mas nunca entravam em layout-tree.rules[] - LayoutTreeService.ResolveRules já documentava essa decisão ("inventar um GUID aqui violaria nunca inventa"). Optei por (b): documentar explicitamente via novo campo LayoutTreeResponse.Limitations, populado quando o mapper tem regras DSL, em vez de (a) resolver os prefixos pra GUID - o catálogo GuidXPathCatalog resolve por GUID, não por nome de campo, e reconstruir esse contexto está fora do escopo desta issue. Testes cobrindo os dois casos em MappingExplanationAdaptersTests e LayoutTreeServiceTests; ajustado LayoutTreeControllerTests pro novo parâmetro posicional. * docs: documentar GET .../layout-tree e divergência de cobertura das rules (#425/#430) Adiciona §8.3 bilíngue ao README com exemplo de request/response e nota explícita sobre limitations[]: rules[] do layout-tree cobre só vínculo direto campo->campo, diferente de explanation.rules[] que inclui regras condicionais/DSL. XML docs em LayoutTree.cs e LayoutTreeController.cs já estavam completos, sem alteração necessária. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
elson-vinicius-lopes
added a commit
that referenced
this pull request
Sep 17, 2026
* feat(xml-analysis): endpoint de reconstrução reversa + validação contra TXT original (issue #151) (#407) * feat(xml-analysis): fecha issue #151 — endpoint de reconstrução reversa + validação contra TXT original ReverseReconstructionService (best-effort XML->TXT) já existia mas não estava plugado em nenhum controller/DI. Adiciona POST api/xml-analysis/reverse-reconstruct, que recebe LayoutXml + o crosswalk FieldToXmlMapping[] já resolvido + TargetXml, e devolve o TXT reconstruído. Fecha o gap real da issue (item 3 do critério de aceite): quando OriginalTxt é informado, ReverseReconstructionValidator compara campo a campo o valor escrito (via XML) contra o valor real parseado do TXT original (mesmo ILayoutParserService do pathway direto) — sem ele, a resposta não finge validação nenhuma. ReconstructionResult ganha ReconstructedFields (issue #151) para dar a granularidade por campo que a validação precisa, sem reparsear ReconstructedText. Layout com WithBreakLines=false (MQSeries/IDOC) vira scopeWarning, não erro — mantém o escopo MVP já declarado no serviço. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * chore(security): baseline do SCS0003 no reverse-reconstruct (issue #151) O gate de CI (Security Code Scan - gate por severidade) bloqueou o PR #407 por um achado novo: SCS0003 (XPath injection) em Services/XmlAnalysis/ReverseReconstructionService.cs:158 (navigator.SelectSingleNode(target.Xpath)). target.Xpath vem do corpo do POST api/xml-analysis/reverse-reconstruct, mas tanto ele quanto o TargetXml contra o qual roda vem da MESMA request do MESMO chamador autenticado - sem cenario de vazamento cross-documento. E leitura pura, ja dentro de try/catch(XPathException). Aceito conscientemente como debito de baixo risco, documentado no proprio finding. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(ai): preferências de usuário além do prompt customizado (issue #322) (#409) * feat(ai): preferências de usuário além do prompt customizado (issue #322) Adiciona idioma de exibição, nível de detalhe da explicação e engine padrão (TCL/XSLT) como preferências persistentes em tbLpAiUserSession (colunas novas via ALTER idempotente), com upsert parcial (SetPreferencesAsync) e leitura com defaults (GetPreferencesAsync). Endpoint dedicado PUT/GET api/transformation/ ai-preferences, [Authorize] + fail-closed 404 sem identidade, 422 para engine/ nível de detalhe fora dos valores aceitos. O prompt customizado (ai-prompt-adicional, issue #98) continua no AiUserInstructionStore em memória — não migrado para o SQL nesta issue, só exposto junto na leitura de GetAiPreferences para consulta única. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(memory): registra decisão dos dois stores de sessão de IA (issue #322) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * docs(architecture): cross-check gate React#200/epic #368 vs estado atual da API (#412) 6 dos 8 itens originais ja estao implementados (workspaces/me, pacote fiscal, MappingDraft, contrato de saida TCL/XSL/XSLT, MappingExplanation, Test Lab diff+cobertura), 1 esta parcial (OpenAPI gerado mas sem contract-check em CI) e 1 revela gap pequeno nao previsto (capability como payload consultavel). Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * docs: fechar gate React#200/epic #368 — documentar 6 contratos já implementados (issue #413) (#419) Cross-check de 2026-09-15 confirmou que 6 dos 8 itens da tabela original do gate #200 já estão implementados sem código novo: GET /api/workspaces/me, pacote fiscal versionado, MappingDraft (FiscalProfile, editor manual de artefato, filtros de release, arquivamento), contrato de saída TCL/XSL/XSLT (hash/status/imutabilidade), MappingExplanation e o Fiscal Test Lab (diff por regra, diff release×release, cobertura de obrigatórios). Documenta o gap real que sobra (capability Sysmiddle como payload consultável, issue #415) sem tratá-lo como resolvido. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(mapping-drafts): endpoint de listagem por workspace (issue #416) (#420) Front reportou gap: Mapping Studio exigia digitar o GUID do draft manualmente, sem forma de descobrir/listar. Adiciona GET .../mapping-drafts espelhando o padrão de descoberta já usado em mapping-releases (issue #377): paginação, RBAC de leitura (qualquer papel de membro) e filtro opcional por engine. Draft não tem "status" próprio (só as regras têm), então não há filtro de status neste endpoint. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * fix(deploy): portar migracao NSSM -> servico nativo para producao (#426) deploy.yml nunca teve a logica de deteccao/migracao do servico legado NSSM (C:\Users\Administrator\Downloads\nssm-2.24) que o ci-dev.yml ja usa a cada deploy de dev - producao so fazia Stop-Service/Start-Service genericos, sem checar o ImagePath do registro nem recriar como servico Windows nativo (Program.cs usa UseWindowsService() ha tempo). Porta a mesma logica do ci-dev.yml: no stop, checa se o ImagePath contem "nssm" e, se sim, remove o registro (sc.exe delete); no restart, recria o servico nativo (sc.exe create/description/failure) caso ele nao exista - cobrindo tanto a migracao quanto o primeiro deploy num host novo. Como sc.exe delete apaga a chave Environment que o step "Configurar ambiente do servico" ja tinha escrito antes nesse mesmo registro NSSM, captura o Environment antes do delete e restaura apos criar o servico nativo, para nao perder Database__Password/ IdentityDatabase__*/etc. na primeira subida. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(fiscal): endpoint de arvore de layout dupla origem/destino (issue #425) (#427) Implementa GET /api/workspaces/{workspaceId}/mappings/{mappingId}/layout-tree conforme o ADR "adr-layout-tree-endpoint-425": generaliza GuidXPathCatalog (ai/XslSynth.Contracts) com extracao de cardinalidade (MinimalOccurrence/ MaximumOccurrence) e um novo BuildTree recursivo (achatando wrappers Choice/ Sequence como irmaos, mesma convencao do XPath ja existente), troca a fonte de arquivo local por lookup via ICachedLayoutService/ICachedMapperService ja registrados em producao, e expoe o contrato source/target/rules para o React replicar a UI de dupla-arvore do Connect Us. Regras[] reaproveitam apenas LinkMappingItemVO (unico ponto do MapperVO real onde origem e destino sao GUIDs de no, nao path de DSL) - decisao explicita do ADR pra nao inventar GUID de origem para as regras DSL (MapperRule). Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * fix(fiscal): alinhar identidade de nó entre layout-tree e explanation (#430) (#431) * fix(fiscal): alinhar identidade de nó entre layout-tree e explanation (#430) Problema 1: SysmiddleExplanationAdapter.ToExplainedRule priorizava TargetLeafName (nome legível) sobre TargetGuid em SourceRefs/TargetRefs, enquanto LayoutTreeService.ResolveRules sempre usa InputGuid/TargetGuid — o cruzamento regra<->nó no front quebrava quando TargetLeafName estava preenchido. Agora ambos usam sempre InputGuid/TargetGuid; o nome legível continua disponível via HumanDescription. Problema 2: regras DSL (MapperRule/branches condicionais) aparecem em explanation.rules com sourceRefs/targetRefs prefixados I./T. (texto da DSL, não GUID de nó), mas nunca entravam em layout-tree.rules[] - LayoutTreeService.ResolveRules já documentava essa decisão ("inventar um GUID aqui violaria nunca inventa"). Optei por (b): documentar explicitamente via novo campo LayoutTreeResponse.Limitations, populado quando o mapper tem regras DSL, em vez de (a) resolver os prefixos pra GUID - o catálogo GuidXPathCatalog resolve por GUID, não por nome de campo, e reconstruir esse contexto está fora do escopo desta issue. Testes cobrindo os dois casos em MappingExplanationAdaptersTests e LayoutTreeServiceTests; ajustado LayoutTreeControllerTests pro novo parâmetro posicional. * docs: documentar GET .../layout-tree e divergência de cobertura das rules (#425/#430) Adiciona §8.3 bilíngue ao README com exemplo de request/response e nota explícita sobre limitations[]: rules[] do layout-tree cobre só vínculo direto campo->campo, diferente de explanation.rules[] que inclui regras condicionais/DSL. XML docs em LayoutTree.cs e LayoutTreeController.cs já estavam completos, sem alteração necessária. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * fix(learning): corrigir split de linha MQSeries no aprendizado de layout (#434) MQSeries e um stream continuo de largura fixa (600 chars) sem terminador de linha entre "linhas" logicas. LayoutLearningService fazia content.Split('\r','\n') incondicionalmente, tratando o arquivo inteiro como 1 unica linha gigante -> TotalFields=0 (13 dos 14 mapeadores .mq_series em Examples/ afetados; evidencia real em LAY_TXT_MQSERIES_ENVNFE_4.00_NFe/layout_learned.json, LineLength 35400 para um arquivo de 59 linhas de 600 chars). Correcoes: - ParseController: nao colapsa mais "mqseries" em "txt" ao chamar LearnFromFileAsync, preservando a distincao de formato. - LayoutLearningService: para fileType="mqseries", usa o mesmo ILineSplitter/PositionalFormat.ContinuousStream do parse real em vez de split por \r\n, garantindo que aprendizado e parse concordem sobre onde as linhas comecam/terminam. - Corrigido tambem um segundo bug exposto pelo primeiro: o agrupamento de linhas por prefixo literal (DetectLinePatterns) nunca junta 3+ linhas MQSeries porque cada linha comeca com um contador sequencial de 9 digitos unico por linha (nao um prefixo textual repetido como "LINHA001") -- mesmo com o split fisico correto, isso ainda dava TotalFields=0. Agrupamento dedicado (DetectContinuousStreamGroups) separa HEADER do restante. Validado contra 4 arquivos .mq_series reais de clientes diferentes (LAY_TXT_MQSERIES_ENVNFE_4.00_NFe, LAY_CNHI_..., LAY_IVECCO_..., LAY_TXT_COMAU_...): TotalFields foi de 0 para 8/8/8/10 e TotalLines passou a bater com tamanho_arquivo/600 em vez de sempre 1. Testes novos: LayoutLearningServiceMqSeriesTests (fixture sintetico de 600 chars/linha sem terminador, cobrindo split fisico, aprendizado de campos reais, e regressao negativa de IDOC/record-per-line). * Feat/xslt generation loop corpus neogrid (#435) * feat(ai): primeira rodada real do loop RAG->XSLT no corpus Neogrid (caso InutNFe) Reusa o loop ja existente em ai/XslSynth (DatasetFewShotIndex + metrics-batch, RAG->Ollama->validacao) sobre 159 pares reais tcl/xsl indexados do corpus Examples/{tcl,xsl}, avaliando o par NFe006c_InutNFe_NeoGridToSefaz com o modelo fine-tuned layoutparser-sysmiddle-dsl:1.5b. Resultado real (nao simulado): 10/11 campos de <infInut> saem byte-a-byte identicos ao XSLT de producao (Id/tpAmb/xServ/cUF/ano/CNPJ/mod/serie/ nNFIni/nNFFin); xJust diverge (regra de negocio de prefixo+truncamento nao inferivel do TCL); falta o wrapper estrutural (xsl:template, root inutNFe+namespace+versao). appsettings.Development.json ganha RAG:ExamplesPath/XsdValidation:BasePath apontando pro corpus local de sessao (.claude/temp/, gitignored). Persistencia via SqlMappingReleaseStore (padrao dbo.tbMappingRelease) NAO implementada nesta rodada: sem credencial IdentityDatabase nesta sessao para validar contra o schema real - documentado como bloqueio, nao simulado. Detalhe completo na memoria do agente. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(memory): registrar validação real da persistência experimental RAG->XSLT Round-trip real (INSERT+SELECT) via SqlMappingReleaseStore contra o IdentityDatabase confirmado com credencial de dotnet user-secrets: ReleaseId 1d612a3c-8b30-4fcb-9fdf-dad1b085608b criado e relido com conteúdo/hash idênticos. O teste de integração usado para validar foi removido antes do commit (ci-dev.yml não injeta IdentityDatabase:* no step de dotnet test, então o teste quebraria o gate de qualquer PR em vez de fazer skip gracioso) — resultado documentado na memória do agente para não se perder. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> * feat(fiscal): catalogo de exemplos de referencia TCL/XSL da Neogrid (#437) Endpoint GET /api/reference-examples (+ /{id} para conteudo) expondo o corpus real de transformacoes da Neogrid como material de referencia/ oraculo, deliberadamente fora do dominio MappingDraft/MappingRelease (sem workspaceId, sem ArtifactSource) para nao misturar exemplo estatico com governanca de release real. ReferenceExampleCatalogService le disco via ReferenceExamples:BasePath (configuravel, sem hardcode de path local), pareando arquivos .tcl/.xsl por DocType/Versao/nome-base; degrada para lista vazia se o path nao existir. Registrado em Program.cs no grupo Fiscal. Testes cobrem: listagem com fixture sintetica (par completo, tcl sem par, filtro por docType), leitura de conteudo por id, e degradacao graciosa com BasePath vazio/inexistente. Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> --------- 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.
Issue #368 — cruzamento linha a linha dos 8 itens do gate #200 contra o estado atual de `develop`. Só documentação.
Resultado
6 dos 8 itens já estavam implementados (muita coisa avançou desde agosto: #379/#380/#381/#367 fecharam a maior parte de MappingDraft/TCL-XSLT/Test Lab; `workspaces/me` confirmado no incidente do login).
Sub-issues propostas
🤖 Generated with Claude Code