Přeskočit na obsah

Changelog

Changelog

Vybrané novinky z posledních vydání. Pro úplné verze API a zásady změn narušujících zpětnou kompatibilitu (Breaking-Change-Policy) viz Verzování API & LTS zásady.

Podrobné změny u jednotlivých koncových bodů (endpoints): Specifikace OpenAPI a interaktivní API reference.


2026-08 · Keyset-kurzor nyní na všech seznamových koncových bodech

  • Oprava: Oprava kurzoru pro GET /v1/codes a GET /v1/dpp (viz níže) je nyní nasazena na všechny ostatní seznamy s kurzorovým stránkováním: GET /v1/qr-codes/:id/comments, /v1/workspaces, /v1/gs1/identifiers, /v1/members, /v1/audit-logs, /v1/admin/orgs, /v1/admin/users a /v1/webhooks/:id/deliveries. Všechny listovaly pouze podle created_at; řádky se stejným časovým razítkem (záznamy auditu z dávkové operace, opakované pokusy webhooků, importy členů) se mohly na následující stránce ztratit. Třídicí klíč je nyní všude n-tice (created_at, id).
  • Změna API: V těchto seznamech je meta.pagination.next_cursor od nynějška rovněž opakní hodnota (base64url) namísto prostého časového razítka; nečitelné kurzory vracejí 400, staré kurzory s časovým razítkem jsou přechodně nadále akceptovány. Výjimka GET /v1/webhooks/:id/deliveries: tam zůstává next_cursor ID posledního doručení (neznámé ID → první stránka). Klienti, kteří vracejí next_cursor beze změny — Nástěnka, CLI, SDKs, MCP —, nemusí nic měnit.
  • Dopad: Není nutná žádná migrace. Pokud vám v některém z těchto seznamů (např. auditní log nebo log doručení v Nástěnce) při listování chyběly položky: Nikdy nezmizely — seznamy je od nynějška zobrazují kompletně.

2026-08 · Časová razítka po úpravě a smazání opět v souladu s OpenAPI

  • Oprava: Po PATCH /v1/codes/{id} se updated_at vracelo ve formátu SQLite bez časového pásma (2026-08-17 09:00:00), přestože specifikace OpenAPI vyžaduje format: date-time a vytvoření (POST) poskytuje ISO časové razítko (2026-08-17T09:00:00.000Z). Totéž platilo pro deleted_at/updated_at při soft-delete a také pro cesty pro úpravu/smazání u API klíčů, organizací, workspaců, členů, komentářů a webhooků, a dále pro last_used_at u API klíčů a last_triggered_at u webhooků. Všechny zapisovací cesty nyní používají formát ISO 8601 (UTC, T a Z).
  • Dopad: Klienti, kteří parsují updated_at pomocí new Date(...) (SDKs, CLI, Nástěnka), četli formát s mezerou jako místní čas — CLI u jednou upravených kódů zobrazovalo čas posunutý o místní časový posun (Vídeň: −2 h). To je nyní opraveno. Migrace dat navíc normalizuje již uložené hodnoty ve starém formátu na ISO, aby řazení a porovnávání ve smíšených datech fungovalo správně. Žádné změny v názvech polí nebo struktuře odpovědi.
  • Pozadí: Stejná třída chyb jako u dvou oprav níže (vypršení platnosti API klíče, cutoff pro re-scan): SQLite datetime('now') zapisuje YYYY-MM-DD HH:MM:SS, zatímco všechny ostatní zápisy používají ISO 8601. Guard test ve zdrojovém kódu do budoucna zabrání novému výskytu této chyby.

2026-08 · Stránkování seznamů již neztrácí dávkové kódy

  • Oprava: GET /v1/codes a GET /v1/dpp stránkovaly pouze podle created_at. Kódy z POST /v1/codes/batch, POST /v1/dpp/batch a CSV/XLSX importu však sdílejí jedno časové razítko — jakmile byla dávka větší než limit (výchozí hodnota 20), druhá stránka již nevracela zbývající řádky se stejným časovým razítkem. Kódy existovaly a byly dostupné přes GET /v1/codes/:id, ale v seznamu (Nástěnka, CLI qr3 list, SDKs, MCP) se nikdy neobjevily. Kurzor je nyní keyset nad (created_at, id).
  • Změna API: meta.pagination.next_cursor je od nynějška opakní hodnota (base64url) namísto prostého časového razítka. Ti, kteří vracejí kurzor beze změny jako ?cursor= — tak jak to dělá Nástěnka, CLI, všechna SDKs a MCP server — nemusí nic měnit. Staré kurzory s časovým razítkem budou v přechodném období nadále akceptovány; nečitelné kurzory nyní vracejí 400 namísto tichého vrácení první stránky.
  • Dopad: Pokud jste po dávkovém importu viděli v seznamu méně kódů, než kolik jich bylo vytvořeno: Kódy se nikdy neztratily — seznam je od nynějška zobrazuje kompletně. Není nutná žádná migrace.

