""" Training Phases Router - Training Phase Detection & Management Endpoints for managing training phases: - List training phases - Create manual training phases - Update phase status (accept/reject auto-detected phases) Part of v9h Goal System. """ from fastapi import APIRouter, Depends, HTTPException from pydantic import BaseModel from typing import Optional from datetime import date from db import get_db, get_cursor, r2d from auth import require_auth router = APIRouter(prefix="/api/goals", tags=["training-phases"]) # ============================================================================ # Pydantic Models # ============================================================================ class TrainingPhaseCreate(BaseModel): """Create training phase (manual or auto-detected)""" phase_type: str # calorie_deficit, calorie_surplus, deload, maintenance, periodization start_date: date end_date: Optional[date] = None notes: Optional[str] = None # ============================================================================ # Endpoints # ============================================================================ @router.get("/phases") def list_training_phases(session: dict = Depends(require_auth)): """List training phases""" pid = session['profile_id'] with get_db() as conn: cur = get_cursor(conn) cur.execute(""" SELECT id, phase_type, detected_automatically, confidence_score, status, start_date, end_date, duration_days, detection_params, notes, created_at FROM training_phases WHERE profile_id = %s ORDER BY start_date DESC """, (pid,)) return [r2d(row) for row in cur.fetchall()] @router.post("/phases") def create_training_phase(data: TrainingPhaseCreate, session: dict = Depends(require_auth)): """Create training phase (manual)""" pid = session['profile_id'] with get_db() as conn: cur = get_cursor(conn) duration = None if data.end_date: duration = (data.end_date - data.start_date).days cur.execute(""" INSERT INTO training_phases ( profile_id, phase_type, detected_automatically, status, start_date, end_date, duration_days, notes ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING id """, ( pid, data.phase_type, False, 'active', data.start_date, data.end_date, duration, data.notes )) phase_id = cur.fetchone()['id'] return {"id": phase_id, "message": "Trainingsphase erstellt"} @router.put("/phases/{phase_id}/status") def update_phase_status( phase_id: str, status: str, session: dict = Depends(require_auth) ): """Update training phase status (accept/reject auto-detected phases)""" pid = session['profile_id'] valid_statuses = ['suggested', 'accepted', 'active', 'completed', 'rejected'] if status not in valid_statuses: raise HTTPException( status_code=400, detail=f"Ungültiger Status. Erlaubt: {', '.join(valid_statuses)}" ) with get_db() as conn: cur = get_cursor(conn) cur.execute( "UPDATE training_phases SET status = %s WHERE id = %s AND profile_id = %s", (status, phase_id, pid) ) if cur.rowcount == 0: raise HTTPException(status_code=404, detail="Trainingsphase nicht gefunden") return {"message": "Status aktualisiert"}