fix(recipe-generation): BRAND.name-interpolation för creatorDisplayName + rubriker/filnamn

feat(recommendation-engine,api): S4 Smak/Hälsa/Lager-vyer för 'Vad ska vi äta?'

- Ersätter hårdkodat 'Cibello' i scale-batch, scale-smoke-test och export-verified.
- DB-backfill: 224 recept hade 'Cibello AI' i creator_display_name (värdena
  motsvarar nuvarande BRAND.name, ingen rad ändrades men kontrollen är gjord).
- Lägger till view-query-param (default|taste|health|pantry) med fördefinierade
  ScoringWeights och samtyckesgrind.
- Unit-tester för vyer; integrationstester för vy-param, validering och
  fallback utan personalization-samtycke.
- brand-guard grön; pnpm typecheck 19/19; pnpm test --force x2 grönt (34 tasks,
  275 tester).
This commit is contained in:
Sven (AAMOS AI)
2026-08-10 05:17:43 +07:00
parent 881c5bb1e3
commit f4a603e977
8 changed files with 605 additions and 103 deletions
@@ -135,3 +135,79 @@ export const NON_PERSONALIZED_WEIGHTS: ScoringWeights = {
tasteFit: 0,
cookingAssumptionFit: 0,
};
/** Tillåtna vyer för "Vad ska vi äta?". */
export type RecommendationView = "default" | "taste" | "health" | "pantry";
export const RECOMMENDATION_VIEWS: RecommendationView[] = ["default", "taste", "health", "pantry"];
/** Fördefinierade vikter för smak-vyn (S4). */
export const TASTE_VIEW_WEIGHTS: ScoringWeights = {
coverage: 20,
expiry: 10,
nutritionFit: 5,
taste: 25,
rating: 10,
season: 3,
holiday: 3,
time: 5,
budget: 3,
variety: 3,
weather: 1,
craving: 25,
memoryFit: 12,
tasteFit: 12,
cookingAssumptionFit: 6,
};
/** Fördefinierade vikter för hälsa-vyn (S4) — stödjande, icke-restriktiv (R7). */
export const HEALTH_VIEW_WEIGHTS: ScoringWeights = {
coverage: 20,
expiry: 12,
nutritionFit: 35,
taste: 5,
rating: 6,
season: 4,
holiday: 4,
time: 6,
budget: 3,
variety: 4,
weather: 2,
craving: 5,
memoryFit: 3,
tasteFit: 3,
cookingAssumptionFit: 4,
};
/** Fördefinierade vikter för lager-vyn (S4). */
export const PANTRY_VIEW_WEIGHTS: ScoringWeights = {
coverage: 45,
expiry: 35,
nutritionFit: 5,
taste: 4,
rating: 4,
season: 2,
holiday: 2,
time: 6,
budget: 4,
variety: 2,
weather: 1,
craving: 5,
memoryFit: 4,
tasteFit: 4,
cookingAssumptionFit: 8,
};
/** Hämta vikter för en specifik vy. */
export function viewWeights(view: RecommendationView): ScoringWeights {
switch (view) {
case "taste":
return TASTE_VIEW_WEIGHTS;
case "health":
return HEALTH_VIEW_WEIGHTS;
case "pantry":
return PANTRY_VIEW_WEIGHTS;
default:
return DEFAULT_WEIGHTS;
}
}