PMFlow/backend/app/api/signals_api/list_create.py

107 lines
3.4 KiB
Python

"""Signal list/create/project-link endpoints."""
from __future__ import annotations
import json
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.future import select
from ...core.database import get_db
from ...models import Project, ProjectSignalLink, Signal
from ...schemas import SignalCreate
router = APIRouter()
@router.get("/")
async def list_signals(
roles: Optional[str] = Query(None, description="逗号分隔的角色列表,如 'frontend,backend'"),
db: AsyncSession = Depends(get_db),
):
"""获取信号列表,支持按角色过滤"""
result = await db.execute(select(Signal).order_by(Signal.impact_score.desc()))
signals = result.scalars().all()
if roles:
role_list = [r.strip() for r in roles.split(",")]
filtered_signals = []
for signal in signals:
tasks = []
if signal.tasks_generated:
try:
tasks = json.loads(signal.tasks_generated)
except Exception:
tasks = []
filtered_tasks = [task for task in tasks if task.get("type") in role_list]
if filtered_tasks:
signal_dict = {
"id": str(signal.id),
"source": signal.source,
"content": signal.content,
"impact_score": signal.impact_score,
"priority": signal.priority,
"processed": signal.processed,
"strategic_analysis": signal.strategic_analysis,
"tasks_generated": signal.tasks_generated,
"tasks_filtered": filtered_tasks,
"created_at": signal.created_at.isoformat() if signal.created_at else None,
}
filtered_signals.append(signal_dict)
return filtered_signals
return signals
@router.post("/", response_model=dict)
async def create_signal(signal: SignalCreate, db: AsyncSession = Depends(get_db)):
new_signal = Signal(
source=signal.source,
content=signal.content,
impact_score=signal.impact_score,
)
db.add(new_signal)
await db.commit()
await db.refresh(new_signal)
return {"id": str(new_signal.id), "status": "received"}
@router.get("/{signal_id}/projects")
async def get_signal_projects(
signal_id: str,
db: AsyncSession = Depends(get_db),
):
"""获取信号关联的项目"""
try:
sid = int(signal_id)
except (ValueError, TypeError):
raise HTTPException(status_code=400, detail="Invalid signal_id")
signal_result = await db.execute(select(Signal).where(Signal.id == sid))
if not signal_result.scalar_one_or_none():
raise HTTPException(status_code=404, detail="Signal not found")
result = await db.execute(
select(Project, ProjectSignalLink)
.join(ProjectSignalLink, Project.id == ProjectSignalLink.project_id)
.where(ProjectSignalLink.signal_id == sid)
)
rows = result.all()
return [
{
"id": str(project.id),
"title": project.title,
"status": project.status,
"assigned_role": project.assigned_role,
"link_type": link.link_type,
"relevance_score": link.relevance_score,
}
for project, link in rows
]