fix(recipe-generation, database): allergen-blocker åtgärdad

- seed/run.ts uppdaterar nu ALLA canonical-ingrediensfält vid re-seed,
  inklusive allergens (tidigare uppdaterades bara nameSv/nutritionPer100).
- seed/run.ts härleder allergener för seed-recept från ALLA ingredienser,
  inte bara obligatoriska.
- verification.ts hård-avvisar inkompletta kandidater (saknar titel,
  ingredienser, steg, portioner eller tider) som rejected.
- Lägger allergen-invariant-test i @app/recipe-generation som verifierar
  att seed-receptens lagrade allergens matchar färsk derivering.
- Allergener omräknade för alla 246 recept; 0 mismatch återstår.
- Raderade 4 trasiga recept + 1 ordningsdubblett tidigare.
This commit is contained in:
Sven (AAMOS AI)
2026-08-10 01:52:57 +07:00
parent 9c5adaa921
commit b40e1f9d90
4 changed files with 131 additions and 3 deletions
+20 -2
View File
@@ -79,7 +79,25 @@ async function main() {
target: schema.canonicalIngredients.id,
set: {
nameSv: ing.nameSv,
nameEn: ing.nameEn,
aliases: ing.aliases,
category: ing.category,
defaultUnit: ing.defaultUnit,
densityGPerMl: ing.densityGPerMl ?? null,
gramsPerPiece: ing.gramsPerPiece ?? null,
allergens: ing.allergens,
isVegan: ing.isVegan,
isVegetarian: ing.isVegetarian,
containsGluten: ing.containsGluten,
containsLactose: ing.containsLactose,
isPork: ing.isPork,
isBeef: ing.isBeef,
isAlcohol: ing.isAlcohol,
nutritionPer100: ing.nutritionPer100,
nutritionProvenance: ing.nutritionProvenance,
peakSeasons: ing.peakSeasons,
shelfLifeGuidance: ing.shelfLifeGuidance ?? null,
defaultPriceMinorPerKg: ing.defaultPriceMinorPerKg ?? null,
updatedAt: new Date(),
},
});
@@ -646,10 +664,10 @@ async function insertRecipe(
);
}
// Deterministisk allergenhärledning
// Deterministisk allergenhärledning — ALLA ingredienser räknas,
// även valfria (garnering/servering kan innehålla allergener).
const allergens = new Set<Allergen>();
for (const ri of recipe.ingredients) {
if (ri.optional) continue;
for (const a of ingredientMap.get(ri.ing)?.allergens ?? []) allergens.add(a);
}