Expose a dedicated human-language hierarchy endpoint aligned to category/subcategory/course/level/module/sub-module structure and add a complete learner mobile integration guide. Made-with: Cursor
7.3 KiB
Human Language Mobile Integration Guide
This guide explains how to integrate the new Human Language feature in the Yimaru learner mobile app (not admin).
It is designed to keep the existing non-language hierarchy intact while introducing a dedicated CEFR-based flow for language learning.
1) Scope and Goals
What is new
- A dedicated backend API namespace for Human Language:
GET /api/v1/course-management/human-language/courses/:courseId/lessons?cefr_level=A1..C3POST /api/v1/course-management/human-language/lessons(admin/instructor side)PATCH /api/v1/course-management/human-language/lessons/:id(admin/instructor side)
- CEFR levels are fixed to:
A1, A2, A3, B1, B2, B3, C1, C2, C3
- No custom sub-levels in Human Language flow.
What remains unchanged
- Existing non-human-language content hierarchy and APIs.
- Existing course/category/sub-course endpoints for non-language domains (programming, etc.).
2) Target Hierarchy for Human Language
- Course Category (Human Language)
- Course (e.g., English)
- CEFR Lesson Unit (A1..C3 only)
- Intro/lesson videos
- Practices
- Audio questions
- CEFR Lesson Unit (A1..C3 only)
- Course (e.g., English)
Backend implementation stores CEFR lesson units using the existing sub-course model, with CEFR mapped internally and validated strictly.
3) Authentication and Access
All Human Language endpoints are under /api/v1 and require bearer token auth.
- Header:
Authorization: Bearer <access_token>
Permission notes
- Learner mobile app typically needs only the
GETendpoint. POSTandPATCHare content-management endpoints and should generally be used by admin/instructor clients, not learner clients.
If learner roles do not currently have learning_tree.get, coordinate RBAC assignment for read-only access to the GET endpoint.
4) Endpoint Contracts
4.1 Fetch lessons by CEFR level (learner-facing)
Request
GET /api/v1/course-management/human-language/courses/{courseId}/lessons?cefr_level={A1|A2|A3|B1|B2|B3|C1|C2|C3}
Example
GET /api/v1/course-management/human-language/courses/12/lessons?cefr_level=B1
Response (success)
{
"message": "Human-language lessons retrieved successfully",
"data": {
"course_id": 12,
"course_title": "English",
"cefr_level": "B1",
"lessons": [
{
"id": 201,
"course_id": 12,
"title": "B1 Module 1",
"description": "Intermediate conversational patterns",
"thumbnail": "https://.../thumb.jpg",
"display_order": 1,
"level": "B1",
"video_count": 3,
"practice_count": 2,
"videos": [
{
"id": 9001,
"title": "B1 Intro",
"description": "Lesson intro",
"video_url": "https://...",
"duration": 420,
"resolution": "1080p",
"display_order": 1
}
],
"practices": [
{
"id": 4401,
"title": "B1 Speaking Practice",
"status": "PUBLISHED",
"question_count": 10
}
]
}
]
},
"success": true,
"status_code": 200,
"metadata": null
}
Validation errors
- Invalid CEFR level:
400with error message:Use one of: A1,A2,A3,B1,B2,B3,C1,C2,C3
- Course not in human language category:
400with error message indicating invalid human-language course.
4.2 Create Human Language lesson unit (admin/instructor)
Request
POST /api/v1/course-management/human-language/lessons
{
"course_id": 12,
"title": "A2 Module 1",
"description": "A2 speaking fundamentals",
"thumbnail": "https://...",
"display_order": 1,
"cefr_level": "A2"
}
Response
Returns created lesson metadata with CEFR-normalized level behavior.
4.3 Update Human Language lesson unit (admin/instructor)
Request
PATCH /api/v1/course-management/human-language/lessons/{lessonId}
{
"title": "A2 Module 1 - Updated",
"description": "Updated description",
"cefr_level": "A3",
"is_active": true
}
5) Recommended Mobile App Integration Flow
Step 1: Discover courses under Human Language category
Use existing endpoints:
GET /course-management/categories- Pick category where name indicates human language.
GET /course-management/categories/:categoryId/courses
Step 2: Select CEFR level in UI
Use static list in app:
A1, A2, A3, B1, B2, B3, C1, C2, C3
Do not allow custom levels in mobile UI.
Step 3: Fetch lessons by selected CEFR level
Call:
GET /course-management/human-language/courses/:courseId/lessons?cefr_level=<selected>
Render grouped lessons with nested videos/practices from response.
Step 4: Navigate to learning/practice screens
- Lesson video playback uses returned
videos[]. - Practice entry uses returned
practices[]IDs and existing practice-question endpoints.
6) Mobile UI/UX Recommendations
- Use CEFR tabs/segmented control (
A1...C3) at top. - Cache last selected level per course.
- Show empty state per level:
- "No lessons available for this level yet."
- Sort by
display_orderand maintain backend order. - Show badges:
- video count
- practice count
7) Error Handling and Resilience
400invalid level: reset selection to previous valid CEFR value and show toast/snackbar.401/403: trigger token refresh / re-login flow.5xx: show retry UI with exponential backoff.- If category/course fetch succeeds but level fetch fails, keep course visible and allow manual retry.
8) Data Model Mapping (Mobile DTO)
Suggested DTO for learner app:
type CefrLevel = "A1"|"A2"|"A3"|"B1"|"B2"|"B3"|"C1"|"C2"|"C3";
interface HumanLanguageLessonDTO {
id: number;
courseId: number;
title: string;
description?: string;
thumbnail?: string;
order: number;
level: CefrLevel;
videoCount: number;
practiceCount: number;
videos: {
id: number;
title: string;
url: string;
duration: number;
order: number;
}[];
practices: {
id: number;
title: string;
status: string;
questionCount: number;
}[];
}
9) Backward Compatibility
- Existing non-language content (programming and other categories) continues to use current APIs and hierarchy unchanged.
- New Human Language endpoint is additive and isolated.
- Mobile app can progressively enable the new flow for language categories only.
10) QA Checklist for Mobile Team
- Category discovery correctly identifies Human Language category.
- CEFR selector only allows A1..C3.
- Fetch by CEFR level returns only matching lessons.
- Video/practice counts match rendered lists.
- Empty-level state works.
- Unauthorized/session-expired flow works.
- Non-language courses still load via existing app flow.
11) Example Call Matrix
- Load language categories/courses:
GET /course-management/categoriesGET /course-management/categories/:id/courses
- Load A1 lessons:
GET /course-management/human-language/courses/:courseId/lessons?cefr_level=A1
- Load B2 lessons:
GET /course-management/human-language/courses/:courseId/lessons?cefr_level=B2
For backend ownership questions, refer to:
internal/web_server/handlers/course_management.gointernal/web_server/routes.go