feat: extract pure fiscal core from sowai-auto (parity-preserving copy)
Copies the 6 pure fiscal modules (domains, chave_acesso, tpag, presets, resolver, xml_builder) from sowai-auto's backend/app/modules/fiscal/ into this standalone lib, with only the two mechanical changes required to drop the app.* dependency: import prefix rename, and TaxRule (ORM) -> TaxRuleLike (structural Protocol) in the resolver. No other line changes -- byte-level parity with the auto is the point. Ports the pure test suites (domains, chave_acesso, resolver with a local FakeTaxRule satisfying TaxRuleLike, xml_builder) plus a new test_presets_data covering the PRESETS dict directly (the auto's equivalent test exercises the apply-preset HTTP/DB flow, which isn't part of the extracted pure core). 55 tests pass locally via `uv run pytest`, no Postgres/k8s required.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
# 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).
|
||||
- `resolver` — `resolve_fiscal`: `FiscalOperation` × regras (`TaxRuleLike`)
|
||||
→ `FiscalResult`. Puro, determinístico, fail-closed.
|
||||
- `xml_builder` — `build_nfe`: `DadosEmissao` (já resolvido) → objeto `Nfe`
|
||||
(bindings `nfelib`).
|
||||
- `types` — `TaxRuleLike`, o `Protocol` que desacopla o resolver do ORM do
|
||||
produto.
|
||||
- `golden_helpers` — `dados_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
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
100% local — sem Postgres, sem k8s.
|
||||
Reference in New Issue
Block a user