Privacy policy and Terms update emails

When Turtini's Privacy Policy or Terms of Service is materially updated, every active platform user receives a one-time notification email so they can read the change before continuing. These are legally-required transactional notices — there is no opt-out, but they only fire on real policy changes.

How a change becomes an email:
1. A platform admin edits /privacy or /terms in the EditablePage CMS and saves.
2. A new privacyPolicyVersions doc is created with notifyAt = now + 24 hours and status = pending.
3. During that 24-hour window, the admin can keep tweaking the wording — saves to the same pending version don't re-extend the timer.
4. Once notifyAt elapses, an hourly Cloud Function claims the version, fetches every user, and sends the notification email via Resend.

The 24-hour delay window:
This is intentional. It gives admins a buffer to fix typos or add a clarifying sentence after publishing without spamming the user base every time. Once the email goes out, the version is marked sent — further edits to the policy pages start a new pending version.

What the email says:
• Hi {first name}
• "Turtini's {Privacy Policy / Terms of Service} has been updated."
• If a change summary is provided, it appears in a callout block: "What changed: …"
• Link to the updated policy at https://turtini.com/{privacy|terms}
• Standard footer with the company address

Who gets the email:
Every user in the users/ collection with a non-empty email and no global suppression flag (users/{uid}.emailSuppressedAt). That's the entire active platform — orgs, partners, employees, members.

Why no opt-out:
Privacy and Terms updates are a legal obligation, not marketing. Users cannot legally opt out of being told their privacy policy changed. We do not include these in any marketing-suppression list.

Idempotency:
The version moves pending → sending → sent atomically before the fan-out begins, so a retried Cloud Function instance can never double-send.