from fastapi import APIRouter, Header, HTTPException, Depends from pydantic import BaseModel from sqlalchemy import select from app.config import AGENT_API_KEY from app.models.base import async_session from app.models.user import User from app.models.workout import Workout, WorkoutSet from app.models.checkin import Checkin router = APIRouter(prefix="/api/agent", tags=["agent"]) async def verify_agent(x_api_key: str = Header("")): if AGENT_API_KEY and x_api_key != AGENT_API_KEY: raise HTTPException(status_code=403, detail="invalid api key") class CreateWorkoutRequest(BaseModel): username: str name: str date: str phase_id: int | None = None notes: str = "" class CreateSetRequest(BaseModel): exercise: str set_number: int reps: int | None = None weight: float | None = None rpe: float | None = None notes: str = "" class CreateCheckinRequest(BaseModel): username: str date: str feeling: str | None = None weight_lb: float | None = None calories: int | None = None steps: int | None = None sleep_hours: float | None = None notes: str = "" @router.post("/workouts") async def agent_create_workout( body: CreateWorkoutRequest, _=Depends(verify_agent), ): async with async_session() as session: result = await session.execute( select(User).where(User.username == body.username) ) user = result.scalar_one_or_none() if not user: raise HTTPException(status_code=404, detail="user not found") workout = Workout( user_id=user.id, phase_id=body.phase_id, name=body.name, date=body.date, notes=body.notes, status="plan", ) session.add(workout) await session.commit() await session.refresh(workout) return {"id": workout.id, "name": workout.name, "date": workout.date, "status": workout.status} @router.post("/workouts/{workout_id}/sets") async def agent_add_set( workout_id: int, body: CreateSetRequest, _=Depends(verify_agent), ): async with async_session() as session: ws = WorkoutSet( workout_id=workout_id, exercise=body.exercise, set_number=body.set_number, reps=body.reps, weight=body.weight, rpe=body.rpe, notes=body.notes, ) session.add(ws) await session.commit() await session.refresh(ws) return {"id": ws.id, "exercise": ws.exercise, "set_number": ws.set_number} @router.put("/workouts/{workout_id}/complete") async def agent_complete_workout( workout_id: int, _=Depends(verify_agent), ): async with async_session() as session: result = await session.execute( select(Workout).where(Workout.id == workout_id) ) workout = result.scalar_one_or_none() if not workout: raise HTTPException(status_code=404, detail="workout not found") workout.status = "complete" await session.commit() return {"id": workout.id, "status": "complete"} @router.post("/checkins") async def agent_create_checkin( body: CreateCheckinRequest, _=Depends(verify_agent), ): async with async_session() as session: result = await session.execute( select(User).where(User.username == body.username) ) user = result.scalar_one_or_none() if not user: raise HTTPException(status_code=404, detail="user not found") checkin = Checkin( user_id=user.id, date=body.date, feeling=body.feeling, weight_lb=body.weight_lb, calories=body.calories, steps=body.steps, sleep_hours=body.sleep_hours, notes=body.notes, ) session.add(checkin) await session.commit() await session.refresh(checkin) return {"id": checkin.id, "date": checkin.date}