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
293 lines
7.3 KiB
Markdown
293 lines
7.3 KiB
Markdown
# 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..C3`
|
|
- `POST /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
|
|
|
|
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 `GET` endpoint.
|
|
- `POST` and `PATCH` are 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)
|
|
|
|
```json
|
|
{
|
|
"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:
|
|
- `400` with error message: `Use one of: A1,A2,A3,B1,B2,B3,C1,C2,C3`
|
|
- Course not in human language category:
|
|
- `400` with 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`
|
|
|
|
```json
|
|
{
|
|
"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}`
|
|
|
|
```json
|
|
{
|
|
"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:
|
|
|
|
1. `GET /course-management/categories`
|
|
2. Pick category where name indicates human language.
|
|
3. `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_order` and maintain backend order.
|
|
- Show badges:
|
|
- video count
|
|
- practice count
|
|
|
|
---
|
|
|
|
## 7) Error Handling and Resilience
|
|
|
|
- `400` invalid 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:
|
|
|
|
```ts
|
|
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/categories`
|
|
- `GET /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.go`
|
|
- `internal/web_server/routes.go`
|
|
|