Allin — internal
Enter the password to continue.
Allin — GDPR

Allin — GDPR

The single page for this workstream: the full audit, every build and why it happened, what's actively in progress, and what's still an open decision — split by who it's waiting on. Nothing here is "not being worked on"; anything not finished is either mid-build or waiting on a specific person's call, and that's marked either way.

How this list was built

So you can judge whether it's actually complete, not just trust it
This wasn't brainstormed — it comes from working through the standard GDPR obligation categories one at a time and checking each against Allin's actual live code and schema, not the intended design: lawful basis (what allows processing check-in/health-adjacent data at all — Art. 9 explicit consent), transparency (Arts. 12–14, the privacy policy has to be true), data subject rights (Arts. 15/17/20 — access, erasure, portability), storage limitation (Art. 5(1)(e) — a defined retention period), security (Art. 32 — pseudonymization/encryption as named example measures), accountability (Art. 30 ROPA, Art. 35 DPIA for high-risk processing), processor agreements (Art. 28 — a DPA per third party, cross-referenced against every processor actually found in the data-flow mapping), plus the UK-specific pieces (ICO registration, the Children's Code) and Apple's own separate requirements (App Store age rating, the privacy manifest) layered on top — four distinct sources in total, each tagged on its item below: GDPR itself, UK-specific law, Apple's App Store requirements, and Allin's own Terms/Privacy Policy (a self-imposed promise creates its own obligation to actually be true). Several items only surfaced because the live code was checked directly rather than assumed — the consent-recording function that didn't exist, Anthropic as an undisclosed processor, the repo/live drift on recommend-plan. That's the actual basis for calling this reasonably complete: systematic obligation-by-obligation coverage, verified against what's really running. Honest limit: this is a technical/product review, not a solicitor's sign-off — the borderline calls (age-gate, ICO specifics) are worth a real lawyer confirming before treating this as final.

What needs doing, by type

The same open items above, sorted a different way
App changes (code): push the consent screen + audit trail branch · deploy delete-user-data, pseudonymization Stage 1, export-user-data + dormant_accounts · add a "download my data" entry point in Settings · build the age-gate once the approach is picked · apply the redacted admin views · pseudonymization Stage 2/3 and encryption, if/when chosen.
Documents filed: DPIA — done · ROPA — done · iOS privacy manifest — done (Apple requirement) · DPA paperwork — Supabase + Amplitude confirmed auto-covered, no signing needed (checked 2026-08-17) · Customer.io found, needs actual signing (Marie, separate account) · Meta + RevenueCat not started · Anthropic blocked on a separate platform.claude.com login · ICO registration — not started, public register not yet checked.
Terms & Privacy Policy (add corrections, never delete the original claim being fixed): Privacy Policy — corrected text ready; not yet located in the Squarespace editor (checked 2026-08-17, not started); publishing needs both sign-offs · Terms & Conditions — already reviewed once (the "future versions" journaling clause corrected to present-tense, since journaling already shipped) as part of the same draft as the Privacy Policy; the age-gate section below is the one remaining place the Terms claim something (16+) that isn't actually true yet · website pricing — already fixed on the live site (re-verified 2026-08-17), no longer an open item.

A few terms used throughout, in plain English

So this reads without a coding background
Edge function — a small piece of Allin's own server code that runs when the app calls it (for example, the code that deletes a user's data everywhere when they delete their account).
Migration — a saved, ready-to-run database change. Writing one doesn't change anything by itself; someone still has to apply it.
Branch — a separate, safe copy of the code where new work happens before it's made live. Nothing on a branch affects real users until it's specifically pushed and deployed.
Committed, not deployed/live — the work is finished and saved, but hasn't been switched on for real users yet.
Database view — a saved, limited "window" onto the real data — used here to let someone see coarse patterns (like whether mood improved) without ever seeing the actual private text or an email address.
Pseudonym — a random token standing in for someone's account, so data can be grouped by "the same person" without anyone being able to tell who that person actually is, unless they deliberately look it up in one separate, locked table.
RLS / access role — database-level rules controlling who can see which rows, independent of the app itself.

Everything done, and why

the full history behind where this stands today

Consent redesigned into three separate, specific toggles

