Skip to content

GDPR & andmekaitse

Lõimitud andmekaitse

qr3.app on algusest peale loodud vastama GDPR-i nõuetele:

  • IP-pseudonümiseerimine — IP-aadressid teisendatakse Edge-Workeris kohe HMAC-SHA-256 UTC-päeva pseudonüümideks. Algset IP-aadressi ei salvestata kunagi; pseudonüüm jääb isikuandmeks.
  • Andmete minimeerimine — kogutakse ainult toimimiseks hädavajalikke andmeid.

Privaatsuse API

Andmete kokkuvõte (GDPR art 15)

GET /v1/account/privacy — tagastab ülevaate kõigist salvestatud andmetest.

Terminal window
curl https://qr3.app/v1/account/privacy \
-H "Authorization: Bearer qr3_sk_..."

Vastus:

{
"data": {
"workspace_id": "ws_xxx",
"organization_id": "org_xxx",
"account": {
"email": "[email protected]",
"name": "Alex Example",
"locale": "en",
"created_at": "2026-01-15T09:00:00.000Z"
},
"stored_data": {
"qr_codes": 42,
"scan_records": 15000,
"dpp_scan_records": 3200,
"dashboard_activity_records": 0,
"dashboard_document_activity_records": 36,
"api_operation_records": 180,
"webhook_delivery_records": 640,
"api_keys": 2,
"webhooks": 1,
"dpp_passports": 12,
"dpp_documents": 30,
"files": 4,
"gs1_identifiers": 2,
"gs1_verification_requests": 1,
"code_comments": 5,
"audit_log_entries": 0,
"dpp_import_jobs": 1,
"workspace_members": 3,
"scan_quota_alerts": 1
},
"gdpr_rights": {
"access": "GET /v1/account/privacy",
"export": "GET /v1/account/export",
"erasure": "DELETE /v1/account",
"consents": "GET /v1/account/privacy/consents"
},
"data_processing": {
"ip_storage": "Purpose-separated HMAC-SHA-256 UTC-day IP pseudonym — pseudonymous personal data",
"scan_retention": "90 days by default",
"usage_retention": "90 UTC days",
"webhook_delivery_retention": "90 UTC days",
"pii_in_export": true,
"erasure": "DELETE /v1/account erases the person's account: organizations they own with all workspaces and data (unless another org admin takes them over), their memberships in other organizations, their login and their Stripe customer. A running subscription ends immediately, without refund.",
"backup_retention": "Erased rows stay restorable from the database backups (Cloudflare D1 Time Travel) for up to 30 days, then they are gone.",
"billing_records": "Invoices stay with Stripe for the statutory retention period (7 years, § 132 BAO)."
}
},
"meta": { "request_id": "req_xxx" }
}

stored_data loendab salvestatud kirjeid. scan_records on QR-koodide skannimised, dpp_scan_records tootepasside päringud avaliku DPP resolveri kaudu. Mõlemad sisaldavad IP-pseudonüümi.

dashboard_activity_records ja dashboard_document_activity_records loendavad päevi, mil liige dashboardi avas (kaks tabelit), api_operation_records igapäevaseid päringuloendureid API-võtme, operatsiooni ja tulemuse kaupa ning webhook_delivery_records webhookide kohaletoimetamiskatseid, sealhulgas kustutatud webhookide omi. Ükski neist ei salvesta IP-aadressi ega User-Agent’i; kohaletoimetamislogi salvestab aga sündmuse payload’i ja vastuvõtja vastuse esimese kilobaidi (1 KB). Kõik neli kustutatakse 90 UTC-päeva pärast (usage_retention, webhook_delivery_retention).

