This commit is contained in:
2026-01-02 10:43:20 -06:00
commit 14d9af3036
112 changed files with 14274 additions and 0 deletions

View File

@ -0,0 +1,19 @@
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
__all__ = [
"User",
"UserStatus",
"Wallet",
"Transaction",
"TransactionType",
"TransactionStatus",
"Bet",
"BetProposal",
"BetCategory",
"BetStatus",
"BetVisibility",
"ProposalStatus",
]

103
backend/app/models/bet.py Normal file
View File

@ -0,0 +1,103 @@
from sqlalchemy import ForeignKey, Numeric, String, DateTime, Enum, Float
from sqlalchemy.orm import Mapped, mapped_column, relationship
from datetime import datetime
from decimal import Decimal
import enum
from app.database import Base
class BetCategory(enum.Enum):
SPORTS = "sports"
ESPORTS = "esports"
POLITICS = "politics"
ENTERTAINMENT = "entertainment"
CUSTOM = "custom"
class BetStatus(enum.Enum):
OPEN = "open"
MATCHED = "matched"
IN_PROGRESS = "in_progress"
PENDING_RESULT = "pending_result"
COMPLETED = "completed"
CANCELLED = "cancelled"
DISPUTED = "disputed"
class BetVisibility(enum.Enum):
PUBLIC = "public"
PRIVATE = "private"
FRIENDS_ONLY = "friends_only"
class Bet(Base):
__tablename__ = "bets"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
creator_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
opponent_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True)
title: Mapped[str] = mapped_column(String(200))
description: Mapped[str] = mapped_column(String(2000))
category: Mapped[BetCategory] = mapped_column(Enum(BetCategory))
# Event info
event_name: Mapped[str] = mapped_column(String(200))
event_date: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
# Terms
creator_position: Mapped[str] = mapped_column(String(500))
opponent_position: Mapped[str] = mapped_column(String(500))
creator_odds: Mapped[float] = mapped_column(Float, default=1.0)
opponent_odds: Mapped[float] = mapped_column(Float, default=1.0)
# Stake
stake_amount: Mapped[Decimal] = mapped_column(Numeric(12, 2))
currency: Mapped[str] = mapped_column(String(3), default="USD")
status: Mapped[BetStatus] = mapped_column(Enum(BetStatus), default=BetStatus.OPEN)
visibility: Mapped[BetVisibility] = mapped_column(Enum(BetVisibility), default=BetVisibility.PUBLIC)
# Blockchain integration
blockchain_bet_id: Mapped[int | None] = mapped_column(nullable=True)
blockchain_tx_hash: Mapped[str | None] = mapped_column(String(66), nullable=True)
blockchain_status: Mapped[str | None] = mapped_column(String(20), nullable=True)
# Result
winner_id: Mapped[int | None] = mapped_column(ForeignKey("users.id"), nullable=True)
settled_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
settled_by: Mapped[str | None] = mapped_column(String(20), nullable=True)
expires_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
creator: Mapped["User"] = relationship(back_populates="created_bets", foreign_keys=[creator_id])
opponent: Mapped["User"] = relationship(back_populates="accepted_bets", foreign_keys=[opponent_id])
proposals: Mapped[list["BetProposal"]] = relationship(back_populates="bet")
class ProposalStatus(enum.Enum):
PENDING = "pending"
ACCEPTED = "accepted"
REJECTED = "rejected"
EXPIRED = "expired"
class BetProposal(Base):
__tablename__ = "bet_proposals"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
bet_id: Mapped[int] = mapped_column(ForeignKey("bets.id"))
proposer_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
proposed_stake: Mapped[Decimal] = mapped_column(Numeric(12, 2))
proposed_creator_odds: Mapped[float] = mapped_column(Float)
proposed_opponent_odds: Mapped[float] = mapped_column(Float)
message: Mapped[str | None] = mapped_column(String(500), nullable=True)
status: Mapped[ProposalStatus] = mapped_column(Enum(ProposalStatus), default=ProposalStatus.PENDING)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
expires_at: Mapped[datetime] = mapped_column(DateTime)
# Relationships
bet: Mapped["Bet"] = relationship(back_populates="proposals")

