Files
bakery-ia/services/ai_insights/app/repositories/feedback_repository.py
2025-11-05 13:34:56 +01:00

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)))