feat: cooking history/gallery, unit conversion, nutrition diary, pantry scan, digest cron, nutrition-targeted meal plans
Six M-sized items from HANDOFF.md's new-features backlog: - Profile tabs: cooking-history stats (total cooked, last-cooked, streak) and a "cooked it" photo gallery, both owner-only - Display-time unit conversion (metric<->imperial) for recipe ingredients, respecting each user's unitPref; original value always shown alongside the conversion - Nutrition daily diary: per-day macro totals computed from cooking history x recipe nutritionData, compared against user goals - Pantry scan: real barcode lookup (zxing + Open Food Facts, no API key) with an AI-vision fallback for unbarcoded items, always confirm-before- insert, both paths tier/rate-limited like other AI features - Weekly digest email: new followers/comments/ratings + trending recipes, sent via a new `cron` Docker stage (alpine+crond+curl) and `digest-cron` compose service hitting a bearer-token-protected internal route - Meal-plan generation can now target a user's nutrition goals as a prompt-level nudge (recipes are AI-invented, not DB-sourced, so this can't be a hard macro constraint) Caught a real deploy-breaking issue while adding the cron stage: appending it after `runner` silently changed the Dockerfile's default build target, and `web`'s compose config didn't pin one — fixed by pinning `target: runner` explicitly. Verified with typecheck, lint, and three separate `docker build --target` runs (runner/cron/migrator) plus `docker compose config` validation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -37,6 +37,12 @@ export async function generateMealPlan(
|
||||
days?: Array<"mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun">;
|
||||
pantryMode?: boolean;
|
||||
difficulty?: "easy" | "medium" | "hard";
|
||||
nutritionGoals?: {
|
||||
caloriesKcal?: number | null;
|
||||
proteinG?: number | null;
|
||||
carbsG?: number | null;
|
||||
fatG?: number | null;
|
||||
};
|
||||
},
|
||||
config?: AiConfig & { userContext?: string },
|
||||
locale?: string
|
||||
@@ -59,6 +65,17 @@ export async function generateMealPlan(
|
||||
? `Available pantry ingredients to use: ${options.pantryItems.slice(0, 20).join(", ")}.`
|
||||
: "";
|
||||
|
||||
const goals = options.nutritionGoals;
|
||||
const goalParts: string[] = [];
|
||||
if (goals?.caloriesKcal) goalParts.push(`~${goals.caloriesKcal} kcal`);
|
||||
if (goals?.proteinG) goalParts.push(`${goals.proteinG}g protein`);
|
||||
if (goals?.carbsG) goalParts.push(`${goals.carbsG}g carbs`);
|
||||
if (goals?.fatG) goalParts.push(`${goals.fatG}g fat`);
|
||||
const nutritionClause =
|
||||
goalParts.length > 0
|
||||
? `The user has a daily nutrition target of approximately ${goalParts.join(", ")} in total across breakfast, lunch, and dinner combined. Design each day's meals so that, together, they roughly add up to these daily targets — favor recipes and portions that plausibly fit (e.g. protein-forward mains if protein is high relative to calories, lighter sides if calories are constrained). This is a directional guide, not a strict constraint: never sacrifice food safety, coherence, or the dietary requirements above to hit a number exactly.`
|
||||
: "";
|
||||
|
||||
const systemPrompt = pantryMode
|
||||
? `You are a professional nutritionist and chef. Generate a meal plan that maximizes use of the provided pantry items. Prefer meals using multiple pantry ingredients. Minimize additional shopping required. Vary cuisines and cooking methods where possible. Make meals achievable for home cooks. For ingredients: quantity must be a number only (e.g. 0.25, 1.5, 2), unit is a separate string (e.g. 'cup', 'tbsp', 'g', 'ml'). Never combine quantity and unit. Respond in ${lang}.`
|
||||
: `You are a professional nutritionist and chef. Generate balanced, practical, and delicious weekly meal plans. Vary cuisines and cooking methods throughout the week. Make meals achievable for home cooks. For ingredients: quantity must be a number only (e.g. 0.25, 1.5, 2), unit is a separate string (e.g. 'cup', 'tbsp', 'g', 'ml'). Never combine quantity and unit. Respond in ${lang}.`;
|
||||
@@ -76,6 +93,7 @@ export async function generateMealPlan(
|
||||
dietaryClause,
|
||||
difficultyClause,
|
||||
pantryClause,
|
||||
nutritionClause,
|
||||
pantryMode
|
||||
? "Prioritize using the listed pantry ingredients across as many meals as possible. Minimize ingredients that need to be purchased."
|
||||
: "Ensure nutritional balance across the week. Vary ingredients and cooking styles.",
|
||||
|
||||
Reference in New Issue
Block a user