Fix onboarding process not getting the subcription plan
This commit is contained in:
@@ -360,12 +360,12 @@ async def get_user_progress(
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""Get current user's onboarding progress"""
|
||||
|
||||
|
||||
try:
|
||||
onboarding_service = OnboardingService(db)
|
||||
progress = await onboarding_service.get_user_progress(current_user["user_id"])
|
||||
return progress
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Get onboarding progress error: {e}")
|
||||
raise HTTPException(
|
||||
@@ -373,6 +373,39 @@ async def get_user_progress(
|
||||
detail="Failed to get onboarding progress"
|
||||
)
|
||||
|
||||
@router.get("/{user_id}/onboarding/progress", response_model=UserProgress)
|
||||
async def get_user_progress_by_id(
|
||||
user_id: str,
|
||||
current_user: Dict[str, Any] = Depends(get_current_user_dep),
|
||||
db: AsyncSession = Depends(get_db)
|
||||
):
|
||||
"""
|
||||
Get onboarding progress for a specific user
|
||||
Available for service-to-service calls and admin users
|
||||
"""
|
||||
|
||||
# Allow service tokens or admin users
|
||||
user_type = current_user.get("type", "user")
|
||||
user_role = current_user.get("role", "user")
|
||||
|
||||
if user_type != "service" and user_role not in ["admin", "super_admin"]:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN,
|
||||
detail="Insufficient permissions to access other users' onboarding progress"
|
||||
)
|
||||
|
||||
try:
|
||||
onboarding_service = OnboardingService(db)
|
||||
progress = await onboarding_service.get_user_progress(user_id)
|
||||
return progress
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Get onboarding progress error for user {user_id}: {e}")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail="Failed to get onboarding progress"
|
||||
)
|
||||
|
||||
@router.put("/me/onboarding/step", response_model=UserProgress)
|
||||
async def update_onboarding_step(
|
||||
update_request: UpdateStepRequest,
|
||||
|
||||
@@ -179,6 +179,57 @@ class OnboardingRepository:
|
||||
await self.db.rollback()
|
||||
return False
|
||||
|
||||
async def save_step_data(
|
||||
self,
|
||||
user_id: str,
|
||||
step_name: str,
|
||||
step_data: Dict[str, Any]
|
||||
) -> UserOnboardingProgress:
|
||||
"""Save data for a specific step without marking it as completed"""
|
||||
try:
|
||||
# Get existing step or create new one
|
||||
existing_step = await self.get_user_step(user_id, step_name)
|
||||
|
||||
if existing_step:
|
||||
# Update existing step data (merge with existing data)
|
||||
merged_data = {**(existing_step.step_data or {}), **step_data}
|
||||
|
||||
stmt = update(UserOnboardingProgress).where(
|
||||
and_(
|
||||
UserOnboardingProgress.user_id == user_id,
|
||||
UserOnboardingProgress.step_name == step_name
|
||||
)
|
||||
).values(
|
||||
step_data=merged_data,
|
||||
updated_at=datetime.now(timezone.utc)
|
||||
).returning(UserOnboardingProgress)
|
||||
|
||||
result = await self.db.execute(stmt)
|
||||
await self.db.commit()
|
||||
return result.scalars().first()
|
||||
else:
|
||||
# Create new step with data but not completed
|
||||
return await self.upsert_user_step(
|
||||
user_id=user_id,
|
||||
step_name=step_name,
|
||||
completed=False,
|
||||
step_data=step_data
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error saving step data for {step_name}, user {user_id}: {e}")
|
||||
await self.db.rollback()
|
||||
raise
|
||||
|
||||
async def get_step_data(self, user_id: str, step_name: str) -> Optional[Dict[str, Any]]:
|
||||
"""Get data for a specific step"""
|
||||
try:
|
||||
step = await self.get_user_step(user_id, step_name)
|
||||
return step.step_data if step else None
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting step data for {step_name}, user {user_id}: {e}")
|
||||
return None
|
||||
|
||||
async def get_completion_stats(self) -> Dict[str, Any]:
|
||||
"""Get completion statistics across all users"""
|
||||
try:
|
||||
@@ -187,7 +238,7 @@ class OnboardingRepository:
|
||||
select(UserOnboardingSummary).count()
|
||||
)
|
||||
total_users = total_result.scalar()
|
||||
|
||||
|
||||
# Get completed users
|
||||
completed_result = await self.db.execute(
|
||||
select(UserOnboardingSummary)
|
||||
@@ -195,13 +246,13 @@ class OnboardingRepository:
|
||||
.count()
|
||||
)
|
||||
completed_users = completed_result.scalar()
|
||||
|
||||
|
||||
return {
|
||||
"total_users_in_onboarding": total_users,
|
||||
"fully_completed_users": completed_users,
|
||||
"completion_rate": (completed_users / total_users * 100) if total_users > 0 else 0
|
||||
}
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting completion stats: {e}")
|
||||
return {
|
||||
|
||||
@@ -19,6 +19,9 @@ class UserRegistration(BaseModel):
|
||||
full_name: str = Field(..., min_length=1, max_length=255)
|
||||
tenant_name: Optional[str] = Field(None, max_length=255)
|
||||
role: Optional[str] = Field("admin", pattern=r'^(user|admin|manager|super_admin)$')
|
||||
subscription_plan: Optional[str] = Field("starter", description="Selected subscription plan (starter, professional, enterprise)")
|
||||
use_trial: Optional[bool] = Field(False, description="Whether to use trial period")
|
||||
payment_method_id: Optional[str] = Field(None, description="Stripe payment method ID")
|
||||
|
||||
class UserLogin(BaseModel):
|
||||
"""User login request"""
|
||||
|
||||
@@ -111,7 +111,33 @@ class EnhancedAuthService:
|
||||
|
||||
# Commit transaction
|
||||
await uow.commit()
|
||||
|
||||
|
||||
# Store subscription plan selection in onboarding progress for later retrieval
|
||||
if user_data.subscription_plan or user_data.use_trial or user_data.payment_method_id:
|
||||
try:
|
||||
from app.repositories.onboarding_repository import OnboardingRepository
|
||||
from app.models.onboarding import UserOnboardingProgress
|
||||
|
||||
onboarding_repo = OnboardingRepository(db_session)
|
||||
plan_data = {
|
||||
"subscription_plan": user_data.subscription_plan or "starter",
|
||||
"use_trial": user_data.use_trial or False,
|
||||
"payment_method_id": user_data.payment_method_id,
|
||||
"saved_at": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
|
||||
await onboarding_repo.save_step_data(
|
||||
str(new_user.id),
|
||||
"user_registered",
|
||||
plan_data
|
||||
)
|
||||
|
||||
logger.info("Subscription plan saved to onboarding progress",
|
||||
user_id=new_user.id,
|
||||
plan=user_data.subscription_plan)
|
||||
except Exception as e:
|
||||
logger.warning("Failed to save subscription plan to onboarding progress", error=str(e))
|
||||
|
||||
# Publish registration event (non-blocking)
|
||||
try:
|
||||
await publish_user_registered({
|
||||
@@ -119,7 +145,8 @@ class EnhancedAuthService:
|
||||
"email": new_user.email,
|
||||
"full_name": new_user.full_name,
|
||||
"role": new_user.role,
|
||||
"registered_at": datetime.now(timezone.utc).isoformat()
|
||||
"registered_at": datetime.now(timezone.utc).isoformat(),
|
||||
"subscription_plan": user_data.subscription_plan or "starter"
|
||||
})
|
||||
except Exception as e:
|
||||
logger.warning("Failed to publish registration event", error=str(e))
|
||||
|
||||
@@ -83,15 +83,39 @@ class EnhancedTenantService:
|
||||
}
|
||||
|
||||
owner_membership = await member_repo.create_membership(membership_data)
|
||||
|
||||
# Create starter subscription
|
||||
|
||||
# Get subscription plan from user's registration using standardized auth client
|
||||
selected_plan = "starter" # Default fallback
|
||||
try:
|
||||
from shared.clients.auth_client import AuthServiceClient
|
||||
from app.core.config import settings
|
||||
|
||||
auth_client = AuthServiceClient(settings)
|
||||
selected_plan = await auth_client.get_subscription_plan_from_registration(owner_id)
|
||||
|
||||
logger.info("Retrieved subscription plan from registration",
|
||||
tenant_id=tenant.id,
|
||||
owner_id=owner_id,
|
||||
plan=selected_plan)
|
||||
|
||||
except Exception as e:
|
||||
logger.warning("Could not retrieve subscription plan from auth service, using default",
|
||||
error=str(e),
|
||||
owner_id=owner_id,
|
||||
default_plan=selected_plan)
|
||||
|
||||
# Create subscription with selected or default plan
|
||||
subscription_data = {
|
||||
"tenant_id": str(tenant.id),
|
||||
"plan": "starter",
|
||||
"plan": selected_plan,
|
||||
"status": "active"
|
||||
}
|
||||
|
||||
|
||||
subscription = await subscription_repo.create_subscription(subscription_data)
|
||||
|
||||
logger.info("Subscription created",
|
||||
tenant_id=tenant.id,
|
||||
plan=selected_plan)
|
||||
|
||||
# Commit the transaction
|
||||
await uow.commit()
|
||||
|
||||
Reference in New Issue
Block a user