SDD-010 · Đường đi của Unit ở Phòng Lab
Một phần của SDD-010.
9. Đường đi của Unit ở Phòng Lab (REQ-LRN-16 — SRC-102)
Trước SRC-102, mỗi node (bài) là một card kèm 2–3 dòng mô tả → một Unit có 4 node là 4 card × 3 dòng chữ, learner không biết bắt đầu từ đâu. Chủ dự án chỉ đạo học cách Duolingo: Unit là đơn vị đường đi, mỗi bước chỉ một hình.
Cấu trúc 9 ô (client dựng bằng unitPath(), không lưu bảng riêng — nội dung vẫn là node + item của unit):
Học vượt → Khám phá/Luyện tập ×3 → Đo giữa → Khám phá/Luyện tập ×3 → Đo cuối
assessment learning assessment learning assessmentHình trong ô (SRC-116) — art SVG procedural của apps/learn/src/N12Art.tsx, cùng một style 3D Pixar (gradient radial, rim light, mắt to), ô tròn cùng kích thước 80px và hình chiếm 56px cho dễ nhìn:
| Ô | Con vật | Vì sao |
|---|---|---|
| Học vượt | chim mòng biển mỏ rất to | bay vượt lên trên, qua cả unit trong một lần |
| Khám phá | cá ngựa | bơi chậm, tò mò nhìn ngó |
| Luyện tập · Luyện thêm | cua (dùng chung một icon) | cùng một việc, khác số lần |
| Đo giữa · Đo cuối | hải đăng · phao tiêu | mốc để định vị mình đang ở đâu |
Ba cỡ ô (SRC-138): ô đang làm 96px, ô mở bình thường 80px, ô khoá 48px + xám mờ — cùng một đường đi nhưng đọc ra "một việc bây giờ" thay vì "mười lăm việc". Màu viền ô vẫn nói trạng thái (chưa làm · đã xong · làm ngay) nhưng không làm mờ art nữa — mờ thì hình 3D mất hết khối. Bỏ luôn bộ đếm "0/9" ở cuối hàng (SRC-092: Phòng Lab không đếm số).
- Học vượt (Assessment,
kind=skip): 10 câu discriminator/boundary trải trên mọi node của unit, 1 bong bóng — sai một câu là trượt lượt đó, làm lại từ đầu. Đúng trọn vẹn thì cả unit ghi nhận là đã qua (mọi ô hiện màu "đã xong"). Học vượt là lựa chọn, không phải đường mặc định: ô "làm ngay" luôn là ô học chưa xong đầu tiên. - Đo giữa / Đo cuối (
kind=check): 6 câu; đo giữa lấy nửa đầu node của unit, đo cuối lấy cả unit. - Learning Experience (viết lại 2026-08-15, SRC-138): mỗi node cho các ô có NỘI DUNG THẬT — 🔬 Lab (nếu bài có lab), 🧪 Khám phá (nếu có nội dung khám phá), ✏️ Luyện tập. Không bù cho đủ 6 ô nữa: vòng 🔁 Luyện thêm chỉ mọc ra sau khi learner làm xong lượt trước, tối đa 4 lượt. Vẽ sẵn ba lượt lặp trên cùng một kho câu hỏi chỉ làm đường đi trông dài còn learner thì ngợp — một unit thật đo được đã giảm từ 15 ô xuống 4 ô. Đo giữa chỉ xuất hiện khi có từ 4 ô học trở lên, không thì chỉ còn Học vượt + học + Đo cuối.
Sai thì gặp lại ở CUỐI hàng (chỉ đạo 2026-08-15 sửa lại luật ngày 14): trả lời sai thì learner xem đáp án + giải thích rồi đi tiếp, còn câu đó được chèn xuống cuối danh sách — 10 câu, sai 1 thành 11 lượt, sai nữa thành 12. Bắt làm lại ngay tại chỗ chỉ là chép lại đáp án vừa hiện ra; gặp lại sau vài câu mới là nhớ thật (spaced retrieval). Mỗi lần sai vẫn mất một bong bóng; hết bong bóng thì làm lại cả Experience. Học vượt chỉ có 1 bong bóng nên sai một câu là trượt luôn.
Skip đi thẳng câu sau (SRC-117): bấm Skip = "con chưa biết câu này" → không chấm, không hiện đáp án, không mất bong bóng, không chèn lại xuống cuối, nhảy luôn câu kế. Tín hiệu "chưa biết" vẫn được ghi ngầm một lần làm evidence (SDD-002 §18 — thành thật là dữ liệu quý), nhưng learner không bị dừng lại vì nó.
Chỉ lần trả lời đầu tiên của mỗi câu là bằng chứng. Lượt gặp lại được chấm ở client bằng correct_index của feedback lần đầu và không gửi lên /answer — nếu gửi thì mọi learner đều kết thúc ở 100% và Assessment Experience mất hết giá trị đo (SDD-002 §5). Bảng ôn cuối bài và mastery vẫn phản ánh lần đầu; việc sửa lại là để học, không phải để làm đẹp điểm.
Cập nhật SRC-384 (2026-08-19). Trình tự học ở cấp trên Unit (cửa vào, hàng chờ, các lần đo) chuyển sang SDD-021. Phần dưới đây vẫn là nguồn đúng cho mọi thứ BÊN TRONG một Unit. Một điểm đổi: Học vượt và "đo khi nhảy vào vùng chưa có bằng chứng" nay là một Experience (SDD-021 §7), khác nhau chỉ ở chỗ ai khởi xướng.
9.1 Luật hiển thị và mở khoá — bản hiện hành (2026-08-19)
Phần này là nguồn đúng cho câu hỏi "màn Học hiển thị như thế nào". Các đoạn phía trên mô tả bản 2026-08-14/15 (ba màu, accordion một-mở-một, Package làm tag) — giữ lại làm lịch sử vì chúng giải thích vì sao từng luật ra đời, nhưng khi lệch nhau thì lấy phần này.
Bốn trạng thái của một ô Experience
| Trạng thái | Điều kiện | Vẽ thế nào |
|---|---|---|
| chưa mở | ô đứng sau ô chưa-động-tới đầu tiên, hoặc thuộc unit còn khoá | bong bóng mờ, không quầng, hình màu chữ mờ; bấm vào chỉ mở popover giải thích |
| sẵn sàng | đã mở, chưa đụng tới | bong bóng trong, viền sáng |
| đang làm | ô chưa-động-tới đầu tiên của unit đang học | bong bóng sáng nhất + quầng rộng, kèm chữ BẮT ĐẦU nảy nhẹ phía trên |
| đã xong | status = completed | viền và quầng ánh xanh lá, dấu ✓ ở góc |
Ba thứ này nói bằng độ sáng, không bằng màu tô (SRC-348). Bảng ba màu cũ (--border / --success / --accent) đã nghỉ hưu cùng với giao diện nền trắng.
Chỉ MỘT chữ "Bắt đầu" trên cả màn (SRC-359)
Mỗi lúc chỉ một ô mang chữ "Bắt đầu": ô chưa-động-tới đầu tiên của unit đang học — tức unit đầu tiên đang mở mà chưa đi qua Đo cuối. Các unit đang mở khác không có chữ này. Trước đây mỗi unit tự gắn một cái, nên cuộn xuống là gặp ba bốn chữ "Bắt đầu" và learner hết biết đâu là chỗ mình đứng.
Học vượt: cửa vào, không phải lối tắt luôn mở (SRC-363)
Trong một Unit, "Học vượt" và đường thường không bao giờ cùng mở:
| Tình trạng Unit | Ô Học vượt | Ô đường thường |
|---|---|---|
| còn khoá (chưa tới lượt) | có, và là ô duy nhất bấm được | hiện mờ, bấm vào chỉ mở popover nói cần gì để mở |
| đang mở (đang học) | không hiện | mở theo luật tuần tự bên dưới |
| đã học vượt xong | có, mang dấu ✓ | tất cả đều mang dấu ✓ |
Bày cả hai lối cùng lúc là mời learner bỏ dở đường đang đi. Học vượt là cách chứng minh một lần thay vì đi từng bước, nên nó chỉ có nghĩa ở cửa vào.
Bố cục màn Học vượt: luật nói lúc có ích, phản hồi tách khỏi điều khiển (SRC-453)
Hai luật bố cục, cùng một nguyên tắc — mỗi chữ trên màn phải tới đúng lúc nó dùng được:
- Điều kiện đạt (9/10 câu, sai từ hai câu là làm lại từ đầu) KHÔNG hiển thị dưới tiêu đề màn làm bài. Đứng ở đó, trước khi learner làm câu nào, nó chỉ là một câu đe: biết ngưỡng khắt khe mà chưa biết đề dễ hay khó thì learner chần chừ chứ không chuẩn bị được gì. Luật vẫn nguyên hiệu lực ở server (§12) và được màn kết quả nói ra khi trượt — đúng lúc con số ấy giải thích được chuyện vừa xảy ra. Đây là luật hiển thị, không phải nới điều kiện.
- Cụm "Quá dễ · Quá khó · Báo cáo" là một khu RIÊNG ở đáy màn, căn giữa, ngăn bằng một đường kẻ, không đứng chung hàng với Skip và nút trợ giúp. Ba lối đó nói về chất lượng câu hỏi (phản hồi cho hệ), còn Skip/trợ giúp là điều khiển của lượt làm bài. Trộn chúng vào một hàng khiến learner đọc "Quá khó" như một nước đi trong bài — bấm để thoát câu — thay vì một lời nhận xét về đề.
Áp ở apps/learn/src/Learning.tsx, dùng chung cho mọi Experience có ba lối phản hồi này.
Học vượt xong ⇒ cả Unit là đã xong, không phải "được mở" (SRC-102, khoá bằng test ở SRC-362)
Khi exp_key = skip đạt completed:
- mọi ô trong unit chuyển sang đã xong (dấu ✓), không phải chỉ được bỏ khoá;
- unit tính vào "Đã vững" ở cột phải và vào
units_solidcủa API/xp; - unit kế tiếp mở ra.
Đánh đổi cần biết: học vượt không sinh bằng chứng cho từng node bên trong — Learner Model chỉ nhận 10 câu của bài học vượt. Vì thế một unit học vượt sẽ có mức vững mỏng hơn một unit đi đủ đường, dù trên đường đi cả hai đều xanh.
Mở khoá TRONG một Unit — "đã làm" mở đường (SRC-354)
Ô kế tiếp mở khi ô trước đã được làm, tức learner_experience_state có một dòng cho nó — kể cả failed. Trước đây phải completed mới mở, nên hết bong bóng là learner kẹt: làm xong rồi mà đường đi vẫn khoá như chưa đụng vào.
Tách bạch hai việc, và đây là chỗ dễ lẫn nhất của cả khu vực này:
| Việc | Điều kiện |
|---|---|
| mở đường (ô sau, unit sau) | đã làm — completed hoặc failed |
| tô ✓, tính "Đã vững", cộng XP | chỉ completed |
Mở khoá GIỮA các Unit — phải đi qua Đo cuối (SRC-356)
Unit sau mở khi unit trước đã có một dòng cho exp_key = final (đạt hay chưa cũng được), hoặc đã học vượt. Cửa gác vẫn còn — phải làm Đo cuối mới đi tiếp, không nhảy cóc — nhưng không bắt phải đạt, vì đứng mãi một chỗ không làm learner giỏi lên.
Phần (Section) và chỗ learner đang đứng (SRC-321, SRC-329, SRC-330)
- Đường học trải cả môn, không lọc theo lớp; lớp chỉ quyết định learner bắt đầu ở Phần nào.
- Số Phần suy ra từ số unit: tối thiểu 10 unit một Phần, tối đa 10 Phần. Dưới 10 unit thì gộp vào một Phần.
- Learner đang đứng ở Phần chứa unit đầu tiên chưa đi qua Đo cuối; ai chưa học gì thì đứng ở Phần có unit đúng lớp mình. Phần đó ghi "con đang ở đây" và không có nút dẫn tới chính nó.
Lưu trạng thái
learner_experience_state (migration 0028), khoá (learner_id, subject_id, unit_key, exp_key):
unit_key = "<strand>|<module>|<unit>"— client dựng, khớp cách gom nhóm ở đường học.exp_key ∈ {skip, mid, final, explore:<node>, practice:<node>, practice<n>:<node>, lab:<id>}. Vào bài bằng deep link cũng phải mượn đúng khoá slot này, không được bịapractice:<node_id>— bịa thì ghi xong không ô nào đọc được và ô vẫn hiện như chưa làm (SRC-341).POST /v1/learners/{id}/experience/completeghicompleted/failed; upsert chỉ nâng, không hạ — trượt Học vượt không xoá dấu đã hoàn thành cũ.GET /labstrả kèm mảngexperiencesđể đường đi tô đúng trạng thái.
Bảng luật — tra nhanh
| Luật | Nguồn | Test khoá |
|---|---|---|
| Ô sau mở khi ô trước đã làm | SRC-354 | Làm xong một ô thì ô kế tiếp mở, kể cả khi chưa đạt |
| Unit sau mở khi đã đi qua Đo cuối | SRC-356 | Unit sau mở khi unit trước đã làm Đo cuối, dù chưa đạt |
| Học vượt xong ⇒ cả unit đã xong | SRC-102 · SRC-362 | Học vượt xong thì mọi ô trong unit đều là đã xong |
| Học vượt không đứng cạnh đường thường | SRC-363 | Học vượt chỉ có ở unit còn khoá… |
| Cả màn chỉ một chữ "Bắt đầu" | SRC-359 | Chỉ một chữ Bắt đầu trên cả màn… |
| Popover đóng khi bấm ra ngoài | SRC-310 · SRC-361 | cùng test trên |