fix: auto-fix code issues (cron)

- 修复重复导入/字段
- 修复异常处理
- 修复PEP8格式问题
- 添加类型注解
This commit is contained in:
OpenClaw Bot
2026-02-27 18:09:24 +08:00
parent 646b64daf7
commit 17bda3dbce
38 changed files with 1993 additions and 1972 deletions

View File

@@ -10,25 +10,26 @@ InsightFlow Growth Manager - Phase 8 Task 5
作者: InsightFlow Team
"""
import os
import json
import sqlite3
import httpx
import asyncio
import hashlib
import json
import os
import random
from typing import List, Dict, Optional, Any, Tuple
import re
import sqlite3
import uuid
from dataclasses import dataclass
from datetime import datetime, timedelta
from enum import Enum
import hashlib
import uuid
import re
from enum import StrEnum
from typing import Any
import httpx
# Database path
DB_PATH = os.path.join(os.path.dirname(__file__), "insightflow.db")
class EventType(str, Enum):
class EventType(StrEnum):
"""事件类型"""
PAGE_VIEW = "page_view" # 页面浏览
@@ -44,7 +45,7 @@ class EventType(str, Enum):
REFERRAL_REWARD = "referral_reward" # 推荐奖励
class ExperimentStatus(str, Enum):
class ExperimentStatus(StrEnum):
"""实验状态"""
DRAFT = "draft" # 草稿
@@ -54,7 +55,7 @@ class ExperimentStatus(str, Enum):
ARCHIVED = "archived" # 已归档
class TrafficAllocationType(str, Enum):
class TrafficAllocationType(StrEnum):
"""流量分配类型"""
RANDOM = "random" # 随机分配
@@ -62,7 +63,7 @@ class TrafficAllocationType(str, Enum):
TARGETED = "targeted" # 定向分配
class EmailTemplateType(str, Enum):
class EmailTemplateType(StrEnum):
"""邮件模板类型"""
WELCOME = "welcome" # 欢迎邮件
@@ -74,7 +75,7 @@ class EmailTemplateType(str, Enum):
NEWSLETTER = "newsletter" # 新闻通讯
class EmailStatus(str, Enum):
class EmailStatus(StrEnum):
"""邮件状态"""
DRAFT = "draft" # 草稿
@@ -88,7 +89,7 @@ class EmailStatus(str, Enum):
FAILED = "failed" # 失败
class WorkflowTriggerType(str, Enum):
class WorkflowTriggerType(StrEnum):
"""工作流触发类型"""
USER_SIGNUP = "user_signup" # 用户注册
@@ -100,7 +101,7 @@ class WorkflowTriggerType(str, Enum):
CUSTOM_EVENT = "custom_event" # 自定义事件
class ReferralStatus(str, Enum):
class ReferralStatus(StrEnum):
"""推荐状态"""
PENDING = "pending" # 待处理
@@ -118,14 +119,14 @@ class AnalyticsEvent:
user_id: str
event_type: EventType
event_name: str
properties: Dict[str, Any] # 事件属性
properties: dict[str, Any] # 事件属性
timestamp: datetime
session_id: Optional[str]
device_info: Dict[str, str] # 设备信息
referrer: Optional[str]
utm_source: Optional[str]
utm_medium: Optional[str]
utm_campaign: Optional[str]
session_id: str | None
device_info: dict[str, str] # 设备信息
referrer: str | None
utm_source: str | None
utm_medium: str | None
utm_campaign: str | None
@dataclass
@@ -139,8 +140,8 @@ class UserProfile:
last_seen: datetime
total_sessions: int
total_events: int
feature_usage: Dict[str, int] # 功能使用次数
subscription_history: List[Dict]
feature_usage: dict[str, int] # 功能使用次数
subscription_history: list[dict]
ltv: float # 生命周期价值
churn_risk_score: float # 流失风险分数
engagement_score: float # 参与度分数
@@ -156,7 +157,7 @@ class Funnel:
tenant_id: str
name: str
description: str
steps: List[Dict] # 漏斗步骤
steps: list[dict] # 漏斗步骤
created_at: datetime
updated_at: datetime
@@ -169,9 +170,9 @@ class FunnelAnalysis:
period_start: datetime
period_end: datetime
total_users: int
step_conversions: List[Dict] # 每步转化数据
step_conversions: list[dict] # 每步转化数据
overall_conversion: float # 总体转化率
drop_off_points: List[Dict] # 流失点
drop_off_points: list[dict] # 流失点
@dataclass
@@ -184,14 +185,14 @@ class Experiment:
description: str
hypothesis: str
status: ExperimentStatus
variants: List[Dict] # 实验变体
variants: list[dict] # 实验变体
traffic_allocation: TrafficAllocationType
traffic_split: Dict[str, float] # 流量分配比例
target_audience: Dict # 目标受众
traffic_split: dict[str, float] # 流量分配比例
target_audience: dict # 目标受众
primary_metric: str # 主要指标
secondary_metrics: List[str] # 次要指标
start_date: Optional[datetime]
end_date: Optional[datetime]
secondary_metrics: list[str] # 次要指标
start_date: datetime | None
end_date: datetime | None
min_sample_size: int # 最小样本量
confidence_level: float # 置信水平
created_at: datetime
@@ -210,7 +211,7 @@ class ExperimentResult:
sample_size: int
mean_value: float
std_dev: float
confidence_interval: Tuple[float, float]
confidence_interval: tuple[float, float]
p_value: float
is_significant: bool
uplift: float # 提升幅度
@@ -228,11 +229,11 @@ class EmailTemplate:
subject: str
html_content: str
text_content: str
variables: List[str] # 模板变量
preview_text: Optional[str]
variables: list[str] # 模板变量
preview_text: str | None
from_name: str
from_email: str
reply_to: Optional[str]
reply_to: str | None
is_active: bool
created_at: datetime
updated_at: datetime
@@ -254,9 +255,9 @@ class EmailCampaign:
clicked_count: int
bounced_count: int
failed_count: int
scheduled_at: Optional[datetime]
started_at: Optional[datetime]
completed_at: Optional[datetime]
scheduled_at: datetime | None
started_at: datetime | None
completed_at: datetime | None
created_at: datetime
@@ -272,13 +273,13 @@ class EmailLog:
template_id: str
status: EmailStatus
subject: str
sent_at: Optional[datetime]
delivered_at: Optional[datetime]
opened_at: Optional[datetime]
clicked_at: Optional[datetime]
ip_address: Optional[str]
user_agent: Optional[str]
error_message: Optional[str]
sent_at: datetime | None
delivered_at: datetime | None
opened_at: datetime | None
clicked_at: datetime | None
ip_address: str | None
user_agent: str | None
error_message: str | None
created_at: datetime
@@ -291,8 +292,8 @@ class AutomationWorkflow:
name: str
description: str
trigger_type: WorkflowTriggerType
trigger_conditions: Dict # 触发条件
actions: List[Dict] # 执行动作
trigger_conditions: dict # 触发条件
actions: list[dict] # 执行动作
is_active: bool
execution_count: int
created_at: datetime
@@ -327,15 +328,15 @@ class Referral:
program_id: str
tenant_id: str
referrer_id: str # 推荐人
referee_id: Optional[str] # 被推荐人
referee_id: str | None # 被推荐人
referral_code: str
status: ReferralStatus
referrer_rewarded: bool
referee_rewarded: bool
referrer_reward_value: float
referee_reward_value: float
converted_at: Optional[datetime]
rewarded_at: Optional[datetime]
converted_at: datetime | None
rewarded_at: datetime | None
expires_at: datetime
created_at: datetime
@@ -382,11 +383,11 @@ class GrowthManager:
user_id: str,
event_type: EventType,
event_name: str,
properties: Dict = None,
properties: dict = None,
session_id: str = None,
device_info: Dict = None,
device_info: dict = None,
referrer: str = None,
utm_params: Dict = None,
utm_params: dict = None,
) -> AnalyticsEvent:
"""追踪事件"""
event_id = f"evt_{uuid.uuid4().hex[:16]}"
@@ -554,7 +555,7 @@ class GrowthManager:
conn.commit()
def get_user_profile(self, tenant_id: str, user_id: str) -> Optional[UserProfile]:
def get_user_profile(self, tenant_id: str, user_id: str) -> UserProfile | None:
"""获取用户画像"""
with self._get_db() as conn:
row = conn.execute(
@@ -567,7 +568,7 @@ class GrowthManager:
def get_user_analytics_summary(
self, tenant_id: str, start_date: datetime = None, end_date: datetime = None
) -> Dict:
) -> dict:
"""获取用户分析汇总"""
with self._get_db() as conn:
query = """
@@ -619,7 +620,7 @@ class GrowthManager:
"event_type_distribution": {r["event_type"]: r["count"] for r in type_rows},
}
def create_funnel(self, tenant_id: str, name: str, description: str, steps: List[Dict], created_by: str) -> Funnel:
def create_funnel(self, tenant_id: str, name: str, description: str, steps: list[dict], created_by: str) -> Funnel:
"""创建转化漏斗"""
funnel_id = f"fnl_{uuid.uuid4().hex[:16]}"
now = datetime.now().isoformat()
@@ -657,7 +658,7 @@ class GrowthManager:
def analyze_funnel(
self, funnel_id: str, period_start: datetime = None, period_end: datetime = None
) -> Optional[FunnelAnalysis]:
) -> FunnelAnalysis | None:
"""分析漏斗转化率"""
with self._get_db() as conn:
funnel_row = conn.execute("SELECT * FROM funnels WHERE id = ?", (funnel_id,)).fetchone()
@@ -728,7 +729,7 @@ class GrowthManager:
drop_off_points=drop_off_points,
)
def calculate_retention(self, tenant_id: str, cohort_date: datetime, periods: List[int] = None) -> Dict:
def calculate_retention(self, tenant_id: str, cohort_date: datetime, periods: list[int] = None) -> dict:
"""计算留存率"""
if periods is None:
periods = [1, 3, 7, 14, 30]
@@ -787,12 +788,12 @@ class GrowthManager:
name: str,
description: str,
hypothesis: str,
variants: List[Dict],
variants: list[dict],
traffic_allocation: TrafficAllocationType,
traffic_split: Dict[str, float],
target_audience: Dict,
traffic_split: dict[str, float],
target_audience: dict,
primary_metric: str,
secondary_metrics: List[str],
secondary_metrics: list[str],
min_sample_size: int = 100,
confidence_level: float = 0.95,
created_by: str = None,
@@ -859,7 +860,7 @@ class GrowthManager:
return experiment
def get_experiment(self, experiment_id: str) -> Optional[Experiment]:
def get_experiment(self, experiment_id: str) -> Experiment | None:
"""获取实验详情"""
with self._get_db() as conn:
row = conn.execute("SELECT * FROM experiments WHERE id = ?", (experiment_id,)).fetchone()
@@ -868,7 +869,7 @@ class GrowthManager:
return self._row_to_experiment(row)
return None
def list_experiments(self, tenant_id: str, status: ExperimentStatus = None) -> List[Experiment]:
def list_experiments(self, tenant_id: str, status: ExperimentStatus = None) -> list[Experiment]:
"""列出实验"""
query = "SELECT * FROM experiments WHERE tenant_id = ?"
params = [tenant_id]
@@ -883,7 +884,7 @@ class GrowthManager:
rows = conn.execute(query, params).fetchall()
return [self._row_to_experiment(row) for row in rows]
def assign_variant(self, experiment_id: str, user_id: str, user_attributes: Dict = None) -> Optional[str]:
def assign_variant(self, experiment_id: str, user_id: str, user_attributes: dict = None) -> str | None:
"""为用户分配实验变体"""
experiment = self.get_experiment(experiment_id)
if not experiment or experiment.status != ExperimentStatus.RUNNING:
@@ -929,7 +930,7 @@ class GrowthManager:
return variant_id
def _random_allocation(self, variants: List[Dict], traffic_split: Dict[str, float]) -> str:
def _random_allocation(self, variants: list[dict], traffic_split: dict[str, float]) -> str:
"""随机分配"""
variant_ids = [v["id"] for v in variants]
weights = [traffic_split.get(v_id, 1.0 / len(variants)) for v_id in variant_ids]
@@ -940,7 +941,7 @@ class GrowthManager:
return random.choices(variant_ids, weights=normalized_weights, k=1)[0]
def _stratified_allocation(
self, variants: List[Dict], traffic_split: Dict[str, float], user_attributes: Dict
self, variants: list[dict], traffic_split: dict[str, float], user_attributes: dict
) -> str:
"""分层分配(基于用户属性)"""
# 简化的分层分配:根据用户 ID 哈希值分配
@@ -952,7 +953,7 @@ class GrowthManager:
return self._random_allocation(variants, traffic_split)
def _targeted_allocation(self, variants: List[Dict], target_audience: Dict, user_attributes: Dict) -> Optional[str]:
def _targeted_allocation(self, variants: list[dict], target_audience: dict, user_attributes: dict) -> str | None:
"""定向分配(基于目标受众条件)"""
# 检查用户是否符合目标受众条件
conditions = target_audience.get("conditions", [])
@@ -1005,7 +1006,7 @@ class GrowthManager:
)
conn.commit()
def analyze_experiment(self, experiment_id: str) -> Dict:
def analyze_experiment(self, experiment_id: str) -> dict:
"""分析实验结果"""
experiment = self.get_experiment(experiment_id)
if not experiment:
@@ -1083,7 +1084,7 @@ class GrowthManager:
"variant_results": results,
}
def start_experiment(self, experiment_id: str) -> Optional[Experiment]:
def start_experiment(self, experiment_id: str) -> Experiment | None:
"""启动实验"""
with self._get_db() as conn:
now = datetime.now().isoformat()
@@ -1099,7 +1100,7 @@ class GrowthManager:
return self.get_experiment(experiment_id)
def stop_experiment(self, experiment_id: str) -> Optional[Experiment]:
def stop_experiment(self, experiment_id: str) -> Experiment | None:
"""停止实验"""
with self._get_db() as conn:
now = datetime.now().isoformat()
@@ -1125,7 +1126,7 @@ class GrowthManager:
subject: str,
html_content: str,
text_content: str = None,
variables: List[str] = None,
variables: list[str] = None,
from_name: str = None,
from_email: str = None,
reply_to: str = None,
@@ -1185,7 +1186,7 @@ class GrowthManager:
return template
def get_email_template(self, template_id: str) -> Optional[EmailTemplate]:
def get_email_template(self, template_id: str) -> EmailTemplate | None:
"""获取邮件模板"""
with self._get_db() as conn:
row = conn.execute("SELECT * FROM email_templates WHERE id = ?", (template_id,)).fetchone()
@@ -1194,7 +1195,7 @@ class GrowthManager:
return self._row_to_email_template(row)
return None
def list_email_templates(self, tenant_id: str, template_type: EmailTemplateType = None) -> List[EmailTemplate]:
def list_email_templates(self, tenant_id: str, template_type: EmailTemplateType = None) -> list[EmailTemplate]:
"""列出邮件模板"""
query = "SELECT * FROM email_templates WHERE tenant_id = ? AND is_active = 1"
params = [tenant_id]
@@ -1209,7 +1210,7 @@ class GrowthManager:
rows = conn.execute(query, params).fetchall()
return [self._row_to_email_template(row) for row in rows]
def render_template(self, template_id: str, variables: Dict) -> Dict[str, str]:
def render_template(self, template_id: str, variables: dict) -> dict[str, str]:
"""渲染邮件模板"""
template = self.get_email_template(template_id)
if not template:
@@ -1235,7 +1236,7 @@ class GrowthManager:
}
def create_email_campaign(
self, tenant_id: str, name: str, template_id: str, recipient_list: List[Dict], scheduled_at: datetime = None
self, tenant_id: str, name: str, template_id: str, recipient_list: list[dict], scheduled_at: datetime = None
) -> EmailCampaign:
"""创建邮件营销活动"""
campaign_id = f"ec_{uuid.uuid4().hex[:16]}"
@@ -1314,7 +1315,7 @@ class GrowthManager:
return campaign
async def send_email(self, campaign_id: str, user_id: str, email: str, template_id: str, variables: Dict) -> bool:
async def send_email(self, campaign_id: str, user_id: str, email: str, template_id: str, variables: dict) -> bool:
"""发送单封邮件"""
template = self.get_email_template(template_id)
if not template:
@@ -1380,7 +1381,7 @@ class GrowthManager:
conn.commit()
return False
async def send_campaign(self, campaign_id: str) -> Dict:
async def send_campaign(self, campaign_id: str) -> dict:
"""发送整个营销活动"""
with self._get_db() as conn:
campaign_row = conn.execute("SELECT * FROM email_campaigns WHERE id = ?", (campaign_id,)).fetchone()
@@ -1432,7 +1433,7 @@ class GrowthManager:
return {"campaign_id": campaign_id, "total": len(logs), "success": success_count, "failed": failed_count}
def _get_user_variables(self, tenant_id: str, user_id: str) -> Dict:
def _get_user_variables(self, tenant_id: str, user_id: str) -> dict:
"""获取用户变量用于邮件模板"""
# 这里应该从用户服务获取用户信息
# 简化实现
@@ -1444,8 +1445,8 @@ class GrowthManager:
name: str,
description: str,
trigger_type: WorkflowTriggerType,
trigger_conditions: Dict,
actions: List[Dict],
trigger_conditions: dict,
actions: list[dict],
) -> AutomationWorkflow:
"""创建自动化工作流"""
workflow_id = f"aw_{uuid.uuid4().hex[:16]}"
@@ -1491,7 +1492,7 @@ class GrowthManager:
return workflow
async def trigger_workflow(self, workflow_id: str, event_data: Dict):
async def trigger_workflow(self, workflow_id: str, event_data: dict):
"""触发自动化工作流"""
with self._get_db() as conn:
row = conn.execute(
@@ -1519,7 +1520,7 @@ class GrowthManager:
return True
def _check_trigger_conditions(self, conditions: Dict, event_data: Dict) -> bool:
def _check_trigger_conditions(self, conditions: dict, event_data: dict) -> bool:
"""检查触发条件"""
# 简化的条件检查
for key, value in conditions.items():
@@ -1527,7 +1528,7 @@ class GrowthManager:
return False
return True
async def _execute_action(self, action: Dict, event_data: Dict):
async def _execute_action(self, action: dict, event_data: dict):
"""执行工作流动作"""
action_type = action.get("type")
@@ -1691,7 +1692,7 @@ class GrowthManager:
if not row:
return code
def _get_referral_program(self, program_id: str) -> Optional[ReferralProgram]:
def _get_referral_program(self, program_id: str) -> ReferralProgram | None:
"""获取推荐计划"""
with self._get_db() as conn:
row = conn.execute("SELECT * FROM referral_programs WHERE id = ?", (program_id,)).fetchone()
@@ -1746,7 +1747,7 @@ class GrowthManager:
return True
def get_referral_stats(self, program_id: str) -> Dict:
def get_referral_stats(self, program_id: str) -> dict:
"""获取推荐统计"""
with self._get_db() as conn:
stats = conn.execute(
@@ -1841,7 +1842,7 @@ class GrowthManager:
def check_team_incentive_eligibility(
self, tenant_id: str, current_tier: str, team_size: int
) -> List[TeamIncentive]:
) -> list[TeamIncentive]:
"""检查团队激励资格"""
with self._get_db() as conn:
now = datetime.now().isoformat()
@@ -1859,7 +1860,7 @@ class GrowthManager:
# ==================== 实时分析仪表板 ====================
def get_realtime_dashboard(self, tenant_id: str) -> Dict:
def get_realtime_dashboard(self, tenant_id: str) -> dict:
"""获取实时分析仪表板数据"""
now = datetime.now()
today_start = now.replace(hour=0, minute=0, second=0, microsecond=0)