GrailAtlasAn independent mechanical watch reference
English

Records of processing activities

Every kind of personal data Grail Atlas processes, what we use it for, the lawful basis we rely on, how long we keep it, and who (if anyone) we share it with. This is the full GDPR Art. 30 record, published voluntarily because transparency beats lawyer-speak.

If you want a copy of every record we hold on you specifically (or want it all deleted), use the privacy request form.

14 active activities

RP-ACCT-01Account management

v1 · effective 2026-05-22

Create, authenticate, and maintain user accounts so the visitor can save a Grail List or saved searches across sessions.

Lawful basis
Art. 6(1)(b); performance of a contract with the data subject
Subjects
registered visitors
Data categories
email · hashed password · display name · account preferences
Sources
the data subject directly via the signup form
Retention
While the account is active. 30 days post-deletion for cleanup; immediate on confirmed erasure request.
Recipients
  • Supabase, database + auth (US, EU-US DPF (SCC fallback))
  • Vercel, hosting (request transit only) (US, EU-US DPF (SCC fallback))
Security
Salted scrypt password hashing; RLS deny-all-anon; TLS in transit; encryption at rest at the Supabase storage layer.
Tables
  • accounts (email)

RP-NL-01Newsletter (Grail Notebook)

v1 · effective 2026-05-22

Deliver the Grail Notebook newsletter only to subscribers who have completed the double-opt-in confirmation.

Lawful basis
Art. 6(1)(a); consent; Art. 7(1) demonstrability
Subjects
newsletter subscribers
Data categories
email · signup-page URL · IP address at confirm · confirmation timestamp
Sources
the data subject directly via the newsletter form
Retention
While subscribed. Proof-of-consent row (IP + timestamp) retained 24 months post-unsubscribe to defend against PECR / ePrivacy enforcement claims (typical limitation period 2-3 years; reviewed annually).
Recipients
  • Supabase, database (US, EU-US DPF (SCC fallback))
  • Resend, transactional email delivery (US, EU-US DPF (SCC fallback))
Security
RLS deny-all-anon; service-role-only writes; salted email hash for lookup.
Tables
  • newsletter_subscribers (email)
Erasure rules
  • newsletter_subscribers: defer 30d, Art. 17(3)(e); proof-of-consent row retained 30 days post-request to defend against a possible "I never opted in" claim. The active subscription is suppressed immediately; the proof row is deleted at day 30.

RP-SS-01Saved searches + email alerts

v1 · effective 2026-05-22

Persist the visitor’s saved-search constraints and dispatch alert digests they opted into.

Lawful basis
Art. 6(1)(b); contract; Art. 6(1)(a) consent for alert emails
Subjects
registered visitors
Data categories
email · account id · saved search constraints · alert cadence · digest send history
Sources
the data subject directly
Retention
While the search is active. 90 days archive after the visitor deletes; immediate on confirmed erasure.
Recipients
  • Supabase, database (US, EU-US DPF (SCC fallback))
  • Resend, digest delivery (US, EU-US DPF (SCC fallback))
Security
RLS per-account; per-account rate limit; query shape validated server-side; feed token hashed at rest.
Tables
  • saved_searches (email)

RP-GL-01Grail List

v1 · effective 2026-05-22

Track the visitor’s shortlisted target watches and (optionally) owned pieces with acquired price/date for valuation.

Lawful basis
Art. 6(1)(b); contract (opt-in feature)
Subjects
registered visitors who add Grail List entries
Data categories
email · account id · watch reference · condition · box/papers · acquired price · acquired date
Sources
the data subject directly
Retention
While the account is active; immediate on confirmed erasure.
Recipients
  • Supabase, database (US, EU-US DPF (SCC fallback))
Security
RLS per-account; financial-status-adjacent fields encrypted at the storage layer.
Tables
  • grail_lists (email)

RP-REQ-01Catalog / brand suggestion submissions

v1 · effective 2026-05-22

Accept the visitor’s request to add a watch or brand to the catalog; respond by email when the suggestion is acted on.

Lawful basis
Art. 6(1)(a); consent (the submitter chooses to provide an email for follow-up)
Subjects
catalog-suggestion submitters
Data categories
contact_email (if provided) · submission text
Sources
the data subject directly via /request
Retention
12 months from submission; immediate on confirmed erasure.
Recipients
  • Supabase, database (US, EU-US DPF (SCC fallback))
Security
RLS deny-all-anon; honeypot + rate-limit on the form.
Tables
  • user_submissions (contact_email)

RP-CONS-01Cookie / tracking consent record

v1 · effective 2026-05-22

Record the visitor’s consent choice so the banner does not re-prompt every visit, and so we can demonstrate consent under Art. 7(1).

