"""Signal feedback endpoints.""" from __future__ import annotations import json from typing import List from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.future import select from ...core.response import success_response from ...core.database import get_db from ...dependencies.auth import get_current_user from ...dependencies.tenant import get_tenant_id from ...models import Signal, SignalFeedback, User from ...schemas import SignalFeedbackCreate, SignalFeedbackResponse from ...services.feedback_center import FeedbackCenterService router = APIRouter() @router.post("/{signal_id}/feedback") async def submit_signal_feedback( signal_id: int, feedback: SignalFeedbackCreate, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_tenant_id), ): """提交信号反馈""" effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id) result = await db.execute( select(Signal).where( Signal.id == signal_id, Signal.tenant_id == effective_tenant_id, ) ) signal = result.scalar_one_or_none() if not signal: raise HTTPException(status_code=404, detail="Signal not found") ai_predicted_strategic = False ai_confidence = 0.0 if signal.strategic_analysis: try: analysis = json.loads(signal.strategic_analysis) ai_predicted_strategic = analysis.get("is_strategic", signal.impact_score >= 0.9) ai_confidence = analysis.get("confidence", 0.0) except Exception: ai_predicted_strategic = signal.impact_score >= 0.9 new_feedback = SignalFeedback( tenant_id=effective_tenant_id, signal_id=signal_id, was_strategic=feedback.was_strategic, reason=feedback.reason, user_id=str(getattr(current_user, "id", feedback.user_id) or feedback.user_id or ""), ai_predicted_strategic=ai_predicted_strategic, ai_confidence=ai_confidence, ) db.add(new_feedback) await db.commit() await db.refresh(new_feedback) try: await FeedbackCenterService(db).ingest_signal_feedback( signal_feedback=new_feedback, signal=signal, commit=True, ) except Exception: await db.rollback() is_correct = ai_predicted_strategic == feedback.was_strategic return success_response( SignalFeedbackResponse( id=new_feedback.id, signal_id=new_feedback.signal_id, was_strategic=new_feedback.was_strategic, ai_predicted_strategic=new_feedback.ai_predicted_strategic, ai_confidence=new_feedback.ai_confidence or 0.0, is_correct=is_correct, ).model_dump() ) @router.get("/{signal_id}/feedbacks") async def get_signal_feedbacks( signal_id: int, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db), tenant_id: int = Depends(get_tenant_id), ): """获取某信号的全部反馈""" effective_tenant_id = int(getattr(current_user, "tenant_id", tenant_id) or tenant_id) result = await db.execute( select(SignalFeedback) .where( SignalFeedback.signal_id == signal_id, SignalFeedback.tenant_id == effective_tenant_id, ) .order_by(SignalFeedback.created_at.desc()) ) feedbacks = result.scalars().all() items = [ SignalFeedbackResponse( id=feedback.id, signal_id=feedback.signal_id, was_strategic=feedback.was_strategic, ai_predicted_strategic=feedback.ai_predicted_strategic, ai_confidence=feedback.ai_confidence or 0.0, is_correct=feedback.ai_predicted_strategic == feedback.was_strategic, ).model_dump() for feedback in feedbacks ] return success_response({"items": items})