Add AI-powered nutrition and plan modules

Introduces DSPy-based nutrition and plan generation modules, including image analysis for nutritional info and personalized diet/exercise plans. Adds new API endpoints for health metrics/goals, nutrition image analysis, and plan management. Updates models, schemas, and backend structure to support these features, and includes initial training data and configuration for prompt optimization.
This commit is contained in:
Carlos Escalante
2026-01-18 17:14:56 -06:00
parent 5dc6dc88f7
commit 184c8330a7
36 changed files with 2868 additions and 110 deletions

View File

@@ -1,8 +1,10 @@
from datetime import datetime
from typing import Optional, List, Dict
from sqlmodel import Field, SQLModel, JSON
from typing import Dict, List, Optional
from pgvector.sqlalchemy import Vector
from sqlalchemy import Column
from sqlmodel import JSON, Field, SQLModel
class FoodItem(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
@@ -12,13 +14,14 @@ class FoodItem(SQLModel, table=True):
carbs: float
fats: float
micros: Dict = Field(default={}, sa_column=Column(JSON))
embedding: List[float] = Field(sa_column=Column(Vector(1536))) # OpenAI embedding size
embedding: List[float] = Field(sa_column=Column(Vector(1536))) # OpenAI embedding size
class FoodLog(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
user_id: int = Field(foreign_key="user.id")
food_item_id: Optional[int] = Field(default=None, foreign_key="fooditem.id")
name: str # In case no food item is linked or custom entry
name: str # In case no food item is linked or custom entry
calories: float
protein: float
carbs: float

View File

@@ -1,19 +1,22 @@
from datetime import datetime
from typing import Optional
from sqlmodel import Field, SQLModel
class HealthMetric(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
user_id: int = Field(foreign_key="user.id")
metric_type: str = Field(index=True) # e.g., "weight", "cholesterol", "testosterone"
metric_type: str = Field(index=True) # e.g., "weight", "cholesterol", "testosterone"
value: float
unit: str
timestamp: datetime = Field(default_factory=datetime.utcnow)
class HealthGoal(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
user_id: int = Field(foreign_key="user.id")
goal_type: str # e.g., "lose_weight", "gain_muscle"
goal_type: str # e.g., "lose_weight", "gain_muscle"
target_value: float
target_date: Optional[datetime] = None
created_at: datetime = Field(default_factory=datetime.utcnow)

View File

@@ -0,0 +1,13 @@
from datetime import datetime
from typing import Optional
from sqlmodel import JSON, Field, SQLModel
class Plan(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
user_id: int = Field(foreign_key="user.id")
goal: str = Field(index=True) # e.g., "lose weight", "gain muscle"
content: str = Field(description="The full plan content in markdown or text")
structured_content: dict = Field(default={}, sa_type=JSON) # For UI rendering
created_at: datetime = Field(default_factory=datetime.utcnow)

View File

@@ -1,7 +1,9 @@
from datetime import datetime
from typing import Optional
from sqlmodel import Field, SQLModel
class User(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
username: str = Field(index=True, unique=True)