account nimetab päringu taga oleva isiku — dashboardis sisselogitud isiku, muidu võtme loonud isiku — koos e-posti, nime, keele ja loomise kuupäevaga; Publishable Key puhul on väärtus null. Ülejäänud loendurid katavad iga muu konto andmetega tabeli: tootepassid, DPP-dokumendid, failid, GS1-identifikaatorid, kommentaarid, auditikirjed, impordikäivitused, workspace’i liikmed ja organisatsiooni kvooditeated (scan_quota_alerts). Pehmelt kustutatud read loetakse kaasa, sest need on endiselt salvestatud. erasure, backup_retention ja billing_records kirjeldavad, mida DELETE /v1/account kustutab ja mis jääb mõneks ajaks alles; pii_in_export on true, sest eksport nimetab isiku (e-post, nimi) — IP-pseudonüümid ei lahku andmebaasist kunagi.


Andmete eksport (GDPR art 20 — andmete ülekantavus)

GET /v1/account/export — laadib kõik andmed alla JSON-failina.

Terminal window
curl https://qr3.app/v1/account/export \
-H "Authorization: Bearer qr3_sk_..." \
-o my-data.json

Eksport sisaldab:

  • Kõiki QR-koode (sh kustutatud)
  • Agregeeritud skannimisstatistikat (mitte tooreid IP-räsisid)
  • Agregeeritud DPP-päringuid tootepasside kaupa (dpp_scan_aggregates, samuti ilma IP-räsideta)
  • Kasutusstatistika koondandmetena (dashboard_activity_aggregates, api_operation_aggregates): aktiivsed päevad ja aktiivsete kasutajate arv dashboardi kanali kaupa, päringuloendurid operatsiooni ja tulemuse kaupa — ilma kasutaja- ja võtme-ID-deta
  • Webhookide kohaletoimetamiskatsed webhooki ja sündmuse tüübi kaupa (webhook_delivery_aggregates), ilma payload’i ja vastuseta
  • Päringu taga oleva isiku (account), organisatsiooni (organization; arveldus- ja teavitusaadress ainult organisatsiooni administraatoritele) ja workspace’i (workspace)
  • Tootepassid, DPP-dokumentide ja failide metaandmed (mitte faile ennast), GS1-identifikaatorid, nende kinnitamise taotlused ja impordikäivitused (dpp_passports, dpp_documents, files, gs1_identifiers, gs1_verification_requests, dpp_import_jobs)
  • Kommentaarid ilma autoriväljadeta (code_comments), auditikirjed agregaatidena (audit_log_aggregates) ja liikmed rollide kaupa (member_aggregates)
  • API-võtmed ilma ID ja räsita (api_keys), webhookid ilma URL-i ja saladuseta (webhooks) ning organisatsiooni kvooditeated (scan_quota_alerts)
  • Loomise ja muutmise ajatempleid

Publishable Keys (qr3_pk_) saavad vastuseks 403: fail sisaldab kõigi koodide sihtaadresse ja märkmeid.


Konto kustutamine (GDPR art 17 — õigus olla unustatud)

DELETE /v1/account — Kustutab päringu taga oleva isiku konto kohe ja pöördumatult: dashboardis sisselogitud isiku, muidu võtme loonud isiku. Kustutustaotlus e-posti teel viib sama kustutamiseni: teenuse haldaja kustutab Clerki sisselogimise ja qr3 kustutab seejärel konto.

Terminal window
curl -X DELETE https://qr3.app/v1/account \
-H "Authorization: Bearer qr3_sk_..."

Mis juhtub:

  1. Isikule kuuluvad organisatsioonid kustutatakse koos kõigi workspace’ide, koodide, tootepasside, failide, statistika ja logidega, sealhulgas nende failidega salvestusruumis. Kui sellisel organisatsioonil on teine aktiivne organisatsiooni administraator, võtab selle asemel organisatsiooni koos andmete ja tellimusega üle kõige kauem ametis olnud administraator.
  2. Tellimus: käimasolev tellimus lõpeb kohe, ilma proportsionaalse tagasimakse ja lõpparveta; seejärel kustutatakse Stripe’i klient. Arved jäävad Stripe’i seadusjärgseks säilitusajaks (7 aastat, § 132 BAO).
  3. Meeskonnad: isiku liikmesused teistes organisatsioonides lõpevad; need meeskonnad säilitavad oma andmed. Isiku kommentaarid ei nimeta enam autorit, tema auditikirjetelt eemaldatakse IP-pseudonüüm ja user agent ning tema seal loodud API-võtmed tühistatakse.
  4. Isik: sisselogimine (Clerk) ja kasutajakirje kustutatakse.

