Skip to content

Muutosloki

Muutosloki

Viimeisimpien julkaisujen kuratoidut kohokohdat. Katso täydelliset API-versiot ja rikkovien muutosten käytännöt (breaking changes) sivulta API-versiointi & LTS-käytäntö.

Yksityiskohtaiset muutokset yksittäisiin päätepisteisiin: OpenAPI-määritys ja interaktiivinen API-viite.


2026-10 · Värit Dashboardissa

  • Uutta: Koodin tietosivulla on kortti Värit: etuala ja tausta heksa-arvoina, läpinäkyvä tausta ja esikatselu todellisen kuvareitin kautta. Tarkistus on sama kuin PATCH /v1/codes/{id}: kriittiset parit vaativat vahvistuksen, alle 1,5:1 olevia pareja ei voi tallentaa.
  • Palautus mustavalkoiseksi tuottaa kaikissa neljässä formaatissa taas samat tavut kuin ilman värejä. Koodit ilman värejä eivät muutu.
  • Läpinäkyvät koodit näkyvät kaikissa Dashboardin esikatseluissa shakkiruudukon päällä. Lisätietoja: Värit Dashboardissa.

2026-10 · Värit PDF- ja EPS-muodoissa

  • Uutta: qr.pdf ja qr.eps piirtävät värit fg ja bg sekä parametreina että tallennettuina väreinä. Musta ja kaikki harmaasävyt kirjoitetaan harmaasävyinä (vain musta osaväri), kaikki muut värit CMYK-arvoina kokonaisina prosentteina, esimerkiksi 1F4E79 muodossa C74 M36 Y0 K53.
  • Tausta kuten SVG-muodossa: Heti kun väri on valittu, koodin ja sen suojavyöhykkeen takana on peittävä tausta, joko valkoinen tai bg. bg=transparent ei piirrä taustaa. Otsikko säilyy mustana, logolevy valkoisena.
  • Ei muutoksia ilman värejä: Ilman värejä fg/bg ja ilman tallennettuja värejä molemmat muodot palauttavat samat tavut kuin ennenkin. Tuotepassin PDF-tiedosto säilyy värittömänä.
  • Rajoitukset: ei ICC-profiilia, ei PDF/X-tukea. Lisätietoja: Värit painatuksessa.

2026-09 · Staattiset koodit ilman uudelleenohjausvälimuistia, samanaikainen poistaminen

  • Muuttunut: Staattiset koodit eivät enää ole uudelleenohjausvälimuistissa. Niiden lyhytlinkin (redirect_url) kutsuminen lukee aina ajantasaisen tilan. Tämän vuoksi DELETE /v1/account -pyynnön jälkeen staattinen koodi ei enää ohjaa eteenpäin seuraavalla kutsukerralla, kun taas aiemmin tämä saattoi kestää jopa 24 tuntia. Myös tilauspaketin vaihto vaikuttaa staattisiin koodeihin välittömästi. Tilin poistaminen siivoaa dynaamiset koodit kuten tähänkin asti. Tulostetut staattiset koodit sisältävät kohteensa suoraan, eikä asia vaikuta niihin.
  • Korjattu: Kaksi samanaikaista DELETE /v1/codes/:id -pyyntöä samaan koodiin palauttavat kerran 200 ja kerran 404. Webhook qr.deleted lähetetään tasan kerran, aiemmin kahdesti.
  • Uutta: POST- ja DELETE /v1/codes/:id/logo -pyynnöt vastaavat tilakoodilla 409 (errors/conflict), jos toinen pyyntö on muuttanut saman koodin logoa samanaikaisesti, eivätkä ne silloin muuta mitään. Aiemmin ladattu logo saattoi jäädä tallennetuksi ilman, että sitä käytettiin. Kaksi samanaikaista DELETE /v1/codes/:id/logo -pyyntöä palauttavat molemmat 200. Lisätietoja: Logo.

2026-09 · TypeScript-SDK 1.2.0

  • Uutta @qr3/sdk 1.2.0 -versiossa: client.codes.update() ottaa vastaan parametrin appearance ja palauttaa kontrastitarkistuksen havainnot issues-kentässä tuloksessa; jos havaintoja ei ole, kenttä puuttuu. client.codes.imageUrl() ottaa vastaan parametrit fg, bg ja ecc. Jokainen API:n palauttama koodi (get, list, create, update, batchCreate) sisältää kentät title ja appearance.
  • Päivittäminen: npm install @qr3/sdk@latest. Python, Go ja PHP seuraavat perässä. Lisätietoja: SDK:t ja CLI ja Värien tallentaminen koodiin.

