PMFlow/backend/app/api/ai_steward_api/routes_stats_config.py

198 lines
6.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
from .shared import *
from .helpers import _utc_now_naive
@router.get("/stats")
async def get_ai_steward_stats(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
tenant_id: int = Depends(get_tenant_id)
):
"""
获取 AI Steward 统计数据
展示 AI 为团队节省的工作量:
- 自动捕获的信号数
- 避免的认知冲突数
- 自动解决的阻塞数
- 节省的会议时间(小时)
"""
from ..models import Signal, CognitiveConflict
from sqlalchemy import func, text
# 统计信号数量
week_ago = _utc_now_naive() - timedelta(days=7)
month_ago = _utc_now_naive() - timedelta(days=30)
signal_result = await db.execute(
select(func.count(Signal.id)).where(
Signal.tenant_id == tenant_id,
Signal.created_at >= week_ago
)
)
signals_captured = signal_result.scalar() or 0
# 统计高影响信号
high_impact_result = await db.execute(
select(func.count(Signal.id)).where(
Signal.tenant_id == tenant_id,
Signal.impact_score >= 0.8,
Signal.created_at >= week_ago
)
)
high_impact_count = high_impact_result.scalar() or 0
# 统计认知冲突
conflict_result = await db.execute(
select(func.count(CognitiveConflict.id)).where(
CognitiveConflict.tenant_id == tenant_id,
CognitiveConflict.status.in_(['detected', 'active'])
)
)
active_conflicts = conflict_result.scalar() or 0
# 统计已解决的冲突
resolved_conflict_result = await db.execute(
select(func.count(CognitiveConflict.id)).where(
CognitiveConflict.tenant_id == tenant_id,
CognitiveConflict.status == 'resolved',
CognitiveConflict.resolved_at >= month_ago
)
)
conflicts_resolved = resolved_conflict_result.scalar() or 0
# 统计阻塞
blocker_result = await db.execute(
text("""
SELECT COUNT(*) FROM cognitive_conflicts
WHERE tenant_id = :tenant_id
AND conflict_type IN ('code_blocker', 'task_blocker')
AND status = 'detected'
"""),
{"tenant_id": tenant_id}
)
active_blockers = blocker_result.scalar() or 0
# 活跃项目数
from ..models import Project
project_result = await db.execute(
select(func.count(Project.id)).where(
Project.tenant_id == tenant_id,
Project.status == 'active'
)
)
active_projects = project_result.scalar() or 0
# 估算节省时间(每个冲突/阻塞避免约2小时会议)
hours_saved = conflicts_resolved * 2
stats = {
'signals_captured': signals_captured,
'high_impact_signals': high_impact_count,
'active_conflicts': active_conflicts,
'conflicts_resolved': conflicts_resolved,
'active_blockers': active_blockers,
'active_projects': active_projects,
'hours_saved': hours_saved,
'last_updated': now_cn_aware().isoformat()
}
return stats
@router.get("/config/suggest")
async def get_ai_config_suggestion(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
tenant_id: int = Depends(get_tenant_id)
):
"""
AI 建议配置方案
根据团队现状,智能推荐应该优先配置哪些集成源
"""
from ..models import Integration, Project, Signal
from sqlalchemy.future import select
from sqlalchemy import func
# 检查已配置的集成
configured_sources = []
# 检查飞书配置
feishu_result = await db.execute(
select(Integration).where(
Integration.tenant_id == tenant_id,
Integration.type == 'feishu',
Integration.is_active == True
)
)
if feishu_result.scalar_one_or_none():
configured_sources.append('feishu')
# 检查活跃项目数
project_result = await db.execute(
select(func.count(Project.id)).where(
Project.tenant_id == tenant_id,
Project.status == 'active'
)
)
active_projects = project_result.scalar() or 0
# 检查近期信号数量
signal_result = await db.execute(
select(func.count(Signal.id)).where(
Signal.tenant_id == tenant_id,
Signal.created_at >= (_utc_now_naive() - timedelta(days=7))
)
)
recent_signals = signal_result.scalar() or 0
# AI 分析并推荐配置
recommended = []
reasoning_parts = []
# 根据项目数量推荐
if active_projects > 0:
if 'feishu' not in configured_sources:
recommended.append('feishu')
reasoning_parts.append(f"您有 {active_projects} 个活跃项目,建议配置飞书群聊集成以自动捕获需求讨论")
# 根据信号量推荐
if recent_signals < 10:
if 'hn' not in [s.split('_')[0] for s in configured_sources]:
recommended.append('hn')
reasoning_parts.append("近期信号较少,建议启用 HackerNews 监控获取更多技术趋势")
# 默认推荐
if not recommended:
if 'feishu' not in configured_sources:
recommended.append('feishu')
if 'hn' not in [s.split('_')[0] for s in configured_sources]:
recommended.append('hn')
reasoning_parts.append("建议配置基础集成源以启动 AI 主动捕获能力")
reasoning = ";".join(reasoning_parts) if reasoning_parts else "所有基础集成已配置,AI 主动捕获能力已全面启用"
# 估算影响
impact_levels = {
0: "暂无明显影响",
1: "预计每周节省 2 小时手动录入时间",
2: "预计每周节省 4 小时手动录入时间,捕获 10+ 个需求信号",
3: "预计每周节省 6 小时会议时间,自动对齐 5+ 个认知冲突",
4: "预计每周节省 8 小时会议时间,主动捕获 20+ 个需求信号"
}
impact = impact_levels.get(len(recommended), impact_levels[4])
return {
'recommended_sources': recommended,
'reasoning': reasoning,
'estimated_impact': impact,
'current_config': {
'feishu_configured': 'feishu' in configured_sources,
'hn_configured': any('hn' in s for s in configured_sources),
'github_configured': any('github' in s for s in configured_sources),
'browser_installed': False # 需要前端检测
}
}