Skip to content

Latest commit

 

History

History
263 lines (217 loc) · 7.7 KB

File metadata and controls

263 lines (217 loc) · 7.7 KB

Phase 1A Implementation: Enhanced AI Extraction

Summary

Successfully implemented 13 new AI-extracted fields that provide deeper nutrition insights with zero additional user input. All data is automatically extracted from meal photos and descriptions.

What Was Changed

1. Database Schema (V11 Migration)

File: backend/src/main/resources/db/migration/V11__add_enhanced_ai_fields.sql

Added 13 new columns to meals table:

  • cooking_method - VARCHAR(50) - How food was prepared
  • nova_score - DECIMAL(3,2) - Food processing level (1-4)
  • is_ultra_processed - BOOLEAN - Quick UPF flag
  • is_fried - BOOLEAN - Fried food detection
  • has_refined_grains - BOOLEAN - White bread/rice/pasta
  • estimated_gi - INTEGER - Glycemic index (0-100)
  • estimated_gl - INTEGER - Glycemic load
  • plant_count - INTEGER - Number of unique plant species
  • unique_plants - JSONB - List of plant names
  • is_fermented - BOOLEAN - Fermented food flag
  • protein_source_type - VARCHAR(50) - animal/plant/dairy/seafood/mixed
  • fat_quality - VARCHAR(20) - healthy/neutral/unhealthy
  • meal_type_guess - VARCHAR(20) - breakfast/lunch/dinner/snack

2. Entity Layer

File: backend/src/main/java/com/nutritheous/meal/Meal.java

Added 13 new fields with proper JPA annotations and @Builder.Default for booleans.

3. DTO Layer

Files Updated:

  • backend/src/main/java/com/nutritheous/common/dto/AnalysisResponse.java - Added 13 fields
  • backend/src/main/java/com/nutritheous/common/dto/MealResponse.java - Added 13 fields

Both DTOs include proper @JsonProperty annotations for snake_case API responses.

4. Service Layer

File: backend/src/main/java/com/nutritheous/meal/MealService.java

Updated updateMealWithAnalysis() method to map all 13 new fields from AnalysisResponse to Meal entity.

5. AI Integration

File: backend/src/main/java/com/nutritheous/analyzer/OpenAIVisionService.java

Enhanced Prompts:

  • Image analysis prompt (getAnalysisPrompt) - Added detailed field definitions and examples
  • Text-only prompt (getTextOnlyPrompt) - Added same fields with text-based inference

Key Prompt Additions:

- cooking_method: raw/steamed/boiled/grilled/baked/fried/roasted/pressure_cooked/sauteed
- nova_score: 1-4 decimal (1=whole foods, 4=ultra-processed)
- estimated_gi/gl: Based on typical glycemic values
- plant_count: Count ALL distinct plant species
- unique_plants: List each plant by name
- is_fermented: yogurt, kimchi, sourdough, etc.
- protein_source_type: Categorize primary protein
- fat_quality: Based on fat sources and cooking method
- meal_type_guess: Infer from food types and portions

Parsing Logic:

  • Added getBooleanValue() helper method for safe boolean extraction
  • Updated parseResponse() to extract all 13 new fields
  • Graceful handling of missing/null values

6. Configuration

File: backend/src/main/resources/application.properties

Increased OpenAI max tokens: 8002000 to accommodate expanded JSON response.

New Data Examples

Example 1: Grilled Chicken & Broccoli

{
  "cooking_method": "grilled",
  "nova_score": 1.2,
  "is_ultra_processed": false,
  "is_fried": false,
  "has_refined_grains": false,
  "estimated_gi": 45,
  "estimated_gl": 13,
  "plant_count": 2,
  "unique_plants": ["broccoli", "garlic"],
  "is_fermented": false,
  "protein_source_type": "animal",
  "fat_quality": "healthy",
  "meal_type_guess": "dinner"
}

Example 2: Fast Food Burger & Fries

{
  "cooking_method": "fried",
  "nova_score": 3.8,
  "is_ultra_processed": true,
  "is_fried": true,
  "has_refined_grains": true,
  "estimated_gi": 78,
  "estimated_gl": 42,
  "plant_count": 3,
  "unique_plants": ["lettuce", "tomato", "potato"],
  "is_fermented": false,
  "protein_source_type": "animal",
  "fat_quality": "unhealthy",
  "meal_type_guess": "lunch"
}

