Changelog
Changelog
Curated highlights of recent releases. For complete API versions and the breaking-change policy, see the API versioning & LTS policy.
Detailed changes for individual endpoints: OpenAPI spec and interactive API reference.
2026-04 · Per-code dashboard analytics
- Dashboard: The Analytics button in the QR code list now opens the statistics page for the selected QR code at
/dashboard/codes/{id}. - Routing: The
/dashboard/codesalias still redirects to/dashboard, but it no longer catches detail routes such as/dashboard/codes/{id}. - API: The detail page loads the QR code directly via
GET /v1/codes/:id, so it no longer depends on list pagination limits. - Tests: Regression tests cover the alias redirect and direct code loading.
2026-04 · Dashboard delete dialog for QR codes
- Dashboard: The trash button in the QR code list now opens a custom React dialog instead of a native browser popup.
- Feedback: After deletion, a toast reports success or failure.
- Tests:
packages/dashboard/tests/dashboard.test.tsprevents regressions back toconfirm()in the QR code delete flow.
2026-04 · Dashboard short-link test for dynamic QR codes
- Dashboard: Short codes in the QR code list are now directly clickable external redirect links. The external-link icon next to e.g.
wu3qaaopenshttps://qr3.app/{shortCode}in a new tab. - i18n: Added German and English tooltip copy.
- Tests:
packages/dashboard/tests/dashboard.test.tsprotects the link href, new-tab behavior,noopener noreferrer, and icon against regressions.
2026-04 · Redirect Worker route for dynamic QR codes
- Fix: Dynamic QR codes at
https://qr3.app/{shortCode}are handled by the Redirect Worker again. The production route now usesqr3.app/*because Cloudflare Worker routes do not support:codepath parameters. - Hardening: Non-matching paths pass through to the landing origin, so regular pages like
/en/pricingare not blocked by the Redirect Worker. - Tests:
packages/redirect/tests/unit/redirect.test.tscovers the wildcard route, short-code handling, and origin pass-through.
2026-04 · Workspace-wide DPP scan overview (Q3.4.2)
- New:
GET /v1/workspace/stats/dpp?days=30— aggregates alldpp_scansfor the API key’s workspace (active_dpps,scans_by_day,top_dppswith product name/category). - Dashboard: Home card (
/dashboard) with a 30-day bar chart + top lists — shown alongside QR code cards. - Public: Marketing short link
GET /dpp/dpp_<id>(single path segment) for live demos, alongside/dpp/{gtin}/{serial}.
2026-04 · DPP scan analytics (Q3.4.1)
- New:
GET /v1/dpp/:id/stats?days=30— aggregated scans of the public GS1 resolver per DPP. Fields:total_scans,period_scans,scans_by_day,top_countries,top_devices,top_representations. - New:
dpp_scanstable (migration0011) — separate fromscans(redirect worker). IP addresses are hashed with a daily rotating salt; raw IPs never reach D1. - Dashboard: mini-chart card (SVG, no chart library) on
/dashboard/dpp/:dppIdwith 30-day bars + top-3 breakdowns. Empty-state while a DPP is live but has no scans yet.
2026-04 · Live EU compliance simulator (Q3.3.7)
- New:
POST /v1/dpp/:id/validate-update— simulates partial updates stateless (status, market list, …) without persistence. The response containseu_compliance+preview.changed_fields. - Dashboard: simulator card on the DPP detail page (
/dashboard/dpp/:dppId) — chips forDE/AT/FR/IT/ES/NL+ custom, status dropdown, Preview EU impact / Save changes / Reset. Non-blocking via RemixuseFetcher. - Hardening: extracted simulator helpers (
readUpdatePatchFromForm,marketCountriesKey) + 18 new unit tests; bugfix: lone non-ISO input no longer clears the market list.
2026-04 · Live EU compliance preview in the create form (Q3.3.6)
- Changed:
POST /v1/dpp/validatenow also returnseu_compliance— the same validator asGET /v1/dpp/:id/eu-compliance, stateless before save. - Dashboard: preview under the existing validation panel + new save-guard banner above the submit buttons when errors/warnings remain (i18n pluralization DE/EN).
2026-04 · EU validator + textile UI (Q3.3.4 + Q3.3.5)
- New: EU compliance validator with 5 textile rules (
TEXTILE_AGEC_REQUIRED,TEXTILE_MICROPLASTICS_CONSISTENCY,TEXTILE_SVHC_THRESHOLD,TEXTILE_GREENWASHING,TEXTILE_ESPR_READY). - New:
GET /v1/dpp/:id/eu-compliancewithcompliant/espr_ready/issues[]/summary. - Dashboard: EU compliance section on the DPP detail page (summary tiles, grouped issue cards, ESPR-ready badge in the header).
2026-04 · Textile DPP schema (Q3.3.1–Q3.3.3)
- New:
textilecategory with AGEC mandatory chain (weaving/knitting → dyeing/printing → assembly), per-fiberorigin_country+recycled_pct,svhc_substances[], ESPR opt-in (PEF, lifetime, recyclability). - New: base field
market_countries: string[](ISO 3166-1 alpha-2) across all DPP categories — drives FR-specific AGEC rules and the French consumer mandatory notice. - New: consumer HTML template with AGEC microplastics warning box, 3-step origin chain (flag pills), SVHC list, durability and recyclability sections.
- Migration:
0010_dpp_market_countries(D1).
2026-04 · DPP bulk import (Q3.2.1–Q3.2.5)
- New:
POST /v1/dpp/importaccepts CSV and XLSX (Worker-compatible via SheetJSxlsx, ~283 KB gzip bundle). - Scaled: plan-based limit (Free 100 → Enterprise 10k) + chunked
db.batch()of 100 + 5 MB body limit. - New: error report as CSV in the
errors_csvfield of the 201 response;GET /v1/dpp/import/templates/:category?format=csv|xlsxreturns ready-made templates for battery and textile. - Dashboard: drag-and-drop upload at
/dashboard/dpp/importwith template proxy and inline CSV download.
Non-breaking — LTS additions
All of the above are additive:
- Existing
POST /v1/dpp/validateclients can ignore the neweu_compliancefield without changes. - Existing
batteryflows are unchanged. market_countriesis optional and defaults to[].
See API versioning for the breaking-change policy.