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, )