The foundation everything since builds on
Done
The starting point for this whole workstream. The old flow was one low-friction button — "allow tracking and reminders" or "skip" — covering multiple different purposes (analytics, advertising, reminders) with a single yes/no. GDPR requires consent to be specific: each distinct purpose needs its own separate, informed, freely-given choice, not one blanket switch. That's why this became a genuine 3-decision screen: independent toggles for reminders, analytics ("improve the app"), and advertising, each gettable and revocable on its own — plus a Settings → Privacy screen so someone can come back and change their mind later, since GDPR also requires withdrawal to be as easy as granting. One thing still genuinely unresolved from this redesign: there's no separate decline/skip button — leaving every toggle off and tapping "continue" is the decline path, so someone who says no to everything sees the exact same button, with the exact same word, as someone who said yes to everything. Worth Isabel's read on whether "continue" reads neutral enough either way.
See it

We want to make this practice better,

your choice, for each of these.

🔔
reminders
📈
improve the app
📣
ads
continue
Approximation built from the app's real colors/layout, not a screenshot — full version + editable copy at allin-copy-review.pages.dev. Source: Allin/Home/ConsentSheet.swift

Settings → Privacy screen — the other half of the consent redesign, not shown before

Where someone comes back later to change their mind
Done
The consent screen above is what someone sees once, up front. This is the part that makes withdrawal as easy as granting, per GDPR Art. 7(3) — a real screen inside Settings, not a buried toggle, where the same two revisitable choices (reminders isn't shown here — that's an OS notification permission, not an app-level one) live permanently. Flagging this now specifically because the wiki previously only showed the one-time consent screen and left this out entirely, even though it's equally real, shipped UI.
See it

privacy & data

your sessions, beliefs, and reflections are stored privately on your device and synced to allin's secure backend. change either of these any time.

📈
improve the app
so we can see which sessions help, using your check-in answers
📣
ads
so we can show you relevant ads elsewhere

read full policy ↗

Shown with "improve the app" on, "ads" off, to illustrate the toggles are independent. Source: Allin/Home/SettingsView.swiftPrivacyConsentView

ForceUpgradeView restyled

The force-update screen — most likely to actually block a real user, previously the least on-brand screen in the app
Done
Previously hardcoded its own fonts and hex colors instead of using the app's real design tokens — copy unchanged, purely a restyle so the one screen most likely to actually stop someone matches the rest of Allin instead of looking like a generic placeholder.
See it

A new version is available

Please update the app to continue. This version is no longer supported.

update now
Copy is unchanged from before — only the visual design changed. Source: Allin/Core/ForceUpgradeView.swift

Crisis support screen — Shout added

UK region, sitting alongside the existing Samaritans line
Done
Shown instead of an audio session when a check-in signals someone may be in crisis. Region-aware — resolved from the device's locale, no user data stored. The addition here is one line: UK users now see Shout (text-based) alongside Samaritans (call-based), so there's a non-verbal option too.
See it

you don't have to hold this alone

Some of what you shared sounds really heavy. You deserve support from a real person, not an audio.

samaritans
call 116 123 · free, 24/7
shout new
text SHOUT to 85258 · free, 24/7

if you're in immediate danger, call your local emergency number.

Shown for the GB region — the same screen resolves different resources per country. Source: Allin/Core/CrisisResources.swift

App Store review + referral prompts

Shown after a session where mood measurably improved, alternating so they never both appear
Done
Honest note before the "see it" below: neither of these is a custom-designed Allin screen — both intentionally use Apple's own native system UI rather than a bespoke one, so there's genuinely nothing further to mock up beyond what's shown here. The review prompt is Apple's standard SKStoreReviewController sheet — Allin supplies zero copy, Apple controls the entire look, and Apple's own frequency caps decide whether it even shows regardless of how often the app asks. The referral prompt is the OS's native share sheet, with only the message text below being Allin's own content.
See it
"I've been using Allin to work through what's actually going on underneath how I feel — thought you might find it helpful too."
The referral message — placeholder copy, needs Isabel + Marie sign-off before ship, same as any other user-facing text. Source: Allin/Core/AppView.swiftpresentReferralShare()

Analytics/advertising actually gated behind that consent

