Backend: - Rename recognition_jobs → dish_recognition_jobs; add target_date and target_meal_type columns to capture scan context at submission time - Add job_id FK on meal_diary so entries are linked to their origin job - New GET /ai/jobs endpoint returns today's unlinked jobs for the current user - diary.Entry and CreateRequest gain job_id field; repository reads/writes it - CORS middleware: allow Accept-Language and Cache-Control headers - Logging middleware: implement http.Flusher on responseWriter (needed for SSE) - Consolidate migrations into a single 001_initial_schema.sql Flutter: - POST /ai/recognize-dish now sends target_date and target_meal_type - DishResultSheet accepts jobId; _addToDiary includes it in the diary payload, saves last-used meal type to SharedPreferences, invalidates todayJobsProvider - TodayJobsNotifier + todayJobsProvider: loads unlinked jobs via GET /ai/jobs - Home screen shows _TodayJobsWidget (up to 3 tiles) between macros and meals; tapping a done tile reopens DishResultSheet with the stored result - Quick Actions row: third button "История" → /scan/history - New RecognitionHistoryScreen: full-screen list of today's unlinked jobs - LocalPreferences wrapper over SharedPreferences (last_used_meal_type) - app_theme: apply Google Fonts Roboto as default font family Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
36 lines
1.2 KiB
Go
36 lines
1.2 KiB
Go
package diary
|
|
|
|
import "time"
|
|
|
|
// Entry is a single meal diary record.
|
|
type Entry struct {
|
|
ID string `json:"id"`
|
|
Date string `json:"date"` // YYYY-MM-DD
|
|
MealType string `json:"meal_type"`
|
|
Name string `json:"name"` // from dishes JOIN
|
|
Portions float64 `json:"portions"`
|
|
Calories *float64 `json:"calories,omitempty"` // recipe.calories_per_serving * portions
|
|
ProteinG *float64 `json:"protein_g,omitempty"`
|
|
FatG *float64 `json:"fat_g,omitempty"`
|
|
CarbsG *float64 `json:"carbs_g,omitempty"`
|
|
Source string `json:"source"`
|
|
DishID string `json:"dish_id"`
|
|
RecipeID *string `json:"recipe_id,omitempty"`
|
|
PortionG *float64 `json:"portion_g,omitempty"`
|
|
JobID *string `json:"job_id,omitempty"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
}
|
|
|
|
// CreateRequest is the body for POST /diary.
|
|
type CreateRequest struct {
|
|
Date string `json:"date"`
|
|
MealType string `json:"meal_type"`
|
|
Name string `json:"name"` // input-only; used if DishID is nil
|
|
Portions float64 `json:"portions"`
|
|
Source string `json:"source"`
|
|
DishID *string `json:"dish_id"`
|
|
RecipeID *string `json:"recipe_id"`
|
|
PortionG *float64 `json:"portion_g"`
|
|
JobID *string `json:"job_id"`
|
|
}
|