---
url: https://docs.nemo12.com/architecture/sdd-035-ielts-onboarding.md
description: >-
  Bản nháp luồng vào IELTS (SDD-035): năm bước, quiz hiểu biết và bài đánh giá
  bốn kỹ năng mở rộng lên 24 câu.
---

# SDD-035 — Luồng vào IELTS: năm bước, quiz hiểu biết, bài đánh giá bốn kỹ năng

Chỉ đạo chủ dự án 2026-09-15: *"Hệ thống đưa ra gợi ý để Learner tự điền thông tin Mục tiêu (bước 1/5). Và hệ thống cho Learner làm một cái quiz để đánh giá toàn cảnh, xem learner hiểu về IELTS như thế nào. Sau đó learner có thể làm Assessment. Learner cần chủ động bấm nút gì đó để vào xem giới thiệu về assessment (mục tiêu, ý nghĩa của nó), sau đó learner làm bài."*

## 1. Năm bước, và vì sao đúng năm bước ấy

> **Đã thay (SRC-1077, 27.09.2026).** Năm bước dưới đây, `modules/ielts/journey.ts`, endpoint `ielts-journey` và dải `JourneyStrip` đã bỏ; thay bằng Journey Engine: tám hành trình chạy song song và một việc tiếp theo ([SDD-045](sdd-045-journey-engine.md), [PRD-005](../product/prd-005-journey-engine.md)). Quiz hiểu biết (§2) và bài đánh giá (§3) vẫn chạy nguyên, nay là hai việc của hành trình Diagnosis. Phần dưới giữ làm lịch sử quyết định.

Đúng năm bước đang đứng trên trang công khai `nemo12.com/ielts/journey` (SRC-726): **Mục tiêu → Chẩn đoán → Khoảng cách → Lộ trình → Sẵn sàng**. Một learner đọc trang giới thiệu rồi đăng nhập mà thấy một cách chia bước KHÁC là mất niềm tin ngay ở lần vào đầu tiên, và khó lấy lại: nó không giống một lỗi kỹ thuật, nó giống hai lời hứa khác nhau.

**Trạng thái được suy ra, không được ghi.** Không có cột `onboarding_step`. Mỗi bước hỏi thẳng dữ liệu của chính nó (`modules/ielts/journey.ts`): có mục tiêu chưa, đã nộp bài đánh giá chưa, đã khai nguyện vọng giờ học chưa. Một cột trạng thái riêng chắc chắn sẽ lệch khỏi sự thật: learner xoá mục tiêu thì cột vẫn ghi "xong bước 1" và không ai biết.

| Bước | Xong khi | Làm ở đâu |
| --- | --- | --- |
| 1. Mục tiêu | có `learner_ielts_goals` đang hoạt động | card IELTS trong Hồ sơ |
| 2. Chẩn đoán | **cả** quiz hiểu biết **lẫn** bài đánh giá bốn kỹ năng | trang Con và IELTS |
| 3. Khoảng cách | có lời khai **và** một nguồn điểm (bài đánh giá hoặc baseline) | trang Con và IELTS |
| 4. Lộ trình | có ít nhất một mốc trung gian | trang Lộ trình IELTS |
| 5. Sẵn sàng | đã khai nguyện vọng giờ học **và** ghi tên một buổi | Học cùng thầy cô ([SDD-034](sdd-034-mentor-slots.md)) |

Bước 2 và bước 5 mỗi bước gồm **hai việc**, nên chúng có `parts` và giao diện nói rõ còn thiếu việc nào. Một bước "chưa xong" mà không nói thiếu gì thì learner đứng lại ở đó.

## 2. Quiz hiểu biết: một loại việc khác, nên là một bảng khác

Bài đánh giá hỏi *"con LÀM ĐƯỢC gì"*. Quiz này hỏi *"con HIỂU luật chơi tới đâu"*. Hai thứ hỏng theo hai kiểu và chữa bằng hai cách:

* Reading yếu thì chữa bằng nhiều tháng luyện.
* Tưởng Task 1 và Task 2 nặng ngang nhau thì chữa bằng **một câu** nói cho đúng. Nhưng nếu không ai nói, đứa trẻ ấy chia sai thời gian trong suốt nhiều tháng luyện và cả kỳ thi thật.

Vì thế quiz **chấm ngay**, hiện giải thích cho **mọi** câu kể cả câu đúng (trả lời đúng vì đoán và đúng vì hiểu là hai chuyện), và làm lại bao nhiêu lần cũng được.

**Kết quả quiz KHÔNG vào Learner Model.** Đây là ranh giới quan trọng nhất của mảng này: hiểu nhầm cách tính band không làm Reading của một đứa trẻ yếu đi. Nếu nhét quiz vào `assessment_sessions` thì nó bơm bằng chứng "sai ba câu" vào một model về năng lực tiếng Anh. Bảng riêng `ielts_exam_quiz_attempts` (migration 0224) không nối vào `skill_nodes`, và có test canh đúng điều đó.

**Câu hỏi nằm trong mã nguồn** (`modules/ielts/examQuiz.ts`), không trong CSDL: đây là kiến thức về một kỳ thi ổn định nhiều năm, và một câu SAI ở đây dạy sai cho mọi learner cùng lúc. Sửa nó phải là một commit có người đọc lại, không phải một lượt INSERT. `QUIZ_VERSION` tăng mỗi lần đổi bộ câu.

