Alwrity version 0.5.4
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
||||
"""
|
||||
Content Strategy Educational Content Module
|
||||
Provides educational content and messages for strategy generation process.
|
||||
"""
|
||||
|
||||
from .educational_content import EducationalContentManager
|
||||
|
||||
__all__ = ['EducationalContentManager']
|
||||
@@ -0,0 +1,319 @@
|
||||
"""
|
||||
Educational Content Manager
|
||||
Manages educational content and messages for strategy generation process.
|
||||
"""
|
||||
|
||||
from typing import Dict, Any, List
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class EducationalContentManager:
|
||||
"""Manages educational content for strategy generation steps."""
|
||||
|
||||
@staticmethod
|
||||
def get_initialization_content() -> Dict[str, Any]:
|
||||
"""Get educational content for initialization step."""
|
||||
return {
|
||||
"title": "🤖 AI-Powered Strategy Generation",
|
||||
"description": "Initializing AI analysis and preparing educational content...",
|
||||
"details": [
|
||||
"🔧 Setting up AI services",
|
||||
"📊 Loading user context",
|
||||
"🎯 Preparing strategy framework",
|
||||
"📚 Generating educational content"
|
||||
],
|
||||
"insight": "We're getting everything ready for your personalized AI strategy generation.",
|
||||
"estimated_time": "2-3 minutes total"
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def get_step_content(step: int) -> Dict[str, Any]:
|
||||
"""Get educational content for a specific step."""
|
||||
step_content = {
|
||||
1: EducationalContentManager._get_user_context_content(),
|
||||
2: EducationalContentManager._get_foundation_content(),
|
||||
3: EducationalContentManager._get_strategic_insights_content(),
|
||||
4: EducationalContentManager._get_competitive_analysis_content(),
|
||||
5: EducationalContentManager._get_performance_predictions_content(),
|
||||
6: EducationalContentManager._get_implementation_roadmap_content(),
|
||||
7: EducationalContentManager._get_compilation_content(),
|
||||
8: EducationalContentManager._get_completion_content()
|
||||
}
|
||||
|
||||
return step_content.get(step, EducationalContentManager._get_default_content())
|
||||
|
||||
@staticmethod
|
||||
def get_step_completion_content(step: int, result_data: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||
"""Get educational content for step completion."""
|
||||
completion_content = {
|
||||
3: EducationalContentManager._get_strategic_insights_completion(result_data),
|
||||
4: EducationalContentManager._get_competitive_analysis_completion(result_data),
|
||||
5: EducationalContentManager._get_performance_predictions_completion(result_data),
|
||||
6: EducationalContentManager._get_implementation_roadmap_completion(result_data)
|
||||
}
|
||||
|
||||
return completion_content.get(step, EducationalContentManager._get_default_completion())
|
||||
|
||||
@staticmethod
|
||||
def _get_user_context_content() -> Dict[str, Any]:
|
||||
"""Get educational content for user context analysis."""
|
||||
return {
|
||||
"title": "🔍 Analyzing Your Data",
|
||||
"description": "We're gathering all your onboarding information to create a personalized strategy.",
|
||||
"details": [
|
||||
"📊 Website analysis data",
|
||||
"🎯 Research preferences",
|
||||
"🔑 API configurations",
|
||||
"📈 Historical performance metrics"
|
||||
],
|
||||
"insight": "Your data helps us understand your business context, target audience, and competitive landscape.",
|
||||
"ai_prompt_preview": "Analyzing user onboarding data to extract business context, audience insights, and competitive positioning..."
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_foundation_content() -> Dict[str, Any]:
|
||||
"""Get educational content for foundation building."""
|
||||
return {
|
||||
"title": "🏗️ Building Foundation",
|
||||
"description": "Creating the core strategy framework based on your business objectives.",
|
||||
"details": [
|
||||
"🎯 Business objectives mapping",
|
||||
"📊 Target metrics definition",
|
||||
"💰 Budget allocation strategy",
|
||||
"⏰ Timeline planning"
|
||||
],
|
||||
"insight": "A solid foundation ensures your content strategy aligns with business goals and resources.",
|
||||
"ai_prompt_preview": "Generating strategic foundation: business objectives, target metrics, budget allocation, and timeline planning..."
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_strategic_insights_content() -> Dict[str, Any]:
|
||||
"""Get educational content for strategic insights generation."""
|
||||
return {
|
||||
"title": "🧠 Strategic Intelligence Analysis",
|
||||
"description": "AI is analyzing your market position and identifying strategic opportunities.",
|
||||
"details": [
|
||||
"🎯 Market positioning analysis",
|
||||
"💡 Opportunity identification",
|
||||
"📈 Growth potential assessment",
|
||||
"🎪 Competitive advantage mapping"
|
||||
],
|
||||
"insight": "Strategic insights help you understand where you stand in the market and how to differentiate.",
|
||||
"ai_prompt_preview": "Analyzing market position, identifying strategic opportunities, assessing growth potential, and mapping competitive advantages...",
|
||||
"estimated_time": "15-20 seconds"
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_competitive_analysis_content() -> Dict[str, Any]:
|
||||
"""Get educational content for competitive analysis."""
|
||||
return {
|
||||
"title": "🔍 Competitive Intelligence Analysis",
|
||||
"description": "AI is analyzing your competitors to identify gaps and opportunities.",
|
||||
"details": [
|
||||
"🏢 Competitor content strategies",
|
||||
"📊 Market gap analysis",
|
||||
"🎯 Differentiation opportunities",
|
||||
"📈 Industry trend analysis"
|
||||
],
|
||||
"insight": "Understanding your competitors helps you find unique angles and underserved market segments.",
|
||||
"ai_prompt_preview": "Analyzing competitor content strategies, identifying market gaps, finding differentiation opportunities, and assessing industry trends...",
|
||||
"estimated_time": "20-25 seconds"
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_performance_predictions_content() -> Dict[str, Any]:
|
||||
"""Get educational content for performance predictions."""
|
||||
return {
|
||||
"title": "📊 Performance Forecasting",
|
||||
"description": "AI is predicting content performance and ROI based on industry data.",
|
||||
"details": [
|
||||
"📈 Traffic growth projections",
|
||||
"💰 ROI predictions",
|
||||
"🎯 Conversion rate estimates",
|
||||
"📊 Engagement metrics forecasting"
|
||||
],
|
||||
"insight": "Performance predictions help you set realistic expectations and optimize resource allocation.",
|
||||
"ai_prompt_preview": "Analyzing industry benchmarks, predicting traffic growth, estimating ROI, forecasting conversion rates, and projecting engagement metrics...",
|
||||
"estimated_time": "15-20 seconds"
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_implementation_roadmap_content() -> Dict[str, Any]:
|
||||
"""Get educational content for implementation roadmap."""
|
||||
return {
|
||||
"title": "🗺️ Implementation Roadmap",
|
||||
"description": "AI is creating a detailed implementation plan for your content strategy.",
|
||||
"details": [
|
||||
"📋 Task breakdown and timeline",
|
||||
"👥 Resource allocation planning",
|
||||
"🎯 Milestone definition",
|
||||
"📊 Success metric tracking"
|
||||
],
|
||||
"insight": "A clear implementation roadmap ensures successful strategy execution and measurable results.",
|
||||
"ai_prompt_preview": "Creating implementation roadmap: task breakdown, resource allocation, milestone planning, and success metric definition...",
|
||||
"estimated_time": "15-20 seconds"
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_risk_assessment_content() -> Dict[str, Any]:
|
||||
"""Get educational content for risk assessment."""
|
||||
return {
|
||||
"title": "⚠️ Risk Assessment",
|
||||
"description": "AI is identifying potential risks and mitigation strategies for your content strategy.",
|
||||
"details": [
|
||||
"🔍 Risk identification and analysis",
|
||||
"📊 Risk probability assessment",
|
||||
"🛡️ Mitigation strategy development",
|
||||
"📈 Risk monitoring framework"
|
||||
],
|
||||
"insight": "Proactive risk assessment helps you prepare for challenges and maintain strategy effectiveness.",
|
||||
"ai_prompt_preview": "Assessing risks: identifying potential challenges, analyzing probability and impact, developing mitigation strategies, and creating monitoring framework...",
|
||||
"estimated_time": "10-15 seconds"
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_compilation_content() -> Dict[str, Any]:
|
||||
"""Get educational content for strategy compilation."""
|
||||
return {
|
||||
"title": "📋 Strategy Compilation",
|
||||
"description": "AI is compiling all components into a comprehensive content strategy.",
|
||||
"details": [
|
||||
"🔗 Component integration",
|
||||
"📊 Data synthesis",
|
||||
"📝 Strategy documentation",
|
||||
"✅ Quality validation"
|
||||
],
|
||||
"insight": "A comprehensive strategy integrates all components into a cohesive, actionable plan.",
|
||||
"ai_prompt_preview": "Compiling comprehensive strategy: integrating all components, synthesizing data, documenting strategy, and validating quality...",
|
||||
"estimated_time": "5-10 seconds"
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_completion_content() -> Dict[str, Any]:
|
||||
"""Get educational content for strategy completion."""
|
||||
return {
|
||||
"title": "🎉 Strategy Generation Complete!",
|
||||
"description": "Your comprehensive AI-powered content strategy is ready for review!",
|
||||
"summary": {
|
||||
"total_components": 5,
|
||||
"successful_components": 5,
|
||||
"estimated_roi": "15-25%",
|
||||
"implementation_timeline": "12 months",
|
||||
"risk_level": "Medium"
|
||||
},
|
||||
"key_achievements": [
|
||||
"🧠 Strategic insights generated",
|
||||
"🔍 Competitive analysis completed",
|
||||
"📊 Performance predictions calculated",
|
||||
"🗺️ Implementation roadmap planned",
|
||||
"⚠️ Risk assessment conducted"
|
||||
],
|
||||
"next_steps": [
|
||||
"Review your comprehensive strategy in the Strategic Intelligence tab",
|
||||
"Customize specific components as needed",
|
||||
"Confirm the strategy to proceed",
|
||||
"Generate content calendar based on confirmed strategy"
|
||||
],
|
||||
"ai_insights": "Your strategy leverages advanced AI analysis of your business context, competitive landscape, and industry best practices to create a data-driven content approach.",
|
||||
"personalization_note": "This strategy is uniquely tailored to your business based on your onboarding data, ensuring relevance and effectiveness.",
|
||||
"content_calendar_note": "Content calendar will be generated separately after you review and confirm this strategy, ensuring it's based on your final approved strategy."
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_default_content() -> Dict[str, Any]:
|
||||
"""Get default educational content."""
|
||||
return {
|
||||
"title": "🔄 Processing",
|
||||
"description": "AI is working on your strategy...",
|
||||
"details": [
|
||||
"⏳ Processing in progress",
|
||||
"📊 Analyzing data",
|
||||
"🎯 Generating insights",
|
||||
"📝 Compiling results"
|
||||
],
|
||||
"insight": "The AI is working hard to create your personalized strategy.",
|
||||
"estimated_time": "A few moments"
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_strategic_insights_completion(result_data: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||
"""Get completion content for strategic insights."""
|
||||
insights_count = len(result_data.get("insights", [])) if result_data else 0
|
||||
return {
|
||||
"title": "✅ Strategic Insights Complete",
|
||||
"description": "Successfully identified key strategic opportunities and market positioning.",
|
||||
"achievement": f"Generated {insights_count} strategic insights",
|
||||
"next_step": "Moving to competitive analysis..."
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_competitive_analysis_completion(result_data: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||
"""Get completion content for competitive analysis."""
|
||||
competitors_count = len(result_data.get("competitors", [])) if result_data else 0
|
||||
return {
|
||||
"title": "✅ Competitive Analysis Complete",
|
||||
"description": "Successfully analyzed competitive landscape and identified market opportunities.",
|
||||
"achievement": f"Analyzed {competitors_count} competitors",
|
||||
"next_step": "Moving to performance predictions..."
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_performance_predictions_completion(result_data: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||
"""Get completion content for performance predictions."""
|
||||
estimated_roi = result_data.get("estimated_roi", "15-25%") if result_data else "15-25%"
|
||||
return {
|
||||
"title": "✅ Performance Predictions Complete",
|
||||
"description": "Successfully predicted content performance and ROI.",
|
||||
"achievement": f"Predicted {estimated_roi} ROI",
|
||||
"next_step": "Moving to implementation roadmap..."
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_implementation_roadmap_completion(result_data: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||
"""Get completion content for implementation roadmap."""
|
||||
timeline = result_data.get("total_duration", "12 months") if result_data else "12 months"
|
||||
return {
|
||||
"title": "✅ Implementation Roadmap Complete",
|
||||
"description": "Successfully created detailed implementation plan.",
|
||||
"achievement": f"Planned {timeline} implementation timeline",
|
||||
"next_step": "Moving to compilation..."
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_risk_assessment_completion(result_data: Dict[str, Any] = None) -> Dict[str, Any]:
|
||||
"""Get completion content for risk assessment."""
|
||||
risk_level = result_data.get("overall_risk_level", "Medium") if result_data else "Medium"
|
||||
return {
|
||||
"title": "✅ Risk Assessment Complete",
|
||||
"description": "Successfully identified risks and mitigation strategies.",
|
||||
"achievement": f"Assessed {risk_level} risk level",
|
||||
"next_step": "Finalizing comprehensive strategy..."
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def _get_default_completion() -> Dict[str, Any]:
|
||||
"""Get default completion content."""
|
||||
return {
|
||||
"title": "✅ Step Complete",
|
||||
"description": "Successfully completed this step.",
|
||||
"achievement": "Step completed successfully",
|
||||
"next_step": "Moving to next step..."
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def update_completion_summary(completion_content: Dict[str, Any], strategy_data: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Update completion content with actual strategy data."""
|
||||
if "summary" in completion_content:
|
||||
content_calendar = strategy_data.get("content_calendar", {})
|
||||
performance_predictions = strategy_data.get("performance_predictions", {})
|
||||
implementation_roadmap = strategy_data.get("implementation_roadmap", {})
|
||||
risk_assessment = strategy_data.get("risk_assessment", {})
|
||||
|
||||
completion_content["summary"].update({
|
||||
"total_content_pieces": len(content_calendar.get("content_pieces", [])),
|
||||
"estimated_roi": performance_predictions.get("estimated_roi", "15-25%"),
|
||||
"implementation_timeline": implementation_roadmap.get("total_duration", "12 months"),
|
||||
"risk_level": risk_assessment.get("overall_risk_level", "Medium")
|
||||
})
|
||||
|
||||
return completion_content
|
||||
@@ -1122,4 +1122,4 @@ async def refresh_autofill(
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Error generating fresh auto-fill payload: {str(e)}")
|
||||
raise ContentPlanningErrorHandler.handle_general_error(e, "refresh_autofill")
|
||||
raise ContentPlanningErrorHandler.handle_general_error(e, "refresh_autofill")
|
||||
@@ -60,7 +60,7 @@ class AIStrategyGenerator:
|
||||
strategy_name: Optional custom strategy name
|
||||
|
||||
Returns:
|
||||
Comprehensive strategy with all components
|
||||
Comprehensive strategy with all components (EXCLUDING content calendar)
|
||||
|
||||
Raises:
|
||||
RuntimeError: If any AI component fails to generate
|
||||
@@ -77,19 +77,16 @@ class AIStrategyGenerator:
|
||||
# Step 3: Generate competitive analysis
|
||||
competitive_analysis = await self._generate_competitive_analysis(base_strategy, context)
|
||||
|
||||
# Step 4: Generate content calendar
|
||||
content_calendar = await self._generate_content_calendar(base_strategy, context)
|
||||
|
||||
# Step 5: Generate performance predictions
|
||||
# Step 4: Generate performance predictions
|
||||
performance_predictions = await self._generate_performance_predictions(base_strategy, context)
|
||||
|
||||
# Step 6: Generate implementation roadmap
|
||||
# Step 5: Generate implementation roadmap
|
||||
implementation_roadmap = await self._generate_implementation_roadmap(base_strategy, context)
|
||||
|
||||
# Step 7: Generate risk assessment
|
||||
# Step 6: Generate risk assessment
|
||||
risk_assessment = await self._generate_risk_assessment(base_strategy, context)
|
||||
|
||||
# Step 8: Compile comprehensive strategy
|
||||
# Step 7: Compile comprehensive strategy (NO CONTENT CALENDAR)
|
||||
comprehensive_strategy = {
|
||||
"strategy_metadata": {
|
||||
"generated_at": datetime.utcnow().isoformat(),
|
||||
@@ -99,21 +96,21 @@ class AIStrategyGenerator:
|
||||
"ai_model": "gemini-pro",
|
||||
"personalization_level": "high",
|
||||
"ai_generated": True,
|
||||
"comprehensive": True
|
||||
"comprehensive": True,
|
||||
"content_calendar_ready": False # Indicates calendar needs to be generated separately
|
||||
},
|
||||
"base_strategy": base_strategy,
|
||||
"strategic_insights": strategic_insights,
|
||||
"competitive_analysis": competitive_analysis,
|
||||
"content_calendar": content_calendar,
|
||||
"performance_predictions": performance_predictions,
|
||||
"implementation_roadmap": implementation_roadmap,
|
||||
"risk_assessment": risk_assessment,
|
||||
"summary": {
|
||||
"total_content_pieces": len(content_calendar.get("content_pieces", [])),
|
||||
"estimated_roi": performance_predictions.get("estimated_roi", "15-25%"),
|
||||
"implementation_timeline": implementation_roadmap.get("total_duration", "12 months"),
|
||||
"risk_level": risk_assessment.get("overall_risk_level", "Medium"),
|
||||
"success_probability": performance_predictions.get("success_probability", "85%")
|
||||
"success_probability": performance_predictions.get("success_probability", "85%"),
|
||||
"next_step": "Review strategy and generate content calendar"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,8 +331,55 @@ class AIStrategyGenerator:
|
||||
}
|
||||
},
|
||||
"themes": {"type": "array", "items": {"type": "string"}},
|
||||
"schedule": {"type": "object"},
|
||||
"distribution_strategy": {"type": "object"}
|
||||
"schedule": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"publishing_frequency": {"type": "string"},
|
||||
"optimal_times": {"type": "array", "items": {"type": "string"}},
|
||||
"content_mix": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"blog_posts": {"type": "string"},
|
||||
"social_media": {"type": "string"},
|
||||
"videos": {"type": "string"},
|
||||
"infographics": {"type": "string"},
|
||||
"newsletters": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"seasonal_adjustments": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"holiday_content": {"type": "array", "items": {"type": "string"}},
|
||||
"seasonal_themes": {"type": "array", "items": {"type": "string"}},
|
||||
"peak_periods": {"type": "array", "items": {"type": "string"}}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"distribution_strategy": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"primary_platforms": {"type": "array", "items": {"type": "string"}},
|
||||
"cross_posting_strategy": {"type": "string"},
|
||||
"platform_specific_content": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"linkedin_content": {"type": "array", "items": {"type": "string"}},
|
||||
"twitter_content": {"type": "array", "items": {"type": "string"}},
|
||||
"instagram_content": {"type": "array", "items": {"type": "string"}},
|
||||
"facebook_content": {"type": "array", "items": {"type": "string"}}
|
||||
}
|
||||
},
|
||||
"engagement_timing": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"best_times": {"type": "array", "items": {"type": "string"}},
|
||||
"frequency": {"type": "string"},
|
||||
"timezone_considerations": {"type": "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -483,8 +527,33 @@ class AIStrategyGenerator:
|
||||
}
|
||||
}
|
||||
},
|
||||
"timeline": {"type": "object"},
|
||||
"resource_allocation": {"type": "object"},
|
||||
"timeline": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"start_date": {"type": "string"},
|
||||
"end_date": {"type": "string"},
|
||||
"key_milestones": {"type": "array", "items": {"type": "string"}},
|
||||
"critical_path": {"type": "array", "items": {"type": "string"}}
|
||||
}
|
||||
},
|
||||
"resource_allocation": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"team_requirements": {"type": "array", "items": {"type": "string"}},
|
||||
"budget_allocation": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"total_budget": {"type": "string"},
|
||||
"content_creation": {"type": "string"},
|
||||
"technology_tools": {"type": "string"},
|
||||
"marketing_promotion": {"type": "string"},
|
||||
"external_resources": {"type": "string"}
|
||||
}
|
||||
},
|
||||
"technology_needs": {"type": "array", "items": {"type": "string"}},
|
||||
"external_resources": {"type": "array", "items": {"type": "string"}}
|
||||
}
|
||||
},
|
||||
"success_metrics": {"type": "array", "items": {"type": "string"}},
|
||||
"total_duration": {"type": "string"}
|
||||
}
|
||||
@@ -552,9 +621,25 @@ class AIStrategyGenerator:
|
||||
}
|
||||
},
|
||||
"overall_risk_level": {"type": "string"},
|
||||
"risk_categories": {"type": "object"},
|
||||
"risk_categories": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"technical_risks": {"type": "array", "items": {"type": "string"}},
|
||||
"market_risks": {"type": "array", "items": {"type": "string"}},
|
||||
"operational_risks": {"type": "array", "items": {"type": "string"}},
|
||||
"financial_risks": {"type": "array", "items": {"type": "string"}}
|
||||
}
|
||||
},
|
||||
"mitigation_strategies": {"type": "array", "items": {"type": "string"}},
|
||||
"monitoring_framework": {"type": "object"}
|
||||
"monitoring_framework": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key_indicators": {"type": "array", "items": {"type": "string"}},
|
||||
"monitoring_frequency": {"type": "string"},
|
||||
"escalation_procedures": {"type": "array", "items": {"type": "string"}},
|
||||
"review_schedule": {"type": "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -506,7 +506,7 @@ class EnhancedStrategyService:
|
||||
|
||||
def _merge_strategy_with_onboarding(self, strategy_data: Dict[str, Any], field_transformations: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Merge strategy data with onboarding data."""
|
||||
merged_data = strategy_data.copy()
|
||||
merged_data = strategy_data.copy()
|
||||
|
||||
for field, transformation in field_transformations.items():
|
||||
if field not in merged_data or merged_data[field] is None:
|
||||
|
||||
Reference in New Issue
Block a user