import { z } from "zod"; import { MEAL_LOG_SOURCES, MEAL_TYPES } from "@app/shared-types"; import { dateStringSchema, quantitySchema, unitSchema, uuidSchema } from "./common.js"; const nutritionValuesInputSchema = z.object({ kcal: z.number().min(0).max(20000), proteinG: z.number().min(0).max(1000).default(0), carbsG: z.number().min(0).max(2000).default(0), fatG: z.number().min(0).max(1000).default(0), saturatedFatG: z.number().min(0).max(500).default(0), fiberG: z.number().min(0).max(300).default(0), sugarG: z.number().min(0).max(1000).default(0), saltG: z.number().min(0).max(100).default(0), }); /** * Måltidsloggning (spec §23). Näringsvärden får ALDRIG hittas på av AI: * de kommer från recept (deterministiskt), produkt/streckkod, eller * användarens egen inmatning. Tallriksfoto ger intervall som användaren bekräftar. */ export const logMealInputSchema = z.object({ date: dateStringSchema, mealType: z.enum(MEAL_TYPES), source: z.enum(MEAL_LOG_SOURCES), titleSv: z.string().min(1).max(150), recipeId: uuidSchema.optional(), mealBoxId: uuidSchema.optional(), scanJobId: uuidSchema.optional(), portionFraction: z.number().min(0.1).max(5).default(1), /** Vid produkt/fritext: ange mängd + per-100-värden eller direkta värden. */ items: z .array( z.object({ displayName: z.string().min(1).max(120), canonicalIngredientId: z.string().max(80).optional(), productId: uuidSchema.optional(), quantity: quantitySchema.optional(), unit: unitSchema.optional(), nutrition: nutritionValuesInputSchema.optional(), }), ) .max(30) .default([]), /** Direkta värden när användaren själv anger, eller bekräftat foto-intervall. */ nutritionOverride: nutritionValuesInputSchema.optional(), }); export type LogMealInput = z.infer; export const dayQuerySchema = z.object({ date: dateStringSchema, }); export const createMealBoxInputSchema = z.object({ recipeId: uuidSchema.optional(), titleSv: z.string().min(1).max(150), portions: z.number().int().min(1).max(24), storageLocationId: uuidSchema, frozen: z.boolean().default(false), cookedAt: dateStringSchema.optional(), reservedForUserId: uuidSchema.optional(), }); export type CreateMealBoxInput = z.infer; export const consumeMealBoxInputSchema = z.object({ portions: z.number().int().min(1).max(24).default(1), logAsMeal: z.boolean().default(true), mealType: z.enum(MEAL_TYPES).default("lunch"), date: dateStringSchema.optional(), }); export type ConsumeMealBoxInput = z.infer;