# 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 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 {...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.**