Mười câu phủ sáu chủ đề: cấu trúc bài thi · cách tính band · thời gian làm bài · trọng số Writing · chọn đúng loại bài thi · kết quả và hiệu lực. Tiêu chuẩn chọn câu: **hiểu sai nó thì learner luyện sai**, không phải "kiến thức thú vị". Kết quả nói theo **chủ đề còn nhầm**, không theo số câu sai: "con còn nhầm ở cách tính band" là thứ sửa được, "con sai 3 câu" thì không.

## 3. Bài đánh giá: vào bằng hai nấc, và mở rộng lên 24 câu

**Hai nấc.** Learner bấm "Bài đánh giá này là gì?" để mở phần giới thiệu, đọc xong mới bấm "Bắt đầu làm bài". Mở thẳng vào bài thì phần giới thiệu chỉ là một dòng chữ bị lướt qua.

Phần giới thiệu do **server** trả (`GET .../ielts-assessment-brief`) chứ không viết trong JSX, vì nó mang con số (bao nhiêu câu, mấy kỹ năng) và những con số ấy phải là chính `PER_SKILL` của bài thật. Viết lại chúng trong giao diện là hẹn ngày màn hình hứa "mười hai câu" còn bài thật hỏi hai mươi tư. Đường này **chỉ đọc**: gộp vào `POST ielts-diagnostic` sẽ sinh một phiên bỏ dở cho mỗi lần learner tò mò mở ra.

Thứ tự trong phần giới thiệu cố ý đặt **giới hạn trước lợi ích**: một learner tin bài này ra band sẽ đem con số đi so với mục tiêu du học, rồi mất niềm tin vào cả hệ thống lúc đi thi thật.

**Từ 3 câu lên 6 câu mỗi kỹ năng (12 → 24).** Ba câu là *sàn* của `layer.ts` (`MIN_ATTEMPTS_PER_SKILL`): đủ để dám xếp hạng, nhưng ở mức đó một cú bấm nhầm đổi tỉ lệ đúng của cả một kỹ năng từ 100% xuống 67%, và phép so sánh giữa bốn kỹ năng lật ngược. Sáu câu không làm phép đo thành chính xác, chỉ làm nó bớt lung lay, mà vẫn dưới hai mươi phút. Không nâng tiếp lên tám hay mười vì đó là đổi loại việc: bài hai mươi câu thì learner làm xong, bài bốn mươi câu thì learner bỏ dở, và một bài bỏ dở không đo được gì.

Kho câu mỏng (dưới 6 câu một kỹ năng) thì **vẫn dựng bài** và trả `thin_skills` để người vận hành biết nạp thêm ở đâu; chỉ khi một kỹ năng **không có câu nào** mới từ chối, vì lúc ấy phép so sánh bốn kỹ năng không còn nghĩa.

## 4. API

| Route | Việc |
| --- | --- |
| ~~`GET /v1/learners/{id}/ielts-journey`~~ | Đã bỏ ở SRC-1077; thay bằng `GET /v1/learners/{id}/journeys` (SDD-045 §9) |
| `GET /v1/learners/{id}/ielts-exam-quiz` | Bộ câu hỏi (KHÔNG kèm đáp án) + lượt làm gần nhất |
| `POST /v1/learners/{id}/ielts-exam-quiz/submit` | Chấm ngay, trả giải thích từng câu và chủ đề còn nhầm |
| `GET /v1/learners/{id}/ielts-assessment-brief` | Mục tiêu, giới hạn, việc cần chuẩn bị; không tạo phiên |

Cả bốn đi qua `canAccessLearner` (QG-008). Ghi lượt quiz hỏng thì **vẫn trả kết quả**: learner vừa làm xong mười câu, mất bản ghi là chuyện của ta, bắt họ làm lại vì chuyện đó thì không.

## 5. Giao diện

`apps/learn/src/IeltsOnboarding.tsx` (`ExamQuizCard`; `JourneyStrip` đã thay bằng `JourneyNextUp` ở SRC-1077) và phần giới thiệu hai nấc trong `apps/learn/src/IeltsProfilePage.tsx`. Dải năm bước chỉ nói về **bước đang đứng**: bày việc phải làm của cả năm bước cùng lúc là cách chắc chắn nhất để learner không làm bước nào.

## 6. Phần CỐ Ý chưa làm

* **Gợi ý mục tiêu tự động ở bước 1.** Chủ dự án nói "hệ thống đưa ra gợi ý để learner tự điền Mục tiêu". Đường chia mốc đã có (`milestones/suggest`), nhưng gợi ý **band mục tiêu** thì cần biết learner nhắm trường nào, mà dữ liệu ấy chưa có cấu trúc. Hiện bước 1 vẫn để learner tự điền.
* **Câu tự luận ngắn cho Writing và Speaking.** Bài đánh giá đang thuần trắc nghiệm, nên hai kỹ năng sản sinh được đo gián tiếp. Muốn đo trực tiếp thì cần đường chấm, và đó là một vòng riêng.

## Trace

| REQ | Section |
| --- | --- |
| REQ-ONB-11 | §1, §4, §5 |
| REQ-ONB-12 | §2, §3, §4, §5 |
