From 97b5baa3676ea26a20da6e3ac453c4c5b65a5813 Mon Sep 17 00:00:00 2001 From: "Sven (AAMOS AI)" Date: Mon, 17 Aug 2026 19:17:27 +0700 Subject: [PATCH] =?UTF-8?q?feat(weekplan):=20MIKRO=20WEEK-2=20dagliga=20m?= =?UTF-8?q?=C3=A5ltidsslots=20(vardag=20middag,=20helg=20lunch+middag)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/mobile/src/app/(tabs)/plan.tsx | 7 ++++++- apps/worker/src/processors/weekplan.ts | 4 +++- packages/validation/src/planning.ts | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/mobile/src/app/(tabs)/plan.tsx b/apps/mobile/src/app/(tabs)/plan.tsx index a89bc98..d55f20f 100644 --- a/apps/mobile/src/app/(tabs)/plan.tsx +++ b/apps/mobile/src/app/(tabs)/plan.tsx @@ -79,6 +79,11 @@ export default function PlanScreen() { }, []); const mondayKey = toKey(monday); const weekDays = useMemo(() => Array.from({ length: 7 }, (_, i) => addDays(monday, i)), [monday]); + // Vardag: middag. Helg (lör/sön): lunch + middag. Realistisk förifylld default. + const mealSlots = useMemo( + () => weekDays.map((d) => (d.getDay() === 0 || d.getDay() === 6 ? ["lunch", "dinner"] : ["dinner"])), + [weekDays], + ); const query = useQuery({ queryKey: ["week-plan", mondayKey], @@ -125,7 +130,7 @@ export default function PlanScreen() { mutationFn: () => api("/v1/week-plans/generate", { method: "POST", - body: { weekStartDate: mondayKey, mealTypes: ["lunch", "dinner"] }, + body: { weekStartDate: mondayKey, mealTypes: ["lunch", "dinner"], mealSlots }, }), onSuccess: () => setGenerating(true), onError: onMutationError, diff --git a/apps/worker/src/processors/weekplan.ts b/apps/worker/src/processors/weekplan.ts index a051a7f..4bdde97 100644 --- a/apps/worker/src/processors/weekplan.ts +++ b/apps/worker/src/processors/weekplan.ts @@ -18,6 +18,7 @@ interface WeekPlanJobInput { weekStartDate: string; daysToPlann?: number; mealTypes: MealType[]; + mealSlots?: MealType[][]; portionsPerMeal?: number; budgetMinorTotal?: number; preferLeftoversFirst: boolean; @@ -228,7 +229,8 @@ export async function processGenerateWeekPlan( const date = new Date(Date.parse(data.input.weekStartDate) + day * 86_400_000) .toISOString() .slice(0, 10); - for (const mealType of mealTypes) { + const dayMeals = data.input.mealSlots ? (data.input.mealSlots[day] ?? []) : mealTypes; + for (const mealType of dayMeals) { // Matlåda om det finns och portionerna räcker const box = mealBoxes[boxIndex]; if (box && box.portionsRemaining >= Math.min(portions, 2)) { diff --git a/packages/validation/src/planning.ts b/packages/validation/src/planning.ts index 49cfa38..80d62ce 100644 --- a/packages/validation/src/planning.ts +++ b/packages/validation/src/planning.ts @@ -7,6 +7,7 @@ export const generateWeekPlanInputSchema = z.object({ weekStartDate: dateStringSchema, daysToPlann: z.number().int().min(1).max(14).optional(), mealTypes: z.array(z.enum(MEAL_TYPES)).min(1).default(["dinner"]), + mealSlots: z.array(z.array(z.enum(MEAL_TYPES))).optional(), portionsPerMeal: z.number().int().min(1).max(20).optional(), budgetMinorTotal: z.number().int().min(0).max(5_000_000).optional(), /** T.ex. "Sju middagar för fyra personer under 1 000 kr" (spec §26). */