2026-08 · Bezpečnostní re-scany opět probíhají ve 24hodinovém intervalu

  • Oprava: Periodické re-scany cílových URL a odkazů na landing page (Google Web Risk) přeskakovaly kódy, jejichž poslední sken proběhl ve stejný kalendářní den jako 24hodinový cutoff — v závislosti na čase se re-scan zpozdil až o další den. Cutoff se nyní počítá ve stejném formátu ISO, v jakém jsou uložena časová razítka skenů.
  • Dopad: Cílová URL, která je po posledním skenu vyhodnocena jako nebezpečná, vede opět v rámci zdokumentovaného 24hodinového okna k automatickému pozastavení kódu. Žádná změna API ani formátu odpovědi.

2026-08 · API klíče vyprší v okamžiku vypršení platnosti

  • Oprava: API klíč, jehož expires_at připadal na stejný den, byl dříve akceptován až do půlnoci UTC. Vypršení platnosti se nyní porovnává jako časové razítko namísto řetězce — expirovaný klíč okamžitě vrátí 401.
  • Pozadí: expires_at se ukládá jako ISO časové razítko (2026-08-14T09:00:00Z), porovnávaná strana však poskytovala formát s mezerou (2026-08-14 09:00:00). Porovnání surových řetězců proto fungovalo správně pouze tehdy, pokud se lišilo již samotné datum.
  • Dopad: Není nutná žádná migrace, formát odpovědi z GET /v1/api-keys zůstává nezměněn. Nečitelné hodnoty vypršení platnosti jsou nyní považovány za expirované namísto platných.

2026-08 · API reference: Správa tenantů dokumentována

  • OpenAPI: Specifikace — a tím pádem i interaktivní referenční příručka — nyní dokumentuje organizace (včetně GET /v1/organizations/usage), Workspaces, členy a role a auditní logy.
  • Billing: Přehled tarifů (GET /v1/billing/plans) je veřejný; checkout (POST /v1/billing/checkout) a zákaznický portál Stripe (GET /v1/billing/portal) jsou označeny jako koncové body pro administrátory organizace.
  • Export skenů: Statistiky skenování (GET /v1/codes/{id}/scans) a export surových dat (…/scans.csv, …/scans.xlsx) jsou plně dokumentovány — včetně upozornění ohledně GDPR: ip_hash není nikdy součástí exportu.
  • Chování při chybách: Nově je dokumentována také odpověď 400 při validaci požadavku: Tělo odpovědi je surová chyba Zod, nikoli dokument o problému podle RFC-7807 — přesto je však odesíláno s Content-Type application/problem+json.

2026-08 · Kopírování veřejných odkazů na soubory

  • Dashboard: Veřejné soubory na stránce s podrobnostmi o kódu mají nyní tlačítko, které zkopíruje jejich veřejný odkaz do schránky – ten lze použít přímo jako cílovou URL QR kódu, pokud má naskenování okamžitě otevřít konkrétní dokument namísto vstupní stránky (landing page) se seznamem souborů.
  • API: Koncové body pro soubory (/v1/files) navíc vracejí public_url. Toto pole je nastaveno pouze u souborů s visibility: public – soukromé soubory veřejnou adresu nedostanou.
  • Chování: Odkaz nevyžaduje přihlášení a otevře soubor přímo v prohlížeči. Nahrazení souboru ponechá odkaz beze změny, takže na něm vytištěný kód zůstává platný. Podrobnosti: Soubory & datové listy.

2026-07 · Týmové role: Editor bez možnosti mazání & fakturace administrátora

  • Novinka: Členská role Editor (bez mazání) — vytváří a upravuje QR kódy, soubory a Digital Product Passports, ale nemůže nic mazat ani vytvářet API klíče. Všechny destruktivní koncové body kontrolují roli na straně serveru (403).
  • Fakturace: Upgrady tarifů a zákaznický portál Stripe (POST /v1/billing/checkout, GET /v1/billing/portal) jsou nyní vyhrazeny administrátorům organizace — všechny ostatní role vidí přehled tarifů pouze pro čtení.
  • Dashboard: Akce, které vlastní role neumožňuje, jsou skryty: Prohlížitel (Viewer) například nevidí tlačítka pro vytváření, úpravu nebo mazání; seznamy, stahování a statistiky zůstávají viditelné. Podrobnosti: Tým & role.

