{"openapi":"3.1.0","info":{"title":"FoodIntel API","description":"FoodIntel is an intelligent food recognition and nutritional analysis backend built with FastAPI, MongoDB, and PyTorch. It supports user authentication, image-based food prediction, nutrition estimation, health scoring, recommendations, meal history, and weekly reports. Nutritional outputs are estimates and must not be treated as medical advice.","contact":{"name":"FoodIntel Project Team","email":"project@example.com"},"license":{"name":"MIT"},"version":"1.0.0"},"paths":{"/":{"get":{"tags":["Project Page"],"summary":"Serve the FoodIntel project page","description":"Render the project status page with live API, database, and model state.","operationId":"project_page__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/health":{"get":{"tags":["Project Page","Health"],"summary":"Get health status","description":"Return the API, database, model, and environment status.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Health Health Get"}}}}}}},"/api/v1/auth/register":{"post":{"tags":["Authentication"],"summary":"Register a new user","description":"Create a FoodIntel user account, hash the password, and return a JWT access token.","operationId":"register_api_v1_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_AuthPayload_"}}}},"409":{"description":"Email already exists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/login":{"post":{"tags":["Authentication"],"summary":"Login user","description":"Authenticate a user with email and password, then return a JWT access token.","operationId":"login_api_v1_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_AuthPayload_"}}}},"401":{"description":"Invalid credentials.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/me":{"get":{"tags":["Authentication"],"summary":"Get current user","description":"Return the currently authenticated user from the Bearer token.","operationId":"me_api_v1_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_UserPublic_"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/users/me":{"get":{"tags":["Users"],"summary":"Get current user profile","description":"Return the authenticated user's profile.","operationId":"get_me_api_v1_users_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_UserPublic_"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]}]},"patch":{"tags":["Users"],"summary":"Update current user profile","description":"Update the authenticated user's personal profile fields.","operationId":"update_me_api_v1_users_me_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_UserPublic_"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/users/me/progress":{"get":{"tags":["Users"],"summary":"Get current user progress and badges","description":"Return the authenticated user's gamification progress, streaks, quests, and badges.","operationId":"get_my_progress_api_v1_users_me_progress_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_UserProgressPayload_"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/foods":{"get":{"tags":["Foods"],"summary":"List supported foods","description":"Return all supported foods with placeholder nutrition values per 100g.","operationId":"list_foods_api_v1_foods_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_FoodsListPayload_"}}}}}}},"/api/v1/foods/{slug}":{"get":{"tags":["Foods"],"summary":"Get food by slug","description":"Return a supported food item by slug.","operationId":"get_food_api_v1_foods__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_FoodPublic_"}}}},"404":{"description":"Food not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/foods/seed":{"post":{"tags":["Foods"],"summary":"Seed default foods","description":"Insert or update the development nutrition seed dataset for FoodIntel.","operationId":"seed_foods_api_v1_foods_seed_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_SeedResult_"}}}},"403":{"description":"Only available in development.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/predictions/supported-foods":{"get":{"tags":["Predictions"],"summary":"List model-supported food classes","description":"Return the food classes currently available in the loaded prediction model.","operationId":"supported_foods_api_v1_predictions_supported_foods_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Supported Foods Api V1 Predictions Supported Foods Get"}}}}}}},"/api/v1/predictions/image":{"post":{"tags":["Predictions"],"summary":"Upload an image for food prediction","description":"Accept a food image, run inference, estimate nutrition, compute health score, and save a meal log.","operationId":"predict_food_from_image_api_v1_predictions_image_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_predict_food_from_image_api_v1_predictions_image_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_PredictionResult_"}}}},"400":{"description":"Invalid image.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The model could not confidently identify a supported food.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"ML model unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/predictions/image-url":{"post":{"tags":["Predictions"],"summary":"Predict from a remote image URL","description":"Fetch a public image URL server-side, run inference, estimate nutrition, and save a meal log.","operationId":"predict_food_from_image_url_api_v1_predictions_image_url_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionImageUrlRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_PredictionResult_"}}}},"400":{"description":"Invalid image URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The model could not confidently identify a supported food.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"ML model unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/predictions/feedback":{"post":{"tags":["Predictions"],"summary":"Submit prediction feedback for retraining review","description":"Store user feedback for a predicted meal so it can be reviewed later and, once validated, exported into a retraining dataset. This does not auto-train the model.","operationId":"submit_prediction_feedback_api_v1_predictions_feedback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictionFeedbackRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_PredictionFeedbackPayload_"}}}},"400":{"description":"Invalid feedback payload.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Meal not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/meals":{"get":{"tags":["Meals"],"summary":"List meal history","description":"Return the authenticated user's meal history in reverse chronological order. Pass date (YYYY-MM-DD) to filter to a single day. Limit is capped at 500 when a date filter is provided.","operationId":"list_meals_api_v1_meals_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":10,"title":"Limit"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Skip"}},{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by date YYYY-MM-DD","title":"Date"},"description":"Filter by date YYYY-MM-DD"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_MealListPayload_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/meals/{meal_id}":{"get":{"tags":["Meals"],"summary":"Get meal log by id","description":"Return a single meal log belonging to the authenticated user.","operationId":"get_meal_api_v1_meals__meal_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"meal_id","in":"path","required":true,"schema":{"type":"string","title":"Meal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_MealLogPublic_"}}}},"404":{"description":"Meal not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Meals"],"summary":"Delete meal log","description":"Delete a meal log belonging to the authenticated user.","operationId":"delete_meal_api_v1_meals__meal_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"meal_id","in":"path","required":true,"schema":{"type":"string","title":"Meal Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_dict_"}}}},"404":{"description":"Meal not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/reports/weekly":{"get":{"tags":["Reports"],"summary":"Generate nutrition report for a date range","description":"Aggregate the authenticated user's meal logs for a given date range. Defaults to the current calendar month when no dates are provided. Pass start_date and end_date (YYYY-MM-DD) to query any custom range.","operationId":"get_weekly_report_api_v1_reports_weekly_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Start date YYYY-MM-DD","title":"Start Date"},"description":"Start date YYYY-MM-DD"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"End date YYYY-MM-DD","title":"End Date"},"description":"End date YYYY-MM-DD"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIResponse_WeeklyReportPayload_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"APIResponse_AuthPayload_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/AuthPayload"}},"type":"object","required":["message","data"],"title":"APIResponse[AuthPayload]"},"APIResponse_FoodPublic_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/FoodPublic"}},"type":"object","required":["message","data"],"title":"APIResponse[FoodPublic]"},"APIResponse_FoodsListPayload_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/FoodsListPayload"}},"type":"object","required":["message","data"],"title":"APIResponse[FoodsListPayload]"},"APIResponse_MealListPayload_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/MealListPayload"}},"type":"object","required":["message","data"],"title":"APIResponse[MealListPayload]"},"APIResponse_MealLogPublic_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/MealLogPublic"}},"type":"object","required":["message","data"],"title":"APIResponse[MealLogPublic]"},"APIResponse_PredictionFeedbackPayload_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/PredictionFeedbackPayload"}},"type":"object","required":["message","data"],"title":"APIResponse[PredictionFeedbackPayload]"},"APIResponse_PredictionResult_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/PredictionResult"}},"type":"object","required":["message","data"],"title":"APIResponse[PredictionResult]"},"APIResponse_SeedResult_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/SeedResult"}},"type":"object","required":["message","data"],"title":"APIResponse[SeedResult]"},"APIResponse_UserProgressPayload_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/UserProgressPayload"}},"type":"object","required":["message","data"],"title":"APIResponse[UserProgressPayload]"},"APIResponse_UserPublic_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/UserPublic"}},"type":"object","required":["message","data"],"title":"APIResponse[UserPublic]"},"APIResponse_WeeklyReportPayload_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"$ref":"#/components/schemas/WeeklyReportPayload"}},"type":"object","required":["message","data"],"title":"APIResponse[WeeklyReportPayload]"},"APIResponse_dict_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"type":"string","title":"Message"},"data":{"type":"object","title":"Data"}},"type":"object","required":["message","data"],"title":"APIResponse[dict]"},"AuthPayload":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"user":{"$ref":"#/components/schemas/UserPublic"}},"type":"object","required":["access_token","user"],"title":"AuthPayload"},"Body_predict_food_from_image_api_v1_predictions_image_post":{"properties":{"file":{"type":"string","format":"binary","title":"File","description":"Food image file in jpg, jpeg, png, or webp format."},"serving_size_g":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Serving Size G"}},"type":"object","required":["file"],"title":"Body_predict_food_from_image_api_v1_predictions_image_post"},"DailyCalorieTrendEntry":{"properties":{"date":{"type":"string","title":"Date"},"calories":{"type":"number","title":"Calories"},"meals":{"type":"integer","title":"Meals"}},"type":"object","required":["date","calories","meals"],"title":"DailyCalorieTrendEntry"},"ErrorResponse":{"properties":{"success":{"type":"boolean","title":"Success","default":false},"message":{"type":"string","title":"Message"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["message"],"title":"ErrorResponse"},"FoodPublic":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"category":{"type":"string","title":"Category"},"description":{"type":"string","title":"Description"},"default_serving_size_g":{"type":"number","exclusiveMinimum":0.0,"title":"Default Serving Size G"},"nutrition_per_100g":{"$ref":"#/components/schemas/NutritionValues"},"is_local_food":{"type":"boolean","title":"Is Local Food","default":true},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","name","slug","category","description","default_serving_size_g","nutrition_per_100g"],"title":"FoodPublic"},"FoodsListPayload":{"properties":{"items":{"items":{"$ref":"#/components/schemas/FoodPublic"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["items","total"],"title":"FoodsListPayload"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email","examples":["ada@example.com"]},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password","examples":["StrongPass123"]}},"type":"object","required":["email","password"],"title":"LoginRequest","example":{"email":"ada@example.com","password":"StrongPass123"}},"MacroTotals":{"properties":{"calories":{"type":"number","title":"Calories","default":0},"protein":{"type":"number","title":"Protein","default":0},"carbs":{"type":"number","title":"Carbs","default":0},"fat":{"type":"number","title":"Fat","default":0},"fiber":{"type":"number","title":"Fiber","default":0},"sugar":{"type":"number","title":"Sugar","default":0},"sodium":{"type":"number","title":"Sodium","default":0}},"type":"object","title":"MacroTotals"},"MealFeedbackPublic":{"properties":{"is_correct":{"type":"boolean","title":"Is Correct"},"status":{"type":"string","title":"Status"},"corrected_slug":{"type":"string","title":"Corrected Slug"},"corrected_food":{"type":"string","title":"Corrected Food"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"submitted_at":{"type":"string","format":"date-time","title":"Submitted At"}},"type":"object","required":["is_correct","status","corrected_slug","corrected_food","submitted_at"],"title":"MealFeedbackPublic"},"MealListPayload":{"properties":{"items":{"items":{"$ref":"#/components/schemas/MealLogPublic"},"type":"array","title":"Items"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"skip":{"type":"integer","title":"Skip"}},"type":"object","required":["items","total","limit","skip"],"title":"MealListPayload"},"MealLogPublic":{"properties":{"id":{"type":"string","title":"Id"},"user_id":{"type":"string","title":"User Id"},"food_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Food Id"},"image_url":{"type":"string","title":"Image Url"},"predicted_food":{"type":"string","title":"Predicted Food"},"predicted_slug":{"type":"string","title":"Predicted Slug"},"confidence":{"type":"number","title":"Confidence"},"serving_size_g":{"type":"number","exclusiveMinimum":0.0,"title":"Serving Size G"},"nutrition":{"$ref":"#/components/schemas/NutritionValues"},"health_score":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Health Score"},"recommendations":{"items":{"type":"string"},"type":"array","title":"Recommendations"},"model_version":{"type":"string","title":"Model Version"},"feedback":{"anyOf":[{"$ref":"#/components/schemas/MealFeedbackPublic"},{"type":"null"}]},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","user_id","image_url","predicted_food","predicted_slug","confidence","serving_size_g","nutrition","health_score","recommendations","model_version","created_at"],"title":"MealLogPublic","example":{"confidence":0.9432,"created_at":"2026-04-24T12:00:00Z","food_id":"6629a62f0d24ed2cf9f4d100","health_score":68,"id":"6629a62f0d24ed2cf9f4d550","image_url":"/uploads/sample.jpg","model_version":"mobilenet_v3_small-best","nutrition":{"calories":375,"carbs":70,"fat":10,"fiber":3.75,"protein":8.75,"sodium":750,"sugar":5},"predicted_food":"Jollof Rice","predicted_slug":"jollof_rice","recommendations":["Fiber is low, so the meal may be less filling and balanced."],"serving_size_g":250,"user_id":"6629a62f0d24ed2cf9f4d001"}},"NutritionValues":{"properties":{"calories":{"type":"number","title":"Calories","default":0},"protein":{"type":"number","title":"Protein","default":0},"carbs":{"type":"number","title":"Carbs","default":0},"fat":{"type":"number","title":"Fat","default":0},"fiber":{"type":"number","title":"Fiber","default":0},"sugar":{"type":"number","title":"Sugar","default":0},"sodium":{"type":"number","title":"Sodium","default":0},"iron":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Iron"},"calcium":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Calcium"},"vitamin_c":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Vitamin C"}},"type":"object","title":"NutritionValues"},"PredictionFeedbackPayload":{"properties":{"feedback_id":{"type":"string","title":"Feedback Id"},"meal_id":{"type":"string","title":"Meal Id"},"status":{"type":"string","title":"Status"},"retraining_triggered":{"type":"boolean","title":"Retraining Triggered","default":false},"retraining_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Retraining Status"},"retraining_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Retraining Message"}},"type":"object","required":["feedback_id","meal_id","status"],"title":"PredictionFeedbackPayload"},"PredictionFeedbackRequest":{"properties":{"meal_id":{"type":"string","title":"Meal Id","description":"Meal log ID for the prediction being reviewed."},"is_correct":{"type":"boolean","title":"Is Correct","description":"Whether the prediction was correct."},"corrected_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Corrected Slug","description":"Correct class slug if the prediction was wrong.","examples":["jollof_rice"]},"notes":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Notes","description":"Optional reviewer or user notes about the correction."}},"type":"object","required":["meal_id","is_correct"],"title":"PredictionFeedbackRequest"},"PredictionImageUrlRequest":{"properties":{"image_url":{"type":"string","title":"Image Url","description":"A publicly reachable food image URL, such as a Cloudinary unsigned upload URL.","examples":["https://res.cloudinary.com/demo/image/upload/sample.jpg"]},"serving_size_g":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Serving Size G","default":250,"examples":[250]}},"type":"object","required":["image_url"],"title":"PredictionImageUrlRequest"},"PredictionResult":{"properties":{"meal":{"$ref":"#/components/schemas/MealLogPublic"},"nutrition_available":{"type":"boolean","title":"Nutrition Available"},"notes":{"items":{"type":"string"},"type":"array","title":"Notes"}},"type":"object","required":["meal","nutrition_available"],"title":"PredictionResult"},"RegisterRequest":{"properties":{"full_name":{"type":"string","maxLength":120,"minLength":2,"title":"Full Name","examples":["Ada Obi"]},"email":{"type":"string","format":"email","title":"Email","examples":["ada@example.com"]},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password","examples":["StrongPass123"]}},"type":"object","required":["full_name","email","password"],"title":"RegisterRequest","example":{"email":"ada@example.com","full_name":"Ada Obi","password":"StrongPass123"}},"SeedResult":{"properties":{"inserted":{"type":"integer","title":"Inserted"},"updated":{"type":"integer","title":"Updated"}},"type":"object","required":["inserted","updated"],"title":"SeedResult"},"UserBadge":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"description":{"type":"string","title":"Description"},"unlocked":{"type":"boolean","title":"Unlocked"},"progress_current":{"type":"integer","title":"Progress Current"},"progress_target":{"type":"integer","title":"Progress Target"},"unlocked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Unlocked At"}},"type":"object","required":["id","label","description","unlocked","progress_current","progress_target"],"title":"UserBadge"},"UserProgressPayload":{"properties":{"level":{"type":"integer","title":"Level"},"xp_total":{"type":"integer","title":"Xp Total"},"xp_into_level":{"type":"integer","title":"Xp Into Level"},"xp_for_next_level":{"type":"integer","title":"Xp For Next Level"},"streak_days":{"type":"integer","title":"Streak Days"},"total_scans":{"type":"integer","title":"Total Scans"},"nutrition_ready_meals":{"type":"integer","title":"Nutrition Ready Meals"},"feedback_count":{"type":"integer","title":"Feedback Count"},"correction_count":{"type":"integer","title":"Correction Count"},"high_confidence_scans":{"type":"integer","title":"High Confidence Scans"},"badges":{"items":{"$ref":"#/components/schemas/UserBadge"},"type":"array","title":"Badges"},"quests":{"items":{"$ref":"#/components/schemas/UserQuest"},"type":"array","title":"Quests"}},"type":"object","required":["level","xp_total","xp_into_level","xp_for_next_level","streak_days","total_scans","nutrition_ready_meals","feedback_count","correction_count","high_confidence_scans","badges","quests"],"title":"UserProgressPayload"},"UserPublic":{"properties":{"id":{"type":"string","title":"Id","examples":["6629a62f0d24ed2cf9f4d001"]},"full_name":{"type":"string","title":"Full Name"},"email":{"type":"string","format":"email","title":"Email"},"age":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Age"},"height_cm":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Height Cm"},"weight_kg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Weight Kg"},"goal":{"anyOf":[{"type":"string","enum":["weight_loss","muscle_gain","maintenance","general_health"]},{"type":"null"}],"title":"Goal"},"activity_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activity Level"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","full_name","email"],"title":"UserPublic"},"UserQuest":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"},"completed":{"type":"boolean","title":"Completed"},"xp":{"type":"integer","title":"Xp"}},"type":"object","required":["id","label","completed","xp"],"title":"UserQuest"},"UserUpdateRequest":{"properties":{"full_name":{"anyOf":[{"type":"string","maxLength":120,"minLength":2},{"type":"null"}],"title":"Full Name"},"age":{"anyOf":[{"type":"integer","maximum":120.0,"minimum":1.0},{"type":"null"}],"title":"Age"},"height_cm":{"anyOf":[{"type":"number","maximum":300.0,"minimum":30.0},{"type":"null"}],"title":"Height Cm"},"weight_kg":{"anyOf":[{"type":"number","maximum":500.0,"minimum":1.0},{"type":"null"}],"title":"Weight Kg"},"goal":{"anyOf":[{"type":"string","enum":["weight_loss","muscle_gain","maintenance","general_health"]},{"type":"null"}],"title":"Goal"},"activity_level":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Activity Level"}},"type":"object","title":"UserUpdateRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WeeklyReportPayload":{"properties":{"start_date":{"type":"string","title":"Start Date"},"end_date":{"type":"string","title":"End Date"},"total_meals":{"type":"integer","title":"Total Meals"},"total_calories":{"type":"number","title":"Total Calories"},"average_calories_per_day":{"type":"number","title":"Average Calories Per Day"},"macro_totals":{"$ref":"#/components/schemas/MacroTotals"},"average_health_score":{"type":"number","title":"Average Health Score"},"most_frequent_food":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Most Frequent Food"},"daily_calorie_trend":{"items":{"$ref":"#/components/schemas/DailyCalorieTrendEntry"},"type":"array","title":"Daily Calorie Trend"},"recommendations":{"items":{"type":"string"},"type":"array","title":"Recommendations"}},"type":"object","required":["start_date","end_date","total_meals","total_calories","average_calories_per_day","macro_totals","average_health_score","most_frequent_food","daily_calorie_trend","recommendations"],"title":"WeeklyReportPayload","example":{"average_calories_per_day":305.71,"average_health_score":74.4,"daily_calorie_trend":[{"calories":320,"date":"2026-04-18","meals":1},{"calories":0,"date":"2026-04-19","meals":0}],"end_date":"2026-04-24","macro_totals":{"calories":2140,"carbs":255,"fat":67,"fiber":31,"protein":82,"sodium":1840,"sugar":22},"most_frequent_food":"Beans","recommendations":["Your weekly pattern looks fairly balanced overall. Keep the consistency going."],"start_date":"2026-04-18","total_calories":2140,"total_meals":5}}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}},"tags":[{"name":"Health","description":"Operational health and environment status."},{"name":"Authentication","description":"User registration, login, and current user endpoints."},{"name":"Users","description":"Authenticated user profile management."},{"name":"Foods","description":"Food catalog and development seed data."},{"name":"Predictions","description":"Image upload and ML-powered food predictions."},{"name":"Meals","description":"Meal history operations."},{"name":"Reports","description":"Weekly nutrition reporting."},{"name":"Project Page","description":"Standalone HTML project overview page."}]}