19 KiB
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
- Overview
- Database Structure
- API Endpoints
- Story Structure
- Context Objects
- Vocabulary Integration
- Grade Levels & Tags
- Use Cases & Examples
- Database Queries
- Validation Rules
- 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 nameidx_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:
{
"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):
{
"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 namegrade_filter(string) - Filter by grade leveltag_filter(string) - Filter by tagsort_by(string, default: 'created_at')sort_order('ASC'/'DESC', default: 'DESC')
Response (200):
{
"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):
{
"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)
{
"name": "The Greedy Cat (Updated)",
"tag": ["animals", "food", "lesson", "health", "fiction", "updated"]
}
Response (200):
{
"success": true,
"message": "Story updated successfully",
"data": {...}
}
5. Delete Story
DELETE /api/stories/:id
Response (200):
{
"success": true,
"message": "Story deleted successfully"
}
6. Get Stories by Grade
GET /api/stories/grade?grade=Grade 1
Response (200):
{
"success": true,
"data": [...],
"count": 15
}
7. Get Stories by Tag
GET /api/stories/tag?tag=animals
Response (200):
{
"success": true,
"data": [...],
"count": 12
}
8. Get Story Statistics
GET /api/stories/stats
Response (200):
{
"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
{
"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
{
"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
{
"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
{
"vocabulary": ["cat", "eat", "apple", "happy"]
}
Option 2: Vocab Codes (Recommended)
{
"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
{
"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:
["adventure", "friendship", "family", "courage", "honesty", "kindness"]
Subjects:
["animals", "nature", "food", "school", "home", "travel"]
Skills:
["reading", "listening", "vocabulary", "grammar", "phonics"]
Emotions:
["happy", "sad", "excited", "scared", "surprised"]
Genres:
["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
{
"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
{
"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
{
"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
SELECT * FROM stories
WHERE grade::jsonb @> '["Grade 1"]'::jsonb
ORDER BY created_at DESC;
Query 2: Find Stories by Tag
SELECT * FROM stories
WHERE tag::jsonb @> '["animals"]'::jsonb
ORDER BY name ASC;
Query 3: Search Stories by Name
SELECT * FROM stories
WHERE name LIKE '%cat%'
ORDER BY created_at DESC;
Query 4: Get Stories with Specific Vocabulary
SELECT * FROM stories
WHERE vocabulary::jsonb @> '["cat"]'::jsonb
ORDER BY created_at DESC;
Query 5: Count Stories by Grade
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
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:
{ "name": "My Story" }
Invalid:
{ "logo": "..." }
2. Context Structure
Rule: Each context must have text and order
Valid:
{
"context": [
{ "text": "Scene 1", "order": 1 },
{ "text": "Scene 2", "order": 2 }
]
}
Invalid:
{
"context": [
{ "text": "Scene 1" } // Missing order
]
}
3. Sequential Order
Rule: Order numbers should be sequential
Valid:
{
"context": [
{ "order": 1, "text": "..." },
{ "order": 2, "text": "..." },
{ "order": 3, "text": "..." }
]
}
Invalid:
{
"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:
{
"grade": ["Grade 1"],
"tag": ["animals"]
}
Invalid:
{
"grade": "Grade 1", // Should be array
"tag": "animals" // Should be array
}
5. URL Validation
Rule: logo, image, audio should be valid URLs
Valid:
{
"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
- Identify target audience (grade level)
- Select theme (animals, food, adventure, etc.)
- Determine vocabulary focus
- 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:
- Write concise, age-appropriate text
- Assign sequential order number
- Plan corresponding image
- Prepare audio narration
Step 4: Structure Data
{
"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:
- ✓
nameis provided and descriptive - ✓
contextarray has at least 1 scene - ✓ Each context has
textandorder - ✓ Order numbers are sequential (1, 2, 3...)
- ✓ Vocabulary words match story content
- ✓ Grade levels are appropriate
- ✓ Tags are relevant and descriptive
- ✓ URLs are accessible
- ✓ Text is age-appropriate
- ✓ Story has clear beginning, middle, end
Step 6: Submit via API
POST /api/stories
Content-Type: application/json
Authorization: Bearer <token>
{...story data...}
Common Mistakes to Avoid
-
Missing Context Order
- ❌
{ "context": [{ "text": "Some text" }] } - ✅
{ "context": [{ "text": "Some text", "order": 1 }] }
- ❌
-
Non-Sequential Order
- ❌
[{ "order": 1 }, { "order": 3 }, { "order": 2 }] - ✅
[{ "order": 1 }, { "order": 2 }, { "order": 3 }]
- ❌
-
Invalid Grade Format
- ❌
{ "grade": "Grade 1" } - ✅
{ "grade": ["Grade 1"] }
- ❌
-
Mismatched Vocabulary
- ❌
{ "name": "The Cat", "vocabulary": ["dog", "bird"] } - ✅
{ "name": "The Cat", "vocabulary": ["cat"] }
- ❌
-
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:
- Creating Interactive Stories - Multimedia learning content
- Vocabulary Integration - Link to existing vocab entries
- Grade Targeting - Assign appropriate difficulty levels
- Flexible Categorization - Organize by themes, subjects, skills
- 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:
- Create story content with context scenes
- Link vocabulary from Vocab table
- Assign appropriate grades and tags
- Provide multimedia assets (images, audio)
- Test story flow and engagement
For questions or support, contact the SENA development team.