from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, desc from pydantic import BaseModel from typing import Optional, List from datetime import datetime from app.core.database import get_db from app.core.security import get_current_user from app.models.user import User, PersonalRecord, NamedRoute, HealthMetric, Activity router = APIRouter() # ─── Personal Records ──────────────────────────────────────────────────────── class PROut(BaseModel): id: int sport_type: str distance_m: float distance_label: str duration_s: float achieved_at: datetime activity_id: int class Config: from_attributes = True @router.get("/", response_model=List[PROut]) async def list_records( sport_type: Optional[str] = None, db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): q = select(PersonalRecord).where( PersonalRecord.user_id == current_user.id, PersonalRecord.is_current_record == True, ) if sport_type: q = q.where(PersonalRecord.sport_type == sport_type) q = q.order_by(PersonalRecord.distance_m) result = await db.execute(q) return result.scalars().all() @router.get("/routes") async def route_records( db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """Fastest activity per named route (course records).""" from sqlalchemy import text rows = await db.execute( text(""" SELECT DISTINCT ON (nr.id) nr.id AS route_id, nr.name AS route_name, nr.sport_type, nr.distance_m, nr.reference_polyline, a.id AS activity_id, a.name AS activity_name, a.duration_s, a.start_time, a.avg_speed_ms FROM named_routes nr JOIN activities a ON a.named_route_id = nr.id AND a.user_id = nr.user_id WHERE nr.user_id = :uid AND a.duration_s IS NOT NULL ORDER BY nr.id, a.duration_s ASC """), {"uid": current_user.id}, ) return [dict(r._mapping) for r in rows] @router.get("/history/{distance_label}") async def record_history( distance_label: str, sport_type: str = "running", db: AsyncSession = Depends(get_db), current_user: User = Depends(get_current_user), ): """Show progression of a PR over time.""" result = await db.execute( select(PersonalRecord).where( PersonalRecord.user_id == current_user.id, PersonalRecord.sport_type == sport_type, PersonalRecord.distance_label == distance_label, ).order_by(PersonalRecord.achieved_at) ) return result.scalars().all()