---
name: partner-recipe-validator
description: Validiert Partner-Rezepte auf Vollständigkeit und korrektes Format. Prüft bilinguale Texte, Pflichtfelder und Rezept-Logik. Verwende diesen Skill beim Erstellen neuer Partner-Rezepte oder bei Änderungen an bestehenden.
---
# Partner Recipe Validator
Validiert Partner-Rezepte auf Vollständigkeit und Korrektheit.
## Partner-Rezept Struktur
Partner-Rezepte sind in `app/partner/[partnerId]/[recipeSlug]/page.tsx` definiert.
### Pflicht-Imports
```typescript
import { PartnerIngredientsList } from "@/components/PartnerIngredientsList";
import { PartnerBrewOverview } from "@/components/PartnerBrewOverview";
```
### Pflicht-Struktur
```typescript
// Partner-Info
const PARTNER_ID = "brauundrauchshop";
const RECIPE_SLUG = "amber-ale";
const PARTNER_INFO = {
name: "Brau & Rauchshop GmbH",
website: "https://www.brauundrauchshop.ch",
phone: "056 666 35 15",
logo: null,
};
// Bilinguale Texte
const TEXTS = {
description: { de: "...", en: "..." },
notes: { de: "...", en: "..." },
};
// getLocalizedRecipe Funktion
export function getLocalizedRecipe(lang: "de" | "en"): Recipe {
// ... vollständiges Recipe-Objekt
}
```
## Prüfungs-Checkliste
### 1. Pflichtfelder vorhanden
```markdown
- [ ] PARTNER_ID definiert
- [ ] RECIPE_SLUG definiert
- [ ] PARTNER_INFO.name
- [ ] PARTNER_INFO.website
- [ ] TEXTS.description (de + en)
- [ ] TEXTS.notes (de + en)
- [ ] getLocalizedRecipe exportiert
```
### 2. Recipe-Objekt vollständig
```markdown
- [ ] name (String)
- [ ] description (übersetzt)
- [ ] specs.batch_size
- [ ] specs.boil_time
- [ ] specs.og
- [ ] specs.fg
- [ ] specs.abv
- [ ] specs.ibu
- [ ] specs.ebc
- [ ] specs.mash_water
- [ ] specs.sparge_water
- [ ] malts[] (mind. 1)
- [ ] hops[] (mind. 1)
- [ ] yeast (Objekt)
- [ ] mash_schedule[] (mind. 1)
```
### 3. Bilinguale Texte
Alle diese Felder MÜSSEN in DE und EN vorhanden sein:
```markdown
- [ ] description
- [ ] notes
- [ ] mash_schedule[].step (Name)
- [ ] mash_schedule[].description
- [ ] hops[].amount (Beschreibung)
- [ ] yeast.amount (Beschreibung)
- [ ] boil_instructions[]
- [ ] fermentation_instructions[]
```
**Pattern für bilinguale Felder:**
```typescript
// ✅ Korrekt
description: lang === "de"
? "Amber Ale, obergärig..."
: "Amber Ale, top-fermented...",
// ✅ Auch korrekt (via TEXTS)
description: t(TEXTS.description),
// ❌ Falsch - nur eine Sprache
description: "Amber Ale, obergärig...",
```
### 4. Malz-Prozente
```markdown
- [ ] Summe aller percentage = 100%
- [ ] Keine amount in Gramm (nur %)
- [ ] Mindestens 1 Basismalz (>50%)
```
### 5. Mash Schedule
```markdown
- [ ] Temperaturen aufsteigend
- [ ] Zeiten realistisch (5-60 min)
- [ ] Einmaischen vorhanden
- [ ] Endverzuckerung vorhanden (72°C+)
- [ ] Keine Temperatur > 78°C
```
**Beispiel korrektes Mash Schedule:**
```typescript
mash_schedule: [
{ step: "Einmaischen", temp: "58°C", time: "0 min" },
{ step: "Eiweissrast", temp: "57°C", time: "10 min" }, // ⚠️ niedriger als Einmaischen - OK
{ step: "Maltoserast", temp: "63°C", time: "45 min" },
{ step: "Endverzuckerung", temp: "72°C", time: "30 min" },
{ step: "Läuterrast", temp: "78°C", time: "10 min" },
]
```
### 6. Hopfen-Validierung
```markdown
- [ ] Mindestens 1 Bitterhopfen (>45 min)
- [ ] boil_time als Zahl vorhanden
- [ ] time als String vorhanden
- [ ] Sortierung logisch (60 → 0)
```
### 7. Hefe-Validierung
```markdown
- [ ] name vorhanden
- [ ] temp_range vorhanden (z.B. "18-22°C" oder Gesamtbereich "15-24°C")
- [ ] attenuation vorhanden (z.B. "75-80%")
- [ ] amount beschreibend (übersetzt)
- [ ] Mehrere Hefen? → strains[] mit individuellen name, temp_range, attenuation
- [ ] Flüssighefe oder grosser Sud? → starter_required: true
```
### 8. Karbonisierung vs. Reifung
```markdown
- [ ] carbonation Objekt vorhanden (Zucker/Speise-Mengen)
- [ ] conditioning_instructions SEPARAT definiert (Flaschengärung + Kaltreifung)
- [ ] fermentation_instructions letzter Eintrag = NUR Abfüllen, NICHT Reifung!
- [ ] conditioning_instructions bilingual (DE + EN)
```
### 9. Learn-More Erklärungen
```markdown
- [ ] fermentation_learn_more.abkuehlen (wenn Hefestarter relevant)
- [ ] fermentation_learn_more.gaerung (wenn Hefe ernten/Klären relevant)
- [ ] fermentation_learn_more.abfuellung (Abfüll-Tipps)
- [ ] Alle Texte bilingual (DE + EN)
```
## Registrierung prüfen
### In lib/partner-recipe-content.ts
```typescript
// Import hinzufügen
import { getLocalizedRecipe as getNewRecipe } from "@/app/partner/[partnerId]/[recipeSlug]/page";
// In getPartnerRecipeDisplayContent()
if (partnerId === "partnerId" && recipeSlug === "recipe-slug") {
r = getNewRecipe(lang);
}
```
### Checkliste Registrierung
```markdown
- [ ] Import in partner-recipe-content.ts
- [ ] Switch-Case hinzugefügt
- [ ] Korrekte partnerId/recipeSlug
```
## Report-Format
```markdown
## Partner-Rezept Validierung: [Name]
### Basis-Checks
- [x] PARTNER_ID: brauundrauchshop
- [x] RECIPE_SLUG: amber-ale
- [x] PARTNER_INFO vollständig
- [x] getLocalizedRecipe exportiert
### Recipe-Pflichtfelder
- [x] name ✅
- [x] description ✅ (DE + EN)
- [x] specs komplett ✅
- [x] malts[] ✅ (2 Einträge, 100%)
- [x] hops[] ✅ (2 Einträge)
- [x] yeast ✅
- [x] mash_schedule[] ✅ (5 Schritte)
### Bilinguale Texte
| Feld | DE | EN | Status |
|------|----|----|--------|
| description | ✅ | ✅ | OK |
| mash_schedule[0].step | ✅ | ✅ | OK |
| boil_instructions | ✅ | ✅ | OK |
| fermentation_instructions | ✅ | ✅ | OK |
### Logik-Checks
- [x] Malz-Summe = 100%
- [x] Mash-Temps aufsteigend
- [x] Bitterhopfen vorhanden
- [ ] Hefe passt zu Stil
### Registrierung
- [x] Import in partner-recipe-content.ts
- [x] Switch-Case vorhanden
### Ergebnis
✅ Rezept ist vollständig und valide
```
## Beispiel: Vollständiges Partner-Rezept
Siehe `app/partner/brauundrauchshop/amber-ale/page.tsx` als Referenz.
Wichtige Muster:
```typescript
// 1. Übersetzungs-Helper
const t = (obj: { de: string; en: string }) => obj[lang];
// 2. Verwendung in Recipe
return {
name: "Amber Ale", // Name kann gleich bleiben
description: t(TEXTS.description), // Übersetzt
// 3. Inline-Übersetzung für komplexe Strukturen
mash_schedule: [
{
step: lang === "de" ? "Einmaischen" : "Mash in",
temp: "58°C",
time: "0 min",
description: lang === "de"
? "12–14 L aufheizen, Malz einrühren"
: "Heat 12–14 L, stir in malt"
},
],
};
```
## UI-Komponenten einbinden
Nach den Specs und VOR den CTA-Buttons:
```tsx
{/* Zutatenliste & Brauprozess-Kurzablauf */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 max-w-4xl mx-auto mb-8">
<PartnerIngredientsList recipe={recipe} language={language} />
<PartnerBrewOverview recipe={recipe} language={language} />
</div>
```
**PartnerIngredientsList** zeigt:
- Malz mit Prozenten
- Hopfen mit Zeiten
- Hefe mit Temperatur/Attenuation
- Wasser (Hauptguss/Nachguss)
- Extras (falls vorhanden)
**PartnerBrewOverview** zeigt:
- Timeline: Maischen → Kochen → Abkühlen → Gärung → Abfüllen
- Mash-Temps und -Zeiten
- Hopfengaben
- Gärtemperatur und -dauer
## Häufige Fehler
1. **Nur deutsche Texte** - EN vergessen
2. **Malz in Gramm statt %** - System berechnet selbst
3. **Mash-Temps nicht aufsteigend** - Physikalisch unmöglich
4. **Fehlende Registrierung** - Rezept nicht in partner-recipe-content.ts
5. **Hefe ohne temp_range** - Wichtig für Gärung
6. **Komponenten vergessen** - PartnerIngredientsList und PartnerBrewOverview müssen eingebunden sein
7. **Karbonisierung + Reifung vermischt** - Müssen getrennte Felder sein (`carbonation` vs. `conditioning_instructions`)
8. **Reifung in fermentation_instructions** - Letzter Eintrag soll NUR Abfüllen sein
9. **Mehrere Hefen ohne strains[]** - Individuelle Temps/Vergärung gehen verloren
10. **conditioning_instructions fehlt in partner-recipe-content.ts** - Muss im Interface + Return-Objekt + BrewSession recipeWithLang sein