Files
sena_db_api_layer/LEARNING_CONTENT_GUIDE.md
silverpro89 2c7b4675a7 update
2026-01-26 20:23:08 +07:00

1540 lines
37 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# LEARNING CONTENT GUIDE
**Version:** 1.0.0
**Last Updated:** 2024
**Purpose:** Comprehensive guide for AI to understand and create learning content in the Subject → Chapter → Lesson hierarchy
---
## Table of Contents
1. [Overview](#overview)
2. [Content Hierarchy](#content-hierarchy)
3. [Subject Structure](#subject-structure)
4. [Chapter Structure](#chapter-structure)
5. [Lesson Structure](#lesson-structure)
6. [Lesson Content Types](#lesson-content-types)
7. [Exercise Types](#exercise-types)
8. [API Workflow](#api-workflow)
9. [Code Examples](#code-examples)
10. [Validation Checklist](#validation-checklist)
11. [Common Mistakes](#common-mistakes)
12. [AI Integration Tips](#ai-integration-tips)
---
## Overview
The learning content system is structured in a three-level hierarchy:
```
Subject (Course/Curriculum)
└── Chapter (Unit/Topic)
└── Lesson (Individual Learning Activity)
```
Each level serves a specific purpose:
- **Subject**: Represents a complete course (e.g., "English Grade 1", "Math Grade 5")
- **Chapter**: Represents a major topic within a subject (e.g., "Unit 1: My Family", "Chapter 3: Fractions")
- **Lesson**: Represents individual learning activities with specific content types
---
## Content Hierarchy
### Database Schema
```
┌─────────────┐
│ Subject │
│ (UUID) │
└──────┬──────┘
│ 1:N
┌──────▼──────┐
│ Chapter │
│ (UUID) │
└──────┬──────┘
│ 1:N
┌──────▼──────┐
│ Lesson │
│ (UUID) │
└─────────────┘
```
### Relationships
- One Subject can have **many Chapters**
- One Chapter can have **many Lessons**
- All IDs are **UUID** (for security against crawlers)
- Foreign keys: `subject_id` in Chapter, `chapter_id` in Lesson
---
## Subject Structure
### Database Model: `Subject`
**Table:** `subjects`
**Required Fields:**
| Field | Type | Description | Example |
|-------|------|-------------|---------|
| `id` | UUID | Primary key | `550e8400-e29b-41d4-a716-446655440000` |
| `subject_code` | VARCHAR(20) | Unique subject code | `ENG-G1` |
| `subject_name` | VARCHAR(100) | Subject name (Vietnamese) | `Tiếng Anh Lớp 1` |
**Optional Fields:**
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `subject_name_en` | VARCHAR(100) | NULL | English name |
| `description` | TEXT | NULL | Subject description |
| `is_active` | BOOLEAN | true | Active status |
| `is_premium` | BOOLEAN | false | Premium content flag |
| `is_training` | BOOLEAN | false | Training content flag |
| `is_public` | BOOLEAN | false | Public self-learning flag |
| `required_role` | VARCHAR(50) | NULL | Required role to access |
### Subject Access Control
The `Subject` model includes access control fields:
- **`is_premium`**: Content requires subscription
- **`is_training`**: Content for staff training
- **`is_public`**: Available for public self-learning
- **`required_role`**: Specific role required (e.g., "teacher", "admin")
### Example Subject
```json
{
"subject_code": "ENG-G1",
"subject_name": "Tiếng Anh Lớp 1",
"subject_name_en": "English Grade 1",
"description": "Basic English course for Grade 1 students",
"is_active": true,
"is_premium": false,
"is_public": true
}
```
---
## Chapter Structure
### Database Model: `Chapter`
**Table:** `chapters`
**Required Fields:**
| Field | Type | Description | Example |
|-------|------|-------------|---------|
| `id` | UUID | Primary key | `550e8400-e29b-41d4-a716-446655440001` |
| `subject_id` | UUID | Foreign key to Subject | `550e8400-e29b-41d4-a716-446655440000` |
| `chapter_number` | INTEGER | Sequential chapter number | `1` |
| `chapter_title` | VARCHAR(200) | Chapter title | `Unit 1: My Family` |
**Optional Fields:**
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `chapter_description` | TEXT | NULL | Chapter description |
| `duration_minutes` | INTEGER | NULL | Estimated duration |
| `is_published` | BOOLEAN | false | Published status |
| `display_order` | INTEGER | NULL | Custom display order |
### Chapter Numbering
- **`chapter_number`**: Sequential number (1, 2, 3, ...)
- **`display_order`**: Optional custom order (for reordering without renumbering)
### Example Chapter
```json
{
"subject_id": "550e8400-e29b-41d4-a716-446655440000",
"chapter_number": 1,
"chapter_title": "Unit 1: My Family",
"chapter_description": "Learn about family members and relationships",
"duration_minutes": 120,
"is_published": true,
"display_order": 1
}
```
---
## Lesson Structure
### Database Model: `Lesson`
**Table:** `lessons`
**Required Fields:**
| Field | Type | Description | Example |
|-------|------|-------------|---------|
| `id` | UUID | Primary key | `550e8400-e29b-41d4-a716-446655440010` |
| `chapter_id` | UUID | Foreign key to Chapter | `550e8400-e29b-41d4-a716-446655440001` |
| `lesson_number` | INTEGER | Sequential lesson number | `1` |
| `lesson_title` | VARCHAR(200) | Lesson title | `Family Vocabulary` |
| `lesson_type` | ENUM | Content delivery type | `json_content` or `url_content` |
**Optional Fields:**
| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `lesson_description` | TEXT | NULL | Lesson description |
| `lesson_content_type` | ENUM | NULL | Content category: `vocabulary`, `grammar`, `phonics`, `review`, `mixed` |
| `content_json` | JSON | NULL | JSON content structure |
| `content_url` | VARCHAR(500) | NULL | URL for external content |
| `content_type` | VARCHAR(50) | NULL | URL content type: `video`, `audio`, `pdf`, `image`, `interactive` |
| `duration_minutes` | INTEGER | NULL | Estimated duration |
| `is_published` | BOOLEAN | false | Published status |
| `is_free` | BOOLEAN | false | Free trial access |
| `display_order` | INTEGER | 0 | Custom display order |
| `thumbnail_url` | VARCHAR(500) | NULL | Lesson thumbnail |
### Lesson Types
#### 1. `lesson_type` (Content Delivery)
- **`json_content`**: Content is stored in `content_json` field (structured data)
- **`url_content`**: Content is external, referenced by `content_url`
#### 2. `lesson_content_type` (Content Category)
- **`vocabulary`**: Vocabulary learning lesson
- **`grammar`**: Grammar rules and practice
- **`phonics`**: Pronunciation and phonics
- **`review`**: Review lesson combining multiple types
- **`mixed`**: Mixed content (custom combination)
### Validation Rules
1. If `lesson_type = 'json_content'`, then `content_json` is **required**
2. If `lesson_type = 'url_content'`, then `content_url` is **required**
3. `lesson_content_type` and `content_json.type` should **match** for consistency
4. Lesson numbers should be **sequential** within a chapter
---
## Lesson Content Types
### 1. Vocabulary Lesson
**Purpose:** Teaching vocabulary with word lists and exercises
**`lesson_content_type`:** `vocabulary`
**`content_json` Structure:**
```json
{
"type": "vocabulary",
"words": [
"mother",
"father",
"sister",
"brother"
],
"exercises": [
{
"type": "match",
"question": "Match the words with pictures",
"items": [
{ "word": "mother", "image": "https://..." },
{ "word": "father", "image": "https://..." }
]
}
]
}
```
**Key Fields:**
- **`words`**: Array of vocabulary words (strings). **System will automatically lookup these words in the `Vocab` table when rendering the lesson**
- **`exercises`**: Array of practice exercises
**Important Notes:**
- ⚠️ **No need to use `vocabulary_ids` anymore!**
- Just provide a simple array of words like `["mother", "father", "sister"]`
- The system will search for these words in the `Vocab` table by `base_word` field
- If a word doesn't exist in the database, the system will handle it gracefully
- For custom/inline vocabulary, you can also use detailed objects:
```json
{
"type": "vocabulary",
"words": [
{
"word": "mother",
"translation": "mẹ",
"image": "https://cdn.sena.tech/vocab/mother.jpg",
"audio": "https://cdn.sena.tech/audio/mother.mp3",
"phonetic": "/ˈmʌð.ər/"
}
]
}
```
**When to use simple array vs detailed objects:**
- Use **simple array** (`["mother", "father"]`) when words already exist in `Vocab` table
- Use **detailed objects** when you need custom/temporary vocabulary not in the database
---
### 2. Grammar Lesson
**Purpose:** Teaching grammar rules with examples and practice
**`lesson_content_type`:** `grammar`
**`content_json` Structure:**
```json
{
"type": "grammar",
"grammar_points": ["Present Simple", "Present Continuous"],
"sentences": [
"I eat an apple.",
"She eats an apple.",
"They are eating apples."
],
"exercises": [
{
"type": "fill_blank",
"question": "She ___ (eat) an apple every day.",
"answer": "eats",
"options": ["eat", "eats", "eating"]
}
]
}
```
**Key Fields:**
- **`grammar_points`**: Array of grammar names (e.g., `["Present Simple"]`). **System will search for matching grammar patterns in the `Grammar` table**
- **`sentences`**: Array of example sentences demonstrating the grammar
- **`exercises`**: Array of practice exercises
**Important Notes:**
- ⚠️ **No need to use `grammar_ids` anymore!**
- Just provide grammar names like `["Present Simple"]` or example sentences
- The system will search in the `Grammar` table by `title` or analyze sentence patterns
- You can also use just sentences without grammar_points:
```json
{
"type": "grammar",
"sentences": [
"I eat an apple.",
"She eats an apple."
],
"exercises": [...]
}
```
**Alternative: Inline Grammar Rules**
For custom grammar explanations:
```json
{
"type": "grammar",
"rules": [
{
"rule_name": "Present Simple",
"formula": "S + V(s/es)",
"explanation": "Used for habits and facts"
}
],
"sentences": [...],
"exercises": [...]
}
```
---
### 3. Phonics Lesson
**Purpose:** Teaching pronunciation with IPA and sound practice
**`lesson_content_type`:** `phonics`
**`content_json` Structure:**
```json
{
"type": "phonics",
"phonics_rules": [
{
"ipa": "/æ/",
"sound_name": "short a",
"description": "As in 'cat', 'hat'",
"audio": "https://cdn.sena.tech/phonics/ae.mp3",
"words": [
{
"word": "cat",
"phonetic": "/kæt/",
"audio": "https://cdn.sena.tech/audio/cat.mp3",
"image": "https://cdn.sena.tech/img/cat.jpg"
},
{
"word": "hat",
"phonetic": "/hæt/",
"audio": "https://cdn.sena.tech/audio/hat.mp3",
"image": "https://cdn.sena.tech/img/hat.jpg"
}
]
}
],
"exercises": [
{
"type": "listen_repeat",
"question": "Listen and repeat",
"audio": "https://cdn.sena.tech/audio/cat.mp3",
"word": "cat"
},
{
"type": "identify_sound",
"question": "Which word has the /æ/ sound?",
"options": ["cat", "cut", "cot"],
"answer": "cat"
}
]
}
```
**Key Fields:**
- **`phonics_rules`**: Array of phonics rules with IPA notation
- **`ipa`**: International Phonetic Alphabet symbol (e.g., `/æ/`, `/iː/`)
- **`sound_name`**: Friendly name for the sound (e.g., "short a", "long e")
- **`words`**: Example words demonstrating the sound
- **`exercises`**: Pronunciation practice exercises
---
### 4. Review Lesson
**Purpose:** Reviewing multiple content types (vocabulary + grammar + phonics)
**`lesson_content_type`:** `review`
**`content_json` Structure:**
```json
{
"type": "review",
"sections": [
{
"section_type": "vocabulary",
"title": "Family Vocabulary Review",
"words": ["mother", "father", "sister", "brother"],
"exercises": [
{
"type": "match",
"question": "Match family members",
"items": [...]
}
]
},
{
"section_type": "grammar",
"title": "Present Simple Review",
"grammar_points": ["Present Simple"],
"sentences": ["I eat an apple", "She eats an apple"],
"exercises": [
{
"type": "fill_blank",
"question": "She ___ an apple.",
"answer": "eats",
"options": ["eat", "eats", "eating"]
}
]
},
{
"section_type": "phonics",
"title": "Short A Sound Review",
"phonics_rules": [
{
"ipa": "/æ/",
"words": ["cat", "hat", "bat"]
}
],
"exercises": [...]
}
],
"overall_exercises": [
{
"type": "mixed_quiz",
"questions": [
{
"type": "vocabulary",
"question": "What is 'mẹ' in English?",
"answer": "mother",
"options": ["mother", "father", "sister"]
},
{
"type": "grammar",
"question": "She ___ an apple.",
"answer": "eats",
"options": ["eat", "eats", "eating"]
},
{
"type": "phonics",
"question": "Which word has the /æ/ sound?",
"answer": "cat",
"options": ["cat", "cut", "cot"]
}
]
}
]
}
```
**Key Fields:**
- **`sections`**: Array of review sections (vocabulary, grammar, phonics)
- **`section_type`**: Type of each section (`vocabulary`, `grammar`, `phonics`)
- **`words`**: For vocabulary sections - system will lookup in Vocab table
- **`grammar_points`** / **`sentences`**: For grammar sections - system will lookup in Grammar table
- **`overall_exercises`**: Mixed exercises combining all sections
**Review Lesson Guidelines:**
1. Each section should review 1-3 key concepts from previous lessons
2. Use **word arrays** for vocabulary (e.g., `["mother", "father"]`)
3. Use **sentence arrays** or grammar names for grammar (e.g., `["I eat an apple"]` or `["Present Simple"]`)
4. Include exercises for each section
5. Add `overall_exercises` for comprehensive review
6. Use `mixed_quiz` to test understanding across all content types
---
## Exercise Types
Common exercise types across all lesson types:
### 1. Match Exercise
**Purpose:** Match items (words to images, words to translations)
```json
{
"type": "match",
"question": "Match the words with pictures",
"items": [
{ "word": "mother", "image": "https://cdn.sena.tech/img/mother.jpg" },
{ "word": "father", "image": "https://cdn.sena.tech/img/father.jpg" }
]
}
```
### 2. Fill in the Blank
**Purpose:** Complete sentences with correct words
```json
{
"type": "fill_blank",
"question": "This is my ___",
"answer": "mother",
"options": ["mother", "father", "sister"]
}
```
### 3. Multiple Choice
**Purpose:** Select correct answer from options
```json
{
"type": "multiple_choice",
"question": "What is 'mẹ' in English?",
"options": ["mother", "father", "sister", "brother"],
"answer": "mother"
}
```
### 4. Arrange Words
**Purpose:** Arrange words to form correct sentence
```json
{
"type": "arrange_words",
"question": "Arrange: apple / eat / I / an",
"answer": "I eat an apple",
"words": ["apple", "eat", "I", "an"]
}
```
### 5. Listen and Repeat (Phonics)
**Purpose:** Practice pronunciation
```json
{
"type": "listen_repeat",
"question": "Listen and repeat",
"audio": "https://cdn.sena.tech/audio/cat.mp3",
"word": "cat"
}
```
### 6. Identify Sound (Phonics)
**Purpose:** Identify words with specific sound
```json
{
"type": "identify_sound",
"question": "Which word has the /æ/ sound?",
"options": ["cat", "cut", "cot"],
"answer": "cat"
}
```
### 7. True/False
**Purpose:** Validate statements
```json
{
"type": "true_false",
"question": "The word 'mother' means 'mẹ'.",
"answer": true
}
```
### 8. Mixed Quiz (Review Lessons)
**Purpose:** Combine multiple question types
```json
{
"type": "mixed_quiz",
"questions": [
{
"type": "vocabulary",
"question": "What is 'mẹ' in English?",
"answer": "mother",
"options": ["mother", "father", "sister"]
},
{
"type": "grammar",
"question": "She ___ an apple.",
"answer": "eats",
"options": ["eat", "eats", "eating"]
}
]
}
```
---
## API Workflow
### Step-by-Step Guide to Create Learning Content
#### Step 1: Create Subject
**Endpoint:** `POST /api/subjects`
**Request:**
```json
{
"subject_code": "ENG-G1",
"subject_name": "Tiếng Anh Lớp 1",
"subject_name_en": "English Grade 1",
"description": "Basic English for Grade 1",
"is_active": true,
"is_public": true
}
```
**Response:**
```json
{
"success": true,
"message": "Subject created successfully",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"subject_code": "ENG-G1",
...
}
}
```
**Save the `id` for next step.**
---
#### Step 2: Create Chapter
**Endpoint:** `POST /api/chapters`
**Request:**
```json
{
"subject_id": "550e8400-e29b-41d4-a716-446655440000",
"chapter_number": 1,
"chapter_title": "Unit 1: My Family",
"chapter_description": "Learn about family members",
"duration_minutes": 120,
"is_published": true
}
```
**Response:**
```json
{
"success": true,
"message": "Chapter created successfully",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"subject_id": "550e8400-e29b-41d4-a716-446655440000",
...
}
}
```
**Save the `id` for next step.**
---
#### Step 3: Create Vocabulary Lesson (using word list)
**Endpoint:** `POST /api/learning-content/lessons`
**Note:** ⚠️ **No need to create Vocab entries first!** Just use a simple word list. System will lookup words in Vocab table when rendering.
**Request:**
```json
{
"chapter_id": "550e8400-e29b-41d4-a716-446655440001",
"lesson_number": 1,
"lesson_title": "Family Vocabulary",
"lesson_type": "json_content",
"lesson_content_type": "vocabulary",
"content_json": {
"type": "vocabulary",
"words": ["mother", "father", "sister", "brother"],
"exercises": [
{
"type": "match",
"question": "Match family members",
"items": [
{ "word": "mother", "image": "https://cdn.sena.tech/img/mother.jpg" }
]
}
]
},
"duration_minutes": 30,
"is_published": true
}
```
**Response:**
```json
{
"success": true,
"message": "Lesson created successfully",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440010",
...
}
}
```
---
#### Step 4: Create Grammar Lesson (using sentences)
**Endpoint:** `POST /api/learning-content/lessons`
**Note:** ⚠️ **No need to create Grammar entries first!** Just provide grammar names or example sentences. System will find matching patterns in Grammar table.
**Request:**
```json
{
"chapter_id": "550e8400-e29b-41d4-a716-446655440001",
"lesson_number": 2,
"lesson_title": "Present Simple",
"lesson_type": "json_content",
"lesson_content_type": "grammar",
"content_json": {
"type": "grammar",
"grammar_points": ["Present Simple"],
"sentences": ["I eat an apple", "She eats an apple"],
"exercises": [
{
"type": "fill_blank",
"question": "She ___ an apple.",
"answer": "eats",
"options": ["eat", "eats", "eating"]
}
]
},
"duration_minutes": 30,
"is_published": true
}
```
**Response:**
```json
{
"success": true,
"message": "Lesson created successfully",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440011",
...
}
}
```
---
#### Step 5: Create Review Lesson
**Endpoint:** `POST /api/learning-content/lessons`
**Request:**
```json
{
"chapter_id": "550e8400-e29b-41d4-a716-446655440001",
"lesson_number": 3,
"lesson_title": "Unit Review",
"lesson_type": "json_content",
"lesson_content_type": "review",
"content_json": {
"type": "review",
"sections": [
{
"section_type": "vocabulary",
"title": "Family Words",
"words": ["mother", "father", "sister"]
},
{
"section_type": "grammar",
"title": "Present Simple",
"grammar_points": ["Present Simple"],
"sentences": ["I eat an apple", "She eats an apple"]
}
],
"overall_exercises": [
{
"type": "mixed_quiz",
"questions": [
{
"type": "vocabulary",
"question": "What is 'mẹ' in English?",
"answer": "mother"
}
]
}
]
},
"duration_minutes": 40,
"is_published": true
}
```
---
### API Endpoints Summary
{ "word": "hat", "phonetic": "/hæt/" }
]
}
],
"exercises": [
{
"type": "listen_repeat",
"audio": "https://cdn.sena.tech/audio/cat.mp3",
"word": "cat"
}
]
},
"duration_minutes": 25,
"is_published": true
}
```
**Example 4: Review Lesson**
```json
{
"chapter_id": "550e8400-e29b-41d4-a716-446655440001",
"lesson_number": 4,
"lesson_title": "Unit 1 Review",
"lesson_type": "json_content",
"lesson_content_type": "review",
"content_json": {
"type": "review",
"sections": [
{
"section_type": "vocabulary",
"title": "Family Words",
"vocabulary_ids": ["550e8400-e29b-41d4-a716-446655440020"]
},
{
"section_type": "grammar",
"title": "Present Simple",
"grammar_ids": ["550e8400-e29b-41d4-a716-446655440030"]
}
],
"overall_exercises": [
{
"type": "mixed_quiz",
"questions": [
{
"type": "vocabulary",
"question": "What is 'mẹ' in English?",
"answer": "mother"
}
]
}
]
},
"duration_minutes": 40,
"is_published": true
}
```
---
### API Endpoints Summary
| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/api/subjects` | POST | Create subject |
| `/api/subjects` | GET | Get all subjects |
| `/api/subjects/:id` | GET | Get subject by ID |
| `/api/subjects/:id` | PUT | Update subject |
| `/api/subjects/:id` | DELETE | Delete subject |
| `/api/chapters` | POST | Create chapter |
| `/api/chapters` | GET | Get all chapters |
| `/api/chapters/:id` | GET | Get chapter by ID |
| `/api/chapters/:id` | PUT | Update chapter |
| `/api/chapters/:id` | DELETE | Delete chapter |
| `/api/vocab` | POST | Create vocabulary |
| `/api/vocab` | GET | Get all vocabulary |
| `/api/grammar` | POST | Create grammar rule |
| `/api/grammar` | GET | Get all grammar rules |
| `/api/learning-content/lessons` | POST | Create lesson |
| `/api/learning-content/lessons` | GET | Get all lessons |
| `/api/learning-content/lessons/:id` | GET | Get lesson by ID |
| `/api/learning-content/lessons/:id` | PUT | Update lesson |
| `/api/learning-content/lessons/:id` | DELETE | Delete lesson |
| `/api/learning-content/lessons/chapter/:chapter_id` | GET | Get lessons by chapter |
| `/api/learning-content/guide` | GET | Get learning content guide (JSON) |
---
## Code Examples
### Example 1: Complete Workflow (JavaScript)
```javascript
const axios = require('axios');
const API_URL = 'http://localhost:3000/api';
const TOKEN = 'your-auth-token';
// Headers with authentication
const headers = {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json'
};
async function createLearningContent() {
try {
// Step 1: Create Subject
const subjectRes = await axios.post(`${API_URL}/subjects`, {
subject_code: 'ENG-G1',
subject_name: 'Tiếng Anh Lớp 1',
subject_name_en: 'English Grade 1',
is_public: true
}, { headers });
const subjectId = subjectRes.data.data.id;
console.log('Subject created:', subjectId);
// Step 2: Create Chapter
const chapterRes = await axios.post(`${API_URL}/chapters`, {
subject_id: subjectId,
chapter_number: 1,
chapter_title: 'Unit 1: My Family',
is_published: true
}, { headers });
const chapterId = chapterRes.data.data.id;
console.log('Chapter created:', chapterId);
// Step 3: Create Vocabulary Lesson (using word list - NO NEED to create Vocab first!)
const lesson1Res = await axios.post(`${API_URL}/learning-content/lessons`, {
chapter_id: chapterId,
lesson_number: 1,
lesson_title: 'Family Vocabulary',
lesson_type: 'json_content',
lesson_content_type: 'vocabulary',
content_json: {
type: 'vocabulary',
words: ['mother', 'father', 'sister', 'brother'],
exercises: [
{
type: 'match',
question: 'Match family members',
items: [
{ word: 'mother', image: 'https://...' }
]
}
]
},
is_published: true
}, { headers });
console.log('Vocabulary lesson created:', lesson1Res.data.data.id);
// Step 4: Create Grammar Lesson (using sentences - NO NEED to create Grammar first!)
const lesson2Res = await axios.post(`${API_URL}/learning-content/lessons`, {
chapter_id: chapterId,
lesson_number: 2,
lesson_title: 'Present Simple',
lesson_type: 'json_content',
lesson_content_type: 'grammar',
content_json: {
type: 'grammar',
grammar_points: ['Present Simple'],
sentences: ['I eat an apple', 'She eats an apple'],
exercises: [
{
type: 'fill_blank',
question: 'She ___ an apple.',
answer: 'eats',
options: ['eat', 'eats', 'eating']
}
]
},
is_published: true
}, { headers });
console.log('Grammar lesson created:', lesson2Res.data.data.id);
// Step 5: Create Review Lesson
const lesson3Res = await axios.post(`${API_URL}/learning-content/lessons`, {
chapter_id: chapterId,
lesson_number: 3,
lesson_title: 'Review Lesson',
lesson_type: 'json_content',
lesson_content_type: 'review',
content_json: {
type: 'review',
sections: [
{
section_type: 'vocabulary',
title: 'Vocabulary Review',
words: ['mother', 'father', 'sister']
},
{
section_type: 'grammar',
title: 'Grammar Review',
grammar_points: ['Present Simple'],
sentences: ['I eat an apple']
}
],
overall_exercises: [
{
type: 'mixed_quiz',
questions: [
{
type: 'vocabulary',
question: 'What is "mẹ" in English?',
answer: 'mother'
}
]
}
]
},
is_published: true
}, { headers });
console.log('Review lesson created:', lesson3Res.data.data.id);
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
}
createLearningContent();
```
---
### Example 2: Query Lessons by Chapter
lesson_content_type: 'vocabulary',
content_json: {
type: 'vocabulary',
words: ['mother', 'father', 'sister'],
exercises: [
{
type: 'match',
question: 'Match family members',
items: [
{ word: 'mother', image: 'https://...' }
]
}
]
},
is_published: true
}, { headers });
console.log('Vocabulary lesson created:', lesson1Res.data.data.id);
// Step 6: Create Grammar Lesson
const lesson2Res = await axios.post(`${API_URL}/learning-content/lessons`, {
chapter_id: chapterId,
lesson_number: 2,
lesson_title: 'Present Simple',
lesson_type: 'json_content',
lesson_content_type: 'grammar',
content_json: {
type: 'grammar',
grammar_points: ['Present Simple'],
sentences: ['I eat an apple', 'She eats an apple'],
exercises: [
{
type: 'fill_blank',
question: 'She ___ an apple.',
answer: 'eats',
options: ['eat', 'eats', 'eating']
}
]
},
is_published: true
}, { headers });
console.log('Grammar lesson created:', lesson2Res.data.data.id);
// Step 7: Create Review Lesson
const lesson3Res = await axios.post(`${API_URL}/learning-content/lessons`, {
chapter_id: chapterId,
lesson_number: 3,
lesson_title: 'Review Lesson',
lesson_type: 'json_content',
lesson_content_type: 'review',
content_json: {
type: 'review',
sections: [
{
section_type: 'vocabulary',
title: 'Vocabulary Review',
words: ['mother', 'father', 'sister']
},
{
section_type: 'grammar',
title: 'Grammar Review',
grammar_points: ['Present Simple'],
sentences: ['I eat an apple']
}
],
overall_exercises: [
{
type: 'mixed_quiz',
questions: [
{
type: 'vocabulary',
question: 'What is "mẹ" in English?',
answer: 'mother'
}
]
}
]
},
is_published: true
}, { headers });
console.log('Review lesson created:', lesson3Res.data.data.id);
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
}
createLearningContent();
```
---
### Example 2: Query Lessons by Chapter
```javascript
async function getLessonsByChapter(chapterId) {
try {
const response = await axios.get(
`${API_URL}/learning-content/lessons/chapter/${chapterId}`
);
console.log(`Found ${response.data.count} lessons`);
response.data.data.forEach(lesson => {
console.log(`- ${lesson.lesson_number}. ${lesson.lesson_title} (${lesson.lesson_content_type})`);
});
return response.data.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
}
```
---
### Example 3: Update Lesson Content
```javascript
async function updateLessonExercises(lessonId, newExercises) {
try {
// First, get the lesson
const getRes = await axios.get(`${API_URL}/learning-content/lessons/${lessonId}`);
const lesson = getRes.data.data;
// Update content_json with new exercises
const updatedContentJson = {
...lesson.content_json,
exercises: newExercises
};
// Send update request
const updateRes = await axios.put(
`${API_URL}/learning-content/lessons/${lessonId}`,
{ content_json: updatedContentJson },
{ headers }
);
console.log('Lesson updated successfully');
return updateRes.data.data;
} catch (error) {
console.error('Error:', error.response?.data || error.message);
}
}
```
---
## Validation Checklist
Before creating lessons, validate:
- [ ] **Subject exists**: Check that `subject_id` is valid
- [ ] **Chapter exists**: Check that `chapter_id` is valid
- [ ] **Lesson type matches content**:
- `lesson_type = 'json_content'``content_json` is present
- `lesson_type = 'url_content'``content_url` is present
- [ ] **Content type consistency**: `lesson_content_type` matches `content_json.type`
- [ ] **Valid UUIDs**: All `vocabulary_ids` and `grammar_ids` reference existing records
- [ ] **Exercise structure**: All exercises have required fields (`type`, `question`, `answer`)
- [ ] **URLs are accessible**: Check all `image`, `audio`, `video` URLs
- [ ] **Lesson numbers are sequential**: Lessons in a chapter are numbered 1, 2, 3, ...
- [ ] **Required fields present**: `chapter_id`, `lesson_number`, `lesson_title`, `lesson_type`
---
## Common Mistakes
### Mistake 1: Missing Parent References
**❌ Wrong:**
```json
{
"lesson_title": "Family Vocabulary"
}
```
**✅ Correct:**
```json
{
"chapter_id": "550e8400-e29b-41d4-a716-446655440001",
"lesson_number": 1,
"lesson_title": "Family Vocabulary"
}
```
---
### Mistake 2: Wrong Content Type
**❌ Wrong:**
```json
{
"lesson_type": "json_content",
"content_url": "https://www.youtube.com/watch?v=..."
}
```
**✅ Correct:**
```json
{
"lesson_type": "url_content",
"content_url": "https://www.youtube.com/watch?v=...",
"content_type": "video"
}
```
---
### Mistake 3: Using Old vocabulary_ids Format
**❌ Wrong:**
```json
{
"content_json": {
"type": "vocabulary",
"vocabulary_ids": ["550e8400-e29b-41d4-a716-446655440020"]
}
}
```
**✅ Correct:**
```json
{
"content_json": {
"type": "vocabulary",
"words": ["mother", "father", "sister"]
}
}
```
**Explanation:** Use `words` array instead of `vocabulary_ids`. System will automatically lookup words in Vocab table when rendering.
---
### Mistake 4: Using Old grammar_ids Format
**❌ Wrong:**
```json
{
"content_json": {
"type": "grammar",
"grammar_ids": ["550e8400-e29b-41d4-a716-446655440030"]
}
}
```
**✅ Correct:**
```json
{
"content_json": {
"type": "grammar",
"grammar_points": ["Present Simple"],
"sentences": ["I eat an apple", "She eats an apple"]
}
}
```
**Explanation:** Use `grammar_points` or `sentences` instead of `grammar_ids`. System will find matching patterns in Grammar table.
---
### Mistake 5: Missing Content Type
**❌ Wrong:**
```json
{
"content_json": {
"exercises": [...]
}
}
```
**✅ Correct:**
```json
{
"content_json": {
"type": "vocabulary",
"exercises": [...]
}
}
```
---
### Mistake 5: Inconsistent Type Fields
**❌ Wrong:**
```json
{
"lesson_content_type": "vocabulary",
"content_json": {
"type": "grammar",
...
}
}
```
**✅ Correct:**
```json
{
"lesson_content_type": "vocabulary",
"content_json": {
"type": "vocabulary",
...
}
}
```
---
## AI Integration Tips
### Planning
1. **Plan the hierarchy first**: Subject → Chapters → Lessons
2. **Use simple word and sentence arrays**: No need to create Vocab/Grammar entries first!
3. **Use sequential numbering**: Lesson numbers should be sequential within each chapter
### Word Lists
1. **For vocabulary lessons**: Use simple arrays like `["mother", "father", "sister"]`
2. **System auto-lookup**: System will automatically search for these words in `Vocab` table when rendering
3. **Graceful fallback**: If a word doesn't exist in database, system will handle it gracefully
### Sentences
1. **For grammar lessons**: Use sentence arrays like `["I eat an apple", "She eats an apple"]`
2. **Grammar points**: Or use grammar names like `["Present Simple"]`
3. **System matching**: System will find matching grammar patterns in `Grammar` table
### Consistency
1. **Keep `lesson_content_type` and `content_json.type` consistent**: They should match
2. **Use appropriate exercise types**: Match exercise types to lesson content (e.g., `listen_repeat` for phonics)
### Exercises
1. **Include diverse exercise types**: Use multiple exercise types for better engagement
2. **Provide answer options**: For `fill_blank` and `multiple_choice`, include 3-5 options
3. **Add multimedia**: Include `audio`, `image`, `video` URLs for richer learning experience
### Multimedia
1. **Provide audio for pronunciation**: Especially important for vocabulary and phonics lessons
2. **Use images for vocabulary**: Visual aids improve retention
3. **Test URLs before saving**: Ensure all media URLs are accessible
### No IDs Needed!
⚠️ **IMPORTANT**: You do **NOT** need to create Vocab or Grammar entries before creating lessons!
- ✅ Just use word lists: `["mother", "father"]`
- ✅ Just use sentences: `["I eat an apple"]`
- ✅ System will lookup content when needed
- ❌ Don't use `vocabulary_ids` anymore
- ❌ Don't use `grammar_ids` anymore
---
## API Guide Endpoint
**Endpoint:** `GET /api/learning-content/guide`
**Purpose:** Returns this guide in JSON format for AI consumption
**Response:**
```json
{
"success": true,
"data": {
"guide_version": "1.0.0",
"hierarchy": {...},
"subject_structure": {...},
"chapter_structure": {...},
"lesson_structure": {...},
"lesson_content_types": {...},
"exercise_types": {...},
"api_workflow": {...},
"validation_checklist": [...],
"common_mistakes": [...],
"ai_tips": {...}
}
}
```
**Usage:**
```javascript
const guideRes = await axios.get(`${API_URL}/learning-content/guide`);
const guide = guideRes.data.data;
// Access guide sections
console.log(guide.hierarchy);
console.log(guide.lesson_content_types.vocabulary_lesson);
console.log(guide.api_workflow);
```
---
## Summary
This guide provides:
1. **Complete hierarchy understanding**: Subject → Chapter → Lesson
2. **4 lesson content types**: Vocabulary, Grammar, Phonics, Review
3. **8 exercise types**: Match, Fill Blank, Multiple Choice, Arrange Words, Listen Repeat, Identify Sound, True/False, Mixed Quiz
4. **API workflow**: Step-by-step guide to create learning content
5. **Code examples**: JavaScript examples for common operations
6. **Validation checklist**: Ensure data quality before creation
7. **Common mistakes**: Learn from typical errors
8. **AI integration tips**: Best practices for AI-driven content creation
**Next Steps:**
1. Review the guide
2. Understand the hierarchy
3. Create vocabulary and grammar entries
4. Create lessons with proper content structure
5. Validate all data before saving
6. Test with small datasets first
**For Questions:**
- API Guide: `GET /api/learning-content/guide`
- Vocab Guide: `GET /api/vocab/guide`
- Grammar Guide: `GET /api/grammar/guide`
- Story Guide: `GET /api/stories/guide`
---
**Version:** 1.0.0
**Last Updated:** 2024
**Maintained by:** SENA Learning Platform