feat: Add No Website button to onboarding Step 2 with business description form
This commit is contained in:
@@ -684,4 +684,77 @@ async def get_user_writing_personas(user_id: int = 1):
|
||||
return await get_user_personas(user_id)
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting user personas: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail="Internal server error")
|
||||
raise HTTPException(status_code=500, detail="Internal server error")
|
||||
|
||||
# Business Information endpoints
|
||||
async def save_business_info(business_info: 'BusinessInfoRequest'):
|
||||
"""Save business information for users without websites."""
|
||||
try:
|
||||
from models.business_info_request import BusinessInfoRequest
|
||||
from services.business_info_service import business_info_service
|
||||
|
||||
logger.info(f"🔄 Saving business info for user_id: {business_info.user_id}")
|
||||
result = business_info_service.save_business_info(business_info)
|
||||
logger.success(f"✅ Business info saved successfully for user_id: {business_info.user_id}")
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error saving business info: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"Failed to save business info: {str(e)}")
|
||||
|
||||
async def get_business_info(business_info_id: int):
|
||||
"""Get business information by ID."""
|
||||
try:
|
||||
from services.business_info_service import business_info_service
|
||||
|
||||
logger.info(f"🔄 Getting business info for ID: {business_info_id}")
|
||||
result = business_info_service.get_business_info(business_info_id)
|
||||
if result:
|
||||
logger.success(f"✅ Business info retrieved for ID: {business_info_id}")
|
||||
return result
|
||||
else:
|
||||
logger.warning(f"⚠️ No business info found for ID: {business_info_id}")
|
||||
raise HTTPException(status_code=404, detail="Business info not found")
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error getting business info: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"Failed to get business info: {str(e)}")
|
||||
|
||||
async def get_business_info_by_user(user_id: int):
|
||||
"""Get business information by user ID."""
|
||||
try:
|
||||
from services.business_info_service import business_info_service
|
||||
|
||||
logger.info(f"🔄 Getting business info for user ID: {user_id}")
|
||||
result = business_info_service.get_business_info_by_user(user_id)
|
||||
if result:
|
||||
logger.success(f"✅ Business info retrieved for user ID: {user_id}")
|
||||
return result
|
||||
else:
|
||||
logger.warning(f"⚠️ No business info found for user ID: {user_id}")
|
||||
raise HTTPException(status_code=404, detail="Business info not found")
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error getting business info: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"Failed to get business info: {str(e)}")
|
||||
|
||||
async def update_business_info(business_info_id: int, business_info: 'BusinessInfoRequest'):
|
||||
"""Update business information."""
|
||||
try:
|
||||
from models.business_info_request import BusinessInfoRequest
|
||||
from services.business_info_service import business_info_service
|
||||
|
||||
logger.info(f"🔄 Updating business info for ID: {business_info_id}")
|
||||
result = business_info_service.update_business_info(business_info_id, business_info)
|
||||
if result:
|
||||
logger.success(f"✅ Business info updated for ID: {business_info_id}")
|
||||
return result
|
||||
else:
|
||||
logger.warning(f"⚠️ No business info found to update for ID: {business_info_id}")
|
||||
raise HTTPException(status_code=404, detail="Business info not found")
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error updating business info: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"Failed to update business info: {str(e)}")
|
||||
|
||||
@@ -42,6 +42,10 @@ from api.onboarding import (
|
||||
get_onboarding_summary,
|
||||
get_website_analysis_data,
|
||||
get_research_preferences_data,
|
||||
save_business_info,
|
||||
get_business_info,
|
||||
get_business_info_by_user,
|
||||
update_business_info,
|
||||
StepCompletionRequest,
|
||||
APIKeyRequest
|
||||
)
|
||||
@@ -433,6 +437,45 @@ async def research_preferences_data():
|
||||
logger.error(f"Error in research_preferences_data: {e}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
# Business Information endpoints
|
||||
@app.post("/api/onboarding/business-info")
|
||||
async def business_info_save(request: 'BusinessInfoRequest'):
|
||||
"""Save business information for users without websites."""
|
||||
try:
|
||||
from models.business_info_request import BusinessInfoRequest
|
||||
return await save_business_info(request)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in business_info_save: {e}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.get("/api/onboarding/business-info/{business_info_id}")
|
||||
async def business_info_get(business_info_id: int):
|
||||
"""Get business information by ID."""
|
||||
try:
|
||||
return await get_business_info(business_info_id)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in business_info_get: {e}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.get("/api/onboarding/business-info/user/{user_id}")
|
||||
async def business_info_get_by_user(user_id: int):
|
||||
"""Get business information by user ID."""
|
||||
try:
|
||||
return await get_business_info_by_user(user_id)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in business_info_get_by_user: {e}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
@app.put("/api/onboarding/business-info/{business_info_id}")
|
||||
async def business_info_update(business_info_id: int, request: 'BusinessInfoRequest'):
|
||||
"""Update business information."""
|
||||
try:
|
||||
from models.business_info_request import BusinessInfoRequest
|
||||
return await update_business_info(business_info_id, request)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in business_info_update: {e}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
# Include component logic router
|
||||
app.include_router(component_logic_router)
|
||||
|
||||
|
||||
24
backend/models/business_info_request.py
Normal file
24
backend/models/business_info_request.py
Normal file
@@ -0,0 +1,24 @@
|
||||
"""Business Information Request Models for ALwrity backend."""
|
||||
from pydantic import BaseModel, Field
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
|
||||
class BusinessInfoRequest(BaseModel):
|
||||
user_id: Optional[int] = None
|
||||
business_description: str = Field(..., min_length=10, max_length=1000, description="Description of the business")
|
||||
industry: Optional[str] = Field(None, max_length=100, description="Industry sector")
|
||||
target_audience: Optional[str] = Field(None, max_length=500, description="Target audience description")
|
||||
business_goals: Optional[str] = Field(None, max_length=1000, description="Business goals and objectives")
|
||||
|
||||
class BusinessInfoResponse(BaseModel):
|
||||
id: int
|
||||
user_id: Optional[int]
|
||||
business_description: str
|
||||
industry: Optional[str]
|
||||
target_audience: Optional[str]
|
||||
business_goals: Optional[str]
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
38
backend/models/user_business_info.py
Normal file
38
backend/models/user_business_info.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""User Business Information Model for ALwrity backend."""
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import Column, Integer, String, Text, DateTime, func
|
||||
from loguru import logger
|
||||
from datetime import datetime
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
logger.info("🔄 Loading UserBusinessInfo model...")
|
||||
|
||||
class UserBusinessInfo(Base):
|
||||
__tablename__ = 'user_business_info'
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
user_id = Column(Integer, index=True, nullable=True)
|
||||
business_description = Column(Text, nullable=False)
|
||||
industry = Column(String(100), nullable=True)
|
||||
target_audience = Column(Text, nullable=True)
|
||||
business_goals = Column(Text, nullable=True)
|
||||
created_at = Column(DateTime, default=func.now())
|
||||
updated_at = Column(DateTime, default=func.now(), onupdate=func.now())
|
||||
|
||||
def __repr__(self):
|
||||
return f"<UserBusinessInfo(id={self.id}, user_id={self.user_id}, industry='{self.industry}')>"
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"user_id": self.user_id,
|
||||
"business_description": self.business_description,
|
||||
"industry": self.industry,
|
||||
"target_audience": self.target_audience,
|
||||
"business_goals": self.business_goals,
|
||||
"created_at": self.created_at.isoformat() if self.created_at else None,
|
||||
"updated_at": self.updated_at.isoformat() if self.updated_at else None,
|
||||
}
|
||||
|
||||
logger.info("✅ UserBusinessInfo model loaded successfully!")
|
||||
84
backend/services/business_info_service.py
Normal file
84
backend/services/business_info_service.py
Normal file
@@ -0,0 +1,84 @@
|
||||
"""Business Information Service for ALwrity backend."""
|
||||
from sqlalchemy.orm import Session
|
||||
from models.user_business_info import UserBusinessInfo
|
||||
from models.business_info_request import BusinessInfoRequest, BusinessInfoResponse
|
||||
from services.database import get_db
|
||||
from loguru import logger
|
||||
from typing import Optional
|
||||
|
||||
logger.info("🔄 Loading BusinessInfoService...")
|
||||
|
||||
class BusinessInfoService:
|
||||
def __init__(self):
|
||||
logger.info("🆕 Initializing BusinessInfoService...")
|
||||
|
||||
def save_business_info(self, business_info: BusinessInfoRequest) -> BusinessInfoResponse:
|
||||
db: Session = next(get_db())
|
||||
logger.debug(f"Attempting to save business info for user_id: {business_info.user_id}")
|
||||
|
||||
# Check if business info already exists for this user
|
||||
existing_info = db.query(UserBusinessInfo).filter(UserBusinessInfo.user_id == business_info.user_id).first()
|
||||
|
||||
if existing_info:
|
||||
logger.info(f"Existing business info found for user_id {business_info.user_id}, updating it.")
|
||||
existing_info.business_description = business_info.business_description
|
||||
existing_info.industry = business_info.industry
|
||||
existing_info.target_audience = business_info.target_audience
|
||||
existing_info.business_goals = business_info.business_goals
|
||||
db.commit()
|
||||
db.refresh(existing_info)
|
||||
logger.success(f"Updated business info for user_id {business_info.user_id}, ID: {existing_info.id}")
|
||||
return BusinessInfoResponse(**existing_info.to_dict())
|
||||
else:
|
||||
logger.info(f"No existing business info for user_id {business_info.user_id}, creating new entry.")
|
||||
db_business_info = UserBusinessInfo(
|
||||
user_id=business_info.user_id,
|
||||
business_description=business_info.business_description,
|
||||
industry=business_info.industry,
|
||||
target_audience=business_info.target_audience,
|
||||
business_goals=business_info.business_goals
|
||||
)
|
||||
db.add(db_business_info)
|
||||
db.commit()
|
||||
db.refresh(db_business_info)
|
||||
logger.success(f"Saved new business info for user_id {business_info.user_id}, ID: {db_business_info.id}")
|
||||
return BusinessInfoResponse(**db_business_info.to_dict())
|
||||
|
||||
def get_business_info(self, business_info_id: int) -> Optional[BusinessInfoResponse]:
|
||||
db: Session = next(get_db())
|
||||
logger.debug(f"Retrieving business info by ID: {business_info_id}")
|
||||
business_info = db.query(UserBusinessInfo).filter(UserBusinessInfo.id == business_info_id).first()
|
||||
if business_info:
|
||||
logger.debug(f"Found business info for ID: {business_info_id}")
|
||||
return BusinessInfoResponse(**business_info.to_dict())
|
||||
logger.warning(f"No business info found for ID: {business_info_id}")
|
||||
return None
|
||||
|
||||
def get_business_info_by_user(self, user_id: int) -> Optional[BusinessInfoResponse]:
|
||||
db: Session = next(get_db())
|
||||
logger.debug(f"Retrieving business info by user ID: {user_id}")
|
||||
business_info = db.query(UserBusinessInfo).filter(UserBusinessInfo.user_id == user_id).first()
|
||||
if business_info:
|
||||
logger.debug(f"Found business info for user ID: {user_id}")
|
||||
return BusinessInfoResponse(**business_info.to_dict())
|
||||
logger.warning(f"No business info found for user ID: {user_id}")
|
||||
return None
|
||||
|
||||
def update_business_info(self, business_info_id: int, business_info: BusinessInfoRequest) -> Optional[BusinessInfoResponse]:
|
||||
db: Session = next(get_db())
|
||||
logger.debug(f"Updating business info for ID: {business_info_id}")
|
||||
db_business_info = db.query(UserBusinessInfo).filter(UserBusinessInfo.id == business_info_id).first()
|
||||
if db_business_info:
|
||||
db_business_info.business_description = business_info.business_description
|
||||
db_business_info.industry = business_info.industry
|
||||
db_business_info.target_audience = business_info.target_audience
|
||||
db_business_info.business_goals = business_info.business_goals
|
||||
db.commit()
|
||||
db.refresh(db_business_info)
|
||||
logger.success(f"Updated business info for ID: {business_info_id}")
|
||||
return BusinessInfoResponse(**db_business_info.to_dict())
|
||||
logger.warning(f"No business info found to update for ID: {business_info_id}")
|
||||
return None
|
||||
|
||||
business_info_service = BusinessInfoService()
|
||||
logger.info("✅ BusinessInfoService loaded successfully!")
|
||||
@@ -19,6 +19,7 @@ from models.enhanced_strategy_models import Base as EnhancedStrategyBase
|
||||
from models.monitoring_models import Base as MonitoringBase
|
||||
from models.persona_models import Base as PersonaBase
|
||||
from models.subscription_models import Base as SubscriptionBase
|
||||
from models.user_business_info import Base as UserBusinessInfoBase
|
||||
|
||||
# Database configuration
|
||||
DATABASE_URL = os.getenv('DATABASE_URL', 'sqlite:///./alwrity.db')
|
||||
@@ -72,7 +73,8 @@ def init_database():
|
||||
MonitoringBase.metadata.create_all(bind=engine)
|
||||
PersonaBase.metadata.create_all(bind=engine)
|
||||
SubscriptionBase.metadata.create_all(bind=engine)
|
||||
logger.info("Database initialized successfully with all models including subscription system")
|
||||
UserBusinessInfoBase.metadata.create_all(bind=engine)
|
||||
logger.info("Database initialized successfully with all models including subscription system and business info")
|
||||
except SQLAlchemyError as e:
|
||||
logger.error(f"Error initializing database: {str(e)}")
|
||||
raise
|
||||
|
||||
Reference in New Issue
Block a user