A comprehensive food logging and macro tracking system that allows users to track their daily nutrition intake from multiple sources: USDA database foods, barcode-scanned products, AI-analyzed food photos, and scheduled meal plans.
external type foods from Edamam APIExternalFoodMapping tableai-generated type food items with estimated portionsScheduledMealDeletion| Type | Source | Food ID | Portion Options | Use Case |
|------|--------|---------|----------------|----------|
| branded | USDA FDC (branded foods) | Database food ID | Multiple predefined portions | Packaged products with barcodes |
| foundation_foods | USDA FDC (foundation) | Database food ID | Multiple predefined portions | Basic whole foods (e.g., chicken breast) |
| sr_legacy | USDA SR Legacy | Database food ID | Multiple predefined portions | Legacy standard reference foods |
| external | Edamam API | Database food ID | API-provided + 100g default | Barcode scanned items not in USDA |
| ai-generated | AI image analysis | null | Estimated portions | Photo-analyzed foods |
| recipe | Scheduled meal plans | mealPlanDayRecipeId | Serving | Meal plan recipes |
foodId, stored in Food table with portions in FoodPortionfoodId, portions created dynamically per log, identified by name onlyMealPlanDayRecipe, includes ingredient lists and instructionsisDefault flag for UI pre-selectionlogged_* fields) for historical accuracyfoodId to support recipes and AI itemsname storage for all typesisDeleted)MealPlanWeek_macro-tracking+/
├── api.mobile.macro-tracking.food-item/ # Food search
│ ├── food-search.db.server.ts # FTS queries
│ ├── food-search.service.server.ts # Ranking logic
│ └── route.ts
│
├── api.mobile.macro-tracking.barcode/ # Barcode scanning
│ ├── barcode.db.server.ts # External food creation
│ ├── barcode.service.server.ts # Edamam integration
│ └── route.tsx
│
├── api.mobile.macro-tracking.analyze-image/ # AI analysis
│ ├── analyze-image.service.server.ts # Gemini AI integration
│ └── route.ts
│
├── api.mobile.macro-tracking.log/ # Create food logs
│ ├── log.db.server.ts # Validation queries
│ ├── log.service.server.ts # Log creation logic
│ └── route.ts
│
├── api.mobile.macro-tracking.log.$logId/ # Edit/delete logs
│ ├── log-edit.db.server.ts
│ ├── log-edit.service.server.ts
│ └── route.tsx
│
├── api.mobile.macro-tracking.logs/ # Get logs by date
│ ├── logs.db.server.ts # Main caching layer
│ └── route.ts
│
├── api.mobile.macro-tracking.suggestions/ # Quick-add suggestions
│ ├── suggestions.db.server.ts
│ ├── suggestions.service.server.ts # Deduplication
│ └── route.ts
│
├── api.mobile.macro-tracking.day-completion/ # Mark day complete
│ ├── day-completion.db.server.ts
│ ├── day-completion.service.server.ts
│ └── route.ts
│
├── api.mobile.macro-tracking.meal-plan.*/ # Meal plan scheduling
│ ├── schedule/ # Create schedule
│ ├── scheduled/ # Get scheduled meals
│ ├── dates/ # Get scheduled dates
│ ├── delete-scheduled/ # Mark meal as deleted
│ └── previous-recipes/ # Recipe history
│
├── helpers/
│ └── macro-tracking-types.ts # Zod schemas & types
│
├── macro-tracking-cache-keys.ts # Centralized cache keys
├── macro-tracking.service.server.ts # Shared utilities
└── CACHING-STRATEGY.md # Caching documentation
Redis (via Cachified) - High-frequency data
Prisma Accelerate - Stable data
forceFresh: true for background refreshSee CACHING-STRATEGY.md for detailed documentation.
All data flows through Zod schemas:
Example:
export const loggedFoodItemSchema = z.discriminatedUnion("type", [
foodLogEntrySchema, // Database foods
recipeLogEntrySchema, // Recipes
aiGeneratedLogEntrySchema, // AI items
]);
ExternalFoodMapping for existing itemFood + FoodPortion + ExternalFoodMappingai-generated food itemsScheduledMealPlan entryScheduledMealDeletion for conflictsYYYY-MM-DD format