95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
|
|
"""
|
||
|
|
Fitness Tests Router - Fitness Test Recording & Norm Tracking
|
||
|
|
|
||
|
|
Endpoints for managing fitness tests:
|
||
|
|
- List fitness tests
|
||
|
|
- Record fitness test results
|
||
|
|
- Calculate norm categories
|
||
|
|
|
||
|
|
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=["fitness-tests"])
|
||
|
|
|
||
|
|
# ============================================================================
|
||
|
|
# Pydantic Models
|
||
|
|
# ============================================================================
|
||
|
|
|
||
|
|
class FitnessTestCreate(BaseModel):
|
||
|
|
"""Record fitness test result"""
|
||
|
|
test_type: str
|
||
|
|
result_value: float
|
||
|
|
result_unit: str
|
||
|
|
test_date: date
|
||
|
|
test_conditions: Optional[str] = None
|
||
|
|
|
||
|
|
# ============================================================================
|
||
|
|
# Endpoints
|
||
|
|
# ============================================================================
|
||
|
|
|
||
|
|
@router.get("/tests")
|
||
|
|
def list_fitness_tests(session: dict = Depends(require_auth)):
|
||
|
|
"""List all fitness tests"""
|
||
|
|
pid = session['profile_id']
|
||
|
|
|
||
|
|
with get_db() as conn:
|
||
|
|
cur = get_cursor(conn)
|
||
|
|
cur.execute("""
|
||
|
|
SELECT id, test_type, result_value, result_unit,
|
||
|
|
test_date, test_conditions, norm_category, created_at
|
||
|
|
FROM fitness_tests
|
||
|
|
WHERE profile_id = %s
|
||
|
|
ORDER BY test_date DESC
|
||
|
|
""", (pid,))
|
||
|
|
|
||
|
|
return [r2d(row) for row in cur.fetchall()]
|
||
|
|
|
||
|
|
@router.post("/tests")
|
||
|
|
def create_fitness_test(data: FitnessTestCreate, session: dict = Depends(require_auth)):
|
||
|
|
"""Record fitness test result"""
|
||
|
|
pid = session['profile_id']
|
||
|
|
|
||
|
|
with get_db() as conn:
|
||
|
|
cur = get_cursor(conn)
|
||
|
|
|
||
|
|
# Calculate norm category (simplified for now)
|
||
|
|
norm_category = _calculate_norm_category(
|
||
|
|
data.test_type,
|
||
|
|
data.result_value,
|
||
|
|
data.result_unit
|
||
|
|
)
|
||
|
|
|
||
|
|
cur.execute("""
|
||
|
|
INSERT INTO fitness_tests (
|
||
|
|
profile_id, test_type, result_value, result_unit,
|
||
|
|
test_date, test_conditions, norm_category
|
||
|
|
) VALUES (%s, %s, %s, %s, %s, %s, %s)
|
||
|
|
RETURNING id
|
||
|
|
""", (
|
||
|
|
pid, data.test_type, data.result_value, data.result_unit,
|
||
|
|
data.test_date, data.test_conditions, norm_category
|
||
|
|
))
|
||
|
|
|
||
|
|
test_id = cur.fetchone()['id']
|
||
|
|
|
||
|
|
return {"id": test_id, "norm_category": norm_category}
|
||
|
|
|
||
|
|
# ============================================================================
|
||
|
|
# Helper Functions
|
||
|
|
# ============================================================================
|
||
|
|
|
||
|
|
def _calculate_norm_category(test_type: str, value: float, unit: str) -> Optional[str]:
|
||
|
|
"""
|
||
|
|
Calculate norm category for fitness test
|
||
|
|
(Simplified - would need age/gender-specific norms)
|
||
|
|
"""
|
||
|
|
# Placeholder - should use proper norm tables
|
||
|
|
return None
|