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

79
backend/app/crud/bet.py Normal file
View File

@ -0,0 +1,79 @@
from sqlalchemy import select, or_
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from app.models import Bet, BetStatus, BetCategory
from app.schemas.bet import BetCreate
async def get_bet_by_id(db: AsyncSession, bet_id: int) -> Bet | None:
result = await db.execute(
select(Bet)
.options(
selectinload(Bet.creator),
selectinload(Bet.opponent)
)
.where(Bet.id == bet_id)
)
return result.scalar_one_or_none()
async def get_open_bets(
db: AsyncSession,
skip: int = 0,
limit: int = 20,
category: BetCategory | None = None,
) -> list[Bet]:
query = select(Bet).where(Bet.status == BetStatus.OPEN)
if category:
query = query.where(Bet.category == category)
query = query.options(
selectinload(Bet.creator)
).offset(skip).limit(limit).order_by(Bet.created_at.desc())
result = await db.execute(query)
return list(result.scalars().all())
async def get_user_bets(
db: AsyncSession,
user_id: int,
status: BetStatus | None = None,
) -> list[Bet]:
query = select(Bet).where(
or_(Bet.creator_id == user_id, Bet.opponent_id == user_id)
)
if status:
query = query.where(Bet.status == status)
query = query.options(
selectinload(Bet.creator),
selectinload(Bet.opponent)
).order_by(Bet.created_at.desc())
result = await db.execute(query)
return list(result.scalars().all())
async def create_bet(db: AsyncSession, bet_data: BetCreate, user_id: int) -> Bet:
bet = Bet(
creator_id=user_id,
title=bet_data.title,
description=bet_data.description,
category=bet_data.category,
event_name=bet_data.event_name,
event_date=bet_data.event_date,
creator_position=bet_data.creator_position,
opponent_position=bet_data.opponent_position,
creator_odds=bet_data.creator_odds,
opponent_odds=bet_data.opponent_odds,
stake_amount=bet_data.stake_amount,
visibility=bet_data.visibility,
expires_at=bet_data.expires_at,
)
db.add(bet)
await db.flush()
await db.refresh(bet)
return bet

56
backend/app/crud/user.py Normal file
View File

@ -0,0 +1,56 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models import User, Wallet
from app.schemas.user import UserCreate
from app.utils.security import get_password_hash
from decimal import Decimal
async def get_user_by_id(db: AsyncSession, user_id: int) -> User | None:
result = await db.execute(select(User).where(User.id == user_id))
return result.scalar_one_or_none()
async def get_user_by_email(db: AsyncSession, email: str) -> User | None:
result = await db.execute(select(User).where(User.email == email))
return result.scalar_one_or_none()
async def get_user_by_username(db: AsyncSession, username: str) -> User | None:
result = await db.execute(select(User).where(User.username == username))
return result.scalar_one_or_none()
async def create_user(db: AsyncSession, user_data: UserCreate) -> User:
user = User(
email=user_data.email,
username=user_data.username,
password_hash=get_password_hash(user_data.password),
display_name=user_data.display_name or user_data.username,
)
db.add(user)
await db.flush()
# Create wallet for user
wallet = Wallet(
user_id=user.id,
balance=Decimal("0.00"),
escrow=Decimal("0.00"),
)
db.add(wallet)
await db.flush()
await db.refresh(user)
return user
async def update_user_stats(db: AsyncSession, user_id: int, won: bool) -> None:
user = await get_user_by_id(db, user_id)
if user:
user.total_bets += 1
if won:
user.wins += 1
else:
user.losses += 1
user.win_rate = user.wins / user.total_bets if user.total_bets > 0 else 0.0
await db.flush()

View File

@ -0,0 +1,54 @@
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from decimal import Decimal
from app.models import Wallet, Transaction, TransactionType, TransactionStatus
async def get_user_wallet(db: AsyncSession, user_id: int) -> Wallet | None:
result = await db.execute(
select(Wallet).where(Wallet.user_id == user_id)
)
return result.scalar_one_or_none()
async def get_wallet_transactions(
db: AsyncSession,
user_id: int,
limit: int = 50,
offset: int = 0
) -> list[Transaction]:
result = await db.execute(
select(Transaction)
.where(Transaction.user_id == user_id)
.order_by(Transaction.created_at.desc())
.limit(limit)
.offset(offset)
)
return list(result.scalars().all())
async def create_transaction(
db: AsyncSession,
user_id: int,
wallet_id: int,
transaction_type: TransactionType,
amount: Decimal,
balance_after: Decimal,
description: str,
reference_id: int | None = None,
status: TransactionStatus = TransactionStatus.COMPLETED,
) -> Transaction:
transaction = Transaction(
user_id=user_id,
wallet_id=wallet_id,
type=transaction_type,
amount=amount,
balance_after=balance_after,
reference_id=reference_id,
description=description,
status=status,
)
db.add(transaction)
await db.flush()
return transaction