2026-06 · Externí odkazy na vstupní stránce kódu

  • Vstupní stránka: Vstupní stránka kódu hostovaná na qr3 nyní může zobrazovat externí, vlastnoručně hostované odkazy ({ label, url }) – navíc k nahraným souborům nebo namísto nich, například pro datové listy na vašem vlastním webu.
  • API: POST/PATCH /v1/codes přijímají pole links (0–20 položek, http(s), ≤ 2048 znaků). Každá URL je kontrolována pomocí Google Web Risk; nebezpečná URL vrátí 422. Prázdné pole smaže všechny odkazy.
  • Dashboard: Přidávání, řazení a odebírání odkazů na stránce s podrobnostmi o kódu.
  • Bezpečnost: Vykreslené odkazy zůstávají zabezpečené proti XSS (escapované, pouze http(s)) a stránka si zachovává hlavičku noindex.

2026-04 · Analytika pro jednotlivé QR kódy v Dashboardu

  • Dashboard: Tlačítko analytiky v seznamu QR kódů nyní otevírá stránku se statistikami příslušného QR kódu na adrese /dashboard/codes/{id}.
  • Směrování (Routing): Alias /dashboard/codes nadále přesměrovává na /dashboard, ale již nezachytává detailní trasy jako /dashboard/codes/{id}.
  • API: Stránka s podrobnostmi načítá QR kód přímo pomocí GET /v1/codes/:id; díky tomu již nezávisí na limitech stránkování seznamu.
  • Testy: Regresní testy pokrývají přesměrování aliasu a přímé načtení kódu.

2026-04 · Dialog pro smazání QR kódu v Dashboardu

  • Dashboard: Ikona koše v seznamu QR kódů nyní otevírá vlastní React dialog namísto nativního vyskakovacího okna prohlížeče.
  • Zpětná vazba: Po smazání se zobrazí oznámení (toast) o úspěchu nebo chybě.
  • Testy: packages/dashboard/tests/dashboard.test.ts zabraňuje regresím u confirm() v procesu mazání QR kódu.

2026-04 · Testování krátkých odkazů pro dynamické QR kódy v Dashboardu

  • Dashboard: Zkrácené kódy (shortcodes) v seznamu QR kódů jsou nyní přímo klikatelné jako externí přesměrovávací odkazy. Ikona externího odkazu vedle např. wu3qaa otevře https://qr3.app/{shortCode} na nové kartě.
  • i18n: Doplněny texty tooltipů pro němčinu a angličtinu.
  • Testy: packages/dashboard/tests/dashboard.test.ts chrání href odkazu, chování na nové kartě, noopener noreferrer a ikonu před regresí.

2026-04 · Trasa Redirect-Workeru pro dynamické QR kódy

  • Oprava: Dynamické QR kódy na adrese https://qr3.app/{shortCode} jsou opět zpracovávány Redirect-Workerem. Produkční trasa nyní používá qr3.app/*, protože trasy Cloudflare Workers nepodporují parametry cesty :code.
  • Zabezpečení (Hardening): Neodpovídající cesty jsou předávány na původní cílovou adresu (landing origin), aby běžné stránky jako /de/pricing nebyly blokovány Redirect-Workerem.
  • Testy: packages/redirect/tests/unit/redirect.test.ts ověřuje wildcard trasu, zpracování zkrácených kódů a předávání na origin.

2026-04 · Přehled skenů DPP v pracovním prostoru (Q3.4.2)

  • Novinka: GET /v1/workspace/stats/dpp?days=30 — agreguje všechny dpp_scans daného pracovního prostoru API klíče (active_dpps, scans_by_day, top_dpps s názvem produktu/kategorií).
  • Dashboard: Karta na úvodní stránce (/dashboard) s 30denním sloupcovým grafem + žebříčky nejlepších — paralelně ke kartám QR kódů.
  • Veřejné: Marketingový krátký odkaz GET /dpp/dpp_<id> (jeden segment) pro živá dema, paralelně k /dpp/{gtin}/{serial}.

2026-04 · Analytika skenů DPP (Q3.4.1)

  • Novinka: GET /v1/dpp/:id/stats?days=30 — agregované skeny veřejného GS1 resolveru pro jedno DPP. Pole: total_scans, period_scans, scans_by_day, top_countries, top_devices, top_representations.
  • Novinka: Tabulka dpp_scans (migrace 0011) — oddělená od scans (Redirect-Worker). IP adresy jsou hashovány pomocí denně rotující soli (salt), surové IP adresy se do D1 nikdy nedostanou.
  • Dashboard: Miniaturní karta s grafem (SVG, bez knihovny pro grafy) na /dashboard/dpp/:dppId s 30denními sloupci + rozborem top 3. Prázdný stav (empty state), jakmile je DPP aktivní, ale ještě nemá žádné skeny.

