Changelog
Changelog
Destaques selecionados dos lançamentos mais recentes. Para versões completas da API e política de alterações incompatíveis (breaking changes), consulte a Versão da API e Política LTS.
Alterações detalhadas em endpoints individuais: Especificação OpenAPI e referência interativa da API.
2026-10 · Cores no Dashboard
- Novo: a página de detalhes de um código tem o cartão Cores: primeiro plano e fundo como valor hexadecimal, fundo transparente, pré-visualização pela rota de imagem real. A verificação é a de
PATCH /v1/codes/{id}: pares críticos precisam de confirmação, pares abaixo de 1,5:1 não podem ser salvos. - Redefinir para preto sobre branco volta a entregar nos quatro formatos os mesmos bytes que sem cores. Códigos sem cores não mudam.
- Códigos transparentes aparecem sobre um quadriculado em todas as pré-visualizações do Dashboard. Detalhes: Cores no Dashboard.
2026-10 · Cores em PDF e EPS
- Novo:
qr.pdfeqr.epsdesenhamfgebg, como parâmetros e como cores salvas. O preto e qualquer cinza são gravados como escala de cinza (apenas placa preta), qualquer outra cor como CMYK em porcentagens inteiras, por exemplo1F4E79como C74 M36 Y0 K53. - Fundo como no SVG: Assim que uma cor é selecionada, existe uma área opaca por trás do código e da sua zona de silêncio, branca ou
bg.bg=transparentnão desenha nenhuma. O título permanece preto, a placa do logotipo branca. - Sem alterações sem cores: Sem
fg/bge sem cores salvas, ambos os formatos fornecem os mesmos bytes que antes. O PDF de um passaporte de produto permanece sem cor. - Limites: sem perfil ICC, sem PDF/X. Detalhes: Cores na impressão.
2026-09 · Códigos estáticos sem cache de redirecionamento, exclusão simultânea
- Alterado: Os códigos estáticos não ficam mais no cache de redirecionamento. Uma chamada ao seu link curto (
redirect_url) sempre lê o estado atual. Por isso, apósDELETE /v1/account, um código estático deixa de redirecionar já na chamada seguinte; antes, isso podia continuar por até 24 horas. Uma mudança de plano também tem efeito imediato nos códigos estáticos. A exclusão da conta limpa os códigos dinâmicos como antes. Códigos estáticos impressos contêm o destino diretamente e não são afetados. - Corrigido: Duas requisições
DELETE /v1/codes/:idsimultâneas para o mesmo código retornam uma vez200e uma vez404. O webhookqr.deletedé enviado exatamente uma vez, e não mais duas. - Novo:
POSTeDELETE /v1/codes/:id/logorespondem com409(errors/conflict) se outra requisição tiver alterado o logotipo do mesmo código ao mesmo tempo e, nesse caso, não alteram nada. Antes, um logotipo enviado podia ficar armazenado sem uso. Duas requisiçõesDELETE /v1/codes/:id/logosimultâneas retornam ambas200. Detalhes: Logotipo.
2026-09 · TypeScript-SDK 1.2.0
- Novo no
@qr3/sdk1.2.0: Oclient.codes.update()aceitaappearancee fornece os resultados da verificação de contraste comoissuesno resultado; sem resultados, o campo fica ausente. Oclient.codes.imageUrl()aceitafg,bgeecc. Cada código retornado pela API (get,list,create,update,batchCreate) contémtitleeappearance. - Atualizar:
npm install @qr3/sdk@latest. Python, Go e PHP seguem-se. Detalhes: SDKs & CLI e Salvar cores no código.
2026-09 · Tempo de expiração alterado aplica-se dentro de cerca de um minuto
- Corrigido: Um
PATCHemexpires_atagora limpa o cache de redirecionamento do código. O novo tempo de expiração aplica-se, assim, dentro de cerca de um minuto, em vez de apenas até 24 horas mais tarde. Anteriormente, uma expiração removida ou adiada continuava a retornar410por até 24 horas, e uma expiração definida para agora permitia que o redirecionamento continuasse a funcionar por até 24 horas. - Corrigido: Um código criado com
expires_atexpira agora pontualmente, mesmo que a expiração ocorra dentro das primeiras 24 horas. - Corrigido: Se um código for excluído enquanto o seu logotipo está sendo enviado ou removido, o
POSTe oDELETE /v1/codes/:id/logorespondem com404e não alteram o código excluído, assim como já ocorre com oPATCH. - Corrigido: Mesmo um código estático cujo link curto (
redirect_url) foi acessado fica armazenado no cache de redirecionamento. Alterar, pausar e excluir agora também limpam esse cache, e não apenas no caso de códigos dinâmicos.
2026-09 · Salvar cores no código
- Novo:
PATCH /v1/codes/:idaceitaappearancecomforeground_colorebackground_color(#RRGGBB, o fundo tambémtransparent).qr.svgeqr.pngdesenham as cores armazenadas sem qualquer parâmetro; um parâmetro de consulta como?fg=000000continua a ter precedência. O PDF e o EPS apenas desenharão as cores numa versão posterior. - Verificação de contraste: Um par abaixo de 1,5:1 resulta em
422. Pares mais fracos são salvos e reportados emmeta.issuescomowarningoucritical; um fundo transparente é semprecritical, nunca bloqueado. - Mesclagem: Os campos omitidos mantêm o seu valor salvo,
nullredefine. Alterações simultâneas no mesmo código já não se sobrescrevem mutuamente. - Em cada resposta de código:
appearanceestá presente em cada resposta de código e nos webhooksqr.createdeqr.updated. OPOST, o lote e a importação rejeitam com422. - Sem alterações para códigos existentes: Sem cores salvas, cada código fornece os mesmos bytes que antes. Detalhes: Salvar cores no código.
2026-09 · Cores e correção de erros como parâmetros das rotas de imagem
- Novo: Todas as quatro rotas de imagem aceitam
fg(cor do primeiro plano),bg(cor de fundo outransparent) eecc(correção de errosL,M,Q,H). SVG e PNG desenham as cores; PDF e EPS aceitam-nas, mas só as desenham numa versão posterior.eccfunciona em todos os quatro formatos, um logotipo continua a forçarH. - Transparente:
bg=transparentfornece um SVG sem fundo e um PNG com canal alfa real. O fundo deve ser claro e deixar a zona de silêncio livre. - Nunca é um erro: Valores inválidos são ignorados; a imagem é então fornecida exatamente como sem parâmetros.
- Cache: Cada parâmetro eficaz fornece
Cache-Control: public, max-age=300em vez das 24 horas da imagem padrão. - Sem alteração de comportamento sem parâmetros: Qualquer código existente fornece os mesmos bytes que antes em todos os quatro formatos.
- Disponível em qualquer plano. Detalhes: Cores e correção de erros.
2026-09 · PDF e EPS agora também incorporam o logo
- Extensão:
qr.pdfeqr.epsagora incorporam um logo definido exatamente da mesma forma queqr.svgeqr.png(ver abaixo) — como uma imagem incorporada (PDF através de umImage XObject, EPS através de um dicionário de imagem em PostScript, lá apenas com%%LanguageLevel: 3), centrado na mesma área, com o mesmo aumento da correção de erros paraH. Ambos os formatos anteriormente não forneciam o logo; isto está agora corrigido. - Cache: Com um logo definido,
qr.pdfeqr.epsagora também fornecemCache-Control: public, max-age=300em vez das habituais 24 horas — exatamente como SVG/PNG. - Fallback: Se a própria imagem do logo não puder ser processada (por exemplo, um objeto armazenado corrompido), a correção de erros permanece em
H, mas a área reservada permanece vazia em vez de uma imagem — nunca um erro do servidor. - Sem alteração de comportamento sem logo: Códigos sem logo continuam a fornecer
qr.pdf/qr.epsde forma idêntica em termos de bytes, com o cache de 24 horas inalterado. - Detalhes e instruções de impressão: Logo no código QR.
2026-09 · Logo no QR Code — Dashboard e API
- Novo: Um código agora pode ter um logo no centro. No Dashboard, a página de detalhes de um código cria um cartão de logo próprio: Selecionar logo, ao adicionar pela primeira vez ou ao remover, confirmar um aviso com uma caixa de seleção obrigatória (ambos alteram o padrão de pontos), depois Carregar logo/Remover logo. Uma substituição não precisa de confirmação — apenas a imagem muda, não o padrão. A função
viewervê o estado e a pré-visualização, mas nenhuma das três ações. - API:
POST /v1/codes/{id}/logo(campo multipartfile; PNG, JPEG ou WebP, no máximo 1 MB, SVG é rejeitado) cria ou substitui um logo;DELETE /v1/codes/{id}/logoremove-o novamente e é idempotente. Uma imagem grande demais retorna413, um formato não suportado422, a funçãoviewer403. - Apresentação:
qr.svgeqr.pngincorporam o logo como pixels reais (512 × 512, normalizado) e, para isso, aumentam a correção de erros paraH. A adição e a remoção alteram, assim, o padrão de pontos (M↔H), mas a substituição não.qr.pdfeqr.epsnão incorporam nenhum logo e permanecem inalterados. Um código já impresso continua a funcionar em qualquer caso, porque o destino codificado não depende do logo — só precisa de reimprimir quem quiser ver o (novo) visual do logo também no material físico, e, ao fazê-lo, não misturar arquivos de impressão antigos e novos. - Cache: Com o logo definido,
qr.svgeqr.pngfornecemCache-Control: public, max-age=300em vez das habituais 24 horas. Detalhes, limites e instruções de impressão: Logo no QR Code.
2026-08 · operationId para todas as 75 operações, e um guia de quando usar para agentes
- Adição: Todas as 75 operações da especificação OpenAPI agora possuem uma
operationId—listCodes,createCode,getCodeStats,archiveWorkspacee assim por diante. Anteriormente, este campo estava totalmente ausente, fazendo com que cada gerador tivesse que derivar o nome do método a partir do método HTTP e do caminho (postV1Codes). Esses nomes dependem do caminho e mudam a cada reestruturação de caminho. O formato do nome é o mesmo em todos os 75 locais:list/get/create/update/replace/delete, caso contrário, o verbo da ação de negócio (validateDpp,registerGs1Identifier,pingWebhook). O verbo segue a lógica de negócio, não o método HTTP —archiveWorkspaceé umDELETE,importDppsé umPOST. - Impacto em clientes gerados automaticamente: Quem gera o seu SDK a partir da especificação obterá métodos renomeados na próxima execução (
postV1Codes→createCode). Este é o objetivo da alteração, mas trata-se de uma renomeação em código de terceiros — por isso é explicitamente mencionada aqui. Caminhos, parâmetros, formatos de resposta e códigos de status permanecem inalterados; os SDKs oficiais, CLI e servidores MCP não são afetados. - Introdução para agentes:
https://qr3.app/llms.txttem uma seção## When to use qr3.app— seis tarefas em vez de seis funções, além da frase que explica para o que a qr3.app não é a ferramenta certa. A mesma informação é agora fornecida pelo servidor MCP no handshake:initializecontrahttps://mcp.qr3.app/mcpresponde com um campoinstructions(anteriormente: onze ferramentas sem qualquer classificação). Também está incluído quais chamadas precisam de uma chave de API —initializeetools/listnão precisam, mas cadatools/callsim. - Correções em
llms.txt: Quatro informações foram testadas em produção e não se confirmaram: (1) o SDK Pythonqr3appnão está publicado no PyPI — a linhapip installfoi removida sem substituição; (2)Accept: text/markdownaplica-se à página inicial e ao blog, não a todas as páginas renderizadas no servidor; (3) o endereço de contato é[email protected], inclusive no JSON-LD da página inicial; (4)/de/security/é um redirecionamento para uma âncora, não uma página própria. Novo link:docs.qr3.app/de/skills/. - Garantia de qualidade: Três asserções em
openapi-spec.test.ts— integridade, unicidade,lowerCamelCase—, cada uma verificada com uma mutação. Mais nove testes fixam as quatro informações corrigidas para garantir que não voltem a ocorrer. - Limitação conhecida: Duas das 75 operações estão descritas na especificação, mas respondem com
404(GET /v1/codes/{id}/statseGET /v1/account). Elas receberam um nome aqui e irão perdê-lo assim que for decidido se serão implementadas ou removidas.
2026-08 · Downgrades de plano e cancelamentos agora também afetam os limites
- Fix: O webhook do Stripe, ao alterar ou cancelar o plano, apenas escrevia o nome do plano e não as quatro colunas de limite da organização (
max_workspaces,max_members,max_dynamic_codes,max_scans_per_month). Como a aplicação dos limites utiliza o valor máximo entre o valor salvo e a baseline do plano, uma organização que sofria downgrade ou cancelamento mantinha os seus limites antigos e mais elevados — o downgrade não tinha efeito. O webhook agora define as colunas para a baseline do novo plano em cada alteração real de plano e para a baseline do plano Free em caso de cancelamento — exatamente como a administração de admin já faz. - Comportamento: As atualizações de rotina da assinatura (renovação, meio de pagamento, proration) continuam a não alterar os limites; os limites mais elevados concedidos individualmente permanecem inalterados. Apenas uma alteração real de plano os redefine para a baseline do novo plano.
- Impacto: Sem alterações na API ou no formato de resposta. As organizações cujo downgrade ocorreu antes desta correção mantêm os valores antigos até que a próxima alteração de plano entre em vigor ou o suporte os ajuste.
2026-08 · Cursor keyset agora em todos os endpoints de lista
- Fix: A correção do cursor para
GET /v1/codeseGET /v1/dpp(veja abaixo) foi agora implementada em todas as demais listas paginadas por cursor:GET /v1/qr-codes/:id/comments,/v1/workspaces,/v1/gs1/identifiers,/v1/members,/v1/audit-logs,/v1/admin/orgs,/v1/admin/userse/v1/webhooks/:id/deliveries. Todas paginavam apenas porcreated_at; linhas com carimbo de data/hora idêntico (entradas de auditoria de uma operação em lote, novas tentativas de webhook, importações de membros) podiam se perder na página seguinte. A chave de ordenação agora é, em todas elas, a tupla(created_at, id). - Alteração na API: Nestas listas,
meta.pagination.next_cursorpassa a ser também um valor opaco (base64url) em vez de um carimbo de data/hora simples; cursores ilegíveis retornam400, cursores antigos de carimbo de data/hora continuarão sendo aceitos temporariamente. ExceçãoGET /v1/webhooks/:id/deliveries: ali,next_cursorcontinua sendo o ID da última entrega (ID desconhecido → primeira página). Os clientes que retornamnext_cursorsem alterações — Painel, CLI, SDKs, MCP — não precisam alterar nada. - Impacto: Nenhuma migração é necessária. Se sentiu falta de entradas ao paginar numa destas listas (por exemplo, log de auditoria ou log de entregas no Painel): elas nunca desapareceram — as listas passam a mostrá-las na totalidade a partir de agora.
2026-08 · Timestamps novamente em conformidade com a OpenAPI após edição e exclusão
- Fix: Após
PATCH /v1/codes/{id}, oupdated_atretornava no formato SQLite sem fuso horário (2026-08-17 09:00:00), embora a especificação OpenAPI especifiqueformat: date-timee a criação (POST) forneça o timestamp ISO (2026-08-17T09:00:00.000Z). O mesmo se aplicava adeleted_at/updated_atna exclusão lógica (soft-delete), bem como aos caminhos de edição e exclusão de API-Keys, organizações, workspaces, membros, comentários e webhooks, além delast_used_atde API-Keys elast_triggered_atde webhooks. Todos os caminhos de gravação agora registram em ISO 8601 (UTC,TeZ). - Impacto: Clientes que analisam
updated_atcomnew Date(...)(SDKs, CLI, Painel) liam o formato com espaço como hora local — a CLI mostrava, para códigos que já haviam sido editados, a hora deslocada pelo offset local (Viena: −2 h). Isso foi corrigido. Além disso, uma migração de dados normaliza os valores já salvos no formato antigo para ISO, para que a ordenação e as comparações em registros mistos funcionem corretamente. Nenhuma alteração nos nomes dos campos ou na estrutura de resposta. Isso foi corrigido. Além disso, uma migração de dados normaliza os valores já salvos no formato antigo para ISO, para que a ordenação e as comparações em registros mistos funcionem corretamente. Nenhuma alteração nos nomes dos campos ou na estrutura de resposta. - Contexto: Mesma classe de erro que as duas correções abaixo (expiração de API-Key, limite de re-scan): o
datetime('now')do SQLite gravaYYYY-MM-DD HH:MM:SS, enquanto todos os outros gravadores usam ISO 8601. Um teste de proteção no código-fonte evitará novas ocorrências no futuro.
2026-08 · Paginação de listas não perde mais códigos em lote
- Fix:
GET /v1/codeseGET /v1/dpppaginavam apenas porcreated_at. No entanto, os códigos dePOST /v1/codes/batch,POST /v1/dpp/batche da importação de CSV/XLSX compartilham um único carimbo de data/hora — assim que um lote era maior quelimit(padrão 20), a segunda página não retornava mais as linhas restantes do mesmo carimbo de data/hora. Os códigos existiam e estavam acessíveis viaGET /v1/codes/:id, mas nunca apareciam na lista (Painel, CLIqr3 list, SDKs, MCP). O cursor agora é um keyset sobre(created_at, id). - Alteração na API:
meta.pagination.next_cursoragora é um valor opaco (base64url) em vez de um carimbo de data/hora simples. Quem retorna o cursor inalterado como?cursor=— como o Painel, CLI, todos os SDKs e o servidor MCP fazem — não precisa alterar nada. Cursores antigos de carimbo de data/hora continuarão sendo aceitos temporariamente; cursores ilegíveis agora retornam400em vez de entregar silenciosamente a primeira página. - Impacto: Se você viu menos códigos na lista após uma importação em lote do que os que foram criados: os códigos nunca sumiram — a lista agora os exibe por completo. Nenhuma migração é necessária.
2026-08 · Re-scans de segurança voltam a ser executados a cada 24 horas
- Fix: O re-escaneamento periódico de URLs de destino e links de landing pages (Google Web Risk) ignorava códigos cujo último escaneamento ocorria no mesmo dia civil que o cutoff de 24 horas — dependendo do horário, o re-escaneamento era atrasado em até mais um dia. O cutoff agora é calculado no mesmo formato ISO em que os timestamps de escaneamento são armazenados.
- Impacto: Uma URL de destino classificada como insegura após o último escaneamento resultará novamente na pausa automática do código dentro da janela documentada de 24 horas. Sem alterações na API ou no formato de resposta.
2026-08 · Chaves de API expiram no momento exato de expiração
- Fix: Uma chave de API cujo
expires_atocorria no mesmo dia continuava sendo aceita até a meia-noite UTC. A expiração agora é comparada como um timestamp em vez de uma string — uma chave expirada retorna imediatamente401. - Contexto: O
expires_até armazenado como um timestamp ISO (2026-08-14T09:00:00Z), mas o lado da comparação fornecia o formato com espaço (2026-08-14 09:00:00). Por isso, a comparação direta de strings só funcionava corretamente quando a data em si já era diferente. - Impacto: Nenhuma migração é necessária, o formato de resposta de
GET /v1/api-keyspermanece inalterado. Valores de expiração ilegíveis agora são considerados expirados em vez de válidos.
2026-08 · Referência da API: Gestão de Tenants documentada
- OpenAPI: A especificação — e, portanto, a referência interativa — agora documenta Organizações (incl.
GET /v1/organizations/usage), Workspaces, Membros e Funções e Logs de Auditoria. - Faturamento: A visão geral dos planos (
GET /v1/billing/plans) é pública; o checkout (POST /v1/billing/checkout) e o portal do cliente Stripe (GET /v1/billing/portal) estão identificados como endpoints para administradores da organização. - Exportação de Scans: As estatísticas de scan (
GET /v1/codes/{id}/scans) e a exportação de dados brutos (…/scans.csv,…/scans.xlsx) estão totalmente documentadas — incluindo o aviso de RGPD: oip_hashnunca está incluído na exportação. - Comportamento de erro: Também está documentada a resposta
400da validação de requisições: o corpo é o erro Zod bruto, não um documento de problema RFC-7807 — no entanto, é fornecido sob o Content-Typeapplication/problem+json.
2026-08 · Copiar links públicos de arquivos
- Dashboard: Os arquivos públicos na página de detalhes do código agora têm um botão que copia o seu link público para a área de transferência – utilizável diretamente como URL de destino de um QR Code, caso um escaneamento precise abrir imediatamente um documento específico em vez da landing page com la lista de arquivos.
- API: Os endpoints de arquivos (
/v1/files) agora também retornampublic_url. Este campo é definido apenas para arquivos comvisibility: public– arquivos privados não recebem um endereço público. - Comportamento: O link não requer login e abre o arquivo diretamente no navegador. A substituição do arquivo mantém o link inalterado, portanto, um código impresso com ele continua válido. Detalhes: Arquivos e Fichas Técnicas.
2026-07 · Funções de Equipe: Editor sem exclusão e Faturamento de Administrador
- Novo: Nova função de membro Editor (sem exclusão) — cria e edita QR Codes, arquivos e Digital Product Passports, mas não pode excluir nada nem criar API-Keys. Todos os endpoints destrutivos verificam a função no lado do servidor (
403). - Faturamento: Upgrades de plano e o portal do cliente Stripe (
POST /v1/billing/checkout,GET /v1/billing/portal) agora são reservados para administradores da organização — todas as outras funções visualizam uma visão geral do plano em modo somente leitura. - Dashboard: As ações não permitidas pela função do usuário são ocultadas: um Visualizador, por exemplo, não vê botões para criar, editar ou excluir; listas, downloads e estatísticas continuam visíveis. Detalhes: Equipe e Funções.
2026-06 · Links externos na landing page do código
- Landing page: A landing page de um código hospedada pela qr3 agora pode listar links externos hospedados pelo próprio usuário (
{ label, url }) – além de ou em vez de arquivos enviados, por exemplo, para fichas técnicas em seu próprio site. - API:
POST/PATCH /v1/codesaceitam um arraylinks(0–20 itens,http(s), ≤ 2048 caracteres). Cada URL é verificada com o Google Web Risk; uma URL insegura retorna422. Um array vazio remove todos os links. - Dashboard: Adicionar, ordenar e remover links na página de detalhes do código.
- Segurança: Os links renderizados permanecem protegidos contra XSS (escapados, apenas
http(s)) e a página mantém seu cabeçalhonoindex.
2026-04 · Análise do Dashboard por QR Code
- Dashboard: O botão de análise na lista de QR Codes agora abre a página de estatísticas do respectivo QR Code em
/dashboard/codes/{id}. - Roteamento: O alias
/dashboard/codescontinua redirecionando para/dashboard, mas não intercepta mais rotas de detalhes como/dashboard/codes/{id}. - API: A página de detalhes carrega o QR Code diretamente via
GET /v1/codes/:id; com isso, ela não depende mais dos limites de paginação da lista. - Testes: Testes de regressão cobrem o redirecionamento do alias e o carregamento direto do código.
2026-04 · Diálogo de exclusão do Dashboard para QR Codes
- Dashboard: O ícone de lixeira na lista de QR Codes agora abre um diálogo React próprio em vez de um pop-up nativo do navegador.
- Feedback: Após a exclusão, uma notificação toast é exibida para indicar sucesso ou erro.
- Testes:
packages/dashboard/tests/dashboard.test.tsevita regressões noconfirm()no fluxo de exclusão de QR Codes.
2026-04 · Teste de link curto no Dashboard para QR Codes dinâmicos
- Dashboard: Os shortcodes na lista de QR Codes agora são clicáveis diretamente como links de redirecionamento externos. O ícone de link externo ao lado de, por exemplo,
wu3qaaabrehttps://qr3.app/{shortCode}em uma nova aba. - i18n: Textos de dica de ferramenta (tooltips) adicionados para alemão e inglês.
- Testes:
packages/dashboard/tests/dashboard.test.tsprotege o href do link, o comportamento de nova aba,noopener noreferrere o ícone contra regressões.
2026-04 · Rota do Redirect-Worker para QR Codes dinâmicos
- Fix: Correção: QR Codes dinâmicos em
https://qr3.app/{shortCode}voltam a ser processados pelo Redirect-Worker. A rota de produção agora usaqr3.app/*, pois as rotas do Cloudflare Workers não suportam parâmetros de caminho:code. - Robustez: Caminhos que não correspondem são repassados para a origem da landing page, para que páginas normais como
/de/pricingnão sejam bloqueadas pelo Redirect-Worker. - Testes:
packages/redirect/tests/unit/redirect.test.tsverifica a rota curinga (wildcard), o processamento de shortcodes e o redirecionamento para a origem (pass-through).
2026-04 · Visão geral de escaneamentos de DPP do Workspace (Q3.4.2)
- Novo:
GET /v1/workspace/stats/dpp?days=30— agrega todos osdpp_scansdo workspace da API-Key (active_dpps,scans_by_day,top_dppscom nome do produto/categoria). - Dashboard: Card na página inicial (
/dashboard) com gráfico de barras de 30 dias + listas dos mais acessados — em paralelo com os cards de QR Codes. - Público: Link curto de marketing
GET /dpp/dpp_<id>(um segmento) para demonstrações ao vivo, em paralelo com/dpp/{gtin}/{serial}.
2026-04 · Análise de escaneamentos de DPP (Q3.4.1)
- Novo:
GET /v1/dpp/:id/stats?days=30— escaneamentos agregados do resolvedor GS1 público por DPP. Campos:total_scans,period_scans,scans_by_day,top_countries,top_devices,top_representations. - Novo: Tabela
dpp_scans(migração0011) — separada descans(Redirect-Worker). Os endereços IP são hasheados com um salt rotativo diário, IPs brutos nunca chegam ao D1. - Dashboard: Card de mini-gráfico (SVG, sem biblioteca de gráficos) em
/dashboard/dpp/:dppIdcom barras de 30 dias + detalhamento dos top 3. Estado vazio (empty state) assim que um DPP estiver ativo, mas ainda não tiver escaneamentos.
2026-04 · Simulador de conformidade da UE ao vivo (Q3.3.7)
- Novo:
POST /v1/dpp/:id/validate-update— simula atualizações parciais stateless (status, lista de mercados, …) sem persistência. A resposta contémeu_compliance+preview.changed_fields. - Dashboard: Card do simulador nos detalhes do DPP (
/dashboard/dpp/:dppId) — chips paraDE/AT/FR/IT/ES/NL+ personalizado, menu suspenso de status, Preview EU impact / Save changes / Reset. Não bloqueante via RemixuseFetcher. - Robustez: Helpers do simulador extraídos (
readUpdatePatchFromForm,marketCountriesKey) + 18 novos testes unitários; correção de bug: entrada única não ISO não limpa mais a lista de mercados.
2026-04 · Visualização de conformidade da UE ao vivo no formulário de criação (Q3.3.6)
- Alterado:
POST /v1/dpp/validateagora também retornaeu_compliance— o mesmo validador deGET /v1/dpp/:id/eu-compliance, stateless antes de salvar. - Dashboard: Visualização abaixo do painel de validação existente + novo banner de proteção ao salvar (Save-Guard-Banner) antes dos botões de envio quando houver erros/avisos pendentes (pluralização i18n DE/EN).
2026-04 · Validador da UE + UI de Têxteis (Q3.3.4 + Q3.3.5)
- Novo: Validador de conformidade da UE com 5 regras de têxteis (
TEXTILE_AGEC_REQUIRED,TEXTILE_MICROPLASTICS_CONSISTENCY,TEXTILE_SVHC_THRESHOLD,TEXTILE_GREENWASHING,TEXTILE_ESPR_READY). - Novo:
GET /v1/dpp/:id/eu-compliancecomcompliant/espr_ready/issues[]/summary. - Dashboard: Seção de conformidade da UE nos detalhes do DPP (blocos de resumo, cards de problemas agrupados, selo ESPR-Ready no cabeçalho).
2026-04 · Esquema de DPP para Têxteis (Q3.3.1–Q3.3.3)
- Novo: Categoria
textilecom cadeia obrigatória AGEC (tecelagem/tricô → tingimento/impressão → confecção), por fibraorigin_country+recycled_pct,svhc_substances[], opt-in ESPR (PEF, vida útil, reciclabilidade). - Novo: Campo básico
market_countries: string[](ISO 3166-1 alpha-2) em todas as categorias de DPP — controla as regras AGEC específicas da França e a nota obrigatória do consumidor francês. - Novo: Modelo HTML do consumidor com caixa de aviso de microplásticos AGEC, cadeia de origem de 3 etapas (pílulas com bandeiras), lista SVHC, seção de durabilidade e reciclabilidade.
- Migração:
0010_dpp_market_countries(D1).
2026-04 · Importação em lote de DPP (Q3.2.1–Q3.2.5)
- Novo:
POST /v1/dpp/importaceita CSV e XLSX (compatível com Workers via SheetJSxlsx, pacote gzip de ~283 KB). - Escalável: limite baseado no plano (Free 100 → Enterprise 10k) +
db.batch()em blocos (chunked) de 100 + limite de corpo de 5 MB. - Novo: Relatório de erros como CSV no campo
errors_csvda resposta 201;GET /v1/dpp/import/templates/:category?format=csv|xlsxfornece modelos prontos para baterias e têxteis. - Dashboard: Upload por arrastar e soltar em
/dashboard/dpp/importcom proxy de modelo e download de CSV inline.
Extensões LTS sem alterações incompatíveis (Non-Breaking)
Todas as alterações mencionadas acima são aditivas:
- Clientes existentes de
POST /v1/dpp/validateignoram o novo campoeu_compliancesem alterações. - Fluxos existentes de
batterypermanecem inalterados. market_countriesé opcional e tem como padrão[].
Consulte Versão da API para obter a política de alterações incompatíveis (breaking changes).