Release v5.2.0 — paginação de companies corrigida (1-based) + listV2 (API v2, cursor)#42
Merged
Conversation
O glob '**/*.test.ts' atravessava os symlinks client-php/client-ruby (que apontam de volta para este repo), coletando a mesma suíte 5x (210 arquivos/ 3710 testes aparentes vs 42/698 reais) e causando flakes por corrida no .test-temp compartilhado do generation.test.ts.
…documentada Contratos provados por sonda ao vivo (2026-07-13/14, duas contas): - listAll()/listIterator() falhavam na 1ª chamada por dois motivos independentes: iniciavam em pageIndex=0 (a API rejeita: 1-based) e pediam pageCount=100 (a API aceita 2-50; rejeita 1 apesar da mensagem 'between 1 and 50'). Corrigidos (início em 1, AUTO_PAGINATION_PAGE_SIZE=50) — conserta transitivamente findByTaxNumber, findByName, getCompaniesWithCertificates e getCompaniesWithExpiringCertificates. Provado: 352 empresas / 8 páginas. - list() deixou de subtrair 1 da resposta: convenção 1-based nos dois lados (nota de migração no CHANGELOG). - JSDoc de update() era enganoso: dizia 'only fields to update', mas a API faz PUT (substituição total) — risco de zerar campos. Documentado com exemplo read-modify-write; create() documenta os obrigatórios reais. - Specs: minimum:1 no pageIndex e maximum:50 no pageCount de /v1/companies. - Testes: mock espelha as validações reais da API; alignment test pina os corpos de escrita (Create/Update iguais = evidência PUT, sem email). - Docs/skills: exemplos 0-based corrigidos em API.md, README e na skill nfeio-node-sdk (que também afirmava shape errado para taxCodes).
A API v1 de companies (api.nfe.io/v1/companies) está sendo descontinuada;
o substituto é a contribuintes-v2 (api.nfse.io/v2/companies), cursor-based.
- listV2({ limit, startingAfter, endingBefore }) -> { data, hasMore }, via o
client v2 já injetado. Contrato provado ao vivo (2026-07-14): limit 1-50
(default 10), >50 rejeitado; limit=0 devolveria página vazia silenciosa e
é rejeitado client-side. Itens seguem a projeção v2 (CompanyResourceItem),
shape distinto do Company v1. Tipos: CompanyV2ListOptions/Response.
- list() v1 marcado @deprecated apontando para listV2/listAll/listIterator;
segue funcional durante a convivência.
- listAll()/listIterator() permanecem no transporte v1 nesta release: o gate
de paridade reprovou — enumeração completa via v2 quebra com 500
determinístico num registro específico (bug reportado ao backend) e as
projeções v1/v2 divergem (inclusive municipalTaxNumber com valores
diferentes). Pendências rastreadas em #41.
Refs #41
📋 OpenAPI Spec Validation✅ All specs validated and types generated successfully Specs processed:
Generated types available as artifact in |
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
Corrige o contrato de paginação v1 de
companies(quebrado desde sempre nos helpers de auto-paginação) e inicia a migração para a API v2 com o novolistV2()cursor-based — tudo provado por sondas ao vivo contra contas reais (2026-07-13/14). CHANGELOG da 5.2.0 tem o detalhe completo, incluindo a nota de migração.Pendências pós-merge rastreadas em #41.
🐛 fix(companies): paginação 1-based + teto de pageCount + semântica PUT
listAll()/listIterator()falhavam na 1ª chamada por dois motivos independentes: iniciavam empageIndex=0(a API é 1-based e rejeita 0) e pediampageCount=100(a API aceita 2–50 — rejeita 1, apesar da própria mensagem dizer "between 1 and 50"). Consertados transitivamente os 4 métodos dependentes (findByTaxNumber,findByName,getCompaniesWithCertificates,getCompaniesWithExpiringCertificates). Prova ao vivo:listAll()= 352 empresas / 8 páginas.list()deixou de subtrair 1 da resposta —page.pageIndexagora é 1-based, fiel ao fio. Justificativa: a convenção mista nunca foi documentada e o caminho de auto-paginação estava 100% quebrado. Nota de migração no CHANGELOG.update()era ativamente enganoso: prometia PATCH ("only fields to update"), mas a API faz PUT (substituição total) — risco de zerar campos silenciosamente. Documentado com exemplo read-modify-write;create()documenta os obrigatórios reais (taxRegime,address;emailnão existe no corpo). Exemplos do README idem.minimum: 1nopageIndexemaximum: 50nopageCountde/v1/companies(fix na origemnfe/docspendente — ver companies: pendências da migração v2 — enumeração bloqueada por 500 no cursor; tightening de create/update adiado #41).company-write-alignment.test-d.ts).✨ feat(companies):
listV2()+ deprecação dolist()v1A v1 de companies está sendo descontinuada.
listV2({ limit, startingAfter, endingBefore })→{ data, hasMore }usa a contribuintes-v2 (api.nfse.io/v2/companies); contrato provado ao vivo (limit 1–50 default 10; validação client-side).list()v1 fica@deprecatede funcional na convivência.Por que
listAll/listIteratorNÃO migraram: o gate de paridade reprovou — (1) enumeração completa via v2 quebra com 500 determinístico num registro específico (repro exata em #41, reportado ao backend); (2) as projeções v1/v2 divergem de campos e até de valores (municipalTaxNumber). Detalhes em #41.🔧 chore(test): vitest coletava a suíte 5×
O glob
**/*.test.tsatravessava os symlinksclient-php/client-ruby(loops de volta) — 3710 testes aparentes eram 698 reais, com flakes por corrida no.test-temp.includerestrito atests/**.Verificação
npm run typecheck✅ ·npm run test:types✅ (sem erros de tipo) ·npm test -- --run✅ 702 passed | 44 skippednpm run validate:spec && npm run generate✅ (10/15, 5 known-skipped esperados)listAllponta a ponta,listV2via SDKMétodo
Todo contrato afirmado neste PR foi provado contra a API real antes do código — os specs/tasks completos (com repros e evidências) estão nos OpenSpec changes locais
fix-companies-pagination-1-basedemigrate-companies-to-v2.