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

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

  1. Overview
  2. Database Structure
  3. API Endpoints
  4. Story Structure
  5. Context Objects
  6. Vocabulary Integration
  7. Grade Levels & Tags
  8. Use Cases & Examples
  9. Database Queries
  10. Validation Rules
  11. 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:

{
  "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 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):

{
  "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

  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

{
  "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

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.