Base code
This commit is contained in:
228
backend/services/research_preferences_service.py
Normal file
228
backend/services/research_preferences_service.py
Normal file
@@ -0,0 +1,228 @@
|
||||
"""
|
||||
Research Preferences Service for Onboarding Step 3
|
||||
Handles storage and retrieval of research preferences and style detection data.
|
||||
"""
|
||||
|
||||
from typing import Dict, Any, Optional
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from datetime import datetime
|
||||
import json
|
||||
from loguru import logger
|
||||
|
||||
from models.onboarding import ResearchPreferences, OnboardingSession, WebsiteAnalysis
|
||||
|
||||
|
||||
class ResearchPreferencesService:
|
||||
"""Service for managing research preferences data during onboarding."""
|
||||
|
||||
def __init__(self, db_session: Session):
|
||||
"""Initialize the service with database session."""
|
||||
self.db = db_session
|
||||
|
||||
def save_research_preferences(self, session_id: int, preferences_data: Dict[str, Any], style_data: Optional[Dict[str, Any]] = None) -> Optional[int]:
|
||||
"""
|
||||
Save research preferences to database.
|
||||
|
||||
Args:
|
||||
session_id: Onboarding session ID
|
||||
preferences_data: Research preferences from step 3
|
||||
style_data: Style detection data from step 2 (optional)
|
||||
|
||||
Returns:
|
||||
Preferences ID if successful, None otherwise
|
||||
"""
|
||||
try:
|
||||
# Check if preferences already exist for this session
|
||||
existing_preferences = self.db.query(ResearchPreferences).filter_by(session_id=session_id).first()
|
||||
|
||||
if existing_preferences:
|
||||
# Update existing preferences
|
||||
existing_preferences.research_depth = preferences_data.get('research_depth', 'Comprehensive')
|
||||
existing_preferences.content_types = preferences_data.get('content_types', [])
|
||||
existing_preferences.auto_research = preferences_data.get('auto_research', True)
|
||||
existing_preferences.factual_content = preferences_data.get('factual_content', True)
|
||||
|
||||
# Update style data if provided
|
||||
if style_data:
|
||||
existing_preferences.writing_style = style_data.get('writing_style')
|
||||
existing_preferences.content_characteristics = style_data.get('content_characteristics')
|
||||
existing_preferences.target_audience = style_data.get('target_audience')
|
||||
existing_preferences.recommended_settings = style_data.get('recommended_settings')
|
||||
|
||||
existing_preferences.updated_at = datetime.utcnow()
|
||||
self.db.commit()
|
||||
logger.info(f"Updated research preferences for session {session_id}")
|
||||
return existing_preferences.id
|
||||
else:
|
||||
# Create new preferences
|
||||
preferences = ResearchPreferences(
|
||||
session_id=session_id,
|
||||
research_depth=preferences_data.get('research_depth', 'Comprehensive'),
|
||||
content_types=preferences_data.get('content_types', []),
|
||||
auto_research=preferences_data.get('auto_research', True),
|
||||
factual_content=preferences_data.get('factual_content', True),
|
||||
writing_style=style_data.get('writing_style') if style_data else None,
|
||||
content_characteristics=style_data.get('content_characteristics') if style_data else None,
|
||||
target_audience=style_data.get('target_audience') if style_data else None,
|
||||
recommended_settings=style_data.get('recommended_settings') if style_data else None
|
||||
)
|
||||
|
||||
self.db.add(preferences)
|
||||
self.db.commit()
|
||||
logger.info(f"Created research preferences for session {session_id}")
|
||||
return preferences.id
|
||||
|
||||
except SQLAlchemyError as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"Database error saving research preferences: {e}")
|
||||
return None
|
||||
except Exception as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"Error saving research preferences: {e}")
|
||||
return None
|
||||
|
||||
def get_research_preferences(self, session_id: int) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
Get research preferences for a session.
|
||||
|
||||
Args:
|
||||
session_id: Onboarding session ID
|
||||
|
||||
Returns:
|
||||
Research preferences data or None if not found
|
||||
"""
|
||||
try:
|
||||
preferences = self.db.query(ResearchPreferences).filter_by(session_id=session_id).first()
|
||||
if preferences:
|
||||
return preferences.to_dict()
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting research preferences: {e}")
|
||||
return None
|
||||
|
||||
def get_research_preferences_by_user_id(self, user_id: str) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
Get research preferences for a user by their Clerk user ID.
|
||||
|
||||
Args:
|
||||
user_id: Clerk user ID (string)
|
||||
|
||||
Returns:
|
||||
Research preferences data or None if not found
|
||||
"""
|
||||
try:
|
||||
# First get the onboarding session for this user
|
||||
session = self.db.query(OnboardingSession).filter_by(user_id=user_id).first()
|
||||
if not session:
|
||||
logger.warning(f"No onboarding session found for user {user_id}")
|
||||
return None
|
||||
|
||||
# Then get the research preferences for that session
|
||||
preferences = self.db.query(ResearchPreferences).filter_by(session_id=session.id).first()
|
||||
if preferences:
|
||||
return preferences.to_dict()
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting research preferences by user_id: {e}")
|
||||
return None
|
||||
|
||||
def get_style_data_from_analysis(self, session_id: int) -> Optional[Dict[str, Any]]:
|
||||
"""
|
||||
Get style detection data from website analysis for a session.
|
||||
|
||||
Args:
|
||||
session_id: Onboarding session ID
|
||||
|
||||
Returns:
|
||||
Style data from website analysis or None if not found
|
||||
"""
|
||||
try:
|
||||
analysis = self.db.query(WebsiteAnalysis).filter_by(session_id=session_id).first()
|
||||
if analysis:
|
||||
return {
|
||||
'writing_style': analysis.writing_style,
|
||||
'content_characteristics': analysis.content_characteristics,
|
||||
'target_audience': analysis.target_audience,
|
||||
'recommended_settings': analysis.recommended_settings
|
||||
}
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting style data from analysis: {e}")
|
||||
return None
|
||||
|
||||
def save_preferences_with_style_data(self, session_id: int, preferences_data: Dict[str, Any]) -> Optional[int]:
|
||||
"""
|
||||
Save research preferences with style data from website analysis.
|
||||
|
||||
Args:
|
||||
session_id: Onboarding session ID
|
||||
preferences_data: Research preferences from step 3
|
||||
|
||||
Returns:
|
||||
Preferences ID if successful, None otherwise
|
||||
"""
|
||||
# Get style data from website analysis
|
||||
style_data = self.get_style_data_from_analysis(session_id)
|
||||
|
||||
# Save preferences with style data
|
||||
return self.save_research_preferences(session_id, preferences_data, style_data)
|
||||
|
||||
def update_preferences(self, preferences_id: int, updates: Dict[str, Any]) -> bool:
|
||||
"""
|
||||
Update existing research preferences.
|
||||
|
||||
Args:
|
||||
preferences_id: Research preferences ID
|
||||
updates: Dictionary of fields to update
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
preferences = self.db.query(ResearchPreferences).filter_by(id=preferences_id).first()
|
||||
if not preferences:
|
||||
logger.warning(f"Research preferences {preferences_id} not found")
|
||||
return False
|
||||
|
||||
# Update fields
|
||||
for field, value in updates.items():
|
||||
if hasattr(preferences, field):
|
||||
setattr(preferences, field, value)
|
||||
|
||||
preferences.updated_at = datetime.utcnow()
|
||||
self.db.commit()
|
||||
logger.info(f"Updated research preferences {preferences_id}")
|
||||
return True
|
||||
|
||||
except SQLAlchemyError as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"Database error updating research preferences: {e}")
|
||||
return False
|
||||
except Exception as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"Error updating research preferences: {e}")
|
||||
return False
|
||||
|
||||
def delete_preferences(self, session_id: int) -> bool:
|
||||
"""
|
||||
Delete research preferences for a session.
|
||||
|
||||
Args:
|
||||
session_id: Onboarding session ID
|
||||
|
||||
Returns:
|
||||
True if successful, False otherwise
|
||||
"""
|
||||
try:
|
||||
preferences = self.db.query(ResearchPreferences).filter_by(session_id=session_id).first()
|
||||
if preferences:
|
||||
self.db.delete(preferences)
|
||||
self.db.commit()
|
||||
logger.info(f"Deleted research preferences for session {session_id}")
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
self.db.rollback()
|
||||
logger.error(f"Error deleting research preferences: {e}")
|
||||
return False
|
||||
Reference in New Issue
Block a user