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

252 lines
6.7 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 .schemas import BlockerResolveRequest, CodeCommentScanRequest, DailyBriefingResponse
@router.get("/daily-briefing")
async def get_daily_briefing(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
tenant_id: int = Depends(get_tenant_id)
):
"""
获取个性化每日简报
AI 为每个角色生成定制化简报,只包含:
- 与你相关的任务变更
- 风险提醒
- 需要对齐的事项
- 高影响信号
- 团队更新
彻底过滤无关信息,替代传统日报/周报
"""
try:
service = get_daily_briefing_service(db)
briefing = await service.generate_personalized_briefing(
user_id=int(current_user.id),
tenant_id=tenant_id
)
return briefing
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"生成简报失败: {str(e)}"
)
@router.get("/daily-briefing/team/{project_id}")
async def get_team_briefing(
project_id: int,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
tenant_id: int = Depends(get_tenant_id)
):
"""
获取团队简报(给管理者)
包含:
- 整体进度
- 每个成员的工作量
- 风险和阻塞
- 需要决策的事项
"""
try:
service = get_daily_briefing_service(db)
briefing = await service.generate_team_briefing(
project_id=project_id,
tenant_id=tenant_id
)
return briefing
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"生成团队简报失败: {str(e)}"
)
@router.post("/analyze-blocker")
async def analyze_blocker(
code_context: str,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
tenant_id: int = Depends(get_tenant_id)
):
"""
分析代码阻塞
当开发在代码注释中提到「这个接口达不到效果」时,
AI 自动触发分析,推荐替代方案或生成代码片段
"""
from ..services.llm import LLMService
service = get_ai_steward_service(db)
prompt = f"""分析以下代码/注释中提到的问题,提供解决方案:
代码上下文:
{code_context}
请提供:
1. 问题分析
2. 推荐的替代方案
3. 示例代码(如适用)
以 JSON 格式返回。"""
try:
llm = LLMService()
response = await llm.generate(
prompt,
db=db,
tenant_id=tenant_id,
)
return {
'analysis': response,
'suggestions': [],
'auto_generated': True
}
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"分析失败: {str(e)}"
)
@router.post("/blockers/scan-comment")
async def scan_code_comment_for_blockers(
request: CodeCommentScanRequest,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
tenant_id: int = Depends(get_tenant_id)
):
"""
扫描代码注释,检测阻塞
自动识别阻塞模式:
- "等待 X 接口完成"
- "这个 API 达不到效果"
- "由于 Y 的限制,暂时跳过"
如果检测到阻塞,AI 会自动:
1. 分析严重程度
2. 生成解决方案建议
3. 创建追踪任务(如需要)
"""
try:
service = get_blocker_detection_service(db)
result = await service.scan_code_comment(
code_content=request.code_content,
file_path=request.file_path,
line_number=request.line_number,
project_id=request.project_id,
user_id=int(current_user.id),
tenant_id=tenant_id
)
if result:
return {
'status': 'blocker_detected',
'blocker': result
}
return {
'status': 'no_blocker',
'message': '未检测到阻塞'
}
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"扫描失败: {str(e)}"
)
@router.post("/blockers/detect-tasks")
async def detect_task_blockers(
background_tasks: BackgroundTasks,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
tenant_id: int = Depends(get_tenant_id)
):
"""
检测所有任务中的阻塞
扫描所有超过3天未更新的进行中任务,
使用 AI 判断是否存在阻塞
"""
try:
service = get_blocker_detection_service(db)
blockers = await service.detect_task_blockers(tenant_id=tenant_id)
return {
'total_detected': len(blockers),
'blockers': blockers
}
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"检测失败: {str(e)}"
)
@router.get("/blockers/active")
async def get_active_blockers(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
tenant_id: int = Depends(get_tenant_id)
):
"""
获取所有活跃的阻塞
返回所有未解决的阻塞,按严重程度排序
"""
try:
service = get_blocker_detection_service(db)
blockers = await service.get_active_blockers(tenant_id=tenant_id)
# 按严重程度排序
severity_order = {'high': 0, 'medium': 1, 'low': 2}
blockers.sort(key=lambda b: severity_order.get(b['severity'], 1))
return {
'total': len(blockers),
'blockers': blockers
}
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"获取失败: {str(e)}"
)
@router.post("/blockers/resolve")
async def resolve_blocker(
request: BlockerResolveRequest,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
tenant_id: int = Depends(get_tenant_id)
):
"""
标记阻塞为已解决
记录解决方案并关闭阻塞记录
"""
try:
service = get_blocker_detection_service(db)
result = await service.resolve_blocker(
blocker_id=request.blocker_id,
resolution_note=request.resolution_note,
tenant_id=tenant_id
)
return result
except ValueError as e:
raise HTTPException(status_code=404, detail=str(e))
except Exception as e:
raise HTTPException(
status_code=500,
detail=f"解决失败: {str(e)}"
)