Files
HamHam/docs/IMPORT.md
T

5.2 KiB
Raw Blame History

Importformat HamHam v1

Ablauf

Administration → Importieren → JSON/XML auswählen → Datei hochladen oder Text einfügen → Vorschau prüfen → Import bestätigen. Maximal 2 MB und 100 Rezepte pro Vorgang. Kein Datensatz wird gespeichert, solange die Vorschau läuft. Ein Fehler oder Duplikat blockiert die gesamte Übernahme.

Titel werden für die Duplikatprüfung mit NFKC normalisiert, getrimmt und ohne Groß-/Kleinschreibung verglichen. Vorhandene IDs gelten ebenfalls als Duplikat. Import überschreibt keine bestehenden Rezepte. Zum Bearbeiten den Editor verwenden; zum Anlegen einer Variante eine neue ID bzw. keine ID und einen eigenen Titel verwenden.

JSON-Dateien haben diese Hülle:

{
  "version": 1,
  "recipes": [{ "title": "Mein Rezept", "servings": 2, "ingredients": [], "steps": [] }]
}

Die leeren Arrays im obigen Strukturdiagramm müssen mit mindestens einer gültigen Zutat und einem Schritt befüllt werden. Ein vollständig gültiges Beispiel steht in public/examples/pljeskavica.json. Das verbindliche maschinenlesbare Schema liegt in public/examples/hamham.schema.json (JSON Schema 2020-12).

Felder

Pflicht: title (2–180 Zeichen), servings (positiv), ingredients (1–200), steps (1–100).

Optional: id (UUID), subtitle, description, image, images, categories, tags, cuisine, difficulty (Einfach, Mittel, Anspruchsvoll), prepMinutes, cookMinutes, restMinutes, tips, storage, nutrition, published, createdAt, updatedAt (UTC ISO-8601). Gesamtzeit wird aus den drei Zeitfeldern berechnet. published ist standardmäßig false. Nährwerte gelten pro Originalportion; nutrition ist null oder { "kcal": 500, "protein": 25, "carbs": 60, "fat": 18 }.

Zutat:

{
  "id": "huhn",
  "name": "Hühnerbrust",
  "amount": 400,
  "unit": "g",
  "section": "Hauptgericht",
  "note": "ohne Haut",
  "optional": false
}

amount: positive JSON-Zahl oder null. Dezimalpunkt verwenden, keine Zeichenketten wie "1/2", "400 g" oder "1,5". Für eine halbe Zitrone 0.5 und Stück verwenden. Bei Salz nach Geschmack amount: null, unit: "", note: "nach Geschmack".

Einheiten: g, kg, ml, l, Stück, TL, EL, Prise, Bund, "". Umrechnung: 1 kg = 1000 g, 1 l = 1000 ml, 1 TL = 5 ml, 1 EL = 15 ml. Masse wird nie ohne Dichteannahme in Volumen umgerechnet. IDs sind innerhalb des Rezepts eindeutig, bestehen aus Buchstaben, Ziffern, _ oder -, maximal 80 Zeichen.

Schritt:

{
  "id": "anbraten",
  "title": "Goldbraun anbraten",
  "text": "{{huhn}} in Würfel schneiden und anbraten.",
  "ingredients": ["huhn"],
  "timers": [{ "id": "bratzeit", "label": "Hühnerbrust braten", "seconds": 480 }]
}

{{huhn}} wird zu Menge + Einheit + Zutatenname + Hinweis aufgelöst. Diese Referenz bleibt beim Skalieren konsistent. Keine konkreten skalierbaren Mengen als Freitext wiederholen. Temperaturen und Zeiten bleiben normaler Text. ingredients enthält die in diesem Schritt benötigten Zutaten-IDs. Timer-IDs müssen im gesamten Rezept eindeutig sein; ein Timer dauert 1–172800 Sekunden. Zeiten werden nicht mit Portionen skaliert.

Bilder

Nur lokale URLs: /media/<uuid>.webp oder mitgelieferte /images/<name>.jpg|webp|svg. Bilder zuerst im Adminbereich hochladen, dann den lokalen Pfad verwenden. ChatGPT soll image: "" und images: [] setzen und keine erfundenen URLs ausgeben.

JSON/XML-Exporte enthalten Bildreferenzen, keine Binärdaten. Für einen Umzug das Bildvolume mitnehmen; für ein vollständiges Backup zusätzlich die Datenbank sichern. Metadaten, Zutaten, Schritte, Timer, Zeitstempel und IDs bleiben beim Export erhalten.

XML

Das vollständige Beispiel ist public/examples/pljeskavica.xml. UTF-8, Wurzel <hamham version="1">, darunter <recipes><recipe>…</recipe></recipes>. Rezeptfelder entsprechen JSON. Array-Container:

JSON XML
recipes <recipes><recipe>…</recipe></recipes>
ingredients <ingredients><ingredient>…</ingredient></ingredients>
steps <steps><step>…</step></steps>
timers <timers><timer>…</timer></timers>
categories <categories><category>Vegetarisch</category></categories>
tags <tags><tag>Schnell</tag></tags>
images <images><image>/media/…webp</image></images>
step.ingredients <ingredients><ref>huhn</ref></ingredients>

Leere Menge: <amount/>. Keine Nährwerte: <nutrition/>. Boolean: true/false. Texte standardkonform escapen (&amp;, &lt; etc.). DOCTYPE und Entity-Deklarationen sind verboten, es werden keine externen Ressourcen aufgelöst. Nach dem XML-Parsing gilt dieselbe Zod-Validierung wie bei JSON.

Versionsstrategie

Die Hülle version: 1 ist verbindlich. Inkompatible Änderungen bekommen eine neue Version mit expliziter Konvertierung. Unbekannte Versionen werden abgewiesen. Optionale Felder erhalten dokumentierte Standardwerte. HTML-Inhalte werden nicht übernommen.