2026-09 · Muutettu vanhentumisaika astuu voimaan noin minuutissa

  • Korjattu: PATCH-pyyntö kenttään expires_at tyhjentää nyt koodin edelleenohjausvälimuistin. Uusi vanhentumisaika astuu siten voimaan noin minuutissa sen sijaan, että se tapahtuisi vasta jopa 24 tuntia myöhemmin. Aikaisemmin poistettu tai siirretty vanhentuminen palautti edelleen koodin 410 jopa 24 tunnin ajan, ja nykyhetkeen asetettu vanhentuminen antoi edelleenohjauksen jatkua jopa 24 tuntia.
  • Korjattu: Kentällä expires_at luotu koodi vanhenee ajallaan myös silloin, kun vanhentuminen tapahtuu ensimmäisten 24 tunnin aikana.
  • Korjattu: Jos koodi poistetaan samalla, kun sen logoa ladataan palvelimelle tai poistetaan, POST ja DELETE /v1/codes/:id/logo vastaavat tilakoodilla 404 eivätkä muuta poistettua koodia, kuten PATCH jo tekee.
  • Korjattu: Myös staattinen koodi, jonka lyhytlinkkiä (redirect_url) on kutsuttu, tallentuu edelleenohjausvälimuistiin. Muokkaaminen, tauottaminen ja poistaminen tyhjentävät sen nyt myös, ei vain dynaamisten koodien kohdalla.