2026-04 · Simulátor shody s předpisy EU v reálném čase (Q3.3.7)

  • Novinka: POST /v1/dpp/:id/validate-update — simuluje částečné aktualizace bezstavově (stateless) (status, seznam trhů, …) bez perzistence. Odpověď obsahuje eu_compliance + preview.changed_fields.
  • Dashboard: Karta simulátoru v detailu DPP (/dashboard/dpp/:dppId) — štítky (chips) pro DE/AT/FR/IT/ES/NL + vlastní, rozbalovací nabídka stavu, Preview EU impact / Save changes / Reset. Neblokující přes Remix useFetcher.
  • Zabezpečení (Hardening): Vyčlenění pomocných funkcí simulátoru (readUpdatePatchFromForm, marketCountriesKey) + 18 nových unit testů; oprava chyby: osamocený ne-ISO vstup již nemaže seznam trhů.

2026-04 · Náhled shody s předpisy EU v reálném čase ve formuláři pro vytvoření (Q3.3.6)

  • Změněno: POST /v1/dpp/validate navíc vrací eu_compliance — stejný validátor wie GET /v1/dpp/:id/eu-compliance, bezstavově před uložením.
  • Dashboard: Náhled pod stávajícím validačním panelem + nový Save-Guard banner před odesílacími tlačítky, pokud jsou přítomny chyby/varování (i18n pluralizace DE/EN).

2026-04 · EU validátor + textilní UI (Q3.3.4 + Q3.3.5)

  • Novinka: Validátor shody s předpisy EU s 5 textilními pravidly (TEXTILE_AGEC_REQUIRED, TEXTILE_MICROPLASTICS_CONSISTENCY, TEXTILE_SVHC_THRESHOLD, TEXTILE_GREENWASHING, TEXTILE_ESPR_READY).
  • Novinka: GET /v1/dpp/:id/eu-compliance s compliant / espr_ready / issues[] / summary.
  • Dashboard: Sekce shody s předpisy EU v detailu DPP (souhrnné dlaždice, seskupené karty problémů, štítek ESPR-Ready v hlavičce).

2026-04 · Schéma textilního DPP (Q3.3.1–Q3.3.3)

  • Novinka: Kategorie textile s povinným řetězcem AGEC (tkaní/pletení → barvení/potisk → konfekce), pro každé vlákno origin_country + recycled_pct, svhc_substances[], ESPR-Opt-in (PEF, životnost, recyklovatelnost).
  • Novinka: Základní pole market_countries: string[] (ISO 3166-1 alpha-2) u všech kategorií DPP — řídí specifická pravidla AGEC pro Francii a povinné francouzské upozornění pro spotřebitele.
  • Novinka: HTML šablona pro spotřebitele s varovným boxem AGEC na mikroplasty, 3stupňovým řetězcem původu (štítky s vlajkami), seznamem SVHC a sekcemi pro odolnost (durability) a recyklovatelnost (recyclability).
  • Migrace: 0010_dpp_market_countries (D1).

2026-04 · Hromadný import DPP (Q3.2.1–Q3.2.5)

  • Novinka: POST /v1/dpp/import přijímá CSV a XLSX (kompatibilní s Workers díky SheetJS xlsx, ~283 KB gzip balíček).
  • Škálování: limit podle tarifu (Free 100 → Enterprise 10k) + dávkování db.batch() po 100 + limit velikosti požadavku (body limit) 5 MB.
  • Novinka: Chybový report jako CSV v poli errors_csv odpovědi 201; GET /v1/dpp/import/templates/:category?format=csv|xlsx poskytuje hotové šablony pro baterie a textil.
  • Dashboard: Nahrávání přetažením (drag-and-drop) na /dashboard/dpp/import s proxy šablon a přímým stahováním CSV.

Změny bez dopadu na zpětnou kompatibilitu (Non-Breaking) — rozšíření LTS

Všechny výše uvedené změny jsou aditivní (doplňující):

  • Stávající klienti POST /v1/dpp/validate ignorují nové pole eu_compliance bez nutnosti úprav.
  • Stávající procesy pro battery (baterie) zůstávají nezměněny.
  • Pole market_countries je volitelné a jeho výchozí hodnota je [].

Viz Verzování API pro zásady zpětné kompatibility (Breaking-Change-Policy).