jonatanritter 44941b04e3 feat: golden corpus — DadosEmissao JSON -> canonical pre-signature XML
Adds golden_helpers (dados_from_json/serialize_infnfe, package modules so
the auto's parity test and the future service can import them directly) and
6 golden cases under src/sowai_fiscal/goldens/ as package data:

- caso_padrao_intra: preset Padrao, PR->PR, CSOSN 102/CFOP 5102, 2 itens
- caso_padrao_inter: PR->SP, CFOP 6102, idDest=2
- caso_st_intra: Oleos, CSOSN 500/CFOP 5405, grupo ICMSSN500 (vBCSTRet/pST/vICMSSTRet)
- caso_devolucao_intra: tipo_operacao devolucao, CFOP 1202
- caso_com_ub: FiscalResult com linhas ibs/cbs (grupo UB presente -- builder
  suporta estruturalmente mesmo com o guard de emissao do auto bloqueando hoje)
- caso_fracao_centavo: qty 1.5 x 0.01, 2 linhas -- prova o arredondamento
  por-item (soma_itens_quantizados) contra a soma bruta

Every input pins dh_emi/cnf/chave_acesso for determinism. serialize_infnfe
replicates the exact SerializerConfig(xml_declaration=False, indent=None) +
ns_map used by the auto's emissao.py::_serialize_nfe before signing.

scripts/gen_goldens.py regenerates the .expected.xml files; test_goldens.py
compares byte-for-byte (parametrized per case, readable first-divergent-byte
diff on failure). Verified the comparison has real detection power by
corrupting one expected file and confirming the test fails, then restored.

62 tests pass locally via `uv run pytest`.
2026-07-22 15:10:06 -03:00

sowai-fiscal

Núcleo fiscal puro da SowAI: motor de regras tributário (imposto-como-dado), chave de acesso de NF-e (módulo 11) e builder do XML NF-e 55 (leiaute NT 2025.002 v1.40, bindings nfelib 2.5.x). Extraído do produto sowai-auto (F1 do plano sowai-fiscal-svc) como lib versionada — zero I/O, zero SQLAlchemy, zero FastAPI, zero acoplamento a nenhum produto: a interface com o ORM do consumidor é o Protocol estrutural sowai_fiscal.types.TaxRuleLike.

Módulos

  • domains — catálogo TaxDomain/DOMAIN_FIELDS/MATCHER_WEIGHTS + transposição de CFOP intra→interestadual.
  • chave_acesso — DV módulo 11, sorteio de cNF, montagem da chave de 44 dígitos.
  • tpag — tabela de códigos tPag (MOC, grupo YA02).
  • presets — presets fiscais seed-editáveis (perfis reais extraídos do iCode da Thiago Auto Center).
  • resolverresolve_fiscal: FiscalOperation × regras (TaxRuleLike) → FiscalResult. Puro, determinístico, fail-closed.
  • xml_builderbuild_nfe: DadosEmissao (já resolvido) → objeto Nfe (bindings nfelib).
  • typesTaxRuleLike, o Protocol que desacopla o resolver do ORM do produto.
  • golden_helpersdados_from_json/serialize_infnfe, usados pelo corpus golden (goldens/) e pelo teste de paridade do produto consumidor.

Corpus golden

src/sowai_fiscal/goldens/caso_<nome>.{input.json,expected.xml} — pares determinísticos (dh_emi/cnf/chave_acesso pinados no input) que travam o leiaute XML pré-assinatura gerado a partir de um DadosEmissao. São dados de pacote (lidos via importlib.resources), para que o produto consumidor compare byte a byte contra os MESMOS arquivos da lib instalada — nenhuma cópia que possa divergir. Regenerar com uv run python scripts/gen_goldens.py apenas quando uma NT mudar o leiaute DE PROPÓSITO.

Testes

uv sync
uv run pytest

100% local — sem Postgres, sem k8s.

S
Description
Núcleo fiscal SowAI (lib pura): motor de regras imposto-como-dado, chave de acesso NF-e, builder XML NF-e 4.00/NT 2025.002 v1.40 + corpus golden. Extraída do sowai-auto (F1 do sowai-fiscal-svc).
Readme
100 KiB
Languages
Python 100%