DoneSource: GDPR Art. 6/7 (analytics) + Apple's App Tracking Transparency (advertising) — two separate requirements, one fix covers both
Built alongside the consent redesign: AnalyticsClient/MetaAdsClient now check the stored consent state before sending anything at all, rather than sending first and hoping someone opts out later. This is the part that actually protects people day to day — the audit trail (below) is about proving it happened, this is about it actually not happening when someone says no.
See it
Allin/Core/AnalyticsClient.swift · Allin/Core/MetaAdsClient.swift

Amplitude stopped receiving email

Done — live
Amplitude needs a persistent reference to a person for behavioral analysis, but never needed their actual email — sending it anyway was excess data under the minimization principle (Art. 5(1)(c)), and was flagged as the single most urgent, fastest fix across every audit done this project. Fixed by removing the Segment mapping that forwarded email as a User Property to Amplitude, then independently re-verified against the app's real analytics code (not just the config screen) to confirm it's actually gone, not just configured-to-be-gone. The only item on this whole page that's both fixed and confirmed live in production.
See it
Impact: check Amplitude → User Properties on any new user going forward — no email field. Verified against Allin/Core/AnalyticsClient.swift (the identify() call).

Account deletion, hardened

Done
Found a real problem while reviewing the erasure flow: if deletion failed partway, the failure was silently swallowed and the app proceeded exactly as if it had succeeded — meaning someone could believe they'd exercised their right to erasure while their account and data were still fully live. Pretending success is arguably worse than a visible error, since it removes the person's ability to even know something went wrong and try again. Fixed to surface the failure and stop instead of continuing as if it worked. Also fixed alongside this: consent is per-account, not per-device, so it's now explicitly cleared on delete (not on a plain sign-out, which should let a returning same-account person keep their prior consent) — otherwise a deleted account's consent could silently carry over to whoever signs up next on that same device.
See it
Allin/Core/AuthenticationManager.swiftdeleteAccount(), line 95

Erasure fan-out to third parties (delete-user-data)

Built, not yet deployed
In progress
Account deletion previously only removed Allin's own Supabase rows — it never told Segment, Amplitude, or Customer.io, so a "deleted" person's data kept living indefinitely in every third-party processor. This function fans erasure requests out to all three in parallel, then calls the existing delete_user() database function. A processor failure is logged but deliberately non-fatal — trapping someone in a "we couldn't delete your account" loop because a third-party API had a bad minute would be a worse GDPR posture than proceeding, not a better one, and none of these processors delete synchronously anyway (their own stated SLAs are "within 30 days," not instant). Meta is deliberately not called here — they don't expose an API for requesting erasure of an arbitrary user, only the reverse (they notify you if someone deletes their Facebook account); Allin's actual control over Meta data is upstream, in what it collects and the consent gate already in place.
See it
allin-backend · branch combined-fixes-2026-08-15 · supabase/functions/delete-user-data/index.ts

Consent audit trail — a real gap, found and fixed

In progress
Discovered while reviewing the consent screen's actual server-side behavior: the function the app calls every time someone completes the consent screen, record_consent_granted, never existed anywhere in the backend — not in a migration, not deployed. The call was wrapped in a silent try?, so it had been failing with zero error since the granular screen shipped. The practical protection (not sending events without consent) was fine, enforced separately client-side — what was missing was the ability to prove consent was ever given, which Art. 7(1) specifically requires. Built the missing table and both functions the app needed (one for the initial grant, one for single-toggle changes from Settings, which had no server call of any kind before this), and wired the app to actually call them.
See it
allin-backend · branch feat/gdpr-consent-record · supabase/migrations/20260817000000_user_consents.sql
Allin/Home/SettingsView.swift · Allin/Core/AppView.swift (the two call sites)

Pseudonymization, Stage 1 of 3

In progress
The redacted-views approach below only protects when someone logs in through the restricted role — it does nothing to stop the owner or service-role login from reading identity and content together directly. Getting to "even a full-privilege login sees a random token, not a person" needs the account id actually separated from the content, which is a bigger, staged piece of work. Stage 1 (built): an additive schema — a locked-down mapping table, a trigger that stamps every new check-in with a random token automatically, and RLS policies that accept the old check or the new one, so nothing that works today can break. Stages 2 (backfilling existing rows) and 3 (dropping the real account id column) are the two steps that actually deliver the protection — see the open decision below.
See it
allin-backend · branch feat/gdpr-layer2-pseudonymize · supabase/migrations/20260816000000_layer2_pseudonyms_stage1.sql

Redacted admin views + a restricted login role

In progress
The fast, safe mitigation to do while pseudonymization is properly staged: three SQL views exposing only coarse metadata (a truncated id, mood-shift direction, never the free text or an email) plus a low-privilege login that can see only those views, not the underlying tables. Reduces the everyday risk of someone glancing at a dashboard and seeing a name next to a private note — it just doesn't stop a privileged/owner login, which is exactly what pseudonymization is for. Purely additive, reviewed against the live schema for column accuracy.

Right to export + retention identification

In progress
export-user-data mirrors delete-user-data's pattern — returns everything Allin's own tables hold for the calling user as JSON, scoped to what Allin's systems hold directly (not what third parties separately retain, a stated choice not a hidden one). dormant_accounts() is retention policy Stage 1 — identification only, no deletion or notification — finds accounts inactive past a cutoff (defaulted to 24 months, a proposal not a decision). Both are backend-complete; what's left for each is listed under open decisions below.
See it
allin-backend · branch feat/gdpr-export-retention · supabase/functions/export-user-data/index.ts
supabase/migrations/20260817120000_dormant_accounts.sql (same branch)

Anthropic discovered as an undisclosed processor

Done — corrected the record
recommend-plan had been documented as "100% Postgres full-text search, no LLM call" — that was wrong. The live app activates a Claude/Anthropic composition path on every plan generation; full-text search is the fallback only. That makes Anthropic a real processor, receiving check-in and plan-intake text, that wasn't previously disclosed anywhere. Added to the DPIA, ROPA, and the privacy policy draft the moment this was found — and a signed DPA with Anthropic became the single highest-priority open item as a direct result (see below).
See it
DPIA · ROPA — both updated with Anthropic listed. Living documents — Isabel, these are meant for your ongoing read, not a one-time reference; comment directly in the Google Doc if anything needs a second look.

Privacy Policy corrected — including catching its own mistake

In progress
The live policy states things that are false: "Allin does not actively share personal data with third parties" and "we do not collect health data" — both wrong, given real behavior (Segment→Amplitude/Customer.io/Meta, and the check-in flow literally is special-category data collection). A corrected draft was written to fix this — and a few hours later, that draft was itself found saying check-in text is "never sent to any other outside provider," which stopped being true the moment Anthropic was discovered. Corrected the correction openly rather than quietly editing it, since a document written to fix false claims shouldn't ship containing one of its own. The text is ready; publishing it is a Squarespace action for Isabel, needing both her and Marie's sign-off first (see open decisions).
See it
Full corrected replacement text: Privacy Policy & Terms draft

DPIA and ROPA

DoneSource: GDPR Arts. 30/35
The foundational accountability paperwork Art. 30/35 require for processing this kind of data at all — data protection impact assessment and record of processing activities, both complete and kept current as new processors (Anthropic) were found.
See it
DPIA · ROPAliving documents, Isabel's ongoing review, not a one-time read.

iOS privacy manifest

DoneSource: Apple App Store Connect requirement, not GDPR
Distinct from the GDPR paperwork above — this is Apple's own submission requirement (declaring data collection and "required reason" API usage in PrivacyInfo.xcprivacy), enforced at app review, not a GDPR obligation. Was previously stale; corrected to match actual ATT-gated tracking behavior.
See it
Allin/PrivacyInfo.xcprivacy

A standing rule for any future AI feature that reads someone's own history

