Yimaru-BackEnd/docs/audio-practice-integration.md

10 KiB

Audio Practice (Speaking Practice) — Admin Panel Integration Guide

Overview

The Yimaru backend fully supports audio/speaking practices. This guide covers the steps needed to integrate the feature into the admin panel frontend.


Backend Status ( Already Complete)

Layer File What It Does
Domain internal/domain/questions.go QuestionTypeAudio = "AUDIO" constant, VoicePrompt, SampleAnswerVoicePrompt, AudioCorrectAnswerText fields
Handler internal/web_server/handlers/questions.go CreateQuestion accepts question_type: "AUDIO" with audio-specific fields
Handler internal/web_server/handlers/file_handler.go UploadAudio (general audio upload) and SubmitAudioAnswer (learner recording)
Migration db/migrations/000022_audio_questions.up.sql AUDIO type constraint + question_audio_answers table
Migration db/migrations/000028_user_audio_responses.up.sql user_audio_responses table for learner recordings
SQL db/query/question_audio_answers.sql CRUD for correct answer text per audio question
SQL db/query/user_audio_responses.sql CRUD for learner audio submissions
Routes internal/web_server/routes.go POST /files/audio, POST /questions/audio-answer

Admin Panel Frontend Steps

Step 1: Add "AUDIO" Option to the Question Type Selector

When creating/editing a question, the admin should be able to select AUDIO as a question type alongside MCQ, TRUE_FALSE, and SHORT_ANSWER.


Step 2: Build the AUDIO Question Form

When question_type = "AUDIO" is selected, render these fields:

Field API Field Type Required Description
Question Text question_text string The prompt/instruction text shown to the learner
Voice Prompt voice_prompt string (URL) Optional Audio file URL — the question read aloud or a listening prompt
Sample Answer Voice sample_answer_voice_prompt string (URL) Optional Audio URL of a model/reference answer
Correct Answer Text audio_correct_answer_text string Optional Expected textual answer (used for grading/comparison)
Image image_url string (URL) Optional Supporting image for the question
Explanation explanation string Optional Shown to the learner after answering
Tips tips string Optional Hints shown before/during the question
Difficulty Level difficulty_level string Optional EASY, MEDIUM, or HARD
Points points int Optional Score value (defaults to 1)

Note: Hide the options and short_answers fields when AUDIO is selected — they are not used for this type.


Step 3: Build an Audio Uploader Component

Create a reusable audio uploader used for both voice_prompt and sample_answer_voice_prompt.

API Call:

POST /files/audio
Content-Type: multipart/form-data

Form field: "file" — the audio file

Constraints:

  • Max file size: 50 MB
  • Allowed formats: mp3, wav, ogg, m4a, aac, webm, flac

Response:

{
  "message": "Audio file uploaded successfully",
  "data": {
    "object_key": "audio/1710000000_recording.mp3",
    "url": "https://...",
    "content_type": "audio/mpeg"
  },
  "success": true
}

Usage:

  1. Admin clicks "Upload Voice Prompt" → file picker opens
  2. File is uploaded via POST /files/audio
  3. Store the returned object_key as the value for voice_prompt or sample_answer_voice_prompt
  4. Display the audio player preview (see Step 4)

Step 4: Build an Audio Player / Preview Component

After uploading, let admins preview the audio.

To get a playable URL from an object key:

GET /files/url?key=<object_key>

Frontend implementation:

<audio controls src="<resolved_url>"></audio>

This component should be shown:

  • Next to the voice prompt upload field (after upload)
  • Next to the sample answer voice prompt upload field (after upload)
  • When viewing/editing an existing AUDIO question

Step 5: Create a Practice with Audio Questions

The full admin workflow:

5.1 Create the Practice Set (Question Set)

POST /question-sets

{
  "title": "Speaking Practice - Lesson 1",
  "description": "Practice your pronunciation",
  "set_type": "PRACTICE",
  "owner_type": "SUB_COURSE",
  "owner_id": 42,
  "status": "DRAFT"
}

5.2 Upload Audio Files

