228 lines
5.4 KiB
Markdown
228 lines
5.4 KiB
Markdown
# JSON Structure Documentation
|
||
|
||
Diese Dokumentation erklärt die JSON-Struktur für Lernpfade in der Flalingo-Anwendung.
|
||
|
||
## Übersicht
|
||
|
||
Ein Lernpfad (Path) besteht aus mehreren hierarchischen Elementen:
|
||
- **Path**: Der Hauptcontainer für einen Lernkurs
|
||
- **Metadata**: Versionierung und Zeitstempel
|
||
- **Nodes**: Lerneinheiten innerhalb des Pfads
|
||
- **Exercises**: Einzelne Übungen innerhalb der Nodes
|
||
|
||
## JSON Schema
|
||
|
||
### Path (Hauptstruktur)
|
||
|
||
```json
|
||
{
|
||
"id": "string", // Eindeutige Pfad-ID
|
||
"title": "string", // Titel des Lernpfads
|
||
"description": "string", // Beschreibung des Pfads
|
||
"metadata": [...], // Array von Metadata-Objekten
|
||
"nodes": [...] // Array von Node-Objekten
|
||
}
|
||
```
|
||
|
||
### Metadata
|
||
|
||
```json
|
||
{
|
||
"path_id": "string", // Referenz zur Pfad-ID
|
||
"version": "string", // Versionsnummer (z.B. "1.0.0")
|
||
"created_at": "string", // ISO 8601 Timestamp
|
||
"updated_at": "string" // ISO 8601 Timestamp
|
||
}
|
||
```
|
||
|
||
### Node (Lerneinheit)
|
||
|
||
```json
|
||
{
|
||
"id": number, // Eindeutige Node-ID (Zahl)
|
||
"title": "string", // Titel der Lerneinheit
|
||
"description": "string", // Beschreibung der Einheit
|
||
"path_id": "string", // Referenz zur übergeordneten Pfad-ID
|
||
"exercises": [...] // Array von Exercise-Objekten
|
||
}
|
||
```
|
||
|
||
### Exercise (Übung)
|
||
|
||
```json
|
||
{
|
||
"id": number, // Eindeutige Exercise-ID (Zahl)
|
||
"ex_type": "string", // Typ der Übung (siehe Exercise-Typen)
|
||
"content": "string", // JSON-String mit übungsspezifischen Daten
|
||
"node_id": number // Referenz zur übergeordneten Node-ID
|
||
}
|
||
```
|
||
|
||
## Exercise-Typen
|
||
|
||
Das `content`-Feld enthält einen JSON-String, dessen Struktur je nach `ex_type` variiert:
|
||
|
||
### vocabulary
|
||
Vokabel-Lernkarten
|
||
```json
|
||
{
|
||
"word": "hola",
|
||
"translation": "hallo",
|
||
"audio": "hola.mp3",
|
||
"image": "greeting.jpg",
|
||
"context": "informal greeting",
|
||
"gender": "feminine", // für gendered Sprachen
|
||
"type": "greeting" // Kategorie
|
||
}
|
||
```
|
||
|
||
### multiple_choice
|
||
Multiple-Choice Fragen
|
||
```json
|
||
{
|
||
"question": "Was bedeutet 'apple'?",
|
||
"options": ["Apfel", "Birne", "Orange", "Banane"],
|
||
"correct": 0, // Index der richtigen Antwort
|
||
"explanation": "Apple = Apfel auf Deutsch"
|
||
}
|
||
```
|
||
|
||
### fill_blank
|
||
Lückentexte
|
||
```json
|
||
{
|
||
"sentence": "The cat ___ on the table",
|
||
"answer": "is",
|
||
"options": ["is", "are", "was", "were"], // optional
|
||
"hint": "Verb 'to be' in 3rd person singular"
|
||
}
|
||
```
|
||
|
||
### translation
|
||
Übersetzungsübungen
|
||
```json
|
||
{
|
||
"source": "I am happy",
|
||
"target": "Ich bin glücklich",
|
||
"language_pair": "en-de",
|
||
"hints": ["I = Ich", "am = bin", "happy = glücklich"]
|
||
}
|
||
```
|
||
|
||
### grammar
|
||
Grammatik-Erklärungen und -Übungen
|
||
```json
|
||
{
|
||
"rule": "Present tense of 'ser'",
|
||
"explanation": "Das Verb 'ser' (sein) im Präsens",
|
||
"examples": ["Yo soy estudiante", "Tú eres profesor"],
|
||
"conjugations": [
|
||
{"person": "yo", "form": "soy"},
|
||
{"person": "tú", "form": "eres"}
|
||
]
|
||
}
|
||
```
|
||
|
||
### pronunciation
|
||
Ausspracheübungen
|
||
```json
|
||
{
|
||
"phrase": "Me llamo...",
|
||
"phonetic": "me ˈʎamo",
|
||
"audio": "me_llamo.mp3",
|
||
"tip": "Das 'll' wird wie 'j' ausgesprochen",
|
||
"speed": "normal" // slow, normal, fast
|
||
}
|
||
```
|
||
|
||
### matching
|
||
Zuordnungsübungen
|
||
```json
|
||
{
|
||
"pairs": [
|
||
{"left": "hermano", "right": "Bruder"},
|
||
{"left": "hermana", "right": "Schwester"},
|
||
{"left": "padre", "right": "Vater"}
|
||
],
|
||
"instruction": "Ordne die spanischen Wörter den deutschen zu"
|
||
}
|
||
```
|
||
|
||
### listening
|
||
Hörverständnisübungen
|
||
```json
|
||
{
|
||
"audio": "dialogue.mp3",
|
||
"question": "Was sagt die Frau?",
|
||
"options": ["Ich bin müde", "Ich bin hungrig", "Ich bin glücklich"],
|
||
"correct": 1,
|
||
"transcript": "Tengo hambre" // optional
|
||
}
|
||
```
|
||
|
||
### sentence_building
|
||
Sätze zusammensetzen
|
||
```json
|
||
{
|
||
"words": ["Yo", "soy", "estudiante", "de", "medicina"],
|
||
"correct_order": ["Yo", "soy", "estudiante", "de", "medicina"],
|
||
"translation": "Ich bin Medizinstudent",
|
||
"shuffled": true // Wörter werden gemischt dargestellt
|
||
}
|
||
```
|
||
|
||
### image_selection
|
||
Bildauswahl
|
||
```json
|
||
{
|
||
"instruction": "Wähle das rote Auto",
|
||
"images": ["red_car.jpg", "blue_car.jpg", "green_car.jpg"],
|
||
"correct": "red_car.jpg",
|
||
"audio": "red_car_audio.mp3" // optional
|
||
}
|
||
```
|
||
|
||
### conversation
|
||
Dialogübungen
|
||
```json
|
||
{
|
||
"scenario": "Im Restaurant bestellen",
|
||
"dialogue": [
|
||
{"speaker": "waiter", "text": "¿Qué desea ordenar?"},
|
||
{"speaker": "customer", "text": "Quiero una pizza, por favor"},
|
||
{"speaker": "waiter", "text": "¿Algo para beber?"}
|
||
],
|
||
"user_role": "customer",
|
||
"context": "formal restaurant setting"
|
||
}
|
||
```
|
||
|
||
## Datentypen und Validierung
|
||
|
||
### Pflichtfelder
|
||
- Alle `id` Felder sind erforderlich und müssen eindeutig sein
|
||
- `title` und `description` sind immer erforderlich
|
||
- `content` muss ein gültiger JSON-String sein
|
||
|
||
### Referenzielle Integrität
|
||
- `metadata.path_id` muss mit `path.id` übereinstimmen
|
||
- `node.path_id` muss mit `path.id` übereinstimmen
|
||
- `exercise.node_id` muss mit `node.id` übereinstimmen
|
||
|
||
### Zeitstempel
|
||
Alle Zeitstempel müssen im ISO 8601 Format vorliegen:
|
||
```
|
||
"2024-01-20T10:30:00Z"
|
||
```
|
||
|
||
## Beispiel-Dateien
|
||
|
||
- `example_path.json` - Vollständiger Spanisch-Anfängerkurs
|
||
- `example_path_simple.json` - Vereinfachtes Beispiel mit grundlegenden Typen
|
||
|
||
## Erweiterbarkeit
|
||
|
||
Das System ist so konzipiert, dass neue Exercise-Typen einfach hinzugefügt werden können:
|
||
1. Neuen `ex_type` definieren
|
||
2. Entsprechende `content`-Struktur dokumentieren
|
||
3. Repository-Layer unterstützt automatisch neue Typen |