View File

@ -0,0 +1,42 @@
from sqlalchemy import ForeignKey, Numeric, String, DateTime, Enum, Integer
from sqlalchemy.orm import Mapped, mapped_column, relationship
from datetime import datetime
from decimal import Decimal
import enum
from app.database import Base
class TransactionType(enum.Enum):
DEPOSIT = "deposit"
WITHDRAWAL = "withdrawal"
BET_PLACED = "bet_placed"
BET_WON = "bet_won"
BET_LOST = "bet_lost"
BET_CANCELLED = "bet_cancelled"
ESCROW_LOCK = "escrow_lock"
ESCROW_RELEASE = "escrow_release"
class TransactionStatus(enum.Enum):
PENDING = "pending"
COMPLETED = "completed"
FAILED = "failed"
class Transaction(Base):
__tablename__ = "transactions"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
wallet_id: Mapped[int] = mapped_column(ForeignKey("wallets.id"))
type: Mapped[TransactionType] = mapped_column(Enum(TransactionType))
amount: Mapped[Decimal] = mapped_column(Numeric(12, 2))
balance_after: Mapped[Decimal] = mapped_column(Numeric(12, 2))
reference_id: Mapped[int | None] = mapped_column(Integer, nullable=True)
description: Mapped[str] = mapped_column(String(500))
status: Mapped[TransactionStatus] = mapped_column(Enum(TransactionStatus), default=TransactionStatus.COMPLETED)
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
# Relationships
user: Mapped["User"] = relationship(back_populates="transactions")
wallet: Mapped["Wallet"] = relationship(back_populates="transactions")

View File

@ -0,0 +1,41 @@
from sqlalchemy import String, DateTime, Enum, Float, Integer
from sqlalchemy.orm import Mapped, mapped_column, relationship
from datetime import datetime
import enum
from app.database import Base
class UserStatus(enum.Enum):
ACTIVE = "active"
SUSPENDED = "suspended"
PENDING_VERIFICATION = "pending_verification"
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
email: Mapped[str] = mapped_column(String(255), unique=True, index=True)
username: Mapped[str] = mapped_column(String(50), unique=True, index=True)
password_hash: Mapped[str] = mapped_column(String(255))
# Profile fields
display_name: Mapped[str | None] = mapped_column(String(100), nullable=True)
avatar_url: Mapped[str | None] = mapped_column(String(500), nullable=True)
bio: Mapped[str | None] = mapped_column(String(500), nullable=True)
# Stats
total_bets: Mapped[int] = mapped_column(Integer, default=0)
wins: Mapped[int] = mapped_column(Integer, default=0)
losses: Mapped[int] = mapped_column(Integer, default=0)
win_rate: Mapped[float] = mapped_column(Float, default=0.0)
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)
# Relationships
wallet: Mapped["Wallet"] = relationship(back_populates="user", uselist=False)
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")

View File

@ -0,0 +1,22 @@
from sqlalchemy import ForeignKey, Numeric, String, DateTime
from sqlalchemy.orm import Mapped, mapped_column, relationship
from datetime import datetime
from decimal import Decimal
from app.database import Base
class Wallet(Base):
__tablename__ = "wallets"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), unique=True)
balance: Mapped[Decimal] = mapped_column(Numeric(12, 2), default=Decimal("0.00"))
escrow: Mapped[Decimal] = mapped_column(Numeric(12, 2), default=Decimal("0.00"))
blockchain_escrow: Mapped[Decimal] = mapped_column(Numeric(18, 8), default=Decimal("0.00000000"))
currency: Mapped[str] = mapped_column(String(3), default="USD")
created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)
updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
# Relationships
user: Mapped["User"] = relationship(back_populates="wallet")
transactions: Mapped[list["Transaction"]] = relationship(back_populates="wallet")