Promocode system
This commit is contained in:
@@ -10,7 +10,7 @@ from app.api.deps import CurrentUser, DbSession, require_participant, require_ad
|
||||
from app.models import (
|
||||
User, Marathon, Participant, Assignment, AssignmentStatus,
|
||||
ShopItem, UserInventory, CoinTransaction, ShopItemType,
|
||||
CertificationStatus,
|
||||
CertificationStatus, Challenge, Game,
|
||||
)
|
||||
from app.schemas import (
|
||||
ShopItemResponse, ShopItemCreate, ShopItemUpdate,
|
||||
@@ -19,8 +19,9 @@ from app.schemas import (
|
||||
EquipItemRequest, EquipItemResponse,
|
||||
CoinTransactionResponse, CoinsBalanceResponse, AdminCoinsRequest,
|
||||
CertificationRequestSchema, CertificationReviewRequest, CertificationStatusResponse,
|
||||
ConsumablesStatusResponse, MessageResponse,
|
||||
ConsumablesStatusResponse, MessageResponse, SwapCandidate,
|
||||
)
|
||||
from app.schemas.user import UserPublic
|
||||
from app.services.shop import shop_service
|
||||
from app.services.coins import coins_service
|
||||
from app.services.consumables import consumables_service
|
||||
@@ -296,6 +297,91 @@ async def get_consumables_status(
|
||||
)
|
||||
|
||||
|
||||
@router.get("/copycat-candidates/{marathon_id}", response_model=list[SwapCandidate])
|
||||
async def get_copycat_candidates(
|
||||
marathon_id: int,
|
||||
current_user: CurrentUser,
|
||||
db: DbSession,
|
||||
):
|
||||
"""Get participants with active assignments available for copycat (no event required)"""
|
||||
result = await db.execute(select(Marathon).where(Marathon.id == marathon_id))
|
||||
marathon = result.scalar_one_or_none()
|
||||
if not marathon:
|
||||
raise HTTPException(status_code=404, detail="Marathon not found")
|
||||
|
||||
participant = await require_participant(db, current_user.id, marathon_id)
|
||||
|
||||
# Get all participants except current user with active assignments
|
||||
# Support both challenge assignments and playthrough assignments
|
||||
result = await db.execute(
|
||||
select(Participant, Assignment, Challenge, Game)
|
||||
.join(Assignment, Assignment.participant_id == Participant.id)
|
||||
.outerjoin(Challenge, Assignment.challenge_id == Challenge.id)
|
||||
.outerjoin(Game, Challenge.game_id == Game.id)
|
||||
.options(selectinload(Participant.user))
|
||||
.where(
|
||||
Participant.marathon_id == marathon_id,
|
||||
Participant.id != participant.id,
|
||||
Assignment.status == AssignmentStatus.ACTIVE.value,
|
||||
)
|
||||
)
|
||||
rows = result.all()
|
||||
|
||||
candidates = []
|
||||
for p, assignment, challenge, game in rows:
|
||||
# For playthrough assignments, challenge is None
|
||||
if assignment.is_playthrough:
|
||||
# Need to get game info for playthrough
|
||||
game_result = await db.execute(
|
||||
select(Game).where(Game.id == assignment.game_id)
|
||||
)
|
||||
playthrough_game = game_result.scalar_one_or_none()
|
||||
if playthrough_game:
|
||||
candidates.append(SwapCandidate(
|
||||
participant_id=p.id,
|
||||
user=UserPublic(
|
||||
id=p.user.id,
|
||||
nickname=p.user.nickname,
|
||||
avatar_url=p.user.avatar_url,
|
||||
role=p.user.role,
|
||||
telegram_avatar_url=p.user.telegram_avatar_url,
|
||||
created_at=p.user.created_at,
|
||||
equipped_frame=None,
|
||||
equipped_title=None,
|
||||
equipped_name_color=None,
|
||||
equipped_background=None,
|
||||
),
|
||||
challenge_title=f"Прохождение: {playthrough_game.title}",
|
||||
challenge_description=playthrough_game.playthrough_description or "Прохождение игры",
|
||||
challenge_points=playthrough_game.playthrough_points or 0,
|
||||
challenge_difficulty="medium",
|
||||
game_title=playthrough_game.title,
|
||||
))
|
||||
elif challenge and game:
|
||||
candidates.append(SwapCandidate(
|
||||
participant_id=p.id,
|
||||
user=UserPublic(
|
||||
id=p.user.id,
|
||||
nickname=p.user.nickname,
|
||||
avatar_url=p.user.avatar_url,
|
||||
role=p.user.role,
|
||||
telegram_avatar_url=p.user.telegram_avatar_url,
|
||||
created_at=p.user.created_at,
|
||||
equipped_frame=None,
|
||||
equipped_title=None,
|
||||
equipped_name_color=None,
|
||||
equipped_background=None,
|
||||
),
|
||||
challenge_title=challenge.title,
|
||||
challenge_description=challenge.description,
|
||||
challenge_points=challenge.points,
|
||||
challenge_difficulty=challenge.difficulty,
|
||||
game_title=game.title,
|
||||
))
|
||||
|
||||
return candidates
|
||||
|
||||
|
||||
# === Coins ===
|
||||
|
||||
@router.get("/balance", response_model=CoinsBalanceResponse)
|
||||
|
||||
Reference in New Issue
Block a user