253 lines
10 KiB
Python
253 lines
10 KiB
Python
"""
|
|
Persona Data Service
|
|
Direct service for working with PersonaData table from onboarding.
|
|
Leverages the rich JSON structure for better content generation.
|
|
"""
|
|
|
|
from typing import Dict, Any, Optional, List
|
|
from datetime import datetime
|
|
from loguru import logger
|
|
from sqlalchemy.orm import Session
|
|
|
|
from services.database import get_db_session
|
|
from models.onboarding import PersonaData, OnboardingSession
|
|
|
|
|
|
class PersonaDataService:
|
|
"""Service for working directly with PersonaData table."""
|
|
|
|
def __init__(self, db_session: Optional[Session] = None):
|
|
self.db = db_session or get_db_session()
|
|
|
|
def get_user_persona_data(self, user_id: str) -> Optional[Dict[str, Any]]:
|
|
"""Get complete persona data for a user from PersonaData table."""
|
|
try:
|
|
# Get onboarding session for user
|
|
session = self.db.query(OnboardingSession).filter(
|
|
OnboardingSession.user_id == user_id
|
|
).first()
|
|
|
|
if not session:
|
|
logger.warning(f"No onboarding session found for user {user_id}")
|
|
return None
|
|
|
|
# Get persona data
|
|
persona_data = self.db.query(PersonaData).filter(
|
|
PersonaData.session_id == session.id
|
|
).first()
|
|
|
|
if not persona_data:
|
|
logger.warning(f"No persona data found for user {user_id}")
|
|
return None
|
|
|
|
return persona_data.to_dict()
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting persona data for user {user_id}: {str(e)}")
|
|
return None
|
|
|
|
def get_platform_persona(self, user_id: str, platform: str) -> Optional[Dict[str, Any]]:
|
|
"""Get platform-specific persona data for a user."""
|
|
try:
|
|
persona_data = self.get_user_persona_data(user_id)
|
|
if not persona_data:
|
|
return None
|
|
|
|
platform_personas = persona_data.get('platform_personas', {})
|
|
platform_data = platform_personas.get(platform)
|
|
|
|
if not platform_data:
|
|
logger.warning(f"No {platform} persona found for user {user_id}")
|
|
return None
|
|
|
|
# Return rich platform-specific data
|
|
return {
|
|
"platform": platform,
|
|
"platform_persona": platform_data,
|
|
"core_persona": persona_data.get('core_persona', {}),
|
|
"quality_metrics": persona_data.get('quality_metrics', {}),
|
|
"selected_platforms": persona_data.get('selected_platforms', []),
|
|
"created_at": persona_data.get('created_at'),
|
|
"updated_at": persona_data.get('updated_at')
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting {platform} persona for user {user_id}: {str(e)}")
|
|
return None
|
|
|
|
def get_all_platform_personas(self, user_id: str) -> Dict[str, Any]:
|
|
"""Get all platform personas for a user."""
|
|
try:
|
|
persona_data = self.get_user_persona_data(user_id)
|
|
if not persona_data:
|
|
return {}
|
|
|
|
platform_personas = persona_data.get('platform_personas', {})
|
|
|
|
# Return structured data for all platforms
|
|
result = {}
|
|
for platform, platform_data in platform_personas.items():
|
|
if isinstance(platform_data, dict) and 'error' not in platform_data:
|
|
result[platform] = {
|
|
"platform": platform,
|
|
"platform_persona": platform_data,
|
|
"core_persona": persona_data.get('core_persona', {}),
|
|
"quality_metrics": persona_data.get('quality_metrics', {}),
|
|
"created_at": persona_data.get('created_at'),
|
|
"updated_at": persona_data.get('updated_at')
|
|
}
|
|
|
|
return result
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting all platform personas for user {user_id}: {str(e)}")
|
|
return {}
|
|
|
|
def get_core_persona(self, user_id: str) -> Optional[Dict[str, Any]]:
|
|
"""Get core persona data for a user."""
|
|
try:
|
|
persona_data = self.get_user_persona_data(user_id)
|
|
if not persona_data:
|
|
return None
|
|
|
|
return {
|
|
"core_persona": persona_data.get('core_persona', {}),
|
|
"quality_metrics": persona_data.get('quality_metrics', {}),
|
|
"selected_platforms": persona_data.get('selected_platforms', []),
|
|
"created_at": persona_data.get('created_at'),
|
|
"updated_at": persona_data.get('updated_at')
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting core persona for user {user_id}: {str(e)}")
|
|
return None
|
|
|
|
def get_persona_quality_metrics(self, user_id: str) -> Optional[Dict[str, Any]]:
|
|
"""Get quality metrics for a user's persona."""
|
|
try:
|
|
persona_data = self.get_user_persona_data(user_id)
|
|
if not persona_data:
|
|
return None
|
|
|
|
return persona_data.get('quality_metrics', {})
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting quality metrics for user {user_id}: {str(e)}")
|
|
return None
|
|
|
|
def update_platform_persona(self, user_id: str, platform: str, updates: Dict[str, Any]) -> bool:
|
|
"""Update platform-specific persona data."""
|
|
try:
|
|
# Get onboarding session for user
|
|
session = self.db.query(OnboardingSession).filter(
|
|
OnboardingSession.user_id == user_id
|
|
).first()
|
|
|
|
if not session:
|
|
logger.error(f"No onboarding session found for user {user_id}")
|
|
return False
|
|
|
|
# Get persona data
|
|
persona_data = self.db.query(PersonaData).filter(
|
|
PersonaData.session_id == session.id
|
|
).first()
|
|
|
|
if not persona_data:
|
|
logger.error(f"No persona data found for user {user_id}")
|
|
return False
|
|
|
|
# Update platform-specific data
|
|
platform_personas = persona_data.platform_personas or {}
|
|
if platform in platform_personas:
|
|
platform_personas[platform].update(updates)
|
|
persona_data.platform_personas = platform_personas
|
|
persona_data.updated_at = datetime.utcnow()
|
|
|
|
self.db.commit()
|
|
logger.info(f"Updated {platform} persona for user {user_id}")
|
|
return True
|
|
else:
|
|
logger.warning(f"Platform {platform} not found for user {user_id}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error updating {platform} persona for user {user_id}: {str(e)}")
|
|
self.db.rollback()
|
|
return False
|
|
|
|
def save_platform_persona(self, user_id: str, platform: str, platform_data: Dict[str, Any]) -> bool:
|
|
"""Save or create platform-specific persona data (creates if doesn't exist)."""
|
|
try:
|
|
# Get onboarding session
|
|
session = self.db.query(OnboardingSession).filter(
|
|
OnboardingSession.user_id == user_id
|
|
).first()
|
|
|
|
if not session:
|
|
logger.error(f"No onboarding session found for user {user_id}")
|
|
return False
|
|
|
|
# Get persona data
|
|
persona_data = self.db.query(PersonaData).filter(
|
|
PersonaData.session_id == session.id
|
|
).first()
|
|
|
|
if not persona_data:
|
|
logger.error(f"No persona data found for user {user_id}")
|
|
return False
|
|
|
|
# Update or create platform persona
|
|
platform_personas = persona_data.platform_personas or {}
|
|
platform_personas[platform] = platform_data # Create or overwrite
|
|
persona_data.platform_personas = platform_personas
|
|
persona_data.updated_at = datetime.utcnow()
|
|
|
|
self.db.commit()
|
|
logger.info(f"Saved {platform} persona for user {user_id}")
|
|
return True
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error saving {platform} persona for user {user_id}: {str(e)}")
|
|
self.db.rollback()
|
|
return False
|
|
|
|
def get_supported_platforms(self, user_id: str) -> List[str]:
|
|
"""Get list of platforms for which personas exist."""
|
|
try:
|
|
persona_data = self.get_user_persona_data(user_id)
|
|
if not persona_data:
|
|
return []
|
|
|
|
platform_personas = persona_data.get('platform_personas', {})
|
|
return [platform for platform, data in platform_personas.items()
|
|
if isinstance(data, dict) and 'error' not in data]
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting supported platforms for user {user_id}: {str(e)}")
|
|
return []
|
|
|
|
def get_persona_summary(self, user_id: str) -> Dict[str, Any]:
|
|
"""Get a summary of persona data for a user."""
|
|
try:
|
|
persona_data = self.get_user_persona_data(user_id)
|
|
if not persona_data:
|
|
return {"error": "No persona data found"}
|
|
|
|
platform_personas = persona_data.get('platform_personas', {})
|
|
quality_metrics = persona_data.get('quality_metrics', {})
|
|
|
|
return {
|
|
"user_id": user_id,
|
|
"has_core_persona": bool(persona_data.get('core_persona')),
|
|
"platforms": list(platform_personas.keys()),
|
|
"platform_count": len(platform_personas),
|
|
"quality_score": quality_metrics.get('overall_score', 0),
|
|
"selected_platforms": persona_data.get('selected_platforms', []),
|
|
"created_at": persona_data.get('created_at'),
|
|
"updated_at": persona_data.get('updated_at')
|
|
}
|
|
|
|
except Exception as e:
|
|
logger.error(f"Error getting persona summary for user {user_id}: {str(e)}")
|
|
return {"error": str(e)}
|