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

852 lines
19 KiB
Markdown

# Story System Guide
**Version:** 1.0.0
**Last Updated:** 2026-01-26
**Purpose:** Complete guide for managing interactive stories in the SENA Language Learning System
---
## Table of Contents
1. [Overview](#overview)
2. [Database Structure](#database-structure)
3. [API Endpoints](#api-endpoints)
4. [Story Structure](#story-structure)
5. [Context Objects](#context-objects)
6. [Vocabulary Integration](#vocabulary-integration)
7. [Grade Levels & Tags](#grade-levels--tags)
8. [Use Cases & Examples](#use-cases--examples)
9. [Database Queries](#database-queries)
10. [Validation Rules](#validation-rules)
11. [AI Integration Guide](#ai-integration-guide)
---
## Overview
The Story System provides **interactive multimedia stories** for language learning. Each story combines:
- **Text Content**: Narrative text broken into scenes
- **Visual Media**: Images for each scene
- **Audio Narration**: Voice recordings for listening practice
- **Vocabulary Links**: Connect to existing vocabulary entries
- **Grade Targeting**: Assign appropriate difficulty levels
- **Tag Categorization**: Organize by themes, subjects, and skills
### Key Features
**Scene-Based Structure** - Stories broken into sequential contexts
**Multimedia Support** - Images and audio for each scene
**Vocabulary Integration** - Link to vocab entries for word learning
**Grade Filtering** - Target specific grade levels
**Tag System** - Flexible categorization and search
**UUID Security** - Prevent crawler attacks
**AI-Ready** - Comprehensive guide for automated content creation
---
## Database Structure
### Table: `stories`
| Column | Type | Required | Description |
|--------|------|----------|-------------|
| `id` | UUID | ✓ | Primary key (auto-generated) |
| `name` | STRING(255) | ✓ | Story title/name |
| `logo` | TEXT | - | URL to story logo/thumbnail image |
| `vocabulary` | JSON | - | Array of vocabulary words (default: []) |
| `context` | JSON | - | Array of story scenes (default: []) |
| `grade` | JSON | - | Array of grade levels (default: []) |
| `tag` | JSON | - | Array of tags (default: []) |
| `created_at` | TIMESTAMP | ✓ | Creation timestamp |
| `updated_at` | TIMESTAMP | ✓ | Last update timestamp |
**Indexes:**
- `idx_name` - Fast search by story name
- `idx_created_at` - Sort by creation date
---
## API Endpoints
Base URL: `/api/stories`
### 1. Create Story
**POST** `/api/stories`
**Headers:**
```
Authorization: Bearer <token>
Content-Type: application/json
```
**Request Body:**
```json
{
"name": "The Greedy Cat",
"logo": "https://cdn.sena.tech/thumbs/greedy-cat.jpg",
"vocabulary": ["cat", "eat", "apple", "happy", "greedy"],
"context": [
{
"image": "https://cdn.sena.tech/story/scene1.jpg",
"text": "Once upon a time, there was a greedy cat.",
"audio": "https://cdn.sena.tech/audio/scene1.mp3",
"order": 1
},
{
"image": "https://cdn.sena.tech/story/scene2.jpg",
"text": "The cat loved eating apples every day.",
"audio": "https://cdn.sena.tech/audio/scene2.mp3",
"order": 2
}
],
"grade": ["Grade 1", "Grade 2"],
"tag": ["animals", "food", "lesson", "health", "fiction"]
}
```
**Response (201):**
```json
{
"success": true,
"message": "Story created successfully",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "The Greedy Cat",
"logo": "https://cdn.sena.tech/thumbs/greedy-cat.jpg",
"vocabulary": ["cat", "eat", "apple", "happy", "greedy"],
"context": [...],
"grade": ["Grade 1", "Grade 2"],
"tag": ["animals", "food", "lesson", "health", "fiction"],
"created_at": "2026-01-26T10:00:00Z",
"updated_at": "2026-01-26T10:00:00Z"
}
}
```
### 2. Get All Stories
**GET** `/api/stories?page=1&limit=20&grade_filter=Grade 1&tag_filter=animals&search=cat`
**Query Parameters:**
- `page` (integer, default: 1)
- `limit` (integer, default: 20)
- `search` (string) - Search in story name
- `grade_filter` (string) - Filter by grade level
- `tag_filter` (string) - Filter by tag
- `sort_by` (string, default: 'created_at')
- `sort_order` ('ASC'/'DESC', default: 'DESC')
**Response (200):**
```json
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "The Greedy Cat",
"logo": "https://cdn.sena.tech/thumbs/greedy-cat.jpg",
"grade": ["Grade 1", "Grade 2"],
"tag": ["animals", "food"],
"created_at": "2026-01-26T10:00:00Z",
"updated_at": "2026-01-26T10:00:00Z"
}
],
"pagination": {
"total": 50,
"page": 1,
"limit": 20,
"totalPages": 3
}
}
```
### 3. Get Story by ID
**GET** `/api/stories/:id`
**Response (200):**
```json
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "The Greedy Cat",
"logo": "https://cdn.sena.tech/thumbs/greedy-cat.jpg",
"vocabulary": ["cat", "eat", "apple"],
"context": [...],
"grade": ["Grade 1", "Grade 2"],
"tag": ["animals", "food"],
"created_at": "2026-01-26T10:00:00Z",
"updated_at": "2026-01-26T10:00:00Z"
}
}
```
### 4. Update Story
**PUT** `/api/stories/:id`
**Request Body:** (partial update)
```json
{
"name": "The Greedy Cat (Updated)",
"tag": ["animals", "food", "lesson", "health", "fiction", "updated"]
}
```
**Response (200):**
```json
{
"success": true,
"message": "Story updated successfully",
"data": {...}
}
```
### 5. Delete Story
**DELETE** `/api/stories/:id`
**Response (200):**
```json
{
"success": true,
"message": "Story deleted successfully"
}
```
### 6. Get Stories by Grade
**GET** `/api/stories/grade?grade=Grade 1`
**Response (200):**
```json
{
"success": true,
"data": [...],
"count": 15
}
```
### 7. Get Stories by Tag
**GET** `/api/stories/tag?tag=animals`
**Response (200):**
```json
{
"success": true,
"data": [...],
"count": 12
}
```
### 8. Get Story Statistics
**GET** `/api/stories/stats`
**Response (200):**
```json
{
"success": true,
"data": {
"total": 50,
"by_grade": [
{ "grade": "Grade 1", "count": 20 },
{ "grade": "Grade 2", "count": 15 }
],
"by_tag": [
{ "tag": "animals", "count": 12 },
{ "tag": "food", "count": 8 }
]
}
}
```
### 9. Get Story Guide (for AI)
**GET** `/api/stories/guide`
Returns comprehensive guide in JSON format for AI agents.
---
## Story Structure
### Minimal Story
```json
{
"name": "My Pet Dog",
"context": [
{ "text": "I have a pet dog.", "order": 1 },
{ "text": "My dog is brown.", "order": 2 },
{ "text": "I love my dog.", "order": 3 }
]
}
```
### Complete Story
```json
{
"name": "The Greedy Cat",
"logo": "https://cdn.sena.tech/thumbs/greedy-cat.jpg",
"vocabulary": ["cat", "eat", "apple", "happy", "greedy"],
"context": [
{
"image": "https://cdn.sena.tech/story/gc-scene1.jpg",
"text": "Once upon a time, there was a greedy cat.",
"audio": "https://cdn.sena.tech/audio/gc-scene1.mp3",
"order": 1
},
{
"image": "https://cdn.sena.tech/story/gc-scene2.jpg",
"text": "The cat loved eating apples every day.",
"audio": "https://cdn.sena.tech/audio/gc-scene2.mp3",
"order": 2
},
{
"image": "https://cdn.sena.tech/story/gc-scene3.jpg",
"text": "One day, the cat ate too many apples and felt sick.",
"audio": "https://cdn.sena.tech/audio/gc-scene3.mp3",
"order": 3
},
{
"image": "https://cdn.sena.tech/story/gc-scene4.jpg",
"text": "The cat learned to eat just enough and was happy again.",
"audio": "https://cdn.sena.tech/audio/gc-scene4.mp3",
"order": 4
}
],
"grade": ["Grade 1", "Grade 2"],
"tag": ["animals", "food", "lesson", "health", "fiction"]
}
```
---
## Context Objects
Each context object represents a **scene or page** in the story.
### Context Structure
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `text` | string | ✓ | Story text for this scene |
| `order` | integer | ✓ | Sequence number (1, 2, 3...) |
| `image` | string (URL) | - | Scene illustration image |
| `audio` | string (URL) | - | Audio narration file |
### Example Context
```json
{
"image": "https://cdn.sena.tech/story/scene1.jpg",
"text": "Once upon a time, there was a greedy cat.",
"audio": "https://cdn.sena.tech/audio/scene1.mp3",
"order": 1
}
```
### Best Practices
**Sequential Order** - Use 1, 2, 3, 4... for logical flow
**Concise Text** - Keep sentences short and age-appropriate
**High-Quality Images** - Use clear, engaging illustrations
**Audio Narration** - Provide audio for listening practice
**Consistent Style** - Maintain uniform visual and audio quality
---
## Vocabulary Integration
### Linking to Vocab Entries
**Option 1: Simple Word List**
```json
{
"vocabulary": ["cat", "eat", "apple", "happy"]
}
```
**Option 2: Vocab Codes (Recommended)**
```json
{
"vocabulary": ["vocab-001-cat", "vocab-002-eat", "vocab-015-apple"]
}
```
### Benefits
- **Word Learning** - Students learn vocabulary through context
- **Practice** - Reinforce words from vocabulary lessons
- **Tracking** - Monitor which words appear in which stories
- **Search** - Find stories containing specific vocabulary
### Guidelines
✅ Include only words that **appear in the story**
✅ Use vocab_code from Vocab table for better tracking
✅ Order by frequency or importance
✅ Limit to 5-15 key words per story
---
## Grade Levels & Tags
### Supported Grade Levels
```json
{
"grade": ["Pre-K", "Kindergarten", "Grade 1", "Grade 2", "Grade 3", "Grade 4", "Grade 5", "Grade 6"]
}
```
**Tips:**
- Can assign **multiple grades** for cross-level content
- Consider vocabulary difficulty when assigning grades
- Match with curriculum standards
### Tag Categories
**Themes:**
```json
["adventure", "friendship", "family", "courage", "honesty", "kindness"]
```
**Subjects:**
```json
["animals", "nature", "food", "school", "home", "travel"]
```
**Skills:**
```json
["reading", "listening", "vocabulary", "grammar", "phonics"]
```
**Emotions:**
```json
["happy", "sad", "excited", "scared", "surprised"]
```
**Genres:**
```json
["fiction", "non-fiction", "fantasy", "realistic", "fable"]
```
### Tag Best Practices
✅ Use **3-7 tags** per story
✅ Mix different category types
✅ Keep tags **consistent** across stories
✅ Use **lowercase** for consistency
✅ Avoid redundant tags
---
## Use Cases & Examples
### Use Case 1: Animal Story for Grade 1
```json
{
"name": "The Brave Little Mouse",
"logo": "https://cdn.sena.tech/thumbs/brave-mouse.jpg",
"vocabulary": ["mouse", "brave", "help", "friend"],
"context": [
{
"image": "https://cdn.sena.tech/mouse/scene1.jpg",
"text": "There was a little mouse.",
"audio": "https://cdn.sena.tech/mouse/audio1.mp3",
"order": 1
},
{
"image": "https://cdn.sena.tech/mouse/scene2.jpg",
"text": "The mouse was very brave.",
"audio": "https://cdn.sena.tech/mouse/audio2.mp3",
"order": 2
},
{
"image": "https://cdn.sena.tech/mouse/scene3.jpg",
"text": "The mouse helped his friend.",
"audio": "https://cdn.sena.tech/mouse/audio3.mp3",
"order": 3
}
],
"grade": ["Grade 1"],
"tag": ["animals", "courage", "friendship", "fiction"]
}
```
### Use Case 2: Food Story for Multiple Grades
```json
{
"name": "The Healthy Eating Adventure",
"logo": "https://cdn.sena.tech/thumbs/healthy-eating.jpg",
"vocabulary": ["apple", "orange", "banana", "healthy", "eat"],
"context": [
{
"image": "https://cdn.sena.tech/food/scene1.jpg",
"text": "Lisa loves to eat healthy food.",
"audio": "https://cdn.sena.tech/food/audio1.mp3",
"order": 1
},
{
"image": "https://cdn.sena.tech/food/scene2.jpg",
"text": "She eats apples, oranges, and bananas every day.",
"audio": "https://cdn.sena.tech/food/audio2.mp3",
"order": 2
},
{
"image": "https://cdn.sena.tech/food/scene3.jpg",
"text": "Eating healthy makes her strong and happy!",
"audio": "https://cdn.sena.tech/food/audio3.mp3",
"order": 3
}
],
"grade": ["Grade 1", "Grade 2", "Grade 3"],
"tag": ["food", "health", "lesson", "realistic"]
}
```
### Use Case 3: Educational Non-Fiction
```json
{
"name": "How Plants Grow",
"logo": "https://cdn.sena.tech/thumbs/plants-grow.jpg",
"vocabulary": ["seed", "water", "sun", "grow", "plant"],
"context": [
{
"image": "https://cdn.sena.tech/plant/scene1.jpg",
"text": "A plant starts from a tiny seed.",
"audio": "https://cdn.sena.tech/plant/audio1.mp3",
"order": 1
},
{
"image": "https://cdn.sena.tech/plant/scene2.jpg",
"text": "The seed needs water and sun to grow.",
"audio": "https://cdn.sena.tech/plant/audio2.mp3",
"order": 2
},
{
"image": "https://cdn.sena.tech/plant/scene3.jpg",
"text": "Soon, it becomes a big, beautiful plant!",
"audio": "https://cdn.sena.tech/plant/audio3.mp3",
"order": 3
}
],
"grade": ["Grade 2", "Grade 3"],
"tag": ["nature", "science", "non-fiction", "plants"]
}
```
---
## Database Queries
### Query 1: Find All Stories for Grade 1
```sql
SELECT * FROM stories
WHERE grade::jsonb @> '["Grade 1"]'::jsonb
ORDER BY created_at DESC;
```
### Query 2: Find Stories by Tag
```sql
SELECT * FROM stories
WHERE tag::jsonb @> '["animals"]'::jsonb
ORDER BY name ASC;
```
### Query 3: Search Stories by Name
```sql
SELECT * FROM stories
WHERE name LIKE '%cat%'
ORDER BY created_at DESC;
```
### Query 4: Get Stories with Specific Vocabulary
```sql
SELECT * FROM stories
WHERE vocabulary::jsonb @> '["cat"]'::jsonb
ORDER BY created_at DESC;
```
### Query 5: Count Stories by Grade
```sql
SELECT
grade_elem AS grade,
COUNT(*) AS story_count
FROM stories,
jsonb_array_elements_text(grade) AS grade_elem
GROUP BY grade_elem
ORDER BY story_count DESC;
```
### Query 6: Count Stories by Tag
```sql
SELECT
tag_elem AS tag,
COUNT(*) AS story_count
FROM stories,
jsonb_array_elements_text(tag) AS tag_elem
GROUP BY tag_elem
ORDER BY story_count DESC;
```
---
## Validation Rules
### 1. Required Fields
**Rule:** `name` is required
**Valid:**
```json
{ "name": "My Story" }
```
**Invalid:**
```json
{ "logo": "..." }
```
### 2. Context Structure
**Rule:** Each context must have `text` and `order`
**Valid:**
```json
{
"context": [
{ "text": "Scene 1", "order": 1 },
{ "text": "Scene 2", "order": 2 }
]
}
```
**Invalid:**
```json
{
"context": [
{ "text": "Scene 1" } // Missing order
]
}
```
### 3. Sequential Order
**Rule:** Order numbers should be sequential
**Valid:**
```json
{
"context": [
{ "order": 1, "text": "..." },
{ "order": 2, "text": "..." },
{ "order": 3, "text": "..." }
]
}
```
**Invalid:**
```json
{
"context": [
{ "order": 1, "text": "..." },
{ "order": 3, "text": "..." }, // Skipped 2
{ "order": 2, "text": "..." } // Out of order
]
}
```
### 4. Array Fields
**Rule:** `grade`, `tag`, `vocabulary`, `context` must be arrays
**Valid:**
```json
{
"grade": ["Grade 1"],
"tag": ["animals"]
}
```
**Invalid:**
```json
{
"grade": "Grade 1", // Should be array
"tag": "animals" // Should be array
}
```
### 5. URL Validation
**Rule:** `logo`, `image`, `audio` should be valid URLs
**Valid:**
```json
{
"logo": "https://cdn.sena.tech/logo.jpg",
"context": [
{
"image": "https://cdn.sena.tech/scene.jpg",
"audio": "https://cdn.sena.tech/audio.mp3",
"text": "...",
"order": 1
}
]
}
```
---
## AI Integration Guide
### For AI Agents Creating Stories
#### Step 1: Choose Story Topic
1. Identify target audience (grade level)
2. Select theme (animals, food, adventure, etc.)
3. Determine vocabulary focus
4. Decide story length (3-10 scenes)
#### Step 2: Create Story Outline
```
Title: The Greedy Cat
Grade: Grade 1-2
Theme: Animals + Health Lesson
Vocabulary: cat, eat, apple, greedy, sick, happy
Scenes: 4
```
#### Step 3: Write Context Scenes
For each scene:
1. Write concise, age-appropriate text
2. Assign sequential order number
3. Plan corresponding image
4. Prepare audio narration
#### Step 4: Structure Data
```json
{
"name": "The Greedy Cat",
"logo": "https://cdn.sena.tech/thumbs/greedy-cat.jpg",
"vocabulary": ["cat", "eat", "apple", "greedy", "sick", "happy"],
"context": [
{
"image": "https://cdn.sena.tech/story/gc-scene1.jpg",
"text": "Once upon a time, there was a greedy cat.",
"audio": "https://cdn.sena.tech/audio/gc-scene1.mp3",
"order": 1
}
// ... more scenes
],
"grade": ["Grade 1", "Grade 2"],
"tag": ["animals", "food", "lesson", "health", "fiction"]
}
```
#### Step 5: Validate Data
**Pre-Submit Checklist:**
1.`name` is provided and descriptive
2.`context` array has at least 1 scene
3. ✓ Each context has `text` and `order`
4. ✓ Order numbers are sequential (1, 2, 3...)
5. ✓ Vocabulary words match story content
6. ✓ Grade levels are appropriate
7. ✓ Tags are relevant and descriptive
8. ✓ URLs are accessible
9. ✓ Text is age-appropriate
10. ✓ Story has clear beginning, middle, end
#### Step 6: Submit via API
```bash
POST /api/stories
Content-Type: application/json
Authorization: Bearer <token>
{...story data...}
```
### Common Mistakes to Avoid
1. **Missing Context Order**
-`{ "context": [{ "text": "Some text" }] }`
-`{ "context": [{ "text": "Some text", "order": 1 }] }`
2. **Non-Sequential Order**
-`[{ "order": 1 }, { "order": 3 }, { "order": 2 }]`
-`[{ "order": 1 }, { "order": 2 }, { "order": 3 }]`
3. **Invalid Grade Format**
-`{ "grade": "Grade 1" }`
-`{ "grade": ["Grade 1"] }`
4. **Mismatched Vocabulary**
-`{ "name": "The Cat", "vocabulary": ["dog", "bird"] }`
-`{ "name": "The Cat", "vocabulary": ["cat"] }`
5. **Missing Story Name**
-`{ "context": [...] }`
-`{ "name": "My Story", "context": [...] }`
### AI Tips
- **Content Creation:** Generate age-appropriate, engaging stories with clear moral lessons
- **Vocabulary Integration:** Reference existing vocabulary entries from Vocab table
- **Multimedia:** Always provide audio URLs for better learning engagement
- **Sequencing:** Ensure context order is logical and sequential
- **Testing:** Test story flow by reading context in order
- **Consistency:** Use consistent naming conventions for URLs and vocabulary
---
## Summary
The Story System provides a comprehensive framework for:
1. **Creating Interactive Stories** - Multimedia learning content
2. **Vocabulary Integration** - Link to existing vocab entries
3. **Grade Targeting** - Assign appropriate difficulty levels
4. **Flexible Categorization** - Organize by themes, subjects, skills
5. **AI-Ready** - Comprehensive guide for automated content creation
**Key Benefits:**
- ✅ Engaging multimedia learning experience
- ✅ Vocabulary reinforcement through context
- ✅ Grade-appropriate content filtering
- ✅ Flexible tag-based organization
- ✅ UUID security to prevent crawlers
- ✅ AI-friendly for automated story generation
**Next Steps:**
1. Create story content with context scenes
2. Link vocabulary from Vocab table
3. Assign appropriate grades and tags
4. Provide multimedia assets (images, audio)
5. Test story flow and engagement
---
**For questions or support, contact the SENA development team.**