v1.4 — Envio de arquivo em duas etapas, campos novos e erros literais
Atualização do contrato a partir das mudanças de comportamento dos handlers (baseline 20/07 → 06/08), com auditoria completa das 22 famílias de endpoints tocadas no período. Destaques: o envio de planilha em duas etapas passou a ser documentado, vários campos de resposta que já eram devolvidos entraram nos schemas, e cerca de 80 operações tiveram a lista literal de mensagens de erro corrigida ou criada.
✨ Added
-
POST /sku/templateePOST /orders/templateePOST /job— documentado o fluxo de envio de arquivo em duas etapas, que já é o usado pelo produto e não existia no contrato:Action=RequestUploadUrldevolveUploadUrl,Key,Method,Headers(obrigatórios no envio),SizeByteseExpiresIn; em seguidaAction=ConfirmUploadcom oKeycria o processamento. O envio direto pormultipart/form-datacontinua válido. Reenviar o mesmo arquivo é idempotente: devolve oIDJobjá existente. -
Campos novos de resposta — todos
nullable. Já eram retornados pela API; só não estavam no contrato:Operação Campos Observação POST /user/signin/localToursSeen·OriginGET /user/privilege·GET /user/{iduser}ToursSeenGET /hub/order/claim/{idhuborderclaim}ClaimAffectsReputationNão é booleano: 1não afeta,2afeta,3não se aplica,0o canal não informou,nulla consulta falhouGET /orders/hub/{idorder}·GET /hub/order/{idintegration}SalesChannelLogoUrl·IDConsumer·IndexGET /orders/hub·GET /company/dashboard/order/statusStatusColorCodeGET /sku/distribution-centerDistributionCenterIDConsumerList·DistributionCenterConsumerList·IDStockKeepingUnitWarehouseBestBeforeDays·WarehouseBestBeforeDaysNameGET /type/order/payment/{idtypepayment}/rateAdditionalBusinessDays·AdditionalBusinessDaysPosition·NfTPag·NfTBand·RefundMethodEm AdditionalBusinessDaysPosition:1início,2finalGET /sku/inventory-summary/{idstockkeepingunitinventorysummary}ItemsCount·HasNextPageItems·InventoryLogsGET /skuQtyReserved·QtyHandling·QtyOnStock·QtyReservedHandlingGET /sku/movementIDCategory·AbcCurve·MainImageThumbnailURL·Category·CategoryTreeGET /fulfillment/packing/picking-list/{idpickinglist}KitBarCodeListDentro de cada item GET /fulfillment/picking/basketIDPickingListNo histórico do cesto GET /orders/{idorder}ExchangeReceiptBase64Encode -
Query params documentados — existiam e eram lidos pelo handler, mas não estavam no contrato:
Operação Parâmetro Para que serve GET /ordersLastIDPaginação por cursor GET /orders/hubCreationTimestampFrom·CreationTimestampToRecorte por data de criação PUT /orders/{idorder}Resend·TypeMessageReenvio de mensagem ao cliente GET /accounts/payableIDTypeCostCenterFiltro por centro de custo GET /sku/batchIDCompanySalesPolicyPreço da política informada GET /type/order/typeIsTransferSó tipos de transferência POST /purchase/{idpurchase}/checkCreateNewPurchaseSentMoreRecebimento a mais gera novo recebimento POST /sku/pricing/{idsku}UpdateIfPossibleAtualiza só o que for possível Além desses,
Pagefoi documentado em cinco listagens que já paginavam sem dizer. -
Request bodies modelados onde o contrato trazia corpo vazio ou parcial:
Operação O que entrou POST /ordersCorpo completo, com Items[]ePayments[]detalhadosPOST /consumer·PUT /consumer/{idconsumer}Cadastro de cliente PUT /sku/{idsku}Cadastro de SKU POST /supplier·PUT /supplier/{idsupplier}Cadastro de fornecedor PUT /purchase/{idpurchase}·POST /purchase/{idpurchase}/checkRecebimento e conferência POST /sku/pricing/{idsku}Preços POST /user/reportRelatório customizado POST /company/sales-policyPolítica comercial POST /fulfillment/pickingPicking POST /hub/warehouseDE-PARA de armazém POST /user/signin/localLogin PUT /sku/resupply/{idstockkeepingunitresupplylist}Ressuprimento POST /purchase/feed/invoice-xmlFeed de NF-e -
400documentado no envio de anexo do Hub —POST /hub/order/{idintegration}/action/fileePOST /hub/order/claim/{idhuborderclaim}/action/filesó declaravam200. Agora trazem as sete mensagens de recusa: arquivo não enviado, arquivo inválido, falha ao salvar, recusa do canal por extensão/tamanho, canal sem recurso de anexo, pedido de integração não localizado e integração não autenticada. -
Enums cruzados com os CSVs canônicos: tipos de devolução (31 valores) e categorias e bandeiras de pagamento; CST e modalidade de ICMS na resposta de
POST /tax/{idtaxdepartment}/cfop/{idtax}/interstatee doPUTcorrespondente; status de pedido emGET /company/dashboard/order/status; tipos de SKU emGET /skue nas demais listagens; e status de pedido de compra e de reserva no detalhamento de saldo.
🔄 Changed
GET /sku/balanceeGET /sku/{idsku}/warehouse— mudou o significado deQtyReservedeQtyHandling: pedidos do fluxo de orçamento (50–56) e23Em espera etiqueta passaram a contar como reserva, e97Reversa finalizada saiu de manuseio. O total (QtyOnStock) não muda — muda a distribuição.GET /accounts/receivable/marketplace-conciliation— os campos*Pctsão frações de 0 a 1 (0,15= 15%), não percentuais; e o corte de página é aplicado antes do agrupamento, então uma conciliação pode ficar partida entre duas páginas.PUT /hub/product/{idhubproduct}— comSyncVariations=1a resposta é um objeto (IDHubProduct,TotalUpdates,Results[]), não o anúncio. Falhas individuais não abortam a sincronização.GET /type/order/payment— comOrderReturn=1a lista começa com um item sintético cujoIDTypePaymenté o literalORIGINAL(deixa de ser numérico).GET /sku/inventory-summary/{idstockkeepingunitinventorysummary}e correlatos — a lista deItemspassou a ser paginada em 5000 registros; usePagee confiraHasNextPageItems.GET /sku/production/{idstockkeepingunitproduction}— no detalhe da ordem de produção, a listaItemsé dos insumos consumidos, não do que foi produzido; as descrições dos campos diziam o contrário. Corrigido um a um. O que a ordem produz está no cabeçalho (IDSku,SkuName,Quantity);Itemstraz o que saiu do estoque para fabricá-lo, com custo por linha. Vale para as outras sete operações de produção, que devolvem o mesmo detalhe.- Cerca de 60 operações tiveram a lista de mensagens
[BadRequest]criada ou corrigida com o texto literal do handler — inclui ~25 correções de acentuação (esta→está,excluido→excluído,codigo→código) que quebravam tratamento de erro por comparação de texto.
🐛 Fixed
DELETE /accounts/receivable/{idaccountreceivable}/payment/{idaccountpayment}— a documentação prometia devolver a conta atualizada; o corpo real vem sempre vazio ([]). A exclusão acontece normalmente — refaça oGETpara atualizar a tela. (Defeito de implementação: a recarga usa a chave do lado "a pagar". Reportado ao time.)POST /sku/{idsku}/cost/recalculate— o schema do200documentava{status, message}, campos que o handler nunca produziu. O corpo real é{Message}com texto fixo.POST /sku/template— o schema do200documentava o envelope interno da integração em vez do corpo entregue ao cliente (IDJob+Message).GET /hub/order/claim/{idhuborderclaim}— os valores deShippingMethoddocumentados (carrier,delivered_by_seller) não existem; os reais sãomail,entrusted,personal_deliveryeemail.PUT /company—SefazAmbienteNF,SefazAmbienteNFCeSefazAmbienteServiceInvoiceestavam marcados comonullablesendo colunas obrigatórias: enviarnullfaz a gravação falhar.- 4 descrições de operação que continham texto de instrução em vez do conteúdo
(
POST /sku/promotion,PUT /sku/promotion/{idstockkeepingunitpromotion}, abertura e fechamento de caixa) foram restauradas.
🧹 Limpeza de contrato
Itens que a auditoria encontrou documentados sem existir no comportamento real.
-
500removido dePOST /sku/image/{idsku},PUT /sku/image/{idsku}/{idimage},DELETE /sku/image/{idsku}/{idimage},PUT /accounts/receivable/{idaccountreceivable},GET /fulfillment/picking/basket,PUT /companyeDELETE /consumer/{idconsumer}/voucher/{idconsumervoucher}— nenhum desses fluxos produz erro com o prefixo que o gateway mapeia para500. O404dePUT /consumer/{idconsumer}também saiu pelo mesmo motivo. -
POST /sku/image/{idsku}declarava corpo no404que a resposta não tem. -
POST /sku/production/{idstockkeepingunitproduction}/finish— o formato declarado do200era um array de arrays que a API nunca devolveu. Passou a declarar o detalhe do recebimento, que é o que ela retorna de fato — o mesmo formato deGET /purchase/{idpurchase}. -
POST /sku/distribution-centerePUT /sku/distribution-center/{idstockkeepingunitdistributioncenter}, e o mesmo par em/purchase/schedule— criação e atualização compartilhavam um único formato de corpo, mas as regras diferem: o que é obrigatório ao criar, e o que a omissão de um campo significa ao atualizar (apagar × manter). Agora cada uma declara o seu, e a descrição de cada campo diz o que a omissão faz. -
GET /orders/hubeGET /orders/hub/{idorder}— a listagem e o detalhe do pedido integrado estavam descritos por um formato só, que misturava campos dos dois. Agora cada uma declara o que realmente devolve, com a parte comum compartilhada; e os blocos que eram objetos opacos — SKUs, pagamentos, mensagens e reclamações — passaram a apontar para as descrições que já existiam.Divergências corrigidas no caminho:
ShippingEstimateHandlingLimitDateeradatenuma edate-timena outra (valedate-time);OrderIdestavanullablesem ser;QuantityItemseraintegernuma enumberna outra;CompanyIntegrationvem nas duas, não só no detalhe. EntraramStatusColorCodee o enum deIDStatusInvoice.IDCompanyeIntegrationLogoUrlsaíram — eram documentados na listagem e nenhuma das duas consultas os devolve; o logotipo existe só no detalhe, com o nomeSalesChannelLogoUrl.GET /hub/order/{idintegration}devolve exatamente o mesmo queGET /orders/hub/{idorder}— era essa duplicidade que mantinha os dois formatos.
✅ Fechado nesta leva
Itens que estavam listados como pendentes e foram resolvidos:
PUT /orders/{idorder}/sku/{idskumovement}não devolve o pedido inteiro: devolve um array de um item, em duas formas conforme a apuração de imposto do pedido. Com imposto manual, vem o item completo com todo o cadastro do SKU na mesma linha (177 campos); nos demais casos, o mesmo formato dePOST /orders/{idorder}/sku, agora comIDNfCstIbsCbs. Ambas as formas estão declaradas.PUT /orders/{idorder}/payment/{idaccountpayablereceivable}também não devolve o pedido — a rota é atendida pelo mesmo processo de contas a receber, e o corpo é o detalhe do título, igual ao dePUT /accounts/receivable/{idaccountreceivable}.- Tipos corrigidos:
IDModuleFavorite, no cadastro de usuário (GET /user/{iduser}e correlatas), eIDWarehouseHub, no pedido integrado (GET /orders/hub/{idorder}), são string e não integer. GET /company/dashboard/externaleGET /user/signin/externalforam descritos no spec de origem. Eles continuam fora da referência publicada por decisão de escopo (rotas de uso exclusivo do app, na lista de exclusão deprepare-spec) — o registro serve para quem lê o contrato interno.
🐞 Validação que virava erro de servidor — corrigido
Afetava POST /job, POST /sku/template, POST /orders/template e
POST /sku/{idsku}/cost/recalculate, que compartilham a mesma função.
As validações dessas rotas encerravam a execução com erro em vez de devolver uma
resposta, e o API Gateway convertia isso em 502 com o corpo genérico
{"message": "Internal server error"}. Na prática, quem errava o envio de planilha ou a
ação em massa recebia "erro interno" no lugar da mensagem que dizia o que fazer — eram
100 chamadas por semana terminando assim.
Corrigido nesta versão: as quatro rotas passaram a devolver 400 de verdade, com o
texto em errorMessage, para todas as validações. O 400 documentado aqui vale
integralmente; não há mais caso que escape como 502.
O mesmo defeito existia, numa única ocorrência, no envio de anexo em mensagem do Hub —
POST /hub/order/{idintegration}/action/file e
POST /hub/order/claim/{idhuborderclaim}/action/file —, na recusa por integração não
autenticada. Também corrigido.
A varredura cobriu as 57 rotas de proxy: as 34 atendidas por PHP já respondiam 400
corretamente, e entre as 10 em Node só essas duas funções tinham o problema.
- Nos itens do pedido (
GET /orders/{idorder}), o campoReverseTaxCalculationestava com a condição invertida: o texto dizia que os impostos somam quando o valor é1, e o comportamento soma quando é0. Corrigido.