Recovered state: integrated TrendSurferAgent, restored frontend/backend files, and cleaned up recovery scripts

This commit is contained in:
ajaysi
2026-02-08 13:56:57 +05:30
parent 1db10ccd0f
commit e404a86502
333 changed files with 42223 additions and 10875 deletions

View File

@@ -63,8 +63,17 @@ async def get_usage_alerts(
}
except Exception as e:
logger.error(f"Error getting usage alerts: {e}")
raise HTTPException(status_code=500, detail=str(e))
logger.error(f"Error getting usage alerts: {e}", exc_info=True)
# Return empty alerts instead of 500
return {
"success": True,
"data": {
"alerts": [],
"total": 0,
"unread_count": 0,
"message": f"Error retrieving alerts: {str(e)}"
}
}
@router.post("/alerts/{alert_id}/mark-read")

View File

@@ -164,7 +164,29 @@ async def get_dashboard_data(
return response_payload
except Exception as retry_err:
logger.error(f"Schema fix and retry failed: {retry_err}")
raise HTTPException(status_code=500, detail=f"Database schema error: {str(e)}")
return {
"success": False,
"error": str(retry_err),
"data": {
"current_usage": {"total_calls": 0, "total_cost": 0, "usage_status": "error", "provider_breakdown": {}},
"trends": [],
"limits": {"limits": {"monthly_cost": 0}},
"alerts": [],
"projections": {"projected_monthly_cost": 0, "cost_limit": 0, "projected_usage_percentage": 0},
"summary": {"total_api_calls_this_month": 0, "total_cost_this_month": 0, "usage_status": "error", "unread_alerts": 0}
}
}
logger.error(f"Error getting dashboard data: {e}")
raise HTTPException(status_code=500, detail=str(e))
return {
"success": False,
"error": str(e),
"data": {
"current_usage": {"total_calls": 0, "total_cost": 0, "usage_status": "error", "provider_breakdown": {}},
"trends": [],
"limits": {"limits": {"monthly_cost": 0}},
"alerts": [],
"projections": {"projected_monthly_cost": 0, "cost_limit": 0, "projected_usage_percentage": 0},
"summary": {"total_api_calls_this_month": 0, "total_cost_this_month": 0, "usage_status": "error", "unread_alerts": 0}
}
}

View File

@@ -115,8 +115,15 @@ async def preflight_check(
if op['provider'] in [APIProvider.VIDEO, APIProvider.IMAGE_EDIT, APIProvider.STABILITY]:
cost = pricing_info.get('cost_per_request', 0.0) or pricing_info.get('cost_per_image', 0.0) or 0.0
elif op['provider'] == APIProvider.AUDIO:
# Audio pricing is per character (every character is 1 token)
cost = (pricing_info.get('cost_per_input_token', 0.0) or 0.0) * (op['tokens_requested'] / 1000.0)
model_lower = (model_name or "").lower()
if model_lower == "minimax/voice-clone":
cost = pricing_info.get('cost_per_request', 0.5) or 0.5
elif model_lower == "wavespeed-ai/qwen3-tts/voice-clone":
chars = max(0, int(op.get('tokens_requested') or 0))
cost = max(0.005, 0.005 * (chars / 100.0))
else:
# Audio pricing is per character (every character is 1 token)
cost = (pricing_info.get('cost_per_input_token', 0.0) or 0.0) * (op['tokens_requested'] / 1000.0)
elif op['tokens_requested'] > 0:
# Token-based cost estimation (rough estimate)
cost = (pricing_info.get('cost_per_input_token', 0.0) or 0.0) * (op['tokens_requested'] / 1000)

View File

@@ -12,6 +12,7 @@ import sqlite3
from services.database import get_db
from services.subscription import UsageTrackingService, PricingService
from services.subscription.schema_utils import ensure_subscription_plan_columns
from services.user_workspace_manager import UserWorkspaceManager
from middleware.auth_middleware import get_current_user
from models.subscription_models import (
SubscriptionPlan, UserSubscription, UsageSummary,
@@ -93,7 +94,23 @@ async def get_user_subscription(
except Exception as e:
logger.error(f"Error getting user subscription: {e}")
raise HTTPException(status_code=500, detail=str(e))
return {
"success": False,
"error": str(e),
"data": {
"subscription": None,
"plan": {
"id": "error_fallback",
"name": "Error Fallback",
"tier": "free",
"price_monthly": 0,
"description": "Unable to load subscription details",
"is_free": True
},
"status": "error",
"limits": {}
}
}
@router.get("/status/{user_id}")
@@ -255,11 +272,29 @@ async def get_subscription_status(
}
}
except Exception as retry_err:
logger.error(f"Schema fix and retry failed: {retry_err}")
raise HTTPException(status_code=500, detail=f"Database schema error: {str(e)}")
logger.error(f"Schema fix and retry failed: {retry_err}", exc_info=True)
return {
"success": True,
"data": {
"active": False,
"plan": "none",
"tier": "none",
"can_use_api": False,
"reason": f"Database schema error: {str(e)}"
}
}
logger.error(f"Error getting subscription status: {e}")
raise HTTPException(status_code=500, detail=str(e))
logger.error(f"Error getting subscription status: {e}", exc_info=True)
return {
"success": True,
"data": {
"active": False,
"plan": "none",
"tier": "none",
"can_use_api": False,
"reason": f"Failed to check subscription status: {str(e)}"
}
}
@router.post("/subscribe/{user_id}")
@@ -383,6 +418,18 @@ async def subscribe_to_plan(
auto_renew=True
)
db.add(subscription)
# Ensure user workspace exists for new subscribers
# MOVED: Workspace creation is now handled exclusively in the onboarding flow
# to prevent premature creation before plan selection/onboarding.
# See onboarding_control_service.py
# try:
# logger.info(f"Creating workspace for new subscriber {user_id}")
# workspace_manager = UserWorkspaceManager(db)
# workspace_manager.create_user_workspace(user_id)
# except Exception as ws_error:
# logger.error(f"Failed to create workspace for new subscriber {user_id}: {ws_error}")
# # Don't fail the subscription if workspace creation fails, but log it
db.commit()
@@ -491,6 +538,15 @@ async def subscribe_to_plan(
except Exception as reset_err:
logger.error(f" ❌ Failed to reset usage after subscribe: {reset_err}", exc_info=True)
# Ensure user workspace is created/verified upon subscription
try:
workspace_manager = UserWorkspaceManager(db)
workspace_manager.create_user_workspace(user_id)
logger.info(f" ✅ User workspace verified/created for user {user_id}")
except Exception as ws_err:
# Log but don't fail the subscription response, as workspace can be created later
logger.error(f" ⚠️ Failed to create user workspace during subscription: {ws_err}")
logger.info(f" ✅ Renewal completed: User {user_id}{plan.name} ({billing_cycle})")
logger.info("=" * 80)