diff --git a/backend/app/routers/sport_events.py b/backend/app/routers/sport_events.py index 3182673..8dc028c 100644 --- a/backend/app/routers/sport_events.py +++ b/backend/app/routers/sport_events.py @@ -23,6 +23,105 @@ def generate_spread_grid(min_spread: float, max_spread: float, increment: float return spreads +@router.get("/public", response_model=List[SportEventSchema]) +async def list_public_events( + skip: int = 0, + limit: int = 20, + db: AsyncSession = Depends(get_db) +): + """Public endpoint - no authentication required""" + result = await db.execute( + select(SportEvent) + .where(SportEvent.status == EventStatus.UPCOMING) + .order_by(SportEvent.game_time.asc()) + .offset(skip) + .limit(limit) + ) + return result.scalars().all() + + +@router.get("/public/{event_id}") +async def get_public_event_with_grid( + event_id: int, + db: AsyncSession = Depends(get_db) +): + """Public endpoint - shows event details and bet counts without requiring login""" + # Get event + result = await db.execute( + select(SportEvent).where(SportEvent.id == event_id) + ) + event = result.scalar_one_or_none() + if not event: + raise HTTPException(status_code=404, detail="Event not found") + + # Get admin settings for spread increment + settings_result = await db.execute(select(AdminSettings).limit(1)) + settings = settings_result.scalar_one_or_none() + increment = settings.spread_increment if settings else 0.5 + + # Generate spread grid + spreads = generate_spread_grid(event.min_spread, event.max_spread, increment) + + # Get existing bets for this event + bets_result = await db.execute( + select(SpreadBet) + .options(selectinload(SpreadBet.creator)) + .where( + and_( + SpreadBet.event_id == event_id, + SpreadBet.status.in_([SpreadBetStatus.OPEN, SpreadBetStatus.MATCHED]) + ) + ) + ) + bets = bets_result.scalars().all() + + # Build spread grid with bet info - public view (no can_take, limited info) + spread_grid = {} + for spread in spreads: + bets_at_spread = [b for b in bets if b.spread == spread] + if bets_at_spread: + spread_grid[str(spread)] = [ + { + "bet_id": bet.id, + "creator_id": bet.creator_id, + "creator_username": bet.creator.username, + "stake": float(bet.stake_amount), + "status": bet.status.value, + "team": bet.team.value, + "can_take": False # Public users can't take bets + } + for bet in bets_at_spread + ] + else: + spread_grid[str(spread)] = [] + + # Count open bets + open_bets_count = len([b for b in bets if b.status == SpreadBetStatus.OPEN]) + + return { + "id": event.id, + "sport": event.sport.value, + "home_team": event.home_team, + "away_team": event.away_team, + "official_spread": event.official_spread, + "game_time": event.game_time.isoformat(), + "venue": event.venue, + "league": event.league, + "min_spread": event.min_spread, + "max_spread": event.max_spread, + "min_bet_amount": event.min_bet_amount, + "max_bet_amount": event.max_bet_amount, + "status": event.status.value, + "final_score_home": event.final_score_home, + "final_score_away": event.final_score_away, + "created_by": event.created_by, + "created_at": event.created_at.isoformat(), + "updated_at": event.updated_at.isoformat(), + "spread_grid": spread_grid, + "open_bets_count": open_bets_count + } + + @router.get("", response_model=List[SportEventSchema]) async def list_upcoming_events( skip: int = 0,