POST /files/audio   →  voice_prompt object_key
POST /files/audio   →  sample_answer_voice_prompt object_key

5.3 Create AUDIO Questions

POST /questions

{
  "question_text": "Listen and repeat the following phrase",
  "question_type": "AUDIO",
  "voice_prompt": "minio://audio/1710000000_prompt.mp3",
  "sample_answer_voice_prompt": "minio://audio/1710000000_sample.mp3",
  "audio_correct_answer_text": "Hello, how are you?",
  "difficulty_level": "EASY",
  "points": 10
}
POST /question-sets/:setId/questions

{
  "question_id": 123,
  "display_order": 1
}

5.5 (Optional) Add Personas

POST /question-sets/:setId/personas

{
  "user_id": 5,
  "display_order": 1
}

5.6 (Optional) Reorder Practices in a Sub-course

PUT /course-management/practices/reorder

{
  "sub_course_id": 42,
  "ordered_ids": [10, 11, 12]
}

Step 6: Display Audio Questions in the Question List

When listing questions (GET /questions?question_type=AUDIO), show:

  • An 🔊 audio icon or "AUDIO" badge for the question type
  • A mini audio player if voice_prompt is set
  • The audio_correct_answer_text value (if present)

When viewing a single question (GET /questions/:id), the response includes:

{
  "question_type": "AUDIO",
  "voice_prompt": "minio://audio/...",
  "sample_answer_voice_prompt": "minio://audio/...",
  "audio_correct_answer_text": "Hello, how are you?"
}

Step 7: (Optional) Admin Review of Learner Audio Submissions

⚠️ Not yet built — requires a new backend endpoint if needed.

Currently, learner audio submissions are stored in user_audio_responses but there's no admin-facing endpoint to list/review them.

If this is needed, add:

  1. New SQL query in db/query/user_audio_responses.sql:

    -- name: ListAudioResponsesByQuestionSet :many
    SELECT uar.*, u.first_name, u.last_name
    FROM user_audio_responses uar
    JOIN users u ON u.id = uar.user_id
    WHERE uar.question_set_id = $1
    ORDER BY uar.created_at DESC
    LIMIT $2 OFFSET $3;
    
  2. New endpoint in routes.go:

    GET /admin/question-sets/:setId/audio-responses
    
  3. Admin UI: A table showing learner name, audio player for their recording, timestamp, and the correct answer text for comparison.


API Flow Summary

┌─────────────────────────────────────────────────────────┐
│                    ADMIN CREATES PRACTICE                │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  POST /question-sets                                    │
│    → Creates practice shell (set_type: "PRACTICE")      │
│                                                         │
│  POST /files/audio                                      │
│    → Uploads voice_prompt audio file                    │
│                                                         │
│  POST /files/audio                                      │
│    → Uploads sample_answer_voice_prompt audio file      │
│                                                         │
│  POST /questions                                        │
│    → Creates AUDIO question with voice prompt URLs      │
│      and correct_answer_text                            │
│                                                         │
│  POST /question-sets/:id/questions                      │
│    → Links question to practice set                     │
│                                                         │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│                 LEARNER COMPLETES PRACTICE               │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  GET  /files/url?key=...                                │
│    → Streams voice prompt audio                         │
│                                                         │
│  POST /questions/audio-answer                           │
│    → Submits learner's audio recording                  │
│                                                         │
│  POST /progress/practices/:id/complete                  │
│    → Marks practice as completed                        │
│                                                         │
└─────────────────────────────────────────────────────────┘

Required RBAC Permissions

Ensure the admin role has these permissions:

Permission Used By
questions.create Creating AUDIO questions
questions.update Editing AUDIO questions
questions.list Listing questions (filter by AUDIO)
questions.get Viewing a single question
questions.delete Deleting questions
question_sets.create Creating practice sets
question_sets.update Updating practice sets
question_set_items.add Adding questions to a set
question_set_items.list Listing questions in a set
question_set_items.remove Removing questions from a set
question_set_items.update_order Reordering questions
question_set_personas.add Adding personas
practices.reorder Reordering practices in a sub-course