Bet matching work done.
This commit is contained in:
@ -2,6 +2,9 @@ from app.models.user import User, UserStatus
|
||||
from app.models.wallet import Wallet
|
||||
from app.models.transaction import Transaction, TransactionType, TransactionStatus
|
||||
from app.models.bet import Bet, BetProposal, BetCategory, BetStatus, BetVisibility, ProposalStatus
|
||||
from app.models.sport_event import SportEvent, SportType, EventStatus
|
||||
from app.models.spread_bet import SpreadBet, SpreadBetStatus, TeamSide
|
||||
from app.models.admin_settings import AdminSettings
|
||||
|
||||
__all__ = [
|
||||
"User",
|
||||
@ -16,4 +19,11 @@ __all__ = [
|
||||
"BetStatus",
|
||||
"BetVisibility",
|
||||
"ProposalStatus",
|
||||
"SportEvent",
|
||||
"SportType",
|
||||
"EventStatus",
|
||||
"SpreadBet",
|
||||
"SpreadBetStatus",
|
||||
"TeamSide",
|
||||
"AdminSettings",
|
||||
]
|
||||
|
||||
20
backend/app/models/admin_settings.py
Normal file
20
backend/app/models/admin_settings.py
Normal file
@ -0,0 +1,20 @@
|
||||
from sqlalchemy import String, Float, Numeric, DateTime
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from app.database import Base
|
||||
|
||||
|
||||
class AdminSettings(Base):
|
||||
__tablename__ = "admin_settings"
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
||||
default_house_commission_percent: Mapped[Decimal] = mapped_column(Numeric(5, 2), default=Decimal("10.00"))
|
||||
default_min_bet_amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), default=Decimal("10.00"))
|
||||
default_max_bet_amount: Mapped[Decimal] = mapped_column(Numeric(12, 2), default=Decimal("1000.00"))
|
||||
default_min_spread: Mapped[float] = mapped_column(Float, default=-10.0)
|
||||
default_max_spread: Mapped[float] = mapped_column(Float, default=10.0)
|
||||
spread_increment: Mapped[float] = mapped_column(Float, default=0.5)
|
||||
platform_name: Mapped[str] = mapped_column(String(100), default="H2H Sports Betting")
|
||||
maintenance_mode: Mapped[bool] = mapped_column(default=False)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
50
backend/app/models/sport_event.py
Normal file
50
backend/app/models/sport_event.py
Normal file
@ -0,0 +1,50 @@
|
||||
from sqlalchemy import String, DateTime, Enum, Float, Integer, ForeignKey
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from datetime import datetime
|
||||
import enum
|
||||
from app.database import Base
|
||||
|
||||
|
||||
class SportType(enum.Enum):
|
||||
FOOTBALL = "football"
|
||||
BASKETBALL = "basketball"
|
||||
BASEBALL = "baseball"
|
||||
HOCKEY = "hockey"
|
||||
SOCCER = "soccer"
|
||||
|
||||
|
||||
class EventStatus(enum.Enum):
|
||||
UPCOMING = "upcoming"
|
||||
LIVE = "live"
|
||||
COMPLETED = "completed"
|
||||
CANCELLED = "cancelled"
|
||||
|
||||
|
||||
class SportEvent(Base):
|
||||
__tablename__ = "sport_events"
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
||||
sport: Mapped[SportType] = mapped_column(Enum(SportType))
|
||||
home_team: Mapped[str] = mapped_column(String(100))
|
||||
away_team: Mapped[str] = mapped_column(String(100))
|
||||
official_spread: Mapped[float] = mapped_column(Float)
|
||||
game_time: Mapped[datetime] = mapped_column(DateTime)
|
||||
venue: Mapped[str | None] = mapped_column(String(200), nullable=True)
|
||||
league: Mapped[str | None] = mapped_column(String(100), nullable=True)
|
||||
|
||||
# Spread betting config
|
||||
min_spread: Mapped[float] = mapped_column(Float, default=-10.0)
|
||||
max_spread: Mapped[float] = mapped_column(Float, default=10.0)
|
||||
min_bet_amount: Mapped[float] = mapped_column(Float, default=10.0)
|
||||
max_bet_amount: Mapped[float] = mapped_column(Float, default=1000.0)
|
||||
|
||||
status: Mapped[EventStatus] = mapped_column(Enum(EventStatus), default=EventStatus.UPCOMING)
|
||||
final_score_home: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
final_score_away: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
||||
|
||||
created_by: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
|
||||
# Relationships
|
||||
spread_bets: Mapped[list["SpreadBet"]] = relationship(back_populates="event")
|
||||
47
backend/app/models/spread_bet.py
Normal file
47
backend/app/models/spread_bet.py
Normal file
@ -0,0 +1,47 @@
|
||||
from sqlalchemy import String, DateTime, Enum, Float, Integer, ForeignKey, Numeric
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
import enum
|
||||
from app.database import Base
|
||||
|
||||
|
||||
class TeamSide(enum.Enum):
|
||||
HOME = "home"
|
||||
AWAY = "away"
|
||||
|
||||
|
||||
class SpreadBetStatus(enum.Enum):
|
||||
OPEN = "open"
|
||||
MATCHED = "matched"
|
||||
COMPLETED = "completed"
|
||||
CANCELLED = "cancelled"
|
||||
DISPUTED = "disputed"
|
||||
|
||||
|
||||
class SpreadBet(Base):
|
||||
__tablename__ = "spread_bets"
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
||||
event_id: Mapped[int] = mapped_column(ForeignKey("sport_events.id"))
|
||||
spread: Mapped[float] = mapped_column(Float)
|
||||
team: Mapped[TeamSide] = mapped_column(Enum(TeamSide))
|
||||
|
||||
creator_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
||||
taker_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True)
|
||||
|
||||
stake_amount: Mapped[Decimal] = mapped_column(Numeric(12, 2))
|
||||
house_commission_percent: Mapped[Decimal] = mapped_column(Numeric(5, 2), default=Decimal("10.00"))
|
||||
|
||||
status: Mapped[SpreadBetStatus] = mapped_column(Enum(SpreadBetStatus), default=SpreadBetStatus.OPEN)
|
||||
payout_amount: Mapped[Decimal | None] = mapped_column(Numeric(12, 2), nullable=True)
|
||||
winner_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True)
|
||||
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
|
||||
matched_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
||||
completed_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
|
||||
|
||||
# Relationships
|
||||
event: Mapped["SportEvent"] = relationship(back_populates="spread_bets")
|
||||
creator: Mapped["User"] = relationship(back_populates="created_spread_bets", foreign_keys=[creator_id])
|
||||
taker: Mapped["User"] = relationship(back_populates="taken_spread_bets", foreign_keys=[taker_id])
|
||||
@ -30,6 +30,9 @@ class User(Base):
|
||||
losses: Mapped[int] = mapped_column(Integer, default=0)
|
||||
win_rate: Mapped[float] = mapped_column(Float, default=0.0)
|
||||
|
||||
# Admin flag
|
||||
is_admin: Mapped[bool] = mapped_column(default=False)
|
||||
|
||||
status: Mapped[UserStatus] = mapped_column(Enum(UserStatus), default=UserStatus.ACTIVE)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
|
||||
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||
@ -39,3 +42,5 @@ class User(Base):
|
||||
created_bets: Mapped[list["Bet"]] = relationship(back_populates="creator", foreign_keys="Bet.creator_id")
|
||||
accepted_bets: Mapped[list["Bet"]] = relationship(back_populates="opponent", foreign_keys="Bet.opponent_id")
|
||||
transactions: Mapped[list["Transaction"]] = relationship(back_populates="user")
|
||||
created_spread_bets: Mapped[list["SpreadBet"]] = relationship(back_populates="creator", foreign_keys="SpreadBet.creator_id")
|
||||
taken_spread_bets: Mapped[list["SpreadBet"]] = relationship(back_populates="taker", foreign_keys="SpreadBet.taker_id")
|
||||
|
||||
Reference in New Issue
Block a user