Done — design principle, not a build
Came up when a future feature was confirmed (something like "we've mapped your subconscious," reading a person's own check-in history through a model). Worked out that this needs no identifier sent to the model in either direction, if built as: gather the person's own history → send only the content in one request → get the result back → save it against their record. Identity only ever matters on Allin's own side of that call. If a future version ever needs the model to hold memory across separate calls, the correlation key must be the pseudonym, never the real account id. Written down now so it can't be missed when that feature actually gets built.

Apple's DPA

Done
Already covered by the existing Apple Developer Program License Agreement — the one processor on this whole list that needed no separate action.

Supabase DPA — already covered, confirmed live in the dashboard

DoneSource: GDPR Art. 28
Checked directly, 2026-08-17, via Claude Desktop (Cowork) driving Marie's own logged-in Chrome, read-only. Org Settings → Compliance → Legal Documents (org "Allin," Pro plan) states verbatim: "Our Data Processing Addendum is incorporated into our Terms of Service, so all organizations get its protections automatically. No separate signed DPA is needed. If you signed a DPA with us previously, that agreement remains binding." A Transfer Impact Assessment is also downloadable on the same page — worth grabbing for the DPIA file.
See it
supabase.com/dashboard/org/ixbtevgkpksybwxjptrd/documents

Amplitude DPA — already covered, confirmed at their Trust Center

DoneSource: GDPR Art. 28
Checked directly, 2026-08-17, same session as above. No DPA link inside the Amplitude app itself (Workspace → General confirms org join-allin-253655, still Free Plan) — the DPA lives publicly at Amplitude's Trust Center instead, not gated behind the "request access" step their other compliance docs use. Full text at amplitude.com/dpa: the same "incorporated into and forms part of the Main Services Agreement" auto-coverage language as Supabase — no signature step needed.
See it
trust.amplitude.com → Documentation → "Amplitude DPA" · full text at amplitude.com/dpa

Compulsory — open decisions

real legal obligations — GDPR, UK-specific law, or Apple's own App Store requirements

Nothing above is actually live yet

Everything is sitting on branches
Marie + Isabel — sign off, then push
The consent screen and the consent audit trail are built and safe to ship, but none of it satisfies anything legally until it's actually protecting a real user. Being built isn't the same as being compliant.

DPAs still open: Customer.io, Meta, RevenueCat, Anthropic

Supabase + Amplitude confirmed done — see above
Legal requirementSource: GDPR Art. 28Marie
Customer.io — found, needs actual signing, not automatic
Settings → Privacy & Data (fly.customer.io/settings/privacy) confirms EU Data Center and links directly to both the Data Processing Addendum and Standard Contractual Clauses (customer.io/legal/dpa). Unlike Supabase/Amplitude, this one is written to be executed — "Company (defined in the signature block below)," "by executing this DPA the parties also execute the SCCs," "by signing this Addendum, Customer.io certifies…" — no self-serve accept button, only view links. This needs an actual signing flow, likely a support/sales request. Marie is picking this up herself from a different account.
Meta — not started
A navigation attempt to Business Manager settings (business.facebook.com/settings/info) was rejected (permission prompt declined) — no page actually loaded, nothing checked. Marie paused this deliberately; not a technical block.
RevenueCat — not started, blocked on login
app.revenuecat.com isn't logged into the checked Chrome profile (showed an email/password screen). Still needs both a DPA/legal-status check and generating a new v2-format secret API key — the current key is legacy-format and doesn't work against RevenueCat's v2 API (see the CRM wiki for that item's own detail).
Anthropic — blocked on a separate login, lowest priority regardless
platform.claude.com (formerly console.anthropic.com) is a fully separate login from claude.ai — confirmed twice that being signed into claude.ai in the same browser does not authenticate it; a genuine sign-in screen appears, not a permissions issue. Marie needs to log in there herself before this can be checked. Sequenced last anyway, since it's the processor most likely to need an actual written request rather than a checkbox.
Checked
2026-08-17, via Claude Desktop (Cowork), Marie's own logged-in Chrome, read-only throughout — nothing accepted, signed, or paid for without her present.

ICO registration

Not yet confirmed either way
Legal requirementSource: UK Data Protection Act 2018Isabel
UK data controllers must register with the ICO and pay the annual fee, with narrow exemptions that don't apply here. Unlike most GDPR obligations, this is trivially checkable by anyone via the public register — one of the more commonly enforced gaps precisely because it's so easy to spot. The fee is small (typically the lowest tier, roughly £40–60/year for a company this size).

Publish the corrected Privacy Policy

Text is ready; the live one still makes false statements
Legal requirementSource: GDPR Arts. 12–14Isabel to publish, both to sign off
The most visible item here — unlike the backend gaps, this one is a public page anyone (a user, a journalist, a regulator) can read right now and see is false. Squarespace page is being prepped to receive the text; publishing itself waits on both sign-offs.

