Changelog
Changelog
Wybrane najważniejsze zmiany z ostatnich wydań. Pełne wersje API i zasady wprowadzania zmian niekompatybilnych wstecz (Breaking-Change-Policy) znajdują się w sekcji Wersjonowanie API i polityka LTS.
Szczegółowe zmiany w poszczególnych punktach końcowych: Specyfikacja OpenAPI oraz interaktywna referencja API.
2026-08 · Kursor typu keyset teraz na wszystkich endpointach list
- Poprawka: Poprawka kursora dla
GET /v1/codesiGET /v1/dpp(patrz poniżej) została teraz wdrożona dla wszystkich pozostałych list z paginacją opartą na kursorze:GET /v1/qr-codes/:id/comments,/v1/workspaces,/v1/gs1/identifiers,/v1/members,/v1/audit-logs,/v1/admin/orgs,/v1/admin/usersoraz/v1/webhooks/:id/deliveries. Wszystkie one stronicowały wyłącznie pocreated_at; wiersze o identycznym znaczniku czasu (wpisy audytowe operacji wsadowej, ponowne próby webhooków, importy członków) mogły zostać pominięte na kolejnej stronie. Kluczem sortowania jest teraz wszędzie krotka(created_at, id). - Zmiana w API: Na tych listach
meta.pagination.next_cursorjest od teraz również wartością nieprzezroczystą (base64url) zamiast zwykłego znacznika czasu; nieczytelne kursory zwracają400, a stare kursory oparte na znacznikach czasu będą tymczasowo nadal akceptowane. Wyjątek stanowiGET /v1/webhooks/:id/deliveries: tamnext_cursorpozostaje identyfikatorem ostatniego doręczenia (nieznany identyfikator → pierwsza strona). Klienci, którzy zwracająnext_cursorbez zmian — Dashboard, CLI, SDKs, MCP — nie muszą nic zmieniać. - Wpływ: Brak konieczności migracji. Jeśli na którejś z tych list (np. dzienniku audytu lub dzienniku doręczeń w Dashboardzie) brakowało Ci wpisów podczas stronicowania: nigdy nie zniknęły — od teraz listy wyświetlają je w całości.
2026-08 · Znaczniki czasu po edycji i usunięciu ponownie zgodne z OpenAPI
- Poprawka: Po wykonaniu
PATCH /v1/codes/{id}poleupdated_atbyło zwracane w formacie SQLite bez strefy czasowej (2026-08-17 09:00:00), mimo że specyfikacja OpenAPI deklarujeformat: date-time, a tworzenie (POST) zwraca znacznik czasu ISO (2026-08-17T09:00:00.000Z). To samo dotyczyłodeleted_at/updated_atprzy soft-delete, a także ścieżek edycji i usuwania kluczy API, organizacji, obszarów roboczych, członków, komentarzy i webhooków, jak równieżlast_used_atdla kluczy API ilast_triggered_atdla webhooków. Wszystkie ścieżki zapisu generują teraz znaczniki czasu w formacie ISO 8601 (UTC,TiZ). - Wpływ: Klienty, które parsują
updated_atza pomocąnew Date(...)(SDKs, CLI, Dashboard), odczytywały format ze spacją jako czas lokalny — CLI wyświetlało dla kodów, które były już edytowane, godzinę przesuniętą o lokalny offset (Wiedeń: −2 h). Zostało to naprawione. Dodatkowo migracja danych normalizuje już zapisane wartości w starym formacie do standardu ISO, aby sortowanie i porównania w mieszanych zbiorach danych działały poprawnie. Brak zmian w nazwach pól czy strukturze odpowiedzi. - Tło: Ta sama klasa błędu, co w przypadku dwóch poniższych poprawek (wygaśnięcie klucza API, punkt odcięcia ponownego skanowania): funkcja
datetime('now')w SQLite zapisujeYYYY-MM-DD HH:MM:SS, podczas gdy wszystkie inne procesy zapisu używają ISO 8601. Test zabezpieczający w kodzie źródłowym zapobiegnie ponownemu wystąpieniu tego problemu w przyszłości.
2026-08 · Paginacja list nie gubi już kodów tworzonych wsadowo
- Poprawka: Metody
GET /v1/codesiGET /v1/dpprealizowały paginację wyłącznie na podstawiecreated_at. Jednak kody zPOST /v1/codes/batch,POST /v1/dpp/batchoraz importu CSV/XLSX współdzielą jeden znacznik czasu — gdy tylko partia była większa niżlimit(domyślnie 20), druga strona nie zwracała już pozostałych wierszy z tym samym znacznikiem czasu. Kody istniały i były dostępne przezGET /v1/codes/:id, ale nigdy nie pojawiały się na liście (Dashboard, CLIqr3 list, SDKs, MCP). Kursor jest teraz zestawem kluczy (keyset) opartym na(created_at, id). - Zmiana w API:
meta.pagination.next_cursorjest od teraz wartością nieprzezroczystą (base64url) zamiast zwykłego znacznika czasu. Każdy, kto przekazuje kursor w niezmienionej formie jako?cursor=— tak jak robią to Dashboard, CLI, wszystkie SDKs i serwer MCP — nie musi nic zmieniać. Stare kursory oparte na znacznikach czasu będą tymczasowo nadal akceptowane; nieczytelne kursory zwracają teraz błąd400zamiast po cichu zwracać pierwszą stronę. - Wpływ: Jeśli po imporcie wsadowym na liście widocznych było mniej kodów niż utworzono: kody te nigdy nie zniknęły — od teraz lista wyświetla je w całości. Brak konieczności migracji.
2026-08 · Ponowne skanowanie bezpieczeństwa znów działa w cyklu 24-godzinnym
- Poprawka: Okresowe ponowne skanowanie docelowych adresów URL i linków stron docelowych (Google Web Risk) pomijało kody, których ostatnie skanowanie przypadało na ten sam dzień kalendarzowy, co 24-godzinny punkt odcięcia — w zależności od godziny ponowne skanowanie opóźniało się o maksymalnie kolejny dzień. Punkt odcięcia jest teraz obliczany w tym samym formacie ISO, w którym zapisywane są znaczniki czasu skanowania.
- Wpływ: Docelowy adres URL, który po ostatnim skanowaniu zostanie sklasyfikowany jako niebezpieczny, ponownie powoduje automatyczne wstrzymanie kodu w udokumentowanym 24-godzinnym oknie. Brak zmian w API lub formacie odpowiedzi.
2026-08 · Klucze API wygasają w momencie wygaśnięcia
- Poprawka: Klucz API, którego
expires_atprzypadał na ten sam dzień, był akceptowany do północy UTC. Wygaśnięcie jest teraz porównywane jako znacznik czasu, a nie jako ciąg znaków — wygasły klucz natychmiast zwraca401. - Tło:
expires_atjest zapisywany jako znacznik czasu ISO (2026-08-14T09:00:00Z), natomiast strona porównująca dostarczała format ze spacją (2026-08-14 09:00:00). Surowe porównanie ciągów znaków działało poprawnie tylko wtedy, gdy różniła się już sama data. - Wpływ: Brak konieczności migracji, format odpowiedzi
GET /v1/api-keyspozostaje bez zmian. Nieczytelne wartości wygaśnięcia są teraz traktowane jako wygasłe, a nie jako ważne.
2026-08 · Referencja API: Zarządzanie tenantami udokumentowane
- OpenAPI: Specyfikacja — a tym samym interaktywna referencja — dokumentuje teraz organizacje (w tym
GET /v1/organizations/usage), workspaces, członków i role oraz dzienniki audytu. - Billing: Przegląd planów taryfowych (
GET /v1/billing/plans) jest publiczny; proces płatności (POST /v1/billing/checkout) oraz portal klienta Stripe (GET /v1/billing/portal) są oznaczone jako punkty końcowe dla administratorów organizacji. - Eksport skanów: Statystyki skanowania (
GET /v1/codes/{id}/scans) oraz eksport surowych danych (…/scans.csv,…/scans.xlsx) są w pełni udokumentowane — w tym uwaga dotycząca RODO:ip_hashnigdy nie jest zawarty w eksporcie. - Obsługa błędów: Nowo udokumentowana jest również odpowiedź
400walidacji żądania: treść (body) to surowy błąd Zod, a nie dokument błędu RFC-7807 — niemniej jednak jest on dostarczany z nagłówkiem Content-Typeapplication/problem+json.
2026-08 · Kopiowanie publicznych linków do plików
- Dashboard: Pliki publiczne na stronie szczegółów kodu mają teraz przycisk, który kopiuje ich link publiczny do schowka – wystarczy wkleić go jako docelowy adres URL kodu QR, gdy zeskanowanie ma od razu otwierać konkretny dokument zamiast strony docelowej z listą plików.
- API: Endpointy plików (
/v1/files) zwracają dodatkowopublic_url. Pole jest ustawiane tylko przy plikach zvisibility: public– pliki prywatne nie mają publicznego adresu. - Zachowanie: Link nie wymaga logowania i otwiera plik bezpośrednio w przeglądarce. Opcja Zamień nie zmienia tego adresu, więc wydrukowany kod QR pozostaje ważny. Szczegóły: Pliki i karty danych.
2026-07 · Role zespołowe: Współtwórca bez usuwania i rozliczenia dla Administratorów
- Nowość: Rola członka Współtwórca (bez usuwania) — tworzy i edytuje kody QR, pliki oraz Digital Product Passports, ale nie może niczego usuwać ani tworzyć kluczy API. Wszystkie destrukcyjne endpointy sprawdzają rolę po stronie serwera (
403). - Rozliczenia: Ulepszenia planów i portal klienta Stripe (
POST /v1/billing/checkout,GET /v1/billing/portal) są teraz zarezerwowane dla Administratorów organizacji — wszystkie pozostałe role widzą podgląd planu tylko do odczytu. - Dashboard: Akcje, na które nie pozwala własna rola, są ukrywane: Widz nie widzi na przykład przycisków do tworzenia, edycji ani usuwania; listy, pobieranie plików i statystyki pozostają widoczne. Szczegóły: Zespół i role.
2026-06 · Linki zewnętrzne na stronie docelowej kodu
- Strona docelowa: Hostowana przez qr3 strona docelowa kodu może teraz wyświetlać zewnętrzne, samodzielnie hostowane linki (
{ label, url }) obok przesłanych plików lub zamiast nich – na przykład dla kart katalogowych na Twojej własnej stronie. - API:
POST/PATCH /v1/codesprzyjmują tablicęlinks(0–20 wpisów,http(s), ≤ 2048 znaków). Każdy adres URL jest sprawdzany za pomocą Google Web Risk; niebezpieczny URL zwraca422. Pusta tablica usuwa wszystkie linki. - Dashboard: Dodawanie, zmiana kolejności i usuwanie linków na stronie szczegółów kodu.
- Bezpieczeństwo: Wyrenderowane linki pozostają bezpieczne pod kątem XSS (z zastosowaniem znaków ucieczki, tylko
http(s)), a strona zachowuje swój nagłóweknoindex.
2026-04 · Analityka dla pojedynczego kodu QR w Dashboardzie
- Dashboard: Przycisk analityki na liście kodów QR otwiera teraz stronę statystyk danego kodu QR pod adresem
/dashboard/codes/{id}. - Routing: Alias
/dashboard/codesnadal przekierowuje na/dashboard, ale nie przechwytuje już tras szczegółowych, takich jak/dashboard/codes/{id}. - API: Strona szczegółów ładuje kod QR bezpośrednio przez
GET /v1/codes/:id; dzięki temu nie zależy już od limitów stronicowania listy. - Testy: Testy regresyjne obejmują przekierowanie aliasu oraz bezpośrednie ładowanie kodu.
2026-04 · Okno dialogowe usuwania kodu QR w Dashboardzie
- Dashboard: Ikona kosza na liście kodów QR otwiera teraz dedykowane okno dialogowe React zamiast natywnego wyskakującego okienka przeglądarki.
- Informacja zwrotna: Po usunięciu pojawia się powiadomienie typu toast informujące o sukcesie lub błędzie.
- Testy: Plik
packages/dashboard/tests/dashboard.test.tszapobiega regresjom związanym zconfirm()w procesie usuwania kodu QR.
2026-04 · Test krótkiego linku dla dynamicznych kodów QR w Dashboardzie
- Dashboard: Krótkie kody (shortcodes) na liście kodów QR można teraz klikać bezpośrednio jako zewnętrzne linki przekierowujące. Ikona linku zewnętrznego obok np.
wu3qaaotwierahttps://qr3.app/{shortCode}w nowej karcie. - i18n: Dodano teksty podpowiedzi (tooltips) dla języka niemieckiego i angielskiego.
- Testy: Plik
packages/dashboard/tests/dashboard.test.tschroni przed regresjami atrybut linku href, zachowanie otwierania w nowej karcie,noopener noreferreroraz ikonę.
2026-04 · Trasa Redirect-Worker dla dynamicznych kodów QR
- Poprawka: Dynamiczne kody QR pod adresem
https://qr3.app/{shortCode}są ponownie przetwarzane przez Redirect-Worker. Trasa produkcyjna używa terazqr3.app/*, ponieważ trasy Cloudflare Workers nie obsługują parametrów ścieżki:code. - Zabezpieczenie: Niedopasowane ścieżki są przekazywane do landing origin, aby standardowe strony, takie jak
/de/pricing, nie były blokowane przez Redirect-Worker. - Testy: Plik
packages/redirect/tests/unit/redirect.test.tsweryfikuje trasę wieloznaczną (wildcard), przetwarzanie krótkich kodów oraz przekazywanie do origin.
2026-04 · Przegląd skanowań DPP w przestrzeni roboczej (Q3.4.2)
- Nowość:
GET /v1/workspace/stats/dpp?days=30— agreguje wszystkiedpp_scansdla przestrzeni roboczej klucza API (active_dpps,scans_by_day,top_dppsz nazwą produktu/kategorią). - Dashboard: Karta na stronie głównej (
/dashboard) z 30-dniowym wykresem słupkowym + listami najpopularniejszych — równolegle do kart kodów QR. - Publiczne: Krótki link marketingowy
GET /dpp/dpp_<id>(jeden segment) do prezentacji na żywo, równolegle do/dpp/{gtin}/{serial}.
2026-04 · Analityka skanowań DPP (Q3.4.1)
- Nowość:
GET /v1/dpp/:id/stats?days=30— zagregowane skanowania publicznego resolvera GS1 dla każdego DPP. Pola:total_scans,period_scans,scans_by_day,top_countries,top_devices,top_representations. - Nowość: Tabela
dpp_scans(migracja0011) — oddzielona odscans(Redirect-Worker). Adresy IP są haszowane przy użyciu codziennie rotowanej soli (salt), surowe adresy IP nigdy nie trafiają do D1. - Dashboard: Karta z miniwykresem (SVG, bez zewnętrznej biblioteki wykresów) pod adresem
/dashboard/dpp/:dppIdz 30-dniowymi słupkami + zestawieniem top 3. Stan pusty (empty state), gdy DPP jest aktywny, ale nie ma jeszcze skanowań.
2026-04 · Symulator zgodności z przepisami UE na żywo (Q3.3.7)
- Nowość:
POST /v1/dpp/:id/validate-update— symuluje częściowe aktualizacje w sposób bezstanowy (stateless) (status, lista rynków itp.) bez zapisywania danych. Odpowiedź zawieraeu_compliance+preview.changed_fields. - Dashboard: Karta symulatora w szczegółach DPP (
/dashboard/dpp/:dppId) — znaczniki (chips) dlaDE/AT/FR/IT/ES/NL+ niestandardowe, lista rozwijana statusu, Preview EU impact / Save changes / Reset. Bez blokowania interfejsu dzięki RemixuseFetcher. - Zabezpieczenie: Wydzielone funkcje pomocnicze symulatora (
readUpdatePatchFromForm,marketCountriesKey) + 18 nowych testów jednostkowych; poprawka błędu: pojedyncza wartość wejściowa spoza standardu ISO nie powoduje już wyczyszczenia listy rynków.
2026-04 · Podgląd zgodności z przepisami UE na żywo w formularzu tworzenia (Q3.3.6)
- Zmieniono:
POST /v1/dpp/validatezwraca dodatkowoeu_compliance— ten sam walidator coGET /v1/dpp/:id/eu-compliance, działający bezstanowo przed zapisaniem. - Dashboard: Podgląd pod istniejącym panelem walidacji + nowy baner ostrzegawczy (Save-Guard-Banner) przed przyciskami zapisu, jeśli występują błędy/ostrzeżenia (pluralizacja i18n DE/EN).
2026-04 · EU-Validator + Textil-UI (Q3.3.4 + Q3.3.5)
- Nowość: Walidator zgodności z przepisami UE z 5 regułami dla tekstyliów (
TEXTILE_AGEC_REQUIRED,TEXTILE_MICROPLASTICS_CONSISTENCY,TEXTILE_SVHC_THRESHOLD,TEXTILE_GREENWASHING,TEXTILE_ESPR_READY). - Nowość:
GET /v1/dpp/:id/eu-compliancez polamicompliant/espr_ready/issues[]/summary. - Dashboard: Sekcja zgodności z przepisami UE w szczegółach DPP (kafelki podsumowania, pogrupowane karty problemów, plakietka ESPR-Ready w nagłówku).
2026-04 · Textil-DPP-Schema (Q3.3.1–Q3.3.3)
- Nowość: Kategoria
textilez obowiązkowym łańcuchem AGEC (tkanie/dzianie → barwienie/drukowanie → konfekcjonowanie), dla każdego włóknaorigin_country+recycled_pct,svhc_substances[], ESPR-Opt-in (PEF, żywotność, Recyclability). - Nowość: Podstawowe pole
market_countries: string[](ISO 3166-1 alpha-2) we wszystkich kategoriach DPP — steruje specyficznymi dla Francji regułami AGEC oraz francuską obowiązkową notą dla konsumentów. - Nowość: Szablon HTML dla konsumenta z ostrzeżeniem AGEC o mikroplastiku, 3-stopniowym łańcuchem pochodzenia (pigułki z flagami), listą SVHC oraz sekcjami Durability i Recyclability.
- Migracja:
0010_dpp_market_countries(D1).
2026-04 · DPP-Bulk-Import (Q3.2.1–Q3.2.5)
- Nowość:
POST /v1/dpp/importakceptuje pliki CSV i XLSX (kompatybilne z Workers dzięki SheetJSxlsx, paczka gzip o rozmiarze ok. 283 KB). - Skalowanie: limit zależny od planu (Free 100 → Enterprise 10k) + wsadowe
db.batch()po 100 + limit rozmiaru żądania (body) 5 MB. - Nowość: Raport o błędach jako CSV w polu
errors_csvodpowiedzi 201;GET /v1/dpp/import/templates/:category?format=csv|xlsxdostarcza gotowe szablony dla baterii i tekstyliów. - Dashboard: Przesyłanie metodą przeciągnij i upuść (drag-and-drop) pod adresem
/dashboard/dpp/importz proxy szablonów i pobieraniem CSV inline.
Zmiany nie-breaking — rozszerzenia LTS
Wszystkie wyżej wymienione zmiany mają charakter addytywny:
- Istniejący klienci
POST /v1/dpp/validateignorują nowe poleeu_compliancebez konieczności wprowadzania zmian. - Istniejące procesy (
battery-Flows) pozostają bez zmian. - Pole
market_countriesjest opcjonalne i domyślnie przyjmuje wartość[].
Zasady wprowadzania zmian niekompatybilnych wstecz (Breaking-Change-Policy) opisano w sekcji Wersjonowanie API.