Allin — GDPR
What's done, what's still open, and who it's waiting on — one table to scan, details below for anyone who wants the why/where/how. Sourced from GDPR, UK-specific law, Apple's App Store rules, or Allin's own Terms/Privacy Policy (tagged per item) — checked against live code and dashboards, not the intended design. Not a solicitor's sign-off; a lawyer should confirm the borderline calls.
At a glance
Click any row to jump to its detail below
| Item | Status | Owner |
| Done |
| Consent screen — 3 separate toggles | Built | — |
| Settings → Privacy (revisit consent) | Built | — |
| Analytics/ads gated behind consent | Built | — |
| Amplitude stopped receiving email | Live | — |
| Account deletion, hardened | Built | — |
| Anthropic disclosed as a processor | Documented | — |
| DPIA + ROPA | Filed | — |
| iOS privacy manifest | Filed | — |
| Supabase, Amplitude, Apple DPAs | Confirmed | — |
| Retention window | Decided — 180 days | — |
| Website pricing | Already correct | — |
| Crisis screen, ForceUpgrade, referral/review prompts | Built | — |
| Built, not yet live |
| Erasure fan-out to Amplitude/Customer.io | Not deployed | Marie — go to deploy |
| Consent audit trail (record what was granted) | Not deployed | Marie — go to push |
| Pseudonymization, Stage 1 | Not deployed | Marie — go to push |
| Redacted admin views | Not applied | Marie — go to apply |
| Data export + dormant-account finder | Not deployed | Marie — go to deploy |
| Corrected Privacy Policy | Not published | Isabel to publish |
| Compulsory — open |
| DPAs: Customer.io, Meta, RevenueCat, Anthropic | Open | Marie |
| ICO registration | Not checked | Isabel |
| Publish the corrected Privacy Policy | Open | Isabel to publish, both sign off |
| Pick the age-gate approach | Open | Isabel + Marie |
| Confirm App Store age rating | Not checked | Isabel |
| Desirable — open |
| Pseudonymization, Stage 2 + 3 | Drafted | Marie — watched window |
| Encryption at rest | Backend built | Marie — review iOS side |
| Different legal domain |
| Marketing claims — 2 items need wording | Open | Isabel |
A few terms, in plain English
Edge function — a small piece of Allin's own server code. Migration — a saved database change; writing one doesn't apply it. Branch — a safe copy of the code; nothing on it affects real users until it's pushed and deployed. Committed, not deployed — finished and saved, not yet switched on. Database view — a limited window onto real data, for seeing patterns without seeing private text. Pseudonym — a random token standing in for an account, so data groups by "same person" without revealing who. RLS — database rules on who can see which rows.
Done
Consent screen — 3 separate toggles
DoneSource: GDPR — consent must be specific per purpose
Replaced one bundled "allow tracking and reminders" toggle with three independent, revocable choices: reminders, analytics ("improve the app"), advertising. Open question for Isabel: there's no separate decline button — leaving every toggle off and tapping "continue"
is the decline path, same button either way.
We want to make this practice better,
your choice, for each of these.
continue
Settings → Privacy — revisit consent any time
DoneSource: GDPR Art. 7(3) — withdrawal as easy as granting
The permanent version of the same two toggles, inside Settings, for changing your mind later.
Source: Allin/Home/SettingsView.swift — PrivacyConsentView
Analytics/advertising gated behind consent
DoneSource: GDPR Art. 6/7 + Apple ATT
AnalyticsClient/
MetaAdsClient check stored consent before sending anything — not send-first-hope-they-opt-out-later.
Allin/Core/AnalyticsClient.swift · Allin/Core/MetaAdsClient.swift
Amplitude stopped receiving email
Done — liveSource: GDPR Art. 5(1)(c), minimization
Removed the Segment mapping that forwarded email as a User Property. The only item on this page confirmed live in production, not just committed.
Check Amplitude → User Properties on any new user — no email field. Verified against AnalyticsClient.swift's identify().
Account deletion, hardened
Done
A failed deletion used to fail silently, leaving the account fully live while the app acted like it had succeeded. Now surfaces the failure instead. Also: consent now clears on delete (not on plain sign-out), so it can't carry over to the next person on that device.
Allin/Core/AuthenticationManager.swift — deleteAccount()
Anthropic disclosed as a processor
Done — corrected the record
recommend-plan was documented as "FTS only, no LLM" — wrong. The live app calls Claude/Anthropic on every plan generation (FTS is the fallback). Now disclosed in the DPIA, ROPA, and privacy policy draft; a signed DPA with Anthropic is the top open item as a result.
DPIA + ROPA
DoneSource: GDPR Arts. 30/35
Both complete, kept current as processors changed (Anthropic added). Living documents — comment directly in the Doc.
iOS privacy manifest
DoneSource: Apple App Store Connect, not GDPR
Apple's own submission requirement — corrected to match actual ATT-gated tracking behavior.
Allin/PrivacyInfo.xcprivacy
Processor DPAs
Data Processing Agreements — one per third party (GDPR Art. 28)
| Processor | Status | What's left |
| Apple | Done | Covered by the Developer Program License Agreement. |
| Supabase | Done | Auto-incorporated into its Terms — confirmed directly in the dashboard, no signature needed. |
| Amplitude | Done | Same auto-coverage, confirmed at their Trust Center. |
| Customer.io | Found | Needs actual signing (not automatic) — Marie, from her other account. |
| Meta | Not started | Marie — paused deliberately, not blocked. |
| RevenueCat | Blocked on login | Marie — also needs a new v2 API key while logging in. |
| Anthropic | Blocked on login | Marie — platform.claude.com needs its own separate login. |
| Segment | Not checked | Lower urgency — never receives special-category text. |
Retention window — 180 days
DoneSource: GDPR Art. 5(1)(e)
Marie's decision: 180 days of inactivity, matching Segment's own retention for the same account.
dormant_accounts() identifies accounts past this cutoff — identification only, no auto-delete yet.
allin-backend · feat/gdpr-export-retention · 20260817120000_dormant_accounts.sql
Website pricing — already correct
Done — verified live
join-allin.com states £69.99/year, matching the real App Store price — re-checked live 2026-08-19. A real mismatch once (confirmed 2026-08-14), fixed on the site since; no action needed.
Crisis screen, ForceUpgrade, review + referral prompts
Done
Four smaller shipped pieces, grouped together:
Crisis support — UK users now see Shout (text) alongside Samaritans (call), region-resolved from device locale.
ForceUpgradeView — restyled to match the app's real design tokens, copy unchanged.
Review + referral prompts — both use Apple's native system UI, not a custom screen; only the referral message text is Allin's own (placeholder, needs Isabel + Marie sign-off).
you don't have to hold this alone
samaritans
116 123 · free, 24/7
shout new
text 85258 · free, 24/7
A new version is available
update now
Sources: CrisisResources.swift · ForceUpgradeView.swift · AppView.swift — presentReferralShare()
Standing rule for future AI features
Design principle
For any future feature reading someone's own history through a model ("we've mapped your subconscious"): send only content, never an identifier, in either direction — identity stays Allin's own side. If a future feature needs cross-call memory, the correlation key is the pseudonym, never the real account id.
Built, not yet live
safe to ship — needs your push
Nothing below is actually live yet
Marie + Isabel — sign off, then push
All five items below are built and safe to ship, but none satisfy anything legally until they're actually protecting a real user.
Erasure fan-out to Amplitude/Customer.io
Marie — go to deploy
Account deletion only removed Allin's own rows before — never told Segment/Amplitude/Customer.io. This function fans erasure out to all three, non-fatal per-processor failure.
allin-backend · combined-fixes-2026-08-15 · delete-user-data/index.ts
Consent audit trail
Records which consents were actually granted — currently nothing is
Marie — go to push
record_consent_granted was never wired to a real table — the call has been silently failing since the granular screen shipped. Confirmed directly against the live database: 0 of 112 real users have any consent recorded. Fix is built: a proper table plus matching functions for both the initial grant and later Settings changes.
allin-backend · feat/gdpr-consent-record · 20260817000000_user_consents.sql
Pseudonymization, Stage 1 of 3
Marie — go to push
Additive schema only — a mapping table + trigger stamping every new check-in with a random token, nothing existing can break. Stages 2/3 (below, Desirable) are what actually deliver the protection.
allin-backend · feat/gdpr-layer2-pseudonymize · 20260816000000_..._stage1.sql
Redacted admin views
Marie — go to apply
Three SQL views exposing only coarse metadata (truncated id, mood-shift direction — never free text or email), plus a restricted login role. Doesn't stop a privileged/owner login — that's what pseudonymization is for.
Data export + dormant-account finder
Marie — go to deploySource: GDPR Arts. 15/20
export-user-data returns everything Allin's own tables hold, as JSON, via a new "download my data" row in Settings.
dormant_accounts() just identifies accounts past the 180-day cutoff — no deletion or notification yet.
Allin/Home/SettingsView.swift — exportMyData() · allin-backend · feat/gdpr-export-retention
Privacy Policy — corrected draft ready
Live version currently states two false things
Legal requirementSource: GDPR Arts. 12–14Isabel to publish, both sign off
The live page is publicly readable and currently false. Corrected text is ready; not yet located in the Squarespace editor.
Compulsory — open
real legal obligations
DPAs: Customer.io, Meta, RevenueCat, Anthropic
Legal requirementMarie
See the processor table above for exactly what each needs.
ICO registration
Legal requirementSource: UK Data Protection Act 2018Isabel
UK controllers must register with the ICO and pay the annual fee (~£40–60/year). Publicly checkable — one of the more commonly enforced gaps precisely because it's easy to spot.
Pick the age-gate approach
Terms state 16+; nothing enforces it
Legal exposureUK Children's Code + Allin's own T&CsIsabel + Marie
Two sources: the Children's Code applies to any service children are likely to reach, and Allin's own Terms already promise 16+ with zero enforcement behind it. Three options: rely on the App Store rating alone (weakest); self-declared birthdate, hard-block under-16 (recommended — matches what the Terms already claim); full parental-consent flow for 13–15 (most engineering).
Confirm App Store age rating still matches the content
Legal requirementSource: Apple App Review GuidelinesIsabel
Separate from the age-gate above — Apple's own content questionnaire in App Store Connect. Worth confirming it still reflects the crisis-support content and emotional-distress themes now in the app.
Desirable — open
named GDPR example measures, not mandatory on their own
Pseudonymization, Stage 2 + 3
Drafted, not appliedSource: GDPR Art. 25/32Marie — watched maintenance window
Marie's call: go all the way, not stop at Stage 1. Stage 2 backfills every row; Stage 3 drops the real account id and tightens RLS to pseudonym-only, with a safety check that refuses to run if Stage 2 isn't complete. Needs a full backup first, and a paired one-line iOS change applied at the same moment Stage 3 runs.
allin-backend · feat/gdpr-layer2-pseudonymize · stage2_backfill.sql, stage3_drop_userid.sql
Encryption at rest
Backend done, not deployedSource: GDPR Art. 32Marie — review iOS side before it ships
AES-256-GCM, key exists only as an Edge Function secret, never in Postgres. New rows would populate an encrypted column alongside the existing plaintext one. Deliberately not done yet: switching the iOS app to actually call these functions instead of writing to the table directly — that's the single most-used code path in the app, so it gets its own dedicated review.
allin-backend · feat/gdpr-encryption-at-rest
Different legal domain
not GDPR, but real
Marketing claims — 2 items need wording
Different domainSource: ASA / Consumer Protection lawIsabel
Everything else on the claims register is sourced and safe; two claims need Isabel's exact wording call.
Who does what
Each item below has a ready prompt — paste it into your own Claude.
ICO registration
Prompt for your Claude
Help me check whether Allin Well Ltd is already registered with the ICO — search the public register at ico.org.uk/ESDWebPages/Search. If it's not there, walk me through registration and the data-protection-fee process at ico.org.uk/for-organisations/data-protection-fee — but don't submit anything until I confirm.
Privacy Policy — review, sign off, publish
Prompt for your Claude
Open this corrected Privacy Policy draft: https://claude.ai/code/artifact/1ab9d13b-5a0b-4efa-b2b1-ec19c0708923 — walk me through what changed vs. the live join-allin.com policy and why. Once I've said I'm happy, help me find the Privacy Policy page in Squarespace and get it ready to paste — but don't publish until I explicitly say go.
Marketing claims — 2 items need wording
Prompt for your Claude
Open the Marketing Claims Register: https://claude.ai/code/artifact/2e972533-d0ee-41be-9365-1dcafa3eb943 — 2 flagged claims need my exact wording. Walk me through each and help me draft accurate replacements.
Pick the age-gate approach (with Marie)
Prompt for your Claude
Open https://allin-gdpr.pages.dev (password Isma2026), find "Pick the age-gate approach." Walk me through the three options and trade-offs so I can bring a recommendation to Marie.
Sign off on the consent screen + release branch (with Marie)
Prompt for your Claude
Open https://allin-copy-review.pages.dev (password Isma2026) — walk me through the consent screen copy, the crisis-line addition, and the referral message, so I can approve, reject, or ask for changes on each before this ships.
Confirm the App Store age rating still matches the content
Prompt for your Claude
Help me check Allin's current App Store Connect age rating and content questionnaire, and confirm it honestly reflects the app now — including crisis-support content and emotional-distress themes.
Execute the Customer.io DPA from your other account · check Meta Business Manager's DPA status · log into RevenueCat to check DPA status + generate a new v2 API key · log into platform.claude.com to check Anthropic's DPA status · deploy the 5 built-not-live items above · schedule pseudonymization Stage 2/3's maintenance window · review the encryption iOS integration · age-gate approach (with Isabel) · sign off on the consent screen + release branch (with Isabel)