Add cap_percent field to track CAP percentage at match completion

- Add cap_percent field to MatchModel database schema (default: 70.0)
- Save cap_percent when match completes in games_thread.py
- Include cap_percent in reports sync request payload
- Add Migration_041_AddCapPercentToMatches for database migration

This ensures historical tracking of the CAP percentage configured at the moment each match ends, allowing for accurate analysis and reporting.
parent 9cbf87d3
......@@ -1187,9 +1187,10 @@ class ReportsSyncResponseHandler(ResponseHandler):
# Add extraction stats (only new/updated stats)
for stat in stats_to_sync:
# Get the match to retrieve the stored accumulated shortfall at completion time
# Get the match to retrieve the stored accumulated shortfall and cap_percent at completion time
match = session.query(MatchModel).filter_by(id=stat.match_id).first()
accumulated_shortfall = float(match.accumulated_shortfall) if match and match.accumulated_shortfall is not None else 0.0
cap_percent = float(match.cap_percent) if match and match.cap_percent is not None else 70.0
stat_data = {
'match_id': stat.match_id,
......@@ -1207,7 +1208,8 @@ class ReportsSyncResponseHandler(ResponseHandler):
'over_bets': stat.over_bets,
'over_amount': float(stat.over_amount),
'result_breakdown': stat.result_breakdown,
'accumulated_shortfall': accumulated_shortfall # Historical value at match completion
'accumulated_shortfall': accumulated_shortfall, # Historical value at match completion
'cap_percent': cap_percent # CAP percentage configured at match completion time
}
report_data['extraction_stats'].append(stat_data)
......
......@@ -3175,6 +3175,11 @@ class GamesThread(ThreadedComponent):
accumulated_shortfall = self._get_global_redistribution_adjustment(session)
match.accumulated_shortfall = accumulated_shortfall
logger.info(f"💰 [SHORTFALL TRACKING] Stored accumulated shortfall {accumulated_shortfall:.2f} in match {match_id} at completion time")
# Store the CAP percentage configured at the time of match completion
cap_percentage = self._get_redistribution_cap()
match.cap_percent = cap_percentage
logger.info(f"🎯 [CAP TRACKING] Stored CAP percentage {cap_percentage:.2f}% in match {match_id} at completion time")
# Calculate statistics (excluding cancelled bets)
total_bets = session.query(BetDetailModel).join(MatchModel).filter(
......
......@@ -2981,6 +2981,44 @@ class Migration_040_AddAccumulatedShortfallToMatches(DatabaseMigration):
return True
class Migration_041_AddCapPercentToMatches(DatabaseMigration):
"""Add cap_percent field to matches table for storing CAP percentage at match completion"""
def __init__(self):
super().__init__("041", "Add cap_percent field to matches table")
def up(self, db_manager) -> bool:
"""Add cap_percent column to matches table"""
try:
with db_manager.engine.connect() as conn:
# Check if cap_percent column already exists
result = conn.execute(text("PRAGMA table_info(matches)"))
columns = [row[1] for row in result.fetchall()]
if 'cap_percent' not in columns:
# Add cap_percent column with default value 70.0
conn.execute(text("""
ALTER TABLE matches
ADD COLUMN cap_percent REAL DEFAULT 70.0 NOT NULL
"""))
conn.commit()
logger.info("cap_percent column added to matches table")
else:
logger.info("cap_percent column already exists in matches table")
return True
except Exception as e:
logger.error(f"Failed to add cap_percent field to matches: {e}")
return False
def down(self, db_manager) -> bool:
"""Remove cap_percent column - SQLite doesn't support DROP COLUMN easily"""
logger.warning("SQLite doesn't support DROP COLUMN - cap_percent column will remain")
return True
class Migration_036_AddMatchTemplatesTables(DatabaseMigration):
"""Add matches_templates and match_outcomes_templates tables for storing match templates"""
......@@ -3140,6 +3178,7 @@ MIGRATIONS: List[DatabaseMigration] = [
Migration_038_AddWin1Win2Associations(),
Migration_039_AddMatchNumberToBetDetails(),
Migration_040_AddAccumulatedShortfallToMatches(),
Migration_041_AddCapPercentToMatches(),
]
......
......@@ -496,6 +496,7 @@ class MatchModel(BaseModel):
status = Column(Enum('pending', 'scheduled', 'bet', 'ingame', 'done', 'cancelled', 'failed', 'paused'), default='pending', nullable=False, comment='Match status enum')
fixture_active_time = Column(Integer, nullable=True, comment='Unix timestamp when fixture became active on server')
accumulated_shortfall = Column(Float(precision=2), default=0.0, nullable=False, comment='Accumulated shortfall from redistribution at the time of match completion')
cap_percent = Column(Float(precision=2), default=70.0, nullable=False, comment='CAP percentage configured at the time of match completion')
# File metadata
filename = Column(String(1024), nullable=False, comment='Original fixture filename')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment