batchCooking/apps/api/src/modules/reference/reference.service.ts
Nicolas 5890c62462 fix(recipes): overflow des préférences + régimes liés aux ingrédients
- Fix overflow horizontal sur /parametres/preferences : <fieldset> a un
  min-width: min-content par défaut du navigateur, ce qui empêchait la
  grille de l'IngredientPicker de wrapper (page entière poussée à
  ~3100px de large). Reset min-width: 0 sur .disliked-ingredients-field.
- Recatégorise les laits/crèmes végétaux (coco, amande, avoine) de
  PRODUITS_LAITIERS_OEUFS vers LIQUIDES_BOISSONS — ce ne sont pas des
  produits laitiers.
- Nouveau modèle IngredientDiet (many-to-many ingrédient <-> régime) :
  quels régimes (Végétarien, Végan, Pescétarien) chaque ingrédient
  respecte. Omnivore volontairement absent (trivial) et Sans gluten
  aussi (déjà dérivable de l'allergène Gluten existant).
- reference-seed-data.ts : chaque groupe de catégorie porte un
  defaultDiets, avec dietNames en override pour les exceptions
  (fromages, viandes, poissons, sauces à base d'œuf/poisson...).
- IngredientView.diets exposé par /reference/ingredients et /recipes,
  affiché via DietBadges dans IngredientPicker et IngredientRow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 11:01:57 +02:00

54 lines
2 KiB
TypeScript

import type { AllergyView, DietView, IngredientView } from "@batch-cooking/shared";
import { prisma } from "../../db/prisma.js";
/** All reference dietary regimes, alphabetically — small, static list (see prisma/seed.ts). */
export async function getDiets(): Promise<DietView[]> {
return prisma.diet.findMany({ orderBy: { name: "asc" } });
}
/**
* All reference allergens, alphabetically. `Allergy` carries no `name` of
* its own — it's the selectable instance of a named `Category` (see
* schema.prisma) — so this resolves each allergen's display name from its
* category and flattens the split away for callers.
*/
export async function getAllergies(): Promise<AllergyView[]> {
const allergies = await prisma.allergy.findMany({
include: { category: { select: { name: true, kind: true } } },
orderBy: { category: { name: "asc" } },
});
return allergies.map((allergy) => ({
id: allergy.id,
name: allergy.category.name,
kind: allergy.category.kind,
}));
}
/**
* All reference ingredients, alphabetically, each resolved to its allergens
* (see `IngredientAllergy` in schema.prisma) and compatible diet regimes
* (see `IngredientDiet`) — same aplattening approach as {@link getAllergies}.
* Ingredients with no linked allergen/diet come back with `allergens: []`/
* `diets: []`.
*/
export async function getIngredients(): Promise<IngredientView[]> {
const ingredients = await prisma.ingredient.findMany({
include: {
allergies: { include: { allergy: { include: { category: true } } } },
diets: { include: { diet: true } },
},
orderBy: { name: "asc" },
});
return ingredients.map((ingredient) => ({
id: ingredient.id,
name: ingredient.name,
icon: ingredient.icon,
category: ingredient.category,
allergens: ingredient.allergies.map(({ allergy }) => ({
id: allergy.id,
name: allergy.category.name,
kind: allergy.category.kind,
})),
diets: ingredient.diets.map(({ diet }) => ({ id: diet.id, name: diet.name })),
}));
}