Right to data export — done

DoneSource: GDPR Arts. 15/20
Backend and app entry point both built. A "download my data" row now sits in a new "Your data" section in Settings, right above Danger zone — calls the existing export-user-data function and presents the result as a shareable JSON file via the same share-sheet pattern the referral prompt already uses. Committed on the iOS branch, not yet live.
See it
Allin/Home/SettingsView.swiftexportMyData()

Retention dormancy window — decided: 180 days

DoneSource: GDPR Art. 5(1)(e)
Marie's call: 180 days, matching Segment's own 180-day retention window for the same account, rather than an unrelated number — keeps Allin's own policy aligned with what a processor already downstream of it retains. dormant_accounts() updated from the earlier 24-month proposal to this decided number. Still identification-only — finding a dormant account doesn't delete or notify anyone yet; what actually happens to one once found (delete outright vs. warn first) is a separate, smaller decision still open.
See it
allin-backend · branch feat/gdpr-export-retention · supabase/migrations/20260817120000_dormant_accounts.sql

Pick the age-gate approach

Terms state 16+; nothing enforces it
Legal exposureTwo sources: UK Children's Code (external) + Allin's own Terms & Conditions (internal — a promise the T&Cs already make)Isabel + Marie — pick the approach
Worth being precise that this has two distinct sources, not one: externally, the UK Children's Code applies to any service children are likely to reach, not just ones aimed at them, and paid ads mean the real audience age isn't controlled. But separately — and just as real — Allin's own Terms & Conditions already state a 16+ requirement with parental consent under 18. That's a promise Allin made in its own legal document; having zero enforcement behind a stated promise is its own accuracy problem, the same class of issue as the Privacy Policy's false statements, just in the Terms instead. Three options ranked by friction: (1) rely on the App Store's own age rating alone — weakest, and would need the Terms' own wording softened to match, since it wouldn't actually deliver a 16+ check; (2) self-declared birthdate at signup, hard-block under-16 — low friction, actually matches what the Terms already claim; (3) full parental-consent flow for 13–15 — most engineering, appropriate only if the real audience skews younger than assumed. Lean: option 2, since it's the one that makes the existing Terms wording true rather than requiring it to be rewritten down. The one item here that's a genuine product/legal call, not a pure build.

Confirm the App Store's own age rating still matches the content

A separate Apple requirement, distinct from the Children's Code item above
Legal requirementSource: Apple App Review GuidelinesIsabel — check App Store Connect
Easy to conflate with the age-gate item above, but this is a different authority and a different mechanism: Apple independently requires every app to carry an age rating (4+/9+/12+/17+) based on a content questionnaire answered in App Store Connect, separate from anything GDPR or the ICO requires. Allin deals with emotional distress and has real crisis-support content (Shout/Samaritans) — worth confirming the current rating still reflects that honestly, rather than assuming whatever was set at first submission still fits. This doesn't replace the age-gate decision above; it's Apple's own, separate box to check.

Desirable — open decisions

GDPR names these as example measures, not hard requirements on their own — real risk reduction, your call on timing

Pseudonymization — going all the way to Stage 3, drafted

Drafted, not appliedSource: GDPR Art. 25/32 (named example, not mandatory by itself)Marie — watched maintenance window to apply
Marie's call: go all the way, not stop at Stage 1. Stage 2 (backfill every existing row) and Stage 3 (drop the real account id, tighten RLS to pseudonym-only) are both now drafted. Stage 3 includes its own hard safety check that refuses to run if Stage 2 wasn't actually completed, and a replacement cascade (auth deletion → pseudonym mapping → content rows) so account deletion keeps auto-cleaning up without the account-id column. Real open items before this can run: a full backup taken immediately before, confirming what the live, untracked delete_user() RPC actually does with the account-id column today, and a paired one-line iOS change applied at the same moment Stage 3 runs, not before.
See it
allin-backend · branch feat/gdpr-layer2-pseudonymize · supabase/migrations/20260817130000_..._stage2_backfill.sql and 20260817140000_..._stage3_drop_userid.sql

Encryption at rest — backend built, iOS integration deliberately not rushed

