Files
game-marathon/backend/app/api/v1/feed.py
2025-12-14 02:42:32 +07:00

63 lines
1.7 KiB
Python

from fastapi import APIRouter
from sqlalchemy import select, func
from sqlalchemy.orm import selectinload
from app.api.deps import DbSession, CurrentUser
from app.models import Activity, Participant
from app.schemas import FeedResponse, ActivityResponse, UserPublic
router = APIRouter(tags=["feed"])
@router.get("/marathons/{marathon_id}/feed", response_model=FeedResponse)
async def get_feed(
marathon_id: int,
current_user: CurrentUser,
db: DbSession,
limit: int = 20,
offset: int = 0,
):
"""Get activity feed for marathon"""
# Check user is participant
result = await db.execute(
select(Participant).where(
Participant.user_id == current_user.id,
Participant.marathon_id == marathon_id,
)
)
if not result.scalar_one_or_none():
return FeedResponse(items=[], total=0, has_more=False)
# Get total count
total = await db.scalar(
select(func.count()).select_from(Activity).where(Activity.marathon_id == marathon_id)
)
# Get activities
result = await db.execute(
select(Activity)
.options(selectinload(Activity.user))
.where(Activity.marathon_id == marathon_id)
.order_by(Activity.created_at.desc())
.limit(limit)
.offset(offset)
)
activities = result.scalars().all()
items = [
ActivityResponse(
id=a.id,
type=a.type,
user=UserPublic.model_validate(a.user),
data=a.data,
created_at=a.created_at,
)
for a in activities
]
return FeedResponse(
items=items,
total=total,
has_more=(offset + limit) < total,
)