Add subcription feature

This commit is contained in:
Urtzi Alfaro
2026-01-13 22:22:38 +01:00
parent b931a5c45e
commit 6ddf608d37
61 changed files with 7915 additions and 1238 deletions

View File

@@ -102,6 +102,135 @@ async def register(
detail="Registration failed"
)
@router.post("/api/v1/auth/register-with-subscription", response_model=TokenResponse)
@track_execution_time("enhanced_registration_with_subscription_duration_seconds", "auth-service")
async def register_with_subscription(
user_data: UserRegistration,
request: Request,
auth_service: EnhancedAuthService = Depends(get_auth_service)
):
"""
Register new user and create subscription in one call
This endpoint implements the new registration flow where:
1. User is created
2. Payment customer is created via tenant service
3. Tenant-independent subscription is created via tenant service
4. Subscription data is stored in onboarding progress
5. User is authenticated and returned with tokens
The subscription will be linked to a tenant during the onboarding flow.
"""
metrics = get_metrics_collector(request)
logger.info("Registration with subscription attempt using new architecture",
email=user_data.email)
try:
# Enhanced input validation
if not user_data.email or not user_data.email.strip():
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Email is required"
)
if not user_data.password or len(user_data.password) < 8:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Password must be at least 8 characters long"
)
if not user_data.full_name or not user_data.full_name.strip():
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Full name is required"
)
# Step 1: Register user using enhanced service
logger.info("Step 1: Creating user", email=user_data.email)
result = await auth_service.register_user(user_data)
user_id = result.user.id
logger.info("User created successfully", user_id=user_id)
# Step 2: Create subscription via tenant service (if subscription data provided)
subscription_id = None
if user_data.subscription_plan and user_data.payment_method_id:
logger.info("Step 2: Creating tenant-independent subscription",
user_id=user_id,
plan=user_data.subscription_plan)
subscription_result = await auth_service.create_subscription_via_tenant_service(
user_id=user_id,
plan_id=user_data.subscription_plan,
payment_method_id=user_data.payment_method_id,
billing_cycle=user_data.billing_cycle or "monthly",
coupon_code=user_data.coupon_code
)
if subscription_result:
subscription_id = subscription_result.get("subscription_id")
logger.info("Tenant-independent subscription created successfully",
user_id=user_id,
subscription_id=subscription_id)
# Step 3: Store subscription data in onboarding progress
logger.info("Step 3: Storing subscription data in onboarding progress",
user_id=user_id)
# Update onboarding progress with subscription data
await auth_service.save_subscription_to_onboarding_progress(
user_id=user_id,
subscription_id=subscription_id,
registration_data=user_data
)
logger.info("Subscription data stored in onboarding progress",
user_id=user_id)
else:
logger.warning("Subscription creation failed, but user registration succeeded",
user_id=user_id)
else:
logger.info("No subscription data provided, skipping subscription creation",
user_id=user_id)
# Record successful registration
if metrics:
metrics.increment_counter("enhanced_registration_with_subscription_total", labels={"status": "success"})
logger.info("Registration with subscription completed successfully using new architecture",
user_id=user_id,
email=user_data.email,
subscription_id=subscription_id)
# Add subscription_id to the response
result.subscription_id = subscription_id
return result
except HTTPException as e:
if metrics:
error_type = "validation_error" if e.status_code == 400 else "conflict" if e.status_code == 409 else "failed"
metrics.increment_counter("enhanced_registration_with_subscription_total", labels={"status": error_type})
logger.warning("Registration with subscription failed using new architecture",
email=user_data.email,
error=e.detail)
raise
except Exception as e:
if metrics:
metrics.increment_counter("enhanced_registration_with_subscription_total", labels={"status": "error"})
logger.error("Registration with subscription system error using new architecture",
email=user_data.email,
error=str(e))
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Registration with subscription failed"
)
@router.post("/api/v1/auth/login", response_model=TokenResponse)
@track_execution_time("enhanced_login_duration_seconds", "auth-service")