feat: meal tracking, dish recognition UX improvements, English AI prompts

Backend:
- Translate all recognition prompts (receipt, products, dish) from Russian to English
- Add lang parameter to Recognizer interface and pass locale.FromContext in handlers
- DishResult type uses candidates array for multi-candidate responses

Client:
- Add meal tracking: diary provider, date selector, meal type model
- DishResult parser: backward-compatible with legacy flat format and new candidates format
- DishResultScreen: sticky bottom button, full-width portion/meal-type inputs,
  КБЖУ disclaimer moved under nutrition card, add date field to diary POST body
- Recognition prompts now return dish/product names in user's preferred language
- Onboarding, profile, home screen visual updates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
dbastrikin
2026-03-17 14:29:36 +02:00
parent 2a95bcd53c
commit 87ef2097fc
16 changed files with 1269 additions and 350 deletions

View File

@@ -17,6 +17,7 @@ class UpdateProfileRequest {
final String? activity;
final String? goal;
final String? language;
final List<String>? mealTypes;
final int? dailyCalories;
const UpdateProfileRequest({
@@ -28,6 +29,7 @@ class UpdateProfileRequest {
this.activity,
this.goal,
this.language,
this.mealTypes,
this.dailyCalories,
});
@@ -40,8 +42,12 @@ class UpdateProfileRequest {
if (gender != null) map['gender'] = gender;
if (activity != null) map['activity'] = activity;
if (goal != null) map['goal'] = goal;
if (language != null) map['preferences'] = {'language': language};
if (dailyCalories != null) map['daily_calories'] = dailyCalories;
// Build preferences patch — backend merges into existing JSONB.
final prefPatch = <String, dynamic>{};
if (language != null) prefPatch['language'] = language;
if (mealTypes != null) prefPatch['meal_types'] = mealTypes;
if (prefPatch.isNotEmpty) map['preferences'] = prefPatch;
return map;
}
}