82 lines
3.0 KiB
Python
82 lines
3.0 KiB
Python
"""Repository for Insight Feedback database operations."""
|
|
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select, and_, desc
|
|
from typing import Optional, List
|
|
from uuid import UUID
|
|
from decimal import Decimal
|
|
|
|
from app.models.insight_feedback import InsightFeedback
|
|
from app.schemas.feedback import InsightFeedbackCreate
|
|
|
|
|
|
class FeedbackRepository:
|
|
"""Repository for Insight Feedback operations."""
|
|
|
|
def __init__(self, session: AsyncSession):
|
|
self.session = session
|
|
|
|
async def create(self, feedback_data: InsightFeedbackCreate) -> InsightFeedback:
|
|
"""Create feedback for an insight."""
|
|
# Calculate variance if both values provided
|
|
variance = None
|
|
if (feedback_data.expected_impact_value is not None and
|
|
feedback_data.actual_impact_value is not None and
|
|
feedback_data.expected_impact_value != 0):
|
|
variance = (
|
|
(feedback_data.actual_impact_value - feedback_data.expected_impact_value) /
|
|
feedback_data.expected_impact_value * 100
|
|
)
|
|
|
|
feedback = InsightFeedback(
|
|
**feedback_data.model_dump(exclude={'variance_percentage'}),
|
|
variance_percentage=variance
|
|
)
|
|
self.session.add(feedback)
|
|
await self.session.flush()
|
|
await self.session.refresh(feedback)
|
|
return feedback
|
|
|
|
async def get_by_id(self, feedback_id: UUID) -> Optional[InsightFeedback]:
|
|
"""Get feedback by ID."""
|
|
query = select(InsightFeedback).where(InsightFeedback.id == feedback_id)
|
|
result = await self.session.execute(query)
|
|
return result.scalar_one_or_none()
|
|
|
|
async def get_by_insight(self, insight_id: UUID) -> List[InsightFeedback]:
|
|
"""Get all feedback for an insight."""
|
|
query = select(InsightFeedback).where(
|
|
InsightFeedback.insight_id == insight_id
|
|
).order_by(desc(InsightFeedback.created_at))
|
|
|
|
result = await self.session.execute(query)
|
|
return list(result.scalars().all())
|
|
|
|
async def get_success_rate(self, insight_type: Optional[str] = None) -> float:
|
|
"""Calculate success rate for insights."""
|
|
query = select(InsightFeedback)
|
|
|
|
result = await self.session.execute(query)
|
|
feedbacks = result.scalars().all()
|
|
|
|
if not feedbacks:
|
|
return 0.0
|
|
|
|
successful = sum(1 for f in feedbacks if f.success)
|
|
return (successful / len(feedbacks)) * 100
|
|
|
|
async def get_average_impact_variance(self) -> Decimal:
|
|
"""Calculate average variance between expected and actual impact."""
|
|
query = select(InsightFeedback).where(
|
|
InsightFeedback.variance_percentage.isnot(None)
|
|
)
|
|
|
|
result = await self.session.execute(query)
|
|
feedbacks = result.scalars().all()
|
|
|
|
if not feedbacks:
|
|
return Decimal('0.0')
|
|
|
|
avg_variance = sum(f.variance_percentage for f in feedbacks) / len(feedbacks)
|
|
return Decimal(str(round(float(avg_variance), 2)))
|