Files
Claude e5b81f46b0 Store readiness: in-app account deletion, privacy policy, terms, listing copy
Closes the remaining store-compliance gaps before App Store / Play
submission:

- Account deletion (App Store guideline 5.1.1): DELETE /me removes the
  user row (usage cascades). The app exposes it through one quiet
  'Account' caption link under the chat, visible only when signed in,
  driving two native dialogs (Sign out / Delete account with a
  destructive confirm) — no new views, no menus, minimalism intact.
  Deletion signs out and resets the app; copy notes that store
  subscriptions are cancelled in App Store / Play settings.
- docs/store/privacy-policy.md: the complete data inventory (matching
  the actual schema), transient OpenAI processing with no training, no
  profiling or ads, GDPR legal bases and rights, in-app erasure.
- docs/store/terms-of-service.md: not-therapy positioning with crisis
  guidance, AI-generated-content caveat, 18+ eligibility,
  auto-renewal/cancellation terms, liability, Swedish governing law.
- docs/store/listing.md: App Store and Play copy written to the
  honest-claims rule (subtitle 'Think Beyond Thought', keywords,
  descriptions), plus App Privacy and Data safety questionnaire
  mappings.
- LAUNCH.md updated: host the policy/terms, set store URLs, use the
  prepared listing copy.
- Tests: 30 passing (adds DELETE /me coverage).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0118DaxZR36RpnY524vRqx3z
2026-08-03 22:37:25 +00:00

63 lines
2.0 KiB
TypeScript

import { useEffect, useState } from 'react';
import { StatusBar } from 'expo-status-bar';
import type { ChatMessage } from './src/api/client';
import { getAccessToken } from './src/auth/session';
import { ChatScreen } from './src/screens/ChatScreen';
import { PaywallScreen } from './src/screens/PaywallScreen';
/**
* Two views, no navigation library. The user lands directly in the chat —
* no registration before the first question. The backend decides the paywall
* moment (the analysis is ready); after unlock the conversation continues
* with the full analysis delivered immediately.
*/
export default function App() {
const [view, setView] = useState<'chat' | 'paywall'>('chat');
const [messages, setMessages] = useState<ChatMessage[]>([]);
const [paywalled, setPaywalled] = useState(false);
const [deliverAnalysis, setDeliverAnalysis] = useState(false);
const [signedIn, setSignedIn] = useState(false);
useEffect(() => {
getAccessToken().then((token) => setSignedIn(token !== null));
}, []);
function resetToSignedOut() {
setSignedIn(false);
setMessages([]);
setPaywalled(false);
setDeliverAnalysis(false);
setView('chat');
}
return (
<>
<StatusBar style="dark" />
{view === 'chat' && (
<ChatScreen
messages={messages}
setMessages={setMessages}
paywalled={paywalled}
onPaywallTriggered={() => setPaywalled(true)}
onContinueWithPremium={() => setView('paywall')}
deliverAnalysis={deliverAnalysis}
onAnalysisDelivered={() => setDeliverAnalysis(false)}
signedIn={signedIn}
onSignedOut={resetToSignedOut}
/>
)}
{view === 'paywall' && (
<PaywallScreen
onSubscribed={() => {
setSignedIn(true);
setPaywalled(false);
setDeliverAnalysis(true);
setView('chat');
}}
onDismiss={() => setView('chat')}
/>
)}
</>
);
}