Files
sowai-fiscal/README.md
T

2.9 KiB
Raw Blame History

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.

Versionamento (contrato)

  • SemVer estrito. Os nomes públicos (resolve_fiscal, build_nfe, montar_chave_acesso, TaxDomain, DOMAIN_FIELDS, MATCHER_WEIGHTS, PRESETS, TPAG_CODES, DadosEmissao e sub-dataclasses, FiscalOperation/FiscalItem/ FiscalResult/TributoLinha, exceções) são O CONTRATO — mudança incompatível = major.
  • Consumidores pinam por TAG, nunca por branch: uv add "sowai-fiscal @ git+https://git.sowai.com.br/jonatan/sowai-fiscal.git@vX.Y.Z" (o lock pina o hash).
  • Goldens mudam SÓ quando uma NT muda o leiaute de propósito (ver seção acima) — e isso é sempre pelo menos um minor, com nota de release explicando a NT.

Gap conhecido (registrado na F1, 2026-07-17)

  • Grupo ANP (gProdANP) não é emitidoItemData/builder não têm o campo. NF-e de óleo lubrificante SEM esse grupo é REJEITADA pela SEFAZ. Fechar na cobertura R1 (junto do cClassTrib) ANTES de homologar o caso Óleos na F4. O golden caso_st_intra cobre ICMS-ST/CSOSN 500, NÃO cobre ANP.