Meal Planner AI : What to Eat Last updated: May 28, 2026
This Privacy Policy explains how Creative Adventures Lab ("we", "us", "our") collects, uses, discloses, and protects information in connection with the Meal Planner AI : What to Eat mobile application (available on the App Store and Google Play as "Meal Planner AI : What to Eat", also referred to as "What to Eat" or "the App"). It also describes your rights under applicable data protection law, including the EU General Data Protection Regulation ("GDPR") and the California Consumer Privacy Act ("CCPA").
Please read this policy carefully. By installing or using the App, you acknowledge that you have read and understood it.
1. Our Core Privacy Principle
What to Eat is designed to be private by default. Your household profiles, recipes, meal plans, grocery lists, pantry, leftovers, meal log, and gamification progress are stored exclusively on your device — none of this content is stored on our servers. When you generate an AI meal plan, aggregated household dietary signals pass transiently through our Supabase Edge Function to reach Google Gemini, but are not retained by us (see Section 2.4 for the exact list). We only collect the minimum data necessary to provide and protect the subscription service.
2. Data We Collect and Why
2.1 When a Server-Side Account Is Created
The App does not create any server-side account on first launch. No identifier of any kind is sent to Supabase or any other backend when you open the App for the first time.
A Supabase anonymous session is created only when you tap the "I accept, continue" button on the first onboarding screen. At that moment — and not before — Supabase issues a randomly generated UUID for your device. The UUID has no link to your name, email, phone, or any other identifier; Supabase does not know who you are. The session access token (a JWT) is then stored in your device's secure keychain (via expo-secure-store — iOS Keychain / Android Keystore) so the same anonymous identity persists across App launches.
You can also use the App entirely offline (viewing local profiles, recipes, and meal plans) without any data leaving your device. The server-side account exists to record trial state and subscription entitlements server-side, which prevents trial-restart abuse via reinstall and lets us bind subscription receipts to your account.
You never need to provide an email address, password, name, or phone number to use the App.
2.2 Data Stored on Our Servers
The following data is stored in our server-side database (Supabase, hosted in EU data centres). It is the complete list — nothing else about you is stored server-side.
| Data Element | Purpose | Basis (GDPR) |
|---|---|---|
| Internal numeric user ID | Surrogate key for all server-side records | Contract performance (Art. 6(1)(b)) |
| OpenID identifier | Internally formatted as supabase:<uuid>, where <uuid> is the random Supabase Auth user ID. Uniquely identifies your anonymous server-side account. Not linked to any real-world identity. |
Contract performance (Art. 6(1)(b)) |
| Supabase Auth metadata | Maintained by Supabase Auth on the auth.users table for your anonymous user record: created_at (when your anonymous identity was first issued — i.e. when you tapped "I accept, continue"), last_sign_in_at (the most recent time the App refreshed or re-validated your session token), updated_at (the most recent time the auth row was modified), and the is_anonymous flag (set to true for every account, since the App only ever creates anonymous sessions). No email, phone, password, or external provider identity is associated with the account. |
Contract performance (Art. 6(1)(b)) — required to operate the authenticated subscription service |
| Supabase Auth audit log entries | Supabase Auth automatically writes an entry to auth.audit_log_entries for security-relevant authentication events (initial anonymous sign-in on "I accept, continue", token refresh, sign-out, account deletion). Each entry contains an event timestamp, the event type, the user's UUID, and the IP address and User-Agent string of the device that initiated the request, as captured by Supabase's edge. The App itself does not collect, read, or display this information; it is generated by the Supabase Auth service for security audit purposes. |
Legitimate interest — security and abuse-detection (Art. 6(1)(f)). See Section 8 for the balancing test that also covers this processing. |
| Role | Either user or admin. Almost all accounts are user; admin is reserved for the App owner's own internal account and is never assigned to end-user accounts. |
Legitimate interest — service operation (Art. 6(1)(f)) |
| Account token (UUID, RFC 4122) | A randomly generated per-user UUID embedded in purchase receipts at checkout time (as Apple appAccountToken / Google obfuscatedExternalAccountId). Used solely to verify that a receipt belongs to the submitting account and to prevent receipt-replay fraud. Generated lazily on first purchase; never overwritten. |
Legitimate interest — subscription fraud prevention (Art. 6(1)(f)) |
| Entitlement status | One of: none, trial, premium, expired, refunded. The canonical record of your subscription state, updated by purchase verification and by real-time webhooks from Apple and Google. |
Contract performance (Art. 6(1)(b)) |
Trial start timestamp(trialStartedAt) |
Records when your 3-day free trial began. Set once during onboarding; idempotent — reinstalling the App cannot restart the trial. | Contract performance (Art. 6(1)(b)) |
| Subscription product ID | The App Store / Play Store product identifier for your active plan. | Contract performance (Art. 6(1)(b)) |
| Platform | Whether your subscription is on ios or android. |
Contract performance (Art. 6(1)(b)) |
Subscription expiry timestamp(expiresAt) |
The date your current subscription period ends. Used to determine whether your access is still active on launch. | Contract performance (Art. 6(1)(b)) |
| Auto-renew flag | Whether your subscription is set to auto-renew. Sourced from the store receipt. | Contract performance (Art. 6(1)(b)) |
External receipt identifier (externalId) |
For Apple: the originalTransactionId from the signed StoreKit 2 receipt. For Google: the purchaseToken. Stored to enable receipt-replay protection and to allow Apple/Google webhook events to locate the correct user record. |
Legitimate interest — subscription fraud prevention (Art. 6(1)(f)) |
| Last verification timestamp | When the server last verified your subscription state with Apple or Google. | Contract performance (Art. 6(1)(b)) |
| Monthly AI generation counter | Records the number of AI meal plans you have generated in the current calendar month, stored as a (user_id, month, count) tuple (month in YYYY-MM format, UTC). Used solely to enforce the 35-generation monthly limit; resets automatically each calendar month. |
Contract performance (Art. 6(1)(b)) |
Terms acceptance timestamp(termsAcceptedAt) |
The exact ISO timestamp recorded on your device when you tapped "I accept, continue" on the Terms of Use / Privacy Policy screen during onboarding, transmitted to our server immediately after your anonymous session is created. Stored as the authoritative record of your agreement to the Terms and your acknowledgement of this Privacy Policy. This is the device-side time of your actual acceptance action — not the server receipt time. Set once per account and never overwritten. Deleted in full when you delete your account. | Compliance with legal obligation — demonstrating acceptance of Terms under contract law and GDPR Art. 7(1) (Art. 6(1)(c)) |
AI consent timestamp(aiConsentAcceptedAt) |
The exact ISO timestamp recorded on your device when you tapped "I accept" on the AI data-use disclosure, transmitted to our server at that moment and stored as the authoritative record of your consent to AI processing. This is the device-side time of your actual consent action — not the server receipt time. Set once per account and never overwritten. AI consent is permanent and cannot be revoked — there is no opt-out or toggle to disable AI consent after acceptance. Deleted in full only when you delete your account. | Compliance with legal obligation — demonstrating consent under GDPR Art. 7(1) (Art. 6(1)(c)) |
We do not collect: name, email address, phone number, precise or coarse location data, the IDFA (Identifier for Advertisers) or any personal advertising identifier, browsing history, contact lists, health data, photographs, crash reports, or any behavioural analytics from your use of the App's core features. (See Section 2.8 for our use of Apple's SKAdNetwork framework, which provides anonymous, aggregated ad attribution without collecting personal identifiers.)
About IP addresses: Two things should be noted. (1) Every HTTPS request to any internet service includes the client's IP address at the network layer — we do not collect or store the IP address in our application database. (2) Supabase Auth, as part of the authentication service we use, records the IP address and User-Agent string on auth events (anonymous sign-in, token refresh, sign-out, account deletion) inside its internal auth.audit_log_entries table for security purposes (described in the table above). This is generated by Supabase, not by the App, and is retained according to Supabase's standard retention policy for audit logs. We rely on this audit log only for security incident investigation; we do not access it for analytics or behavioural profiling.
2.3 Data Handled by Third-Party Processors on Our Behalf
When you make a purchase, the platform store (Apple App Store or Google Play Store) processes your payment and provides us with a cryptographically signed receipt. We verify this receipt against the store's API. This verification involves: