64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
import secrets
|
|
from datetime import UTC, datetime, timedelta
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException
|
|
|
|
from config import cfg
|
|
from core.deps import get_auth_context, get_service_identity
|
|
from db.session import UnitOfWork, get_uow
|
|
from repositories.link_codes import create_link_code, get_link_code_by_code, use_link_code
|
|
from repositories.users import UserRepository
|
|
from schemas.dto import AuthContext
|
|
from schemas.enums import LinkCodeStatus
|
|
from schemas.link_codes import LinkCodeConsume, LinkCodeResponse
|
|
from schemas.user import UserInfo
|
|
|
|
router = APIRouter(prefix="/link-codes")
|
|
|
|
|
|
@router.post("", response_model=LinkCodeResponse, status_code=201)
|
|
async def gen_link_code(
|
|
ctx: AuthContext = Depends(get_auth_context), uow: UnitOfWork = Depends(get_uow)
|
|
):
|
|
code = secrets.token_urlsafe(cfg.link_code_length)
|
|
exp = datetime.now(UTC) + timedelta(minutes=cfg.link_code_ttl)
|
|
link_code = await create_link_code(
|
|
uow, code=code, user_id=ctx.user.id, status=LinkCodeStatus.ACTIVE, expires_at=exp
|
|
)
|
|
await uow.commit()
|
|
|
|
return LinkCodeResponse(code=link_code.code, expires_at=link_code.expires_at)
|
|
|
|
|
|
@router.post("/consume", response_model=UserInfo)
|
|
async def consume_link_code(
|
|
payload: LinkCodeConsume,
|
|
ctx: AuthContext = Depends(get_service_identity),
|
|
uow: UnitOfWork = Depends(get_uow),
|
|
):
|
|
link_code = await get_link_code_by_code(uow, payload.code)
|
|
|
|
if not link_code:
|
|
raise HTTPException(404, detail="Code not found")
|
|
|
|
if link_code.status != LinkCodeStatus.ACTIVE:
|
|
raise HTTPException(404, detail="Code expired or is invalid.")
|
|
|
|
users_repo = UserRepository(uow)
|
|
user = await users_repo.get_user_by_id(link_code.user_id)
|
|
|
|
if not user:
|
|
raise HTTPException(404, detail="User not found")
|
|
|
|
user = await users_repo.update_telegram_id(user, payload.telegram_id)
|
|
|
|
await use_link_code(uow, code=link_code)
|
|
await uow.commit()
|
|
|
|
return UserInfo(
|
|
username=user.username,
|
|
telegram_id=user.telegram_id,
|
|
referal_code=user.referal_code,
|
|
bonus_balance=user.balance,
|
|
)
|