from typing import Literal, Optional from pydantic import BaseModel, Field class OnboardingStatus(BaseModel): created_flow: bool ran_session: bool exported_session: bool # Kept for backward-compat during deploy; new code paths should not branch on this. tried_ai_assistant: bool invited_teammate: bool connected_psa: bool is_team_user: bool dismissed: bool # New (Phase 2 — Task 41) — drive the unified next-step card + checklist. email_verified: bool shop_setup_done: bool # --- Welcome wizard (Phase 2) ---------------------------------------------- TeamSizeBucket = Literal["1-2", "3-5", "6-10", "11-25", "26+"] RoleAtSignup = Literal["owner", "lead_tech", "tech", "other"] PrimaryPsa = Literal["connectwise", "autotask", "halopsa", "none"] WizardStep = Literal[1, 2, 3] WizardAction = Literal["complete", "skip"] class OnboardingStepData(BaseModel): """Optional payload carried with `action="complete"` for steps 1 and 2. Step 1 fields: company_name, team_size_bucket, role_at_signup Step 2 fields: primary_psa Step 3 has no data (invitations posted separately). """ # Step 1 company_name: Optional[str] = Field(default=None, max_length=255) team_size_bucket: Optional[TeamSizeBucket] = None role_at_signup: Optional[RoleAtSignup] = None # Step 2 primary_psa: Optional[PrimaryPsa] = None class OnboardingStepRequest(BaseModel): step: WizardStep action: WizardAction data: Optional[OnboardingStepData] = None class OnboardingStepResponse(BaseModel): onboarding_step_completed: Optional[int] onboarding_dismissed: bool