chahinebrini 38a8517259 feat(onboarding): interactive welcome + nickname spotlight tour
Stage 1+2 des post-signup Onboarding-Flows:
- Welcome-Screen: dark-slate Full-Screen mit Pulse-Hero, 3 Mission-Bullets,
  DSGVO-Box, CTA "Los geht's"
- Nickname-Spotlight via react-native-copilot ums TextInput in /profile/edit,
  auto-start wenn step='nickname', nach Save → step='block' + back to /(app)
- Backend: Profile.onboardingStep enum (welcome/nickname/block/done),
  Migration mit Backfill (existing → done), PATCH /api/profile/me/onboarding-step,
  /api/auth/me erweitert
- Frontend: CopilotProvider in root, Routing-Gate in (app)/_layout, useMe um
  onboardingStep ergänzt
- i18n (de/en/fr) für onboarding.welcome.* + onboarding.nickname_spotlight.*

Stage 3 (Block-Aktivierung-Spotlight) folgt in nächster Session — der bestehende
ProtectionOnboardingSheet auf Android wird daran angebunden.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 21:00:20 +02:00

22 lines
989 B
SQL

-- Interaktiver Onboarding-Stand pro Profile.
--
-- Werte: "welcome" (Default) | "nickname" | "block" | "done"
--
-- Das Frontend nutzt diesen Wert als Single-Source-of-Truth für den Stand der
-- Spotlight-Tour. So bleibt der Onboarding-Stand auch nach App-Reinstall oder
-- Re-Login erhalten — kein AsyncStorage-Reset-Problem mehr.
--
-- Backfill: existierende Profile (created_at < NOW()) bekommen "done" — sie
-- haben den Onboarding-Flow nicht durchlaufen können (weil er noch nicht
-- existierte), sollen aber auch keinen retroaktiven Spotlight kriegen.
-- Wer testen will (z.B. eigenes Profile zurücksetzen), kann manuell:
-- UPDATE rebreak.profiles SET onboarding_step = 'welcome' WHERE id = '...';
ALTER TABLE "rebreak"."profiles"
ADD COLUMN IF NOT EXISTS "onboarding_step" TEXT NOT NULL DEFAULT 'welcome';
-- Existing rows: bereits onboardet (zumindest implizit) → "done"
UPDATE "rebreak"."profiles"
SET "onboarding_step" = 'done'
WHERE "created_at" < NOW();