Lawful basis
Art. 6(1)(c); legal obligation (ePrivacy Art. 5(3) demonstrability + Art. 7(1))
Subjects
all visitors
Data categories
accepted categories · policy version · decision timestamp
Sources
the data subject’s banner interaction
Retention
24 months from the most recent decision; mirrored Supabase row deleted on account deletion.
Recipients
  • (none; first-party cookie only for anonymous; Supabase mirror for logged-in), - (-)
Security
First-party cookie; SameSite=Lax; Secure over HTTPS; mirror row RLS-protected.
Tables
  • consent_records (email_hash)

RP-AUDIT-01Privacy operations audit log

v1 · effective 2026-05-22

Maintain a tamper-evident chain of every step of every DSAR + ROPA change so Art. 5(2) accountability is demonstrable.

Lawful basis
Art. 6(1)(c); legal obligation (Art. 5(2) accountability)
Subjects
DSAR requesters · operator
Data categories
pseudonymised email hash · request metadata · IP hashes · event timestamps · hash chain
Sources
automated emission from privacy engine + ROPA change handler
Retention
3 years minimum (Art. 82 actions limitation period); 6 years maximum. Daily salts are retained alongside the audit log for the same period so post-hoc verification remains possible.
Recipients
  • Supabase, database (US, EU-US DPF (SCC fallback))
  • External attestation log, hourly head-hash publication (global, public log)
Security
Append-only at three layers (app, row triggers, event trigger); hash chain; external hourly attestation.
Tables
  • privacy_audit_log (subject_email_hash)
Erasure rules
  • privacy_audit_log: Art. 17(3)(b) + (e); retention necessary for compliance with a legal obligation (accountability) and defense of legal claims. Erasure does not apply to the audit log itself; the subject_email_hash is pseudonymised and not directly identifying.

RP-LAUNCH-01Launch list email capture

v1 · effective 2026-06-02

Collect email addresses of visitors who want to be notified when the site launches and when live pricing data arrives.

Lawful basis
Art. 6(1)(a); consent (affirmative opt-in)
Subjects
pre-launch visitors who submit the launch-notification form
Data categories
email address
Sources
the data subject directly via the launch-notification form
Retention
Until notified or until the data subject submits an erasure request. Maximum 12 months without activity; reviewed and purged at the 12-month mark if unnotified.
Recipients
  • Supabase, database (US, EU-US DPF (SCC fallback))
  • Resend, launch notification email delivery (US, EU-US DPF (SCC fallback))
Security
RLS deny-all-anon; service-role-only writes; rate-limited form endpoint.
Tables
  • launch_list (email)

RP-PRICE-NOTIFY-01Per-reference pricing notification

v1 · effective 2026-06-02

Collect an email address and a watch reference ID from visitors who want to be notified when live pricing data becomes available for a specific reference.

Lawful basis
Art. 6(1)(a); consent (affirmative opt-in)
Subjects
visitors who request pricing notifications for a specific watch reference
Data categories
email address · reference ID (non-sensitive catalog identifier)
Sources
the data subject directly via the reference-page pricing-alert form
Retention
Until the notification is sent or until the data subject submits an erasure request. Maximum 12 months; reviewed and purged at the 12-month mark if unnotified.
Recipients
  • Supabase, database (US, EU-US DPF (SCC fallback))
  • Resend, pricing notification email delivery (US, EU-US DPF (SCC fallback))
Security
RLS deny-all-anon; service-role-only writes; rate-limited form endpoint; reference ID validated against catalog before insert.
Tables
  • pricing_notification_requests (email, reference_id)

RP-BRAND-SUB-01Brand catalog update subscription

v1 · effective 2026-06-02

Collect an email address and a brand preference from visitors who want to be notified when new references are added for a specific brand.

Lawful basis
Art. 6(1)(a); consent (affirmative opt-in)
Subjects
visitors who subscribe to brand-catalog update notifications
Data categories
email address · brand name (non-sensitive preference)
Sources
the data subject directly via the brand-page subscription form
Retention
Until the notification is sent or until the data subject submits an erasure request. Maximum 12 months; reviewed and purged at the 12-month mark if no notification has been sent.
Recipients
  • Supabase, database (US, EU-US DPF (SCC fallback))
  • Resend, brand update notification email delivery (US, EU-US DPF (SCC fallback))
Security
RLS deny-all-anon; service-role-only writes; rate-limited form endpoint; brand name validated against catalog before insert.
Tables
  • brand_subscribers (email, brand)

RP-MIN-01Minor records remediation

v1 · effective 2026-05-22

Erase records inadvertently created by under-18 visitors (or by their parents/guardians on their behalf) when discovered.

Lawful basis
Art. 6(1)(c); legal obligation; Art. 17(1)(f); erasure of unlawful processing
Subjects
under-18 visitors · parent/guardian on behalf
Data categories
(whatever was inadvertently collected; typically email + signup metadata)
Sources
parent/guardian or operator notification
Retention
Immediate on operator confirmation that the subject is under 18; no confirmation handshake required.
Recipients
  • Supabase, database (US, EU-US DPF (SCC fallback))
Security
Operator-initiated DSAR path; audit-chained.

RP-PAGEVIEW-01Aggregate pageview counters

v1 · effective 2026-08-01

Count pageviews per route and referrer source so it is possible to tell whether the site reaches anyone, without identifying or tracking any visitor.

Lawful basis
Art. 6(1)(f); legitimate interest in knowing whether the site reaches anyone, limited to transient processing of the connection IP and of the user agent for bot classification, neither of which is persisted. No ePrivacy Art. 5(3) consent is required because nothing is stored on or read from the visitor's device. The persisted counters themselves are not personal data under Art. 4(1): no cookie, session identifier, IP address or user agent is stored, so no row can be related to an identified or identifiable natural person.
Subjects
site visitors (transient processing only; nothing identifying is retained)
Data categories
normalized route shape (e.g. /reference/[id]) · referrer host (e.g. google.com, or "direct") · date · an integer counter
Sources
the visitor's browser, via a first-party beacon
Retention
Indefinite. The rows are aggregate counters containing no personal data, so storage limitation (Art. 5(1)(e)) does not bite.
Recipients
  • Vercel, hosting (request transit only) (US, EU-US DPF (SCC fallback))
  • Supabase, database (US, EU-US DPF (SCC fallback))
Security
RLS enabled with zero policies (deny-all for anon and authenticated); service-role writes only. The user agent is read in-memory for bot classification and never persisted.

RP-VIDEO-01Third-party video embeds (YouTube)

v1 · effective 2026-08-01

Let a visitor watch a creator review of a watch on its reference page, without contacting Google unless the visitor asks for the video.

Lawful basis
Art. 6(1)(a); consent, given by the explicit "Load video from YouTube" click. No Google host is contacted before that click.
Subjects
site visitors who choose to play an embedded video
Data categories
IP address (disclosed to Google, not stored by us) · device and browser information (disclosed to Google, not stored by us)
Sources
the visitor's browser, only after an explicit click
Retention
None on our side; nothing about the viewer is written anywhere. Google's own retention is governed by its privacy policy.
Recipients
  • Google Ireland Ltd / YouTube LLC, video hosting and playback (US, EU-US DPF (SCC fallback))
Security
Click-to-load facade: thumbnails are proxied same-origin via /api/yt-thumb/[id] so the browser never contacts i.ytimg.com on page load, the iframe targets youtube-nocookie.com and mounts only after an explicit click, and the proxy sets Referrer-Policy: no-referrer.

RP-POSTHOG-01Consent-gated product analytics (PostHog)

v1 · effective 2026-08-01

Measure returning-visitor retention, feature usage, and traffic patterns for visitors who explicitly opt in, so the site can tell whether it is reaching and keeping anyone. PostHog is only initialized after the visitor clicks "Allow analytics" in the consent banner; no PostHog code loads and no request reaches PostHog before that click.

Lawful basis
Art. 6(1)(a); consent, obtained via the consent banner before any PostHog code loads
Subjects
visitors who click "Allow analytics" in the consent banner
Data categories
first-party PostHog cookie/localStorage identifier · page views and route navigation · device and browser information (User-Agent) · country-level geolocation (derived from IP at ingest; raw IP not retained by us)
Sources
the visitor's browser, only after an explicit "Allow analytics" click
Retention
Governed entirely by PostHog's own retention, not ours: no PostHog visitor data is written to any Grail Atlas database table (see tablesPersonalData below). The identifying cookie AND its matching localStorage entry persist on the visitor's device for up to ~1 year, or until the visitor revokes consent, which now clears both immediately (opt_out_capturing() followed by reset(), with opt_out_persistence_by_default: true) rather than merely pausing capture. See app/providers.tsx.
Recipients
  • PostHog Inc., product analytics processor (US, Standard Contractual Clauses (SCCs) via the PostHog DPA)
Security
Consent-gated init: posthog.init() is only ever called after the gw-consent cookie already lists "analytics" (app/providers.tsx, PHProvider). Revoking consent calls posthog.opt_out_capturing() then posthog.reset() on the existing instance, which clears the cookie and localStorage identifier rather than leaving them in place. person_profiles set to identified_only. No advertising identifiers, no cross-site tracking, no ad network integration.

Changes to this list are audit-chained: every addition, edit, or retirement appends an event to the privacy audit log. The chain’s current head is published hourly to an external attestations repo (so a service-role attacker can’t silently rewrite history). See privacy policy for the underlying commitments.