How to Test

1. Run Database Migration

cd backend
./gradlew flywayMigrate

The V11 migration will add all 13 columns to existing meals table.

2. Start Backend

cd backend
./gradlew bootRun

3. Upload a Test Meal

curl -X POST http://localhost:8081/api/meals/upload \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -F "image=@/path/to/meal.jpg" \
  -F "description=grilled chicken with broccoli"

4. Verify New Fields in Response

{
  "id": "...",
  "calories": 450,
  "cooking_method": "grilled",
  "nova_score": 1.2,
  "estimated_gi": 45,
  "plant_count": 2,
  "unique_plants": ["broccoli", "garlic"],
  ...
}

API Response Changes

Before (800 token response):

{
  "calories": 450,
  "protein_g": 35,
  "carbohydrates_g": 28,
  "ingredients": ["chicken", "broccoli"],
  "confidence": 0.85
}

After (2000 token response):

{
  "calories": 450,
  "protein_g": 35,
  "carbohydrates_g": 28,
  "ingredients": ["chicken", "broccoli"],
  "confidence": 0.85,

  "cooking_method": "grilled",
  "nova_score": 1.2,
  "is_ultra_processed": false,
  "is_fried": false,
  "has_refined_grains": false,
  "estimated_gi": 45,
  "estimated_gl": 13,
  "plant_count": 2,
  "unique_plants": ["broccoli", "garlic"],
  "is_fermented": false,
  "protein_source_type": "animal",
  "fat_quality": "healthy",
  "meal_type_guess": "dinner"
}

Benefits

For Users:

  1. Processing Awareness - See NOVA scores and UPF flags
  2. Glycemic Control - GI/GL estimates for blood sugar management
  3. Plant Diversity Tracking - Count unique plants per day/week
  4. Quality Indicators - Fat quality and cooking method insights

For Future Features:

  1. Weekly Reports - "You averaged NOVA 2.1 this week (mostly whole foods!)"
  2. Plant Diversity Goals - "12/30 unique plants this week"
  3. Glycemic Patterns - "Your low-GI meals keep you fuller longer"
  4. Processing Trends - "Restaurant meals have 60% higher NOVA scores"

Cost Impact

  • Token increase: 800 → 2000 (+150% tokens)
  • Estimated cost per meal: ~$0.003 → ~$0.007 (still negligible)
  • For 1000 meals/month: ~$3 → ~$7 (+$4/month)

What's Next: Phase 1B

Phase 1B will add photo metadata extraction and location intelligence:

  1. Extract GPS coordinates from EXIF data
  2. Reverse geocode with Google Maps API
  3. Enhance AI prompts with location context ("taken at Chipotle")
  4. Better estimates for restaurant vs home-cooked meals

Estimated effort: 4-6 hours

Files Changed

New Files:

  • backend/src/main/resources/db/migration/V11__add_enhanced_ai_fields.sql

Modified Files:

  • backend/src/main/java/com/nutritheous/meal/Meal.java
  • backend/src/main/java/com/nutritheous/meal/MealService.java
  • backend/src/main/java/com/nutritheous/common/dto/AnalysisResponse.java
  • backend/src/main/java/com/nutritheous/common/dto/MealResponse.java
  • backend/src/main/java/com/nutritheous/analyzer/OpenAIVisionService.java
  • backend/src/main/resources/application.properties

Total lines changed: ~200 lines

Rollback Plan

If issues arise, rollback with:

-- Revert V11 migration
ALTER TABLE meals
  DROP COLUMN cooking_method,
  DROP COLUMN nova_score,
  DROP COLUMN is_ultra_processed,
  DROP COLUMN is_fried,
  DROP COLUMN has_refined_grains,
  DROP COLUMN estimated_gi,
  DROP COLUMN estimated_gl,
  DROP COLUMN plant_count,
  DROP COLUMN unique_plants,
  DROP COLUMN is_fermented,
  DROP COLUMN protein_source_type,
  DROP COLUMN fat_quality,
  DROP COLUMN meal_type_guess;

Then revert code changes via git.

Notes

  • All new fields are nullable - won't break existing meals
  • Existing meals can be re-analyzed to populate new fields
  • AI confidence scores may be lower for complex fields (GI/GL, NOVA)
  • Frontend can display these fields gradually (no big bang UI change needed)
  • Fields are future-proof - will improve as AI models improve