chartbastan/backend/app/models/energy_score.py
2026-02-01 09:31:38 +01:00

102 lines
4.3 KiB
Python

"""
SQLAlchemy model for energy scores.
This module defines the database model for storing energy score calculations
from multiple sources (Twitter, Reddit, RSS).
"""
from datetime import datetime
from sqlalchemy import Column, Integer, String, Float, DateTime, Index, ForeignKey, JSON
from sqlalchemy.orm import relationship
from app.database import Base
class EnergyScore(Base):
"""
Model for storing energy score calculations.
Attributes:
id: Primary key
match_id: Foreign key to the match
team_id: Foreign key to the team
score: Final energy score (0-100)
confidence: Confidence level (0-1)
sources_used: List of sources used in calculation (JSON)
twitter_score: Energy score from Twitter component
reddit_score: Energy score from Reddit component
rss_score: Energy score from RSS component
temporal_factor: Temporal weighting factor applied
twitter_weight: Adjusted weight for Twitter (in degraded mode)
reddit_weight: Adjusted weight for Reddit (in degraded mode)
rss_weight: Adjusted weight for RSS (in degraded mode)
created_at: Timestamp when the energy score was calculated
updated_at: Timestamp when the energy score was last updated
"""
__tablename__ = "energy_scores"
id = Column(Integer, primary_key=True, index=True)
match_id = Column(Integer, nullable=False, index=True, comment="ID of the match")
team_id = Column(Integer, nullable=False, index=True, comment="ID of the team")
score = Column(Float, nullable=False, index=True, comment="Final energy score (0-100)")
confidence = Column(Float, nullable=False, default=0.0, comment="Confidence level (0-1)")
# Sources used (stored as JSON array)
sources_used = Column(JSON, nullable=False, default=list, comment="List of sources used")
# Component scores
twitter_score = Column(Float, nullable=True, comment="Energy score from Twitter component")
reddit_score = Column(Float, nullable=True, comment="Energy score from Reddit component")
rss_score = Column(Float, nullable=True, comment="Energy score from RSS component")
# Temporal weighting
temporal_factor = Column(Float, nullable=True, comment="Temporal weighting factor applied")
# Adjusted weights (for degraded mode tracking)
twitter_weight = Column(Float, nullable=True, comment="Adjusted weight for Twitter")
reddit_weight = Column(Float, nullable=True, comment="Adjusted weight for Reddit")
rss_weight = Column(Float, nullable=True, comment="Adjusted weight for RSS")
# Timestamps
created_at = Column(DateTime, nullable=False, index=True, default=datetime.utcnow, comment="Creation timestamp")
updated_at = Column(DateTime, nullable=False, index=True, default=datetime.utcnow, onupdate=datetime.utcnow, comment="Last update timestamp")
# Indexes for performance
__table_args__ = (
Index('idx_energy_scores_match_team', 'match_id', 'team_id'),
Index('idx_energy_scores_score', 'score'),
Index('idx_energy_scores_confidence', 'confidence'),
Index('idx_energy_scores_created_at', 'created_at'),
Index('idx_energy_scores_updated_at', 'updated_at'),
)
def __repr__(self) -> str:
return (f"<EnergyScore(id={self.id}, match_id={self.match_id}, "
f"team_id={self.team_id}, score={self.score}, "
f"confidence={self.confidence})>")
def to_dict(self) -> dict:
"""
Convert energy score model to dictionary.
Returns:
Dictionary representation of the energy score
"""
return {
'id': self.id,
'match_id': self.match_id,
'team_id': self.team_id,
'score': self.score,
'confidence': self.confidence,
'sources_used': self.sources_used,
'twitter_score': self.twitter_score,
'reddit_score': self.reddit_score,
'rss_score': self.rss_score,
'temporal_factor': self.temporal_factor,
'twitter_weight': self.twitter_weight,
'reddit_weight': self.reddit_weight,
'rss_weight': self.rss_weight,
'created_at': self.created_at.isoformat() if self.created_at else None,
'updated_at': self.updated_at.isoformat() if self.updated_at else None
}