Changelog
Changelog
Points forts sélectionnés des dernières versions. Pour les versions complètes de l’API et la politique de rupture de compatibilité, consultez la Politique de versioning de l’API & LTS.
Modifications détaillées des différents points de terminaison : Spécification OpenAPI et référence API interactive.
2026-10 · Couleurs dans le Tableau de bord
- Nouveau : la page de détails d’un code comporte la carte Couleurs : premier plan et arrière-plan en valeur hexadécimale, arrière-plan transparent, aperçu via la véritable route d’image. La vérification est celle de
PATCH /v1/codes/{id}: les paires critiques nécessitent une confirmation, les paires inférieures à 1,5 : 1 ne peuvent pas être enregistrées. - La réinitialisation en noir sur blanc fournit de nouveau dans les quatre formats les mêmes octets que sans couleurs. Les codes sans couleurs ne changent pas.
- Les codes transparents apparaissent sur un damier dans tous les aperçus du Tableau de bord. Détails : Couleurs dans le Tableau de bord.
2026-10 · Couleurs en PDF et EPS
- Nouveau :
qr.pdfetqr.epsdessinentfgetbg, en tant que paramètres et en tant que couleurs enregistrées. Le noir et chaque nuance de gris sont écrits en niveaux de gris (uniquement sur la plaque noire), toute autre couleur en CMJN en pourcentages entiers, par exemple1F4E79sous la forme C74 M36 Y0 K53. - Arrière-plan comme pour le SVG : Dès qu’une couleur est sélectionnée, une zone opaque se trouve derrière le code et sa zone de silence, en blanc ou en
bg.bg=transparentn’en dessine aucune. Le titre reste noir, la plaque du logo blanche. - Aucune modification sans couleurs : Sans
fg/bget sans couleurs enregistrées, les deux formats fournissent les mêmes octets qu’auparavant. Le PDF d’un passeport produit reste non coloré. - Limites : pas de profil ICC, pas de PDF/X. Détails : Couleurs à l’impression.
2026-09 · Codes statiques sans cache de redirection, suppression simultanée
- Modifié : Les codes statiques ne se trouvent plus dans le cache de redirection. Un appel de leur lien court (
redirect_url) lit toujours l’état actuel. Après unDELETE /v1/account, un code statique ne redirige donc plus lors du prochain appel, alors qu’il pouvait le faire auparavant pendant jusqu’à 24 heures. Un changement de forfait prend également effet immédiatement pour les codes statiques. La suppression du compte nettoie les codes dynamiques comme auparavant. Les codes statiques imprimés contiennent directement leur destination et ne sont pas concernés. - Corrigé : Deux requêtes
DELETE /v1/codes/:idsimultanées sur le même code renvoient une fois200et une fois404. Le webhookqr.deletedest envoyé exactement une fois, contre deux auparavant. - Nouveau :
POSTetDELETE /v1/codes/:id/logorépondent par409(errors/conflict) si une autre requête a modifié simultanément le logo du même code, et ne modifient rien dans ce cas. Auparavant, un logo téléversé pouvait rester stocké sans être utilisé. Deux requêtesDELETE /v1/codes/:id/logosimultanées renvoient toutes deux200. Détails : Logo.
2026-09 · SDK TypeScript 1.2.0
- Nouveau dans
@qr3/sdk1.2.0 :client.codes.update()accepteappearanceet fournit les résultats de la vérification du contraste sous forme d’issuesdans le résultat ; en l’absence d’anomalie, le champ est absent.client.codes.imageUrl()acceptefg,bgetecc. Chaque code renvoyé par l’API (get,list,create,update,batchCreate) comportetitleetappearance. - Mise à jour :
npm install @qr3/sdk@latest. Python, Go et PHP suivront. Détails : SDK et CLI et Enregistrer les couleurs sur le code.
2026-09 · La nouvelle date d’expiration s’applique dans un délai d’environ une minute
- Corrigé : Un
PATCHsurexpires_atvide désormais le cache de redirection du code. La nouvelle date d’expiration s’applique ainsi dans un délai d’environ une minute, au lieu de prendre jusqu’à 24 heures. Auparavant, une expiration supprimée ou reportée continuait à renvoyer un code410pendant jusqu’à 24 heures, et une expiration définie sur l’instant présent laissait la redirection active pendant jusqu’à 24 heures. - Corrigé : Un code créé avec
expires_atexpire également à l’heure prévue si l’expiration intervient dans les premières 24 heures. - Corrigé : Si un code est supprimé pendant que son logo est en cours de chargement ou de suppression,
POSTetDELETE /v1/codes/:id/logorépondent par un code404et ne modifient pas le code supprimé, tout comme le fait déjàPATCH. - Corrigé : Même un code statique dont le lien court (
redirect_url) a été appelé est stocké dans le cache de redirection. La modification, la mise en pause et la suppression le vident désormais également, et pas seulement pour les codes dynamiques.
2026-09 · Enregistrer des couleurs sur le code
- Nouveau :
PATCH /v1/codes/:idaccepteappearanceavecforeground_coloretbackground_color(#RRGGBB, l’arrière-plan acceptant égalementtransparent).qr.svgetqr.pngdessinent les couleurs enregistrées sans aucun paramètre ; un paramètre de requête tel que?fg=000000reste prioritaire. PDF et EPS ne dessineront les couleurs qu’avec une version ultérieure. - Vérification du contraste : Une paire inférieure à 1,5:1 renvoie
422. Les paires plus faibles sont enregistrées et signalées dansmeta.issuescommewarningoucritical; un arrière-plan transparent est toujourscritical, jamais bloqué. - Fusion : Les champs omis conservent leur valeur enregistrée,
nullréinitialise. Les modifications simultanées sur le même code ne s’écrasent plus mutuellement. - Dans chaque réponse de code :
appearancefigure dans chaque réponse de code et dans les webhooksqr.createdetqr.updated.POST, le batch et l’importation le rejettent avec422. - Aucun changement pour les codes existants : Sans couleurs enregistrées, chaque code fournit les mêmes octets qu’auparavant. Détails : Enregistrer des couleurs sur le code.
2026-09 · Couleurs et correction d’erreurs comme paramètres des routes d’images
- Nouveau : Les quatre routes d’images acceptent
fg(couleur de premier plan),bg(couleur d’arrière-plan outransparent) etecc(correction d’erreursL,M,Q,H). SVG et PNG dessinent les couleurs ; PDF et EPS les acceptent, mais ne les dessineront que lors d’une version ultérieure.eccfonctionne dans les quatre formats, un logo continue d’imposerH. - Transparence :
bg=transparentfournit un SVG sans arrière-plan et un PNG avec un véritable canal alpha. Le fond doit être clair et laisser la zone de silence libre. - Jamais une erreur : Les valeurs invalides sont ignorées ; l’image s’affiche alors exactement comme sans paramètre.
- Mise en cache : Chaque paramètre effectif fournit
Cache-Control: public, max-age=300au lieu des 24 heures de l’image par défaut. - Aucun changement de comportement sans paramètre : Tout code existant fournit les mêmes octets qu’auparavant dans les quatre formats.
- Disponible dans tous les tarifs. Détails : Couleurs et correction d’erreurs.
2026-09 · PDF et EPS intègrent désormais également le logo
- Extension :
qr.pdfetqr.epsintègrent désormais un logo configuré de la même manière queqr.svgetqr.png(voir ci-dessous) — sous forme d’image intégrée (PDF via unImage XObject, EPS via un dictionnaire d’images en PostScript, là uniquement avec%%LanguageLevel: 3), centré sur la même zone, avec la même augmentation de la correction d’erreurs àH. Jusqu’à présent, les deux formats ne fournissaient pas le logo ; cela est maintenant corrigé. - Mise en cache : Lorsqu’un logo est configuré,
qr.pdfetqr.epsrenvoient désormais égalementCache-Control: public, max-age=300au lieu des 24 heures habituelles — tout comme SVG/PNG. - Solution de repli : Si l’image du logo elle-même ne peut pas être traitée (par exemple, un objet enregistré corrompu), la correction d’erreurs reste à
H, mais la zone réservée reste vide au lieu d’afficher une image — sans jamais générer d’erreur de serveur. - Aucun changement de comportement sans logo : Les codes sans logo continuent de fournir des fichiers
qr.pdf/qr.epsidentiques à l’octet près, avec un cache de 24 heures inchangé. - Détails et consignes d’impression : Logo dans le QR-Code.
2026-09 · Logo dans le code QR — Tableau de bord et API
- Nouveau : Un code peut désormais comporter un logo au centre. Dans le Tableau de bord, la page de détails d’un code crée une carte de logo dédiée : Sélectionner un logo, confirmer un avertissement avec une case à cocher obligatoire lors du premier ajout ou de la suppression (les deux modifient le motif de points), puis Téléverser le logo/Supprimer le logo. Un remplacement ne nécessite aucune confirmation — seule l’image change, pas le motif. Le rôle
viewervoit le statut et l’aperçu, mais n’a accès à aucune des trois actions. - API :
POST /v1/codes/{id}/logo(champ multipartfile; PNG, JPEG ou WebP, maximum 1 Mo, SVG est refusé) crée un logo ou le remplace ;DELETE /v1/codes/{id}/logole supprime à nouveau et est idempotent. Une image trop grande renvoie413, un format non pris en charge422, le rôleviewer403. - Rendu :
qr.svgetqr.pngintègrent le logo sous forme de pixels réels (512 × 512, normalisés) et augmentent pour cela le niveau de correction d’erreurs àH. L’ajout et la suppression modifient ainsi le motif de points (M↔H), mais pas le remplacement.qr.pdfetqr.epsn’intègrent aucun logo et restent inchangés. Un code déjà imprimé continue de fonctionner dans tous les cas, car la cible encodée ne dépend pas du logo — seuls ceux qui souhaitent voir le (nouveau) rendu visuel du logo sur le support physique doivent réimprimer, en veillant à ne pas mélanger les anciens et les nouveaux fichiers d’impression. - Mise en cache : Lorsque le logo est défini,
qr.svgetqr.pngrenvoientCache-Control: public, max-age=300au lieu des 24 heures habituelles. Détails, limites et conseils d’impression : Logo dans le code QR.
2026-08 · operationId pour l’ensemble des 75 opérations, et un guide d’utilisation pour les agents
- Ajout : L’ensemble des 75 opérations de la spécification OpenAPI portent désormais une
operationId—listCodes,createCode,getCodeStats,archiveWorkspaceet ainsi de suite. Jusqu’à présent, ce champ manquait systématiquement, de sorte que chaque générateur devait déduire le nom de la méthode à partir de la méthode HTTP et du chemin (postV1Codes). De tels noms dépendent du chemin et changent à chaque modification de celui-ci. La forme du nom est identique aux 75 emplacements :list/get/create/update/replace/delete, sinon le verbe de l’action métier (validateDpp,registerGs1Identifier,pingWebhook). Le verbe suit la logique métier, non la méthode HTTP —archiveWorkspaceest unDELETE,importDppsest unPOST. - Impact sur les clients auto-générés : Si vous générez votre SDK à partir de la spécification, vous obtiendrez des méthodes renommées (
postV1Codes→createCode) lors de la prochaine exécution. C’est le but de ce changement, mais il s’agit d’un renommage dans du code tiers — c’est pourquoi cela est explicitement mentionné ici. Les chemins, paramètres, formats de réponse et codes d’état restent inchangés ; les SDK officiels, la CLI et le serveur MCP ne sont pas concernés. - Introduction pour les agents :
https://qr3.app/llms.txtcontient une section## When to use qr3.app— six tâches au lieu de six fonctions, plus la phrase indiquant ce pour quoi qr3.app n’est pas le bon outil. Le serveur MCP fournit désormais la même information lors de la phase d’initialisation :initializesurhttps://mcp.qr3.app/mcprépond avec un champinstructions(auparavant : onze outils sans aucune classification). Il indique également quels appels nécessitent une clé API —initializeettools/listnon, mais chaquetools/calloui. - Corrections dans
llms.txt: Quatre informations ont été vérifiées par rapport à la production et se sont révélées incorrectes : (1) le SDK Pythonqr3appn’est pas publié sur PyPI — la lignepip installest supprimée sans remplacement ; (2)Accept: text/markdowns’applique à la page d’accueil et au blog, pas à toutes les pages générées côté serveur ; (3) l’adresse de contact est[email protected], y compris dans le JSON-LD de la page d’accueil ; (4)/de/security/est une redirection vers un ancrage, pas une page distincte. Nouveau lien :docs.qr3.app/de/skills/. - Sécurisation : Trois assertions dans
openapi-spec.test.ts— exhaustivité, unicité,lowerCamelCase—, chacune contre-vérifiée par une mutation. Neuf tests supplémentaires figent les quatre informations corrigées afin d’éviter toute régression. - Limitation connue : Deux des 75 opérations sont décrites dans la spécification mais répondent par un
404(GET /v1/codes/{id}/statsetGET /v1/account). Elles ont reçu un nom ici et le perdront à nouveau dès qu’il aura été décidé si elles seront implémentées ou supprimées.
2026-08 · Les rétrogradations de forfait et les résiliations s’appliquent désormais aussi aux limites
- Correctif : Lors d’un changement de forfait ou d’une résiliation, le webhook Stripe n’enregistrait que le nom du forfait, et non les quatre colonnes de limites de l’organisation (
max_workspaces,max_members,max_dynamic_codes,max_scans_per_month). Comme l’application des limites prend le maximum entre la valeur enregistrée et la valeur de référence du forfait, une organisation rétrogradée ou résiliée conservait ses anciennes limites plus élevées — la rétrogradation était donc sans effet. Le webhook définit désormais ces colonnes sur la valeur de référence du nouveau forfait lors de chaque changement réel de forfait, et sur la valeur de référence Free en cas de résiliation — tout comme le fait déjà la gestion administrative. - Comportement : Les mises à jour de routine de l’abonnement (renouvellement, moyen de paiement, prorata) ne touchent toujours pas aux limites ; les limites plus élevées accordées individuellement restent inchangées. Seul un véritable changement de forfait les réinitialise à la valeur de référence du nouveau forfait.
- Impact : Aucune modification de l’API ou du format de réponse. Les organisations dont la rétrogradation a eu lieu avant ce correctif conservent leurs anciennes valeurs jusqu’à ce que le prochain changement de forfait s’applique ou que le support les ajuste.
2026-08 · Curseur keyset désormais sur tous les endpoints de liste
- Correctif : Le correctif de curseur pour
GET /v1/codesetGET /v1/dpp(voir ci-dessous) est désormais déployé sur toutes les autres listes paginées par curseur :GET /v1/qr-codes/:id/comments,/v1/workspaces,/v1/gs1/identifiers,/v1/members,/v1/audit-logs,/v1/admin/orgs,/v1/admin/userset/v1/webhooks/:id/deliveries. Toutes paginaient uniquement viacreated_at; les lignes ayant un horodatage identique (entrées d’audit d’une opération par lot, tentatives de webhook, importations de membres) pouvaient être perdues sur la page suivante. La clé de tri est désormais partout le tuple(created_at, id). - Modification de l’API : Sur ces listes,
meta.pagination.next_cursorest désormais également une valeur opaque (base64url) au lieu d’un simple horodatage ; les curseurs illisibles renvoient400, les anciens curseurs d’horodatage continuent d’être acceptés de manière transitoire. Exception pourGET /v1/webhooks/:id/deliveries: ici,next_cursorreste l’ID de la dernière livraison (ID inconnu → première page). Les clients qui renvoientnext_cursorsans modification — Tableau de bord, CLI, SDKs, MCP — n’ont rien à changer. - Impact : Aucune migration requise. Si vous avez manqué des entrées lors de la navigation dans l’une de ces listes (par exemple, le journal d’audit ou le journal de livraison dans le Tableau de bord) : elles n’ont jamais disparu — les listes les affichent désormais de manière complète.
2026-08 · Les horodatages après modification et suppression sont à nouveau conformes à OpenAPI
- Correctif : Après
PATCH /v1/codes/{id},updated_atétait renvoyé au format SQLite sans fuseau horaire (2026-08-17 09:00:00), bien que la spécification OpenAPI prometteformat: date-timeet que la création (POST) fournisse l’horodatage ISO (2026-08-17T09:00:00.000Z). Il en allait de même pourdeleted_at/updated_atlors de la suppression logique (soft-delete) ainsi que pour les chemins de modification/suppression des clés API, organisations, workspaces, membres, commentaires et webhooks, ainsi que pourlast_used_atdes clés API etlast_triggered_atdes webhooks. Tous les chemins d’écriture horodatent désormais en ISO 8601 (UTC,TetZ). - Impact : Les clients qui analysent
updated_atavecnew Date(...)(SDKs, CLI, Tableau de bord) lisaient le format avec espace comme l’heure locale — la CLI affichait l’heure décalée de l’offset local pour les codes modifiés une fois (Vienne : −2 h). Ce problème est résolu. De plus, une migration de données normalise les valeurs déjà enregistrées dans l’ancien format vers le format ISO, afin que le tri et les comparaisons soient corrects dans les bases de données mixtes. Aucun changement au niveau des noms de champs ou de la structure des réponses. - Contexte : Même classe d’erreur que les deux corrections ci-dessous (expiration des clés API, limite de re-scan) : le
datetime('now')de SQLite écritYYYY-MM-DD HH:MM:SS, tandis que tous les autres chemins d’écriture utilisent l’ISO 8601. Un test de garde dans le code source empêchera de nouvelles occurrences à l’avenir.
2026-08 · La pagination des listes ne perd plus de codes batch
- Correctif :
GET /v1/codesetGET /v1/dpppaginaient uniquement viacreated_at. Cependant, les codes issus dePOST /v1/codes/batch,POST /v1/dpp/batchet de l’importation CSV/XLSX partagent un seul horodatage — dès qu’un lot était plus grand quelimit(par défaut 20), la deuxième page ne renvoyait plus les lignes restantes de ce même horodatage. Les codes existaient et étaient accessibles viaGET /v1/codes/:id, mais n’apparaissaient jamais dans la liste (Tableau de bord, CLIqr3 list, SDKs, MCP). Le curseur est désormais un Keyset sur(created_at, id). - Modification de l’API :
meta.pagination.next_cursorest désormais une valeur opaque (base64url) au lieu d’un simple horodatage. Ceux qui renvoient le curseur inchangé sous la forme?cursor=— comme le font le Tableau de bord, la CLI, tous les SDKs et le serveur MCP — n’ont rien à modifier. Les anciens curseurs d’horodatage continueront d’être acceptés à titre transitoire ; les curseurs illisibles renvoient désormais400au lieu de renvoyer silencieusement la première page. - Impact : Si vous voyiez moins de codes dans la liste après un import par lot que ce qui avait été créé : les codes n’ont jamais disparu — la liste les affiche désormais en totalité. Aucune migration n’est nécessaire.
2026-08 · Les re-scans de sécurité sont à nouveau exécutés toutes les 24 heures
- Correctif : Le re-scan périodique des URL cibles et des liens de pages de destination (Google Web Risk) ignorait les codes dont la dernière analyse avait eu lieu le même jour civil que le seuil de 24 heures — selon l’heure, le re-scan était retardé jusqu’à un jour supplémentaire. Le seuil est désormais calculé dans le même format ISO que celui dans lequel les horodatages d’analyse sont stockés.
- Impact : Une URL cible classée comme non sécurisée après la dernière analyse entraîne à nouveau la mise en pause automatique du code dans la fenêtre documentée de 24 heures. Aucune modification de l’API ou du format de réponse.
2026-08 · Les clés API expirent à l’instant d’expiration
- Correctif : Une clé API dont le
expires_attombait le même jour continuait d’être acceptée jusqu’à minuit UTC. L’expiration est désormais comparée sous forme d’horodatage plutôt que de chaîne de caractères — une clé expirée renvoie immédiatement401. - Contexte :
expires_atest stocké sous forme d’horodatage ISO (2026-08-14T09:00:00Z), tandis que le côté comparaison fournissait le format avec espace (2026-08-14 09:00:00). La comparaison brute de chaînes de caractères n’était donc correcte que tant que la date elle-même différait. - Impact : Aucune migration n’est nécessaire, le format de réponse de
GET /v1/api-keysreste inchangé. Les valeurs d’expiration illisibles sont désormais considérées comme expirées plutôt que valides.
2026-08 · Référence API : Gestion des tenants documentée
- OpenAPI : La spécification — et donc la référence interactive — documente désormais les organisations (y compris
GET /v1/organizations/usage), les workspaces, les membres & rôles et les journaux d’audit. - Facturation : L’aperçu des tarifs (
GET /v1/billing/plans) est public ; le paiement (POST /v1/billing/checkout) et le portail client Stripe (GET /v1/billing/portal) sont répertoriés comme des points de terminaison pour les administrateurs d’organisation. - Exportation des scans : Les statistiques de scan (
GET /v1/codes/{id}/scans) et l’exportation des données brutes (…/scans.csv,…/scans.xlsx) sont entièrement documentées — y compris la mention RGPD : leip_hashn’est jamais inclus dans l’exportation. - Gestion des erreurs : La réponse
400de la validation de requête est également nouvellement documentée : le corps est l’erreur Zod brute, et non un document de problème RFC-7807 — elle est néanmoins fournie avec le Content-Typeapplication/problem+json.
2026-08 · Copier les liens publics des fichiers
- Tableau de bord : les fichiers publics sur la page de détails d’un code disposent désormais d’un bouton qui copie leur lien public dans le presse-papiers — directement utilisable comme URL cible d’un code QR lorsqu’un scan doit ouvrir un document précis plutôt que la page de destination et sa liste de fichiers.
- API : les endpoints de fichiers (
/v1/files) renvoient en pluspublic_url. Le champ n’est défini que pour les fichiers avecvisibility: public— les fichiers privés n’ont pas d’adresse publique. - Comportement : le lien ne nécessite aucune connexion et ouvre le fichier directement dans le navigateur. Remplacer le fichier laisse le lien inchangé ; un code imprimé avec cette adresse reste donc valide. Détails : Fichiers & Fiches techniques.
2026-07 · Rôles d’équipe : Contributeur sans suppression & facturation admin
- Nouveau : rôle de membre Contributeur (sans suppression) — crée et modifie les codes QR, les fichiers et les Digital Product Passports, mais ne peut rien supprimer ni créer de clés API. Tous les endpoints destructifs vérifient le rôle côté serveur (
403). - Facturation : les mises à niveau de forfait et le portail client Stripe (
POST /v1/billing/checkout,GET /v1/billing/portal) sont désormais réservés aux Administrateurs d’organisation — tous les autres rôles voient un aperçu du forfait en lecture seule. - Tableau de bord : les actions non autorisées par le rôle de l’utilisateur sont masquées : un Lecteur ne voit par exemple aucun bouton pour créer, modifier ou supprimer ; les listes, téléchargements et statistiques restent visibles. Détails : Équipe & Rôles.
2026-06 · Liens externes sur la page de destination du code
- Page de destination : La page de destination hébergée par qr3 d’un code peut désormais lister des liens externes auto-hébergés (
{ label, url }) en plus ou à la place des fichiers téléversés – par exemple pour des fiches techniques hébergées sur votre propre site. - API :
POST/PATCH /v1/codesacceptent un tableaulinks(0–20 entrées,http(s), ≤ 2048 caractères). Chaque URL est vérifiée avec Google Web Risk ; une URL non sécurisée renvoie422. Un tableau vide supprime tous les liens. - Tableau de bord : Ajoutez, réordonnez et supprimez des liens sur la page de détails du code.
- Sécurité : Les liens rendus restent protégés contre les XSS (échappés,
http(s)uniquement) et la page conserve son en-têtenoindex.
2026-04 · Analyses du tableau de bord par code QR
- Tableau de bord : Le bouton d’analyses dans la liste des codes QR ouvre désormais la page de statistiques du code QR correspondant sous
/dashboard/codes/{id}. - Routage : L’alias
/dashboard/codesredirige toujours vers/dashboard, mais n’intercepte plus les routes détaillées comme/dashboard/codes/{id}. - API : La page de détails charge le code QR directement via
GET /v1/codes/:id; elle ne dépend donc plus des limites de pagination de la liste. - Tests : Les tests de régression couvrent la redirection d’alias et le chargement direct du code.
2026-04 · Boîte de dialogue de suppression des codes QR sur le tableau de bord
- Tableau de bord : L’icône de corbeille dans la liste des codes QR ouvre désormais une boîte de dialogue React dédiée au lieu d’une fenêtre contextuelle native du navigateur.
- Retour d’information : Après la suppression, une notification toast apparaît pour indiquer le succès ou l’échec.
- Tests :
packages/dashboard/tests/dashboard.test.tsempêche les régressions surconfirm()dans le flux de suppression de code QR.
2026-04 · Test de lien court sur le tableau de bord pour les codes QR dynamiques
- Tableau de bord : Les codes courts dans la liste des codes QR sont désormais directement cliquables en tant que liens de redirection externes. L’icône de lien externe à côté de par ex.
wu3qaaouvrehttps://qr3.app/{shortCode}dans un nouvel onglet. - i18n : Ajout des textes d’infobulle pour l’allemand et l’anglais.
- Tests :
packages/dashboard/tests/dashboard.test.tsprotège le href du lien, le comportement du nouvel onglet,noopener noreferreret l’icône contre les régressions.
2026-04 · Route du Worker de redirection pour les codes QR dynamiques
- Correctif : Les codes QR dynamiques sous
https://qr3.app/{shortCode}sont à nouveau traités par le Worker de redirection. La route de production utilise désormaisqr3.app/*car les routes de Cloudflare Workers ne prennent pas en charge les paramètres de chemin:code. - Renforcement : Les chemins non correspondants sont transmis à l’origine de la page d’atterrissage afin que les pages normales comme
/de/pricingne soient pas bloquées par le Worker de redirection. - Tests :
packages/redirect/tests/unit/redirect.test.tsvérifie la route générique, le traitement du code court et le passage à l’origine.
2026-04 · Aperçu des scans DPP de l’espace de travail (Q3.4.2)
- Nouveau :
GET /v1/workspace/stats/dpp?days=30— agrège tous lesdpp_scansde l’espace de travail de la clé API (active_dpps,scans_by_day,top_dppsavec nom de produit/catégorie). - Tableau de bord : Carte sur la page d’accueil (
/dashboard) avec un graphique à barres sur 30 jours + listes des tops — en parallèle des cartes de codes QR. - Public : Lien court marketing
GET /dpp/dpp_<id>(un segment) pour les démos en direct, en parallèle de/dpp/{gtin}/{serial}.
2026-04 · Analyses des scans DPP (Q3.4.1)
- Nouveau :
GET /v1/dpp/:id/stats?days=30— scans agrégés du résolveur public GS1 par DPP. Champs :total_scans,period_scans,scans_by_day,top_countries,top_devices,top_representations. - Nouveau : Table
dpp_scans(migration0011) — séparée descans(Worker de redirection). Les adresses IP sont hachées avec un sel rotatif quotidien, les IP brutes n’atteignent jamais D1. - Tableau de bord : Carte mini-graphique (SVG, sans bibliothèque de graphiques) sur
/dashboard/dpp/:dppIdavec barres sur 30 jours + ventilations du top 3. État vide dès qu’un DPP est en ligne mais n’a pas encore eu de scans.
2026-04 · Simulateur de conformité UE en direct (Q3.3.7)
- Nouveau :
POST /v1/dpp/:id/validate-update— simule des mises à jour partielles sans état (statut, liste de marchés, …) sans persistance. La réponse contienteu_compliance+preview.changed_fields. - Tableau de bord : Carte de simulateur dans les détails du DPP (
/dashboard/dpp/:dppId) — puces pourDE/AT/FR/IT/ES/NL+ personnalisé, menu déroulant de statut, Preview EU impact / Save changes / Reset. Non bloquant via RemixuseFetcher. - Renforcement : Assistants de simulation externalisés (
readUpdatePatchFromForm,marketCountriesKey) + 18 nouveaux tests unitaires ; correction de bug : une entrée non-ISO isolée ne supprime plus la liste des marchés.
2026-04 · Aperçu de la conformité UE en direct dans le formulaire de création (Q3.3.6)
- Modifié :
POST /v1/dpp/validatefournit en pluseu_compliance— le même validateur queGET /v1/dpp/:id/eu-compliance, sans état avant l’enregistrement. - Tableau de bord : Aperçu sous le panneau de validation existant + nouvelle bannière de protection de sauvegarde avant les boutons de soumission si des erreurs/avertissements sont en suspens (pluralisation i18n DE/EN).
2026-04 · Validateur UE + UI Textile (Q3.3.4 + Q3.3.5)
- Nouveau : Validateur de conformité UE avec 5 règles textiles (
TEXTILE_AGEC_REQUIRED,TEXTILE_MICROPLASTICS_CONSISTENCY,TEXTILE_SVHC_THRESHOLD,TEXTILE_GREENWASHING,TEXTILE_ESPR_READY). - Nouveau :
GET /v1/dpp/:id/eu-complianceaveccompliant/espr_ready/issues[]/summary. - Tableau de bord : Section de conformité UE dans les détails du DPP (tuiles de résumé, cartes de problèmes groupées, badge ESPR-Ready dans l’en-tête).
2026-04 · Schéma DPP Textile (Q3.3.1–Q3.3.3)
- Nouveau : Catégorie
textileavec chaîne d’obligation AGEC (tissage/tricotage → teinture/impression → confection), par fibreorigin_country+recycled_pct,svhc_substances[], opt-in ESPR (PEF, durée de vie, recyclabilité). - Nouveau : Champ de base
market_countries: string[](ISO 3166-1 alpha-2) sur toutes les catégories de DPP — contrôle les règles AGEC spécifiques à la France et la notice obligatoire pour les consommateurs français. - Nouveau : Modèle HTML consommateur avec boîte d’avertissement sur les microplastiques AGEC, chaîne d’origine à 3 étapes (badges de drapeaux), liste SVHC, sections durabilité et recyclabilité.
- Migration :
0010_dpp_market_countries(D1).
2026-04 · Importation en lot de DPP (Q3.2.1–Q3.2.5)
- Nouveau :
POST /v1/dpp/importaccepte CSV et XLSX (compatible Worker via SheetJSxlsx, bundle gzip d’environ 283 Ko). - Mise à l’échelle : Limite basée sur le forfait (Free 100 → Enterprise 10k) +
db.batch()fragmenté par 100 + limite de corps de 5 Mo. - Nouveau : Rapport d’erreurs au format CSV dans le champ
errors_csvde la réponse 201 ;GET /v1/dpp/import/templates/:category?format=csv|xlsxfournit des modèles prêts à l’emploi pour les batteries et le textile. - Tableau de bord : Téléchargement par glisser-déposer sous
/dashboard/dpp/importavec proxy de modèle et téléchargement CSV en ligne.
Sans rupture — Extensions LTS
Toutes les modifications mentionnées ci-dessus sont additives :
- Les clients existants de
POST /v1/dpp/validateignorent le nouveau champeu_compliancesans modification. - Les flux
batteryexistants restent inchangés. market_countriesest facultatif et a pour valeur par défaut[].
Consultez le Versioning de l’API pour la politique de rupture de compatibilité.