Backend done, not deployedSource: GDPR Art. 32 (named example, not mandatory by itself)Marie — review the iOS side before it ships
Marie approved the edge-function architecture. Built: an additive migration adding encrypted columns alongside the existing plaintext ones (new rows populate only the encrypted side; nothing existing is touched); a shared AES-256-GCM helper using a key that exists only as an Edge Function secret, never in Postgres; a save-emotional-session function that encrypts before insert, using the caller's own JWT so ownership rules apply exactly as they do today; and a get-emotional-sessions function that decrypts on read, falling back to plaintext per-row for anything written before this existed. What's deliberately not done yet: switching the iOS app to actually call these instead of writing to the table directly. That's the single most-used code path in the whole app — every check-in save and load — so it gets its own dedicated review rather than a rewire bundled into the same pass as building the backend. Pseudonymization Stage 3 (above) + this together is what actually delivers "even a full-privilege login learns nothing" — either alone is meaningful but partial.
See it
allin-backend · branch feat/gdpr-encryption-at-restsupabase/functions/save-emotional-session/, get-emotional-sessions/, _shared/session-encryption.ts

Apply the redacted admin views

RecommendedSource: GDPR Art. 32 (named example, not mandatory by itself)Marie's go to apply
Built, reviewed against the live schema, purely additive. Just needs an explicit yes since it's a live-database action.

Different legal area entirely

not GDPR, but real

Marketing claims — 2 items need wording

Advertising standards / consumer protection, not data protection
Different domainSource: ASA / Consumer Protection lawIsabel
Everything else on the claims register is sourced and safe; two claims need Isabel's exact wording call.

Website pricing — already fixed, not an open item

Was a real mismatch on 2026-08-14; corrected on the live site since, carried forward as "still broken" by mistake
Done — verified liveSource: consumer protection / advertised-price accuracy, not GDPR
This was a genuine bug, confirmed live on 2026-08-14: the homepage stated "£69 a year" against a real App Store price of £69.99. Re-checked directly against join-allin.com just now (2026-08-17) rather than trusting the earlier note — the homepage now correctly states "£69.99 a year" in both the body copy and the price display. Someone (Isabel, most likely) already fixed this on Squarespace since the 14th; the wikis and project notes just never caught up. Removed as an open to-do.

Who does what — pulled out on its own

I

Isabel

Each item below has a ready prompt — paste it straight into your own Claude (see the setup page) to get started, once it's set up per allin-isabel-setup.pages.dev.

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 the registration and data-protection-fee process at ico.org.uk/for-organisations/data-protection-fee — tell me which fee tier applies for a company our size, 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 told you I'm happy with the wording, help me find the Privacy Policy page in the Squarespace editor and get it ready to paste in — 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 — there are 2 flagged claims that need my exact wording. Walk me through what each one currently says, why it's flagged, and help me draft accurate replacement wording for both.
Pick the age-gate approach (with Marie)
Prompt for your Claude
Open the Allin GDPR page: https://allin-gdpr.pages.dev (password Isma2026) and find the "Pick the age-gate approach" item. Walk me through the three options and the trade-offs, so I can bring a clear recommendation to Marie.
Sign off on the consent screen + release branch (with Marie)
Prompt for your Claude
Open the copy-review wiki: https://allin-copy-review.pages.dev (password Isma2026) — walk me through the new consent screen copy and mockup, the crisis-line addition, and the referral message, so I can approve, reject, or ask for changes on each one before this ships.
Where the data-export button goes (with Marie)
Prompt for your Claude
Allin now has a backend for letting someone download their own data. Help me think through where a "download my data" option should sit in Settings — most likely near delete-account — and what it should say, so I can bring a recommendation to Marie.
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 answers, and confirm they honestly reflect what's actually in the app now — including the crisis-support content (Shout/Samaritans) and emotional distress themes.
M

Marie

Execute the Customer.io DPA from your other account · check Meta Business Manager's DPA status · log into app.revenuecat.com to check RevenueCat's DPA status and generate a new v2 API key · log into platform.claude.com to check Anthropic's DPA status · ICO register-search + registration · locate the Privacy Policy page in Squarespace and get it ready to paste (don't publish) · schedule pseudonymization Stage 2/3's maintenance window · the go-ahead to apply the redacted admin views · age-gate approach (with Isabel) · sign off on the consent screen + release branch (with Isabel)