FAS 1b: Progressive onboarding (3-layer flow)

- Add PROGRESSIVE_ONBOARDING feature flag to KNOWN_FLAGS
- Add onboarding_step column to users table (a/b/c)
- New backend endpoints:
  - GET /v1/onboarding/status – check current step + feature flag
  - POST /v1/onboarding/quick-start – complete Step A (goal + precision)
  - POST /v1/onboarding/complete-b – complete Step B (diet, allergens, household)
  - POST /v1/onboarding/complete-c – complete Step C (health profile)
  - POST /v1/onboarding/skip – GDPR-friendly skip
- Refactor mobile onboarding screen into 3 progressive layers
- Update auth store with onboardingStep state
- Update tab layout to only block on Step A
- Update registration to set onboardingStep='a'
- Add i18n keys for Step B/C titles across all 12 locales
- Add Zod validation schemas (quickStartInputSchema, onboardingStatusSchema)
- Add tests for validation and feature flag
- Preserve existing /v1/me/onboarding for backward compatibility
- Migration: 0004_progressive_onboarding.sql
This commit is contained in:
Sven (AAMOS AI)
2026-08-06 00:39:44 +07:00
parent b2b6601f54
commit 2f3cdf8016
24 changed files with 4338 additions and 3837 deletions
+17
View File
@@ -70,3 +70,20 @@ export const onboardingInputSchema = z.object({
.default({ kind: "skip" }),
});
export type OnboardingInput = z.infer<typeof onboardingInputSchema>;
/** Progressive onboarding Step A minimal info for immediate value (FAS 1b). */
export const quickStartInputSchema = z.object({
primaryGoal: z.enum(GOAL_TYPES).optional(),
precisionMode: z.enum(PRECISION_MODES).default("simple"),
});
export type QuickStartInput = z.infer<typeof quickStartInputSchema>;
/** Progressive onboarding status response (FAS 1b). */
export const onboardingStatusSchema = z.object({
step: z.enum(["a", "b", "c"]),
onboardingCompleted: z.boolean(),
hasHousehold: z.boolean(),
hasHealthProfile: z.boolean(),
hasPreferences: z.boolean(),
});
export type OnboardingStatus = z.infer<typeof onboardingStatusSchema>;