Vastus on 200 koos status: "completed" ja loenduritega organizations_deleted, organizations_transferred, memberships_removed ja login_deleted. Väga suurte organisatsioonide puhul ühest päringust ei piisa: vastus on siis 202 koos status: "in_progress" ning kustutamine lõpeb automaatselt mõne tunni jooksul.

Nõuab kirjutusõigusega Secret või Test Key’t või dashboardi seanssi (mis tahes roll, sest tegu on isiku enda kontoga). Publishable Keys ja ainult lugemisõigusega võtmed saavad vastuseks 403, võti, mille taga pole isikut (created_by = 'system'), saab 409. 503 tähendab, et paigaldusest puudub kustutamiseks vajalik saladus; midagi ei kustutatud.


Nõusolekute haldamine

GET /v1/account/privacy/consents — praeguste nõusolekute pärimine.

POST /v1/account/privacy/consents — nõusolekute uuendamine.

Terminal window
# Praeguste nõusolekute pärimine
curl https://qr3.app/v1/account/privacy/consents \
-H "Authorization: Bearer qr3_sk_..."
# Turundusmeilide väljalülitamine
curl -X POST https://qr3.app/v1/account/privacy/consents \
-H "Authorization: Bearer qr3_sk_..." \
-H "Content-Type: application/json" \
-d '{ "marketing_emails": false, "analytics": true, "product_updates": true }'

Nõusoleku väljad:

VäliVaikimisiKirjeldus
marketing_emailsfalseUudiskirjad ja reklaamkirjad
analyticstrueAgregeeritud kasutusstatistika
product_updatestrueTooteuuendused ja muudatuste logid

Nõusolekute muutmine nõuab kirjutusõigust: roll viewer ja Publishable Keys saavad vastuseks 403.


Tehniline GDPR-i rakendamine

IP-pseudonümiseerimine (GDPR art 25)

HTTP-päring → Cloudflare Edge Worker
↓
CF-Connecting-IP päis → HMAC-SHA-256(IP_HASH_SALT, eesmärk, UTC-päev, IP)
↓
ip_hash (päevapõhine pseudonüüm) → D1 andmebaas
↓
Algset IP-aadressi ei salvestata kunagi

IP_HASH_SALT on pikaealine põhisaladus; eesmärk ja UTC-päev tuletavad automaatselt eraldi päevapõhised pseudonüümid. Eri UTC-päevade pseudonüümid ei ole otseselt samad, kuid saladuse valdaja saab teadaoleva IP-kandidaadi konkreetse päeva jaoks uuesti arvutada. KV-päevasoola ega käsitsi igapäevast rotatsiooni ei kasutata.

Andmete säilitamine (automatiseeritud)

PakettSäilitamine
Kõik paketid90 päeva

Ka kasutusstatistikat (dashboardi tegevus, API kasutusloendurid) ja webhookide kohaletoimetamislogisid säilitatakse 90 UTC-päeva: jooksev UTC-päev ja 89 eelnevat päeva. Sama igapäevane cron-töö kustutab vanemad read (purgeOldDashboardActivity, purgeOldApiOperationUsage, purgeOldWebhookDeliveries).

Alamtöötleja DPA

Cloudflare, Inc. töötleb andmeid volitatud töötlejana. Andmetöötlusleping (DPA) on saadaval aadressil cloudflare.com/cloudflare-customer-dpa.

Cloudflare töötleb andmeid asukohavihjega EL-i piirkonnale (sh Frankfurt); lepinguliselt tagatud EL-i jurisdiktsioon ei ole praegu tellitud. Kuna Cloudflare, Inc. asub USA-s, kehtivad edastamise alusena standardlepingu tingimused (SCC-d) vastavalt GDPR art 46.


Kontakt