feat(onboarding): add multi-step user onboarding wizard
Add a 5-step onboarding flow for new users: - Migration 017: adds onboarding_completed, onboarding_completed_at, contact_email, preferred_destination to user_profiles - app/api/onboarding.py: REST endpoints (status, profile, plan, storage, complete) with session-based auth using sub/preferred_username/email/id priority chain - app/views/onboarding.py: GET /onboarding view with configured-destination detection helper for all 8 supported storage providers - frontend/templates/onboarding.html: Alpine.js wizard with progress indicator, tier cards (server-rendered), storage destination cards, accessible markup (WCAG AA), and all fetch() API calls - app/auth.py: redirect first-time OAuth users (onboarding_completed=False) to /onboarding after login - 16 unit tests covering all endpoints, auth enforcement, and edge cases Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
+13
@@ -167,6 +167,19 @@ async def oauth_callback(request: Request, db: Session = Depends(get_db)):
|
||||
# Log the successful authentication
|
||||
logger.info(f"[SECURITY] OAUTH_LOGIN_SUCCESS user={user_data.get('email', 'unknown')} admin={is_admin}")
|
||||
|
||||
# Redirect first-time users to onboarding
|
||||
user_id = (
|
||||
user_data.get("sub") or user_data.get("preferred_username") or user_data.get("email") or user_data.get("id")
|
||||
)
|
||||
if user_id:
|
||||
from app.models import UserProfile as _UserProfile
|
||||
|
||||
profile = db.query(_UserProfile).filter(_UserProfile.user_id == user_id).first()
|
||||
if profile and not profile.onboarding_completed:
|
||||
post_onboarding = request.session.pop("redirect_after_login", "/upload")
|
||||
request.session["post_onboarding_redirect"] = post_onboarding
|
||||
return RedirectResponse(url="/onboarding", status_code=status.HTTP_302_FOUND)
|
||||
|
||||
# Redirect to original destination or default
|
||||
redirect_url = request.session.pop("redirect_after_login", "/upload")
|
||||
return RedirectResponse(url=redirect_url, status_code=status.HTTP_302_FOUND)
|
||||
|
||||
Reference in New Issue
Block a user