2026-09 · Värien tallentaminen koodiin

  • Uutta: PATCH /v1/codes/:id hyväksyy parametrin appearance, joka sisältää kentät foreground_color ja background_color (#RRGGBB, taustalle myös transparent). qr.svg ja qr.png piirtävät tallennetut värit ilman parametreja; kyselyparametri kuten ?fg=000000 on edelleen etusijalla. PDF ja EPS piirtävät värit vasta myöhemmässä julkaisussa.
  • Kontrastitarkistus: Pari, jonka kontrasti on alle 1,5:1, palauttaa virheen 422. Heikommat parit tallennetaan ja niistä ilmoitetaan kohteessa meta.issues tilassa warning tai critical; läpinäkyvä tausta on aina critical, eikä sitä koskaan estetä.
  • Yhdistäminen: Pois jätetyt kentät säilyttävät tallennetun arvonsa, ja null nollaa arvon. Samanaikaiset muutokset samaan koodiin eivät enää ylikirjoita toisiaan.
  • Jokaisessa koodivastauksessa: appearance on mukana jokaisessa koodivastauksessa sekä webhookeissa qr.created ja qr.updated. POST, eräajo ja tuonti hylkäävät sen virheellä 422.
  • Ei muutoksia olemassa oleviin koodeihin: Ilman tallennettuja värejä jokainen koodi palauttaa täsmälleen samat tavut kuin ennenkin. Lisätietoja: Värien tallentaminen koodiin.

2026-09 · Värit ja virheenkorjaus kuvareittien parametreina

  • Uutta: Kaikki neljä kuvareittiä hyväksyvät parametrit fg (edustaväri), bg (taustaväri tai transparent) ja ecc (virheenkorjaus L, M, Q, H). SVG ja PNG piirtävät värit; PDF ja EPS hyväksyvät ne, mutta piirtävät ne vasta myöhemmässä julkaisussa. ecc vaikuttaa kaikissa neljässä muodossa, ja logo pakottaa edelleen tason H.
  • Läpinäkyvä: bg=transparent palauttaa SVG-kuvan ilman taustaa ja PNG-kuvan aidolla alfakanavalla. Alustan on oltava vaalea ja jätettävä suoja-alue vapaaksi.
  • Ei koskaan virhettä: Virheelliset arvot ohitetaan; kuva palautetaan tällöin täsmälleen samalla tavalla kuin ilman parametreja.
  • Välimuisti: Jokainen vaikuttava parametri palauttaa otsikon Cache-Control: public, max-age=300 oletuskuvan 24 tunnin sijaan.
  • Ei toiminnallisia muutoksia ilman parametreja: Jokainen olemassa oleva koodi palauttaa kaikissa neljässä muodossa samat tavut kuin aikaisemmin.
  • Saatavilla kaikissa tilausvaihtoehdoissa. Lisätietoja: Värit ja virheenkorjaus.

2026-09 · PDF ja EPS upottavat nyt myös logon

  • Laajennus: qr.pdf ja qr.eps upottavat nyt asetetun logon aivan samalla tavalla kuin qr.svg ja qr.png (katso alta) — upotettuna kuvana (PDF Image XObject -objektin kautta, EPS PostScriptin kuvasanakirjan kautta, siellä vain versiolla %%LanguageLevel: 3), keskitettynä samalle alueelle, samalla virheenkorjauksen nostolla tasolle H. Kumpikaan formaatti ei aiemmin sisältänyt logoa; tämä on nyt korjattu.
  • Välimuisti: Kun logo on asetettu, myös qr.pdf ja qr.eps palauttavat nyt arvon Cache-Control: public, max-age=300 tavallisen 24 tunnin sijaan — aivan kuten SVG/PNG.
  • Varatoiminto: Jos itse logokuvaa ei voida käsitellä (esimerkiksi vioittunut tallennettu objekti), virheenkorjaus pysyy tasolla H, mutta varattu alue jää tyhjäksi kuvan sijaan — tämä ei koskaan aiheuta palvelinvirhettä.
  • Ei toiminnallisia muutoksia ilman logoa: Koodit ilman logoa palauttavat tiedostot qr.pdf/qr.eps edelleen tavuilleen identtisinä ja muuttumattomalla 24 tunnin välimuistilla.
  • Lisätiedot ja tulostusohjeet: Logo QR-koodissa.

2026-09 · Logo QR-koodissa — Dashboard ja API

  • Uutta: Koodissa voi nyt olla logo keskellä. Dashboardissa koodin yksityiskohtasivu luo oman logo-kortin: Valitse logo, vahvista ensimmäisellä lisäyskerralla tai poistettaessa varoitus pakollisella valintaruudulla (molemmat muuttavat pistekuviota), ja sitten Lataa logo/Poista logo. Korvaaminen ei vaadi vahvistusta — vain kuva vaihtuu, ei kuvio. Rooli viewer näkee tilan ja esikatselun, mutta ei mitään näistä kolmesta toiminnosta.
  • API: POST /v1/codes/{id}/logo (multipart-kenttä file; PNG, JPEG tai WebP, enintään 1 MB, SVG hylätään) luo logon tai korvaa sen; DELETE /v1/codes/{id}/logo poistaa sen ja on idempotentti. Liian suuri kuva palauttaa virheen 413, ei-tuettu muoto 422 ja rooli viewer 403.
  • Renderöinti: qr.svg ja qr.png upottavat logon todellisina pikseleinä (512 × 512, normalisoitu) ja nostavat virheenkorjauksen tasolle H. Lisääminen ja poistaminen muuttavat siten pistekuviota (M ↔ H), mutta korvaaminen ei. qr.pdf ja qr.eps eivät upota logoa ja pysyvät muuttumattomina. Jo tulostettu koodi toimii joka tapauksessa edelleen, koska koodattu kohde ei riipu logosta — vain niiden, jotka haluavat nähdä (uuden) logon ulkoasun myös materiaalissa, on tulostettava uudelleen, eikä vanhoja ja uusia tulostustiedostoja tule sekoittaa keskenään.
  • Välimuisti: Kun logo on asetettu, qr.svg ja qr.png palauttavat otsikon Cache-Control: public, max-age=300 tavallisen 24 tunnin sijaan. Lisätiedot, rajat ja tulostusohjeet: Logo QR-koodissa.

2026-08 · operationId kaikille 75 operaatiolle ja milloin-ohje agenteille

  • Lisäys: Kaikilla OpenAPI-spesifikaation 75 operaatiolla on nyt operationId — listCodes, createCode, getCodeStats, archiveWorkspace ja niin edelleen. Aiemmin kenttä puuttui kokonaan, joten jokaisen generaattorin oli johdettava metodin nimi HTTP-metodista ja polusta (postV1Codes). Tällaiset nimet ovat riippuvaisia polusta ja muuttuvat aina, kun polkua muokataan. Nimimuoto on kaikissa 75 kohdassa sama: list/get/create/update/replace/delete, muussa tapauksessa liiketoiminnallista toimintoa kuvaava verbi (validateDpp, registerGs1Identifier, pingWebhook). Verbi noudattaa liiketoimintalogiikkaa, ei HTTP-metodia — archiveWorkspace on DELETE, importDpps on POST.
  • Vaikutus itse generoituihin client-ohjelmiin: Jos generoat SDK-kirjastosi spesifikaatiosta, saat seuraavalla ajokerralla uudelleen nimetyt metodit (postV1Codes → createCode). Tämä on muutoksen tarkoitus, mutta kyseessä on nimeämisen muuttuminen ulkopuolisessa koodissa — siksi se mainitaan tässä erikseen. Polut, parametrit, vastausmuodot ja tilakoodit säilyvät ennallaan; viralliset SDK-kirjastot, CLI ja MCP-palvelin eivät muutu.
  • Agenttien aloituspiste: Tiedostossa https://qr3.app/llms.txt on osio ## When to use qr3.app — kuusi tehtävää kuuden funktion sijaan, sekä maininta siitä, mihin qr3.app ei ole oikea työkalu. MCP-palvelin toimittaa nyt saman tiedon kättelyssä: initialize-kutsu osoitteeseen https://mcp.qr3.app/mcp vastaa kentällä instructions (aiemmin: yksitoista työkalua ilman minkäänlaista luokittelua). Mukana on myös tieto siitä, mitkä kutsut tarvitsevat API-avaimen — initialize ja tools/list eivät tarvitse, jokainen tools/call tarvitsee.
  • Korjaukset tiedostossa llms.txt: Neljä tietoa tarkistettiin tuotantoa vasten, eivätkä ne pitäneet paikkaansa: (1) Python-SDK-kirjastoa qr3app ei ole julkaistu PyPI-palvelussa — pip install -rivi on poistettu kokonaan; (2) Accept: text/markdown koskee etusivua ja blogia, ei jokaista palvelimella renderöityä sivua; (3) yhteystieto-osoite on [email protected], myös etusivun JSON-LD-datassa; (4) /de/security/ on uudelleenohjaus ankkuriin, ei oma sivunsa. Uusi linkitys: docs.qr3.app/de/skills/.
  • Varmistus: Kolme varmistusta tiedostossa openapi-spec.test.ts — kattavuus, yksikäsitteisyys, lowerCamelCase —, jokainen ristiintarkistettu mutaatiolla. Yhdeksän muuta testiä varmistavat neljä korjattua tietoa, jotta virheet eivät toistu.
  • Tunnettu rajoitus: Kaksi 75 operaatiosta on kuvattu spesifikaatiossa, mutta ne palauttavat tilakoodin 404 (GET /v1/codes/{id}/stats ja GET /v1/account). Ne ovat saaneet tässä nimen ja menettävät sen jälleen, kunhan on päätetty, rakennetaanko ne vai poistetaanko ne kokonaan.

2026-08 · Tilaustason alennukset ja peruutukset vaikuttavat nyt myös rajoituksiin

  • Korjaus: Stripe-webhook kirjoitti paketin vaihdon ja peruutuksen yhteydessä vain paketin nimen, ei organisaation neljää rajoitussaraketta (max_workspaces, max_members, max_dynamic_codes, max_scans_per_month). Koska rajoitusten valvonta käyttää tallennetun arvon ja paketin perustason (baseline) maksimiarvoa, tilaustasoaan alentanut tai tilauksensa peruuttanut organisaatio säilytti vanhat, korkeammat rajoituksensa — tason alennuksella ei ollut vaikutusta. Webhook asettaa sarakkeet nyt jokaisen todellisen paketin vaihdon yhteydessä uuden paketin perustasolle ja peruutuksen yhteydessä Free-perustasolle — aivan kuten admin-hallinta jo tekee.
  • Toiminta: Tilauksen (Subscription) rutiinipäivitykset (jatkaminen, maksutapa, proration) eivät edelleenkään koske rajoituksiin; yksilöllisesti myönnetyt korkeammat rajoitukset säilyvät muuttumattomina. Vasta todellinen paketin vaihto palauttaa ne uuden paketin perustasolle.
  • Vaikutus: Ei muutoksia API- tai vastausmuotoihin. Organisaatiot, joiden tilaustason alennus tapahtui ennen tätä korjausta, säilyttävät vanhat arvot, kunnes seuraava paketin vaihto astuu voimaan tai tuki muuttaa niitä.

2026-08 · Keyset-kursori nyt kaikissa lista-päätepisteissä

  • Korjaus: Kursorikorjaus päätepisteille GET /v1/codes ja GET /v1/dpp (katso alta) on nyt otettu käyttöön kaikissa muissa kursorisivutetuissa listoissa: GET /v1/qr-codes/:id/comments, /v1/workspaces, /v1/gs1/identifiers, /v1/members, /v1/audit-logs, /v1/admin/orgs, /v1/admin/users ja /v1/webhooks/:id/deliveries. Kaikki sivuttivat aiemmin pelkästään kentän created_at perusteella; rivit, joilla oli identtinen aikaleima (eräajon audit-merkinnät, webhook-uudelleenyritykset, jäsenten tuonnit), saattoivat kadota seuraavalta sivulta. Lajitteluavain on nyt kaikkialla yhdistelmä (created_at, id).
  • API-muutos: Näissä listoissa meta.pagination.next_cursor on tästä lähtien myös läpinäkymätön arvo (base64url) pelkän aikaleiman sijaan; lukukelvottomat kursorit palauttavat virheen 400, ja vanhoja aikaleimakursoreita hyväksytään edelleen siirtymäajan. Poikkeuksena GET /v1/webhooks/:id/deliveries: siellä next_cursor säilyy viimeisimmän toimituksen tunnuksena (tuntematon ID → ensimmäinen sivu). Asiakasohjelmien, jotka palauttavat arvon next_cursor muuttumattomana — Dashboard, CLI, SDK:t, MCP —, ei tarvitse muuttaa mitään.
  • Vaikutus: Ei vaadi migraatiota. Jos olet kaivannut merkintöjä jossakin näistä listoista (esim. audit-loki tai toimitusloki Dashboardissa) sivuja selatessasi: ne eivät olleet kadonneet — listat näyttävät ne tästä lähtien kokonaisuudessaan.

2026-08 · Aikaleimat muokkauksen ja poiston jälkeen jälleen OpenAPI-yhteensopivia

  • Korjaus: PATCH /v1/codes/{id} -pyynnön jälkeen updated_at palautui SQLite-muodossa ilman aikavyöhykettä (2026-08-17 09:00:00), vaikka OpenAPI-määrittely lupaa muodon format: date-time ja luominen (POST) palauttaa ISO-aikaleiman (2026-08-17T09:00:00.000Z). Sama päti kenttiin deleted_at/updated_at soft-delete-toiminnossa sekä API-avainten, organisaatioiden, työtilojen, jäsenten, kommenttien ja webhookien muokkaus- ja poistopolkuihin, ja lisäksi API-avainten last_used_at-kenttään ja webhookien last_triggered_at-kenttään. Kaikki kirjoituspolut käyttävät nyt ISO 8601 -aikaleimaa (UTC, T ja Z).
  • Vaikutus: Asiakasohjelmat, jotka jäsentävät updated_at-kentän käyttäen new Date(...) -metodia (SDK:t, CLI, Dashboard), tulkitsivat välilyönnillisen muodon paikalliseksi ajaksi — CLI näytti kerran muokattujen koodien kohdalla ajan siirtyneenä paikallisen poikkeaman (offset) verran (Wien: −2 h). Tämä on korjattu. Lisäksi tietojen migraatio normalisoi jo tallennetut vanhanmuotoiset arvot ISO-muotoon, jotta lajittelu ja vertailut toimivat oikein sekalaisten tietojen joukossa. Ei muutoksia kenttien nimiin tai vastauksen rakenteeseen.
  • Tausta: Sama virheluokka kuin kahdessa alla olevassa korjauksessa (API-avaimen vanheneminen, uudelleenskannauksen aikaraja): SQLiten datetime('now') kirjoittaa muodossa YYYY-MM-DD HH:MM:SS, kun taas kaikki muut kirjoittajat käyttävät ISO 8601 -muotoa. Lähdekoodin suojatesti estää vastaavat tapaukset jatkossa.

2026-08 · Listasivutus ei enää kadota batch-koodeja

  • Korjaus: GET /v1/codes ja GET /v1/dpp sivuttivat tietoja ainoastaan kentän created_at perusteella. Kuitenkin koodit, jotka on luotu reiteistä POST /v1/codes/batch, POST /v1/dpp/batch tai CSV/XLSX-tuonnista, jakavat yhden aikaleiman — heti kun erä (batch) oli suurempi kuin limit (oletusarvo 20), toinen sivu ei enää palauttanut saman aikaleiman jäljellä olevia rivejä. Koodit olivat olemassa ja ne olivat saatavilla reitistä GET /v1/codes/:id, mutta ne eivät koskaan näkyneet listassa (Dashboard, CLI qr3 list, SDK:t, MCP). Kursori on nyt keyset-pohjainen yhdistelmällä (created_at, id).
  • API-muutos: meta.pagination.next_cursor on tästä lähtien läpinäkymätön arvo (base64url) pelkän aikaleiman sijaan. Niiden, jotka palauttavat kursorin muuttumattomana parametrina ?cursor= — kuten Dashboard, CLI, kaikki SDK:t ja MCP-palvelin tekevät — ei tarvitse muuttaa mitään. Vanhoja aikaleimakursoreita hyväksytään edelleen siirtymäajan; lukukelvottomat kursorit palauttavat nyt tilakoodin 400 sen sijaan, että ne palauttaisivat hiljaisesti ensimmäisen sivun.
  • Vaikutus: Jos näit batch-tuonnin jälkeen listassa vähemmän koodeja kuin luotiin: koodit eivät olleet kadonneet — lista näyttää ne tästä lähtien kokonaisuudessaan. Mitään migraatiota ei tarvita.

2026-08 · Turvallisuuden uudelleenskannaukset suoritetaan jälleen 24 tunnin välein

  • Korjaus: Kohde-URL-osoitteiden ja laskeutumissivujen linkkien (Google Web Risk) jaksottainen uudelleenskannaus ohitti koodit, joiden viimeisin skannaus oli samana kalenteripäivänä kuin 24 tunnin aikaraja — kellonajasta riippuen uudelleenskannaus viivästyi jopa yhdellä lisäpäivällä. Aikaraja lasketaan nyt samassa ISO-muodossa, jossa skannauksen aikaleimat on tallennettu.
  • Vaikutus: Kohde-URL, joka luokitellaan turvattomaksi viimeisimmän skannauksen jälkeen, johtaa jälleen koodin automaattiseen keskeyttämiseen dokumentoidun 24 tunnin aikaikkunan sisällä. Ei muutoksia API- tai vastausmuotoon.

2026-08 · API-avaimet vanhenevat tarkkana vanhentumisajankohtana

  • Korjaus: API-avain, jonka expires_at oli samana päivänä, hyväksyttiin aiemmin keskiyöhön UTC asti. Vanhentumista verrataan nyt aikaleimana merkkijonon sijaan — vanhentunut avain palauttaa välittömästi virheen 401.
  • Tausta: expires_at tallennetaan ISO-aikaleimana (2026-08-14T09:00:00Z), kun taas vertailupuoli antoi välilyönnillisen muodon (2026-08-14 09:00:00). Raaka merkkijonovertailu täsmäsi siksi vain silloin, kun jo päivämäärä oli eri.
  • Vaikutus: Migraatiota ei tarvita, vastausmuoto kohteessa GET /v1/api-keys pysyy muuttumattomana. Lukukelvottomat vanhentumisarvot tulkitaan nyt vanhentuneiksi voimassa olevien sijaan.

2026-08 · API-viite: Tenant-hallinta dokumentoitu

  • OpenAPI: Spesifikaatio — ja sen myötä interaktiivinen viite — dokumentoi nyt organisaatiot (sis. GET /v1/organizations/usage), työtilat, jäsenet ja roolit sekä audit-lokit.
  • Billing: Hinnoittelun yleiskatsaus (GET /v1/billing/plans) on julkinen; Checkout (POST /v1/billing/checkout) ja Stripe-asiakasportaali (GET /v1/billing/portal) on määritelty päätepisteiksi organisaation ylläpitäjille.
  • Skannausvienti: Skannaustilastot (GET /v1/codes/{id}/scans) ja raakadatavienti (…/scans.csv, …/scans.xlsx) on dokumentoitu kokonaan — mukaan lukien GDPR-huomautus: ip_hash ei koskaan sisälly vientiin.
  • Virhekäyttäytyminen: Uutena on dokumentoitu myös pyynnön validoinnin 400-vastaus: Vastauksen runko on raaka Zod-virhe, ei RFC-7807-ongelmadokumentti — se toimitetaan kuitenkin sisältötyypillä application/problem+json.

2026-08 · Julkisten tiedostolinkkien kopiointi

  • Dashboard: Koodin tietosivulla on nyt jokaisen julkisen tiedoston kohdalla painike, joka kopioi tiedoston julkisen linkin leikepöydälle – suoraan käytettäväksi QR-koodin kohde-URL-osoitteena, kun skannauksen pitää avata heti tietty dokumentti laskeutumissivun ja sen tiedostoluettelon sijaan.
  • API: Tiedostopäätepisteet (/v1/files) palauttavat lisäksi kentän public_url. Kenttä on asetettu vain tiedostoille, joilla on visibility: public – yksityiset tiedostot eivät saa julkista osoitetta.
  • Toiminta: Linkki ei vaadi kirjautumista ja avaa tiedoston suoraan selaimessa. Tiedoston Korvaa-toiminto jättää linkin ennalleen, joten siihen osoittava tulostettu koodi pysyy voimassa. Lisätiedot: Tiedostot & datalehdet.

2026-07 · Tiimiroolit: Avustaja ilman poisto-oikeutta & ylläpitäjän laskutus

  • Uutta: Jäsenrooli Avustaja (ei poisto-oikeutta) — luo ja muokkaa QR-koodeja, tiedostoja ja Digital Product Passports -passeja, mutta ei voi poistaa mitään eikä luoda API-avaimia. Kaikki tuhoavat päätepisteet tarkistavat roolin palvelimen puolella (403).
  • Laskutus: Tilauspakettien päivitykset ja Stripe-asiakasportaali (POST /v1/billing/checkout, GET /v1/billing/portal) on nyt rajattu vain organisaation Ylläpitäjille — kaikki muut roolit näkevät tilaussivun vain luku -tilassa.
  • Dashboard: Toiminnot, joita käyttäjän oma rooli ei salli, piilotetaan käyttöliittymästä: Katselija ei esimerkiksi näe painikkeita luomiseen, muokkaamiseen tai poistamiseen, mutta listaukset, lataukset ja tilastot pysyvät näkyvissä. Lisätiedot: Tiimi & roolit.

2026-06 · Ulkoiset linkit koodin laskeutumissivulla

  • Laskeutumissivu: Koodin qr3-isännöimä laskeutumissivu voi nyt luetella ulkoisia, itse isännöityjä linkkejä ({ label, url }) ladattujen tiedostojen lisäksi tai niiden sijaan – esimerkiksi omalla sivustollasi oleville teknisille tiedoille.
  • API: POST/PATCH /v1/codes hyväksyvät links-taulukon (0–20 merkintää, http(s), ≤ 2048 merkkiä). Jokainen URL-osoite tarkistetaan Google Web Risk -palvelulla; turvaton URL-osoite palauttaa 422. Tyhjä taulukko poistaa kaikki linkit.
  • Dashboard: Lisää, järjestä uudelleen ja poista linkkejä koodin tietosivulla.
  • Tietoturva: Renderöidyt linkit pysyvät XSS-turvallisina (escapetettu, vain http(s)), ja sivu säilyttää noindex-otsakkeensa.

2026-04 · QR-koodikohtainen Dashboard-analytiikka

  • Dashboard: QR-koodiluettelon Analytics-painike avaa nyt kyseisen QR-koodin tilastosivun osoitteessa /dashboard/codes/{id}.
  • Reititys: Alias /dashboard/codes ohjaa edelleen osoitteeseen /dashboard, mutta ei enää kaappaa yksityiskohtaisia reittejä, kuten /dashboard/codes/{id}.
  • API: Yksityiskohtasivu lataa QR-koodin suoraan kutsulla GET /v1/codes/:id; tämän ansiosta se ei ole enää riippuvainen luettelon sivutusrajoista (pagination limits).
  • Testit: Regressiotestit kattavat alias-uudelleenohjauksen ja suoran koodin latauksen.

2026-04 · QR-koodien poistovalintaikkuna Dashboardissa

  • Dashboard: QR-koodiluettelon roskakorikuvake avaa nyt oman React-valintaikkunan selaimen natiivin ponnahdusikkunan sijaan.
  • Palaute: Poistamisen jälkeen näytetään toast-ilmoitus onnistumisesta tai virheestä.
  • Testit: packages/dashboard/tests/dashboard.test.ts estää regressiot confirm()-kutsussa QR-koodin poistovuossa.

2026-04 · Dynaamisten QR-koodien lyhytlinkkitesti Dashboardissa

  • Dashboard: QR-koodiluettelon lyhytkoodit (shortcodes) ovat nyt suoraan klikattavissa ulkoisina uudelleenohjauslinkkeinä. Ulkoisen linkin kuvake esimerkiksi koodin wu3qaa vieressä avaa osoitteen https://qr3.app/{shortCode} uudessa välilehdessä.
  • i18n: Työkaluvihjetekstit (tooltips) lisätty saksaksi ja englanniksi.
  • Testit: packages/dashboard/tests/dashboard.test.ts suojaa linkin href-osoitetta, uuden välilehden toimintaa, määritteitä noopener noreferrer ja kuvaketta regressioilta.

2026-04 · Ohjaus-Workerin reitti dynaamisille QR-koodeille

  • Korjaus: Redirect-Worker käsittelee jälleen dynaamiset QR-koodit osoitteessa https://qr3.app/{shortCode}. Tuotantoreitti käyttää nyt muotoa qr3.app/*, koska Cloudflare Worker -reitit eivät tue :code-polkuparametreja.
  • Vankistus: Täsmäämättömät polut välitetään eteenpäin laskeutumissivun alkuperään (landing origin), jotta Redirect-Worker ei estä normaaleja sivuja, kuten /de/pricing.
  • Testit: packages/redirect/tests/unit/redirect.test.ts testaa wildcard-reitin, lyhytkoodien käsittelyn ja alkuperän läpiviennin (origin pass-through).

2026-04 · Työtilan DPP-skannausyleiskatsaus (Q3.4.2)

  • Uutta: GET /v1/workspace/stats/dpp?days=30 — aggregoi kaikki API-avaimen työtilan dpp_scans-tapahtumat (active_dpps, scans_by_day, top_dpps tuotenimellä/kategorialla).
  • Dashboard: Aloitussivun (/dashboard) kortti, jossa on 30 päivän pylväskaavio + Top-listat — rinnakkain QR-koodikorttien kanssa.
  • Julkinen: Markkinoinnin lyhytlinkki GET /dpp/dpp_<id> (yksi segmentti) live-demoja varten, rinnakkain polun /dpp/{gtin}/{serial} kanssa.

2026-04 · DPP-skannausanalytiikka (Q3.4.1)

  • Uutta: GET /v1/dpp/:id/stats?days=30 — julkisen GS1-selvityspalvelun (resolver) aggregoidut skannaukset DPP-kohtaisesti. Kentät: total_scans, period_scans, scans_by_day, top_countries, top_devices, top_representations.
  • Uutta: Taulukko dpp_scans (migraatio 0011) — erillään taulukosta scans (Redirect-Worker). IP-osoitteet tiivistetään (hash) päivittäin vaihtuvalla suolalla (salt), raa’at IP-osoitteet eivät koskaan päädy tietokantaan D1.
  • Dashboard: Mini-kaaviokortti (SVG, ei kaaviokirjastoa) osoitteessa /dashboard/dpp/:dppId, jossa on 30 päivän pylväät + Top 3 -erittelyt. Tyhjä tila (empty state) heti, kun DPP on julkaistu mutta sillä ei ole vielä skannauksia.

2026-04 · Reaaliaikainen EU-vaatimustenmukaisuussimulaattori (Q3.3.7)

  • Uutta: POST /v1/dpp/:id/validate-update — simuloi osittaisia päivityksiä tilattomasti (stateless) (tila, markkinaluettelo, …) ilman tallennusta. Vastaus sisältää kentät eu_compliance + preview.changed_fields.
  • Dashboard: Simulaattorikortti DPP-yksityiskohdissa (/dashboard/dpp/:dppId) — pillerit (chips) arvoille DE/AT/FR/IT/ES/NL + mukautettu, tilan pudotusvalikko, Preview EU impact / Save changes / Reset. Ei-blokkaava Remix-kirjaston useFetcher-kutsun kautta.
  • Vankistus: Ulkoistetut simulaattorin apufunktiot (readUpdatePatchFromForm, marketCountriesKey) + 18 uutta yksikkötestiä; bugikorjaus: yksittäinen ei-ISO-syöte ei enää tyhjennä markkinaluetteloa.

2026-04 · Reaaliaikainen EU-vaatimustenmukaisuuden esikatselu luontilomakkeessa (Q3.3.6)

  • Muuttunut: POST /v1/dpp/validate palauttaa lisäksi kentän eu_compliance — sama validaattori kuin GET /v1/dpp/:id/eu-compliance, tilattomasti ennen tallennusta.
  • Dashboard: Esikatselu olemassa olevan validointipaneelin alapuolella + uusi Save-Guard-banneri ennen lähetyspainikkeita, jos virheitä/varoituksia on avoinna (i18n-monikkomuodot DE/EN).

2026-04 · EU-validaattori + tekstiilikäyttöliittymä (Q3.3.4 + Q3.3.5)

  • Uutta: EU-vaatimustenmukaisuusvalidaattori, jossa on 5 tekstiilisääntöä (TEXTILE_AGEC_REQUIRED, TEXTILE_MICROPLASTICS_CONSISTENCY, TEXTILE_SVHC_THRESHOLD, TEXTILE_GREENWASHING, TEXTILE_ESPR_READY).
  • Uutta: GET /v1/dpp/:id/eu-compliance, joka palauttaa kentät compliant / espr_ready / issues[] / summary.
  • Dashboard: EU-vaatimustenmukaisuusosio (EU-Compliance) DPP-yksityiskohdissa (yhteenvetolaatat, ryhmitellyt ongelmakortit, ESPR-Ready-merkki ylätunnisteessa).

2026-04 · Tekstiili-DPP-skeema (Q3.3.1–Q3.3.3)

  • Uutta: Kategoria textile ja lakisääteinen AGEC-ketju (kudonta/neulonta → värjäys/painatus → vaatteen valmistus), kuitukohtainen origin_country + recycled_pct, svhc_substances[], ESPR-opt-in (PEF, elinkaari, kierrätettävyys).
  • Uutta: Peruskenttä market_countries: string[] (ISO 3166-1 alpha-2) kaikissa DPP-kategorioissa — ohjaa Ranska-kohtaisia AGEC-sääntöjä ja ranskankielistä pakollista kuluttajailmoitusta.
  • Uutta: Kuluttajille suunnattu HTML-malli, jossa on AGEC-mikromuovivaroituslaatikko, 3-vaiheinen alkuperäketju (lippupillerit), SVHC-luettelo sekä kestävyys- ja kierrätettävyysosiot.
  • Migraatio: 0010_dpp_market_countries (D1).

2026-04 · DPP-massatuonti (Q3.2.1–Q3.2.5)

  • Uutta: POST /v1/dpp/import hyväksyy CSV- ja XLSX-tiedostot (Worker-yhteensopiva SheetJS xlsx -kirjaston kautta, ~283 kt:n gzip-paketti).
  • Skaalautuva: tilaustasoon perustuva raja (Free 100 → Enterprise 10k) + paloiteltu db.batch() 100 erissä + 5 megatavun pyynnön koon (body) raja.
  • Uutta: Virheraportti CSV-muodossa 201-vastauksen errors_csv-kentässä; GET /v1/dpp/import/templates/:category?format=csv|xlsx palauttaa valmiit mallit akulle ja tekstiilille.
  • Dashboard: Vedä ja pudota -lataus (drag-and-drop) osoitteessa /dashboard/dpp/import mallipohjavälityspalvelimen (template proxy) ja upotetun CSV-latauksen kanssa.

Ei-rikkovat muutokset — LTS-laajennukset

Kaikki edellä mainitut muutokset ovat lisääviä (additive):

  • Nykyiset POST /v1/dpp/validate-asiakkaat ohittavat uuden eu_compliance-kentän ilman muutoksia.
  • Nykyiset battery-työvoot säilyvät muuttumattomina.
  • market_countries on valinnainen ja sen oletusarvo on [].

Katso rikkovien muutosten käytäntö (breaking changes) sivulta API-versiointi.