Skip to content

SDD-038 · Cổng bốn bước và chẩn đoán ​

Một phần của SDD-038 Cổng IELTS. Phần đầu là đặc tả đang áp dụng, mỗi mục giữ số § cũ; diễn biến và lý do các vòng quyết định nằm ở mục Lịch sử quyết định cuối trang.

1. /ielts là một cổng, không phải một hub ​

Giờ /ielts chỉ là một danh sách tám việc, mỗi việc một dòng, bấm sang trang riêng: /ielts/goal, /ielts/declarations, /ielts/quiz, /ielts/assessment, /ielts/writing, /ielts/speaking, /ielts/booking, /ielts/plan. Được ba thứ mà bản gộp không có: gửi được link tới đúng một việc, bấm back ra đúng chỗ vừa đứng, và mỗi màn chỉ hỏi một câu. Danh sách khoá của trang con rút thẳng từ bảng IELTS_TASKS, không chép tay lần hai — thêm trang mà quên khai thì URL của nó lặng lẽ đổ về hub.

Ít chữ là ràng buộc, không phải khẩu vị (SRC-048 + chỉ đạo "siêu siêu minimal"): mỗi dòng ở hub là tên việc cộng một dấu xong. Câu "vì sao có bước này" đã bỏ khỏi màn hình; lý do vẫn cần cho người sửa mã nên nó ở trong chú thích và trong tài liệu này, không ở trước mắt đứa trẻ.

/ielts là một route cấp cao nhất (view: "ieltsPathway" trong apps/learn/src/App.tsx), khung tối giản: logo, đổi ngôn ngữ, menu tài khoản. Không Lighthouse, không Khoá học, không Rủ bạn, không lưới school. Mỗi nút thêm vào là một lối ra khỏi bốn bước, và bốn bước chỉ có nghĩa khi đi hết. Logo vẫn bấm về trang chủ được: một trang không có đường ra là một cái bẫy, khác hẳn một trang không mời gọi đi chỗ khác.

2. Bốn bước này khác gì năm bước của SDD-035 ​

SDD-035 mô tả hành trình học (Mục tiêu → Chẩn đoán → Khoảng cách → Lộ trình → Sẵn sàng), đúng năm bước của trang công khai, và không có điểm dừng. SDD-038 mô tả việc nhận một người mới, và nó kết thúc ở một buổi gặp người thật.

Hai thứ cùng đọc một kho dữ liệu nhưng kể hai câu chuyện, nên là hai file (journey.ts và pathway.ts). Cả hai đều suy ra trạng thái từ dữ liệu của chính từng bước; không file nào ghi cột "đang ở bước mấy".

BướcXong khiLàm ở đâu
1. Đặt mục tiêucó mục tiêu đang hoạt động và có lời khai hoàn cảnh học/ielts/goal, /ielts/declarations
2. Chẩn đoánquiz và bài bốn kỹ năng và một bài viết và một đoạn ghi âm/ielts/quiz, /ielts/assessment, /ielts/writing, /ielts/speaking
3. Gặp thầy côđã khai nguyện vọng giờ và ghi tên một buổi/ielts/booking, dùng lại Học cùng thầy cô (SDD-034)
4. Kế hoạch họccó ít nhất một mốc trung gian/ielts/plan

Khoá theo dây chuyền: bước N chỉ mở khi mọi bước trước đã xong, và bước khoá vẫn hiện ra (mờ) chứ không bị giấu. Một learner đặt lịch gặp trước khi làm bài chẩn đoán sẽ tới buổi gặp mà không có gì để nói; còn giấu các bước sau thì mỗi lần bấm Tiếp là một lần bất ngờ, và người ta không giao việc học của mình cho thứ mình chưa nhìn hết.

3. Hai kỹ năng sản sinh: một bài viết, một đoạn nói ​

Bảng ielts_productions (migration 0228), không dùng lại assessment_responses: bài trắc nghiệm có selected_index và chảy vào Learner Model dưới dạng learner_evidence; một đoạn văn và một tệp âm thanh thì không có "đúng/sai", và điểm của chúng là một nhận định — của model trước, của mentor sau. Ép chúng vào bảng trắc nghiệm sẽ bơm nhận định của máy vào Learner Model như thể là bằng chứng đo được.

  • Đề bài nằm trong mã nguồn (modules/ielts/production.ts), một đề mỗi kỹ năng. Cố ý một đề: ở bước chẩn đoán, hai learner làm hai đề khác nhau thì hai bản nhận định không so được với nhau.
  • Âm thanh ở R2, D1 chỉ giữ khoá. Trần: 3 phút (chỉ đạo), sàn 20 giây, 8 MB. Giao diện tự dừng ở trần — learner đang kể chuyện thì không nhìn đồng hồ.
  • Speaking: phiên âm rồi mới chấm. Model chấm là model chữ, nên prompt ielts.production-feedback cấm thẳng mọi nhận xét về phát âm, trọng âm, ngữ điệu. Một nhận xét về trọng âm sinh ra từ chữ nghe rất thật và sai hoàn toàn; mentor đọc rồi nhắc lại với learner là hệ đã nói dối qua miệng một người thật. Bản phiên âm được giữ lại: mentor đọc nhanh hơn nghe, và khi nhận định có vẻ lệch thì đó là chỗ đầu tiên để soi.
  • Nhận lưu trước, chấm sau. Learner đã nói xong ba phút thì không được mất bài vì một model bận: status='failed' là kết cục hợp lệ, bước vẫn tính là xong.

4. Luật hé lộ ​

Chỉ đạo: hệ ra báo cáo nhưng không đưa hết cho learner trước buổi gặp, chỉ hé lộ một phần.

  • learnerReveal() trong modules/ielts/pathway.ts là chỗ duy nhất quyết định phần hé lộ, và nó dựng một đối tượng mới chứ không lọc bớt báo cáo đầy đủ. Lọc bớt nghĩa là mọi trường thêm vào sau này mặc định lộ và người thêm phải nhớ đi che — thứ chắc chắn sẽ quên. Dựng mới nghĩa là mặc định kín.
  • Phần hé lộ không mang con số nào: một learner cầm "ước lượng 5.5" đi trước buổi gặp sẽ dành cả buổi để cãi hoặc để buồn về con số ấy. Câu hé lộ là teaser_vi do chính model viết dưới lệnh cấm chứa số.
  • Trang nói thẳng là đang giữ lại, và nói vì sao. Giấu mà không nói là giấu thì learner tự kết luận theo hướng xấu hơn sự thật.
  • Đường learner (ielts-pathway, ielts-productions) cố ý không SELECT các cột nhận định. Báo cáo đầy đủ chỉ mở ở /v1/mentor/learners/{id}/ielts-report, sau cổng vai mentor, và đoạn ghi âm phát qua worker chứ không ký URL R2 công khai — một URL đã ký sống tiếp sau khi mentor mất vai.

3b. Hai màn được làm lại theo chỉ đạo 2026-09-17 (vòng 3) ​

Trang Mục tiêu chỉ hỏi một câu. Các mốc trung gian đã rời khỏi /ielts/goal sang /ielts/plan, cùng với ô khai điểm hiện tại — điểm hiện tại không phải một cái đích, nó là đầu vào của phép chia mốc (suggest từ chối thẳng khi thiếu). Đặt nó cạnh band mục tiêu là bắt learner khai hai con số trông giống hệt nhau ở cùng một màn, đúng cách để họ gõ nhầm ô. /ielts/goal vì thế dùng một biểu mẫu riêng chứ không dùng lại IeltsGoalCard — card ấy còn phục vụ trang Hồ sơ, sửa nó cho vừa màn này sẽ làm hỏng màn kia.

Quiz: một câu một màn. Bản cũ đổ cả mười câu với bốn mươi phương án vào một cột cuộn. Ba thứ hỏng cùng lúc: mắt phải tự tìm mình đang ở câu nào, phương án dài phải co chữ cho vừa, và learner thấy ngay còn chín câu nữa nên đọc lướt cho xong — mà quiz này tồn tại để sửa hiểu biết, đọc lướt thì không sửa được gì. Giờ chữ to, phương án là ô bấm rộng, chọn xong tự sang câu sau (không có nút "Tiếp" — một cú bấm thừa nhân cho mười câu), vẫn quay lại đổi ý được. Tiến độ là một vạch mảnh cộng 3/10, thay cho một dòng chữ.

Màn giới thiệu quiz cố ý lớn: nó là chỗ duy nhất nói "đây không phải bài kiểm tra tiếng Anh", và một câu quan trọng in cỡ chữ phụ đề thì không ai đọc. Lớn ở đây là cỡ chữ và khoảng thở, không phải thêm element — đúng hướng với luật tối giản, không ngược.

4b. Màn mentor: nơi báo cáo được mở ra ​

Tab IELTS trong cổng Dolphin (apps/mentors/src/IeltsReport.tsx), đứng ngay sau About: với learner đi qua cổng bốn bước, buổi gặp đầu tiên sinh ra để mở đúng bản báo cáo này.

  • Mỗi phần mở riêng, mặc định đóng. Không đổ cả bảng điểm ra một lúc. Mentor chọn thứ tự mở, và thứ tự ấy là một phần của việc dạy: mở chỗ mạnh trước hay chỗ hụt trước là hai buổi gặp khác nhau.
  • Lời cảnh báo đứng đầu, không gấp lại được: học sinh chưa từng thấy những con số này. Mentor quên điều đó sẽ hỏi "em thấy điểm sao" và làm hỏng đúng buổi gặp mà cả luồng bốn bước tồn tại để dẫn tới.
  • Hai cột band không bao giờ gộp: ai_band (máy đoán) và mentor_band (người chốt). PATCH /v1/mentor/ielts-productions/{id} là đường ghi cột thứ hai — không có nó thì cột ấy vĩnh viễn NULL và bản báo cáo rút lại còn đúng con số của model. Đường này không đụng tới bài viết, bản phiên âm hay nhận định của model: mentor chốt điểm và ghi một câu của mình, không sửa thứ learner đã nộp. Trường không gửi thì giữ nguyên, gửi null thì xoá — gộp hai ý ấy sẽ khiến một lần sửa ghi chú lặng lẽ xoá mất band đã chốt.
  • Bài của learner hiện nguyên văn, không cắt, không "xem thêm". Với speaking, nhãn nói rõ đây là bản phiên âm và máy chưa từng nghe tiếng — một mentor tưởng mình đang đọc bài viết sẽ nhận xét sai loại.

5. Bước 4 là bản nháp, và nói ra điều đó ​

Kế hoạch sơ bộ dùng lại ielts-goal/milestones/suggest (SDD-035, planner.ts). Giao diện nói ngay dòng đầu rằng đây là bản sơ bộ để buổi gặp bắt đầu từ việc sửa thay vì từ trang giấy trắng. Learner tin nhầm ở đây thì mọi câu mentor sửa trong buổi gặp đều nghe như một lần bị đổi ý.

6. Cổng kiểm ​

SRC-801 thêm 39 test: modules/ieltsSkills/progress.test.ts (chuỗi ngày khi hôm nay chưa học, phút không bị làm tròn nuốt mất, vốn từ không tụt khi nghỉ tuần, tuần trước bằng 0 thì không chia), encouragement.test.ts (learner chưa có gì thì tuyệt đối không nhận câu khen nào), next.test.ts (nút "ôn lại" không bao giờ đưa ra bài chưa từng làm), routes.test.ts (quyền, trần theo ngày, và xem số lượt còn lại không tiêu mất lượt nào). Ở apps/learn: 2 case e2e gác bốn thẻ kỹ năng trỏ đúng ielts.nemo12.com và tám việc cũ vẫn tới được ở /ielts/settings.

workers/api/src/modules/ielts/pathway.test.ts — 13 test qua HTTP thật, phủ năm thứ hỏng im lặng (cộng 8 test cho Evidence Registry ở shared/evidence.test.ts và 8 test cho Learner Model ở modules/ielts/model.test.ts): luật hé lộ (learner không thấy band hay nhận xét, kể cả sau khi mentor đã chốt), khoá theo dây chuyền, cổng độ dài bài viết, "chấm hỏng không làm mất bài", và "sửa ghi chú không xoá mất band đã chốt".

9. Cổng SAT dùng lại đúng khuôn này (SRC-839, 2026-09-19) ​

Phần SAT nằm trong tài liệu này chứ không tách SDD riêng vì nó không có thiết kế riêng nào: nó là cùng một quyết định sản phẩm — một kỳ thi là một cổng CẤP CAO NHẤT, khung tối giản, một thẻ chứa các lối vào — áp cho một tên khác. Tách ra một tài liệu thứ hai là hẹn ngày hai bản mô tả cùng một khuôn trôi khỏi nhau.

Khác /ielts ở đúng ba chỗ, và mỗi chỗ có lý do:

/ielts/sat
Dashboard nỗ lựccó, đọc ielts-effortchưa có: không có endpoint sat-effort, và bốn thẻ toàn số 0 là bản kê những việc learner chưa làm
Các dòng trong thẻbốn kỹ năng của kỳ thibốn lối vào nội dung SAT đang có ở Squid: Khoá học · Luyện đề · Labs · Toàn cảnh
Ngôn ngữtiếng Anh (chỉ đạo 2026-09-18, chỉ áp cho sân IELTS)tiếng Việt, theo luật chung của CLAUDE.md

Cổng này KHÔNG sinh ra màn hình mới: bốn dòng trỏ vào /squid/<trang>/sat đang chạy. Việc nó làm là thôi bắt người tới vì SAT phải chọn một con vật trước khi được nói về kỳ thi mình đang lo.

Chỗ của dashboard, khi có sat-effort, là ngay dưới h1 — đúng vị trí EffortDashboard đứng ở /ielts.

Mã: từ SRC-1024 cổng này là trang chủ khu NEMO SAT, apps/learn/src/sat/Sat.tsx (SDD-044 §3); nhánh route sat trong apps/learn/src/App.tsx. Cổng kiểm: e2e smoke.spec.ts — "cổng SAT đứng riêng ở /sat, không rơi về hub school".

10. Khu IELTS mở cổng ra mắt sớm (SRC-843, 2026-09-19) ​

Trang công khai đưa người đọc từ khu IELTS thẳng vào learn.nemo12.com/ielts (SRC-841, SDD-029). Cổng ra mắt chặn ở đó thì cả một luồng vừa dựng xong kết thúc bằng một trang "hẹn ngày mai" — trong khi 140 trang luyện IELTS vốn đã công khai, nên chặn phần còn lại của sân ấy không giữ kín được gì. LaunchNotice.tsx vì thế mở riêng khu IELTS (đường dẫn đọc từ thanh địa chỉ; tham số path có để test hỏi "ở đường dẫn này thì sao"); phần còn lại của learn vẫn đóng tới 08:00 20.09 vì chỉ đạo nói về khu IELTS, không nói về cả app. Test chốt cả hai hướng, vì cả hai đều hỏng im lặng: mở hụt thì luồng trên kết thúc bằng trang hẹn ngày mai, mở quá tay thì cả app ra mắt sớm hơn ngày đã hẹn với phụ huynh. App.tsx không đổi một dòng.

33. Ba lượt nói chẩn đoán, và learner chọn lượt ưng nhất (SRC-890, 2026-09-20) ​

a. Ba lượt, không phải một và cũng không phải vô hạn ​

Tới §29 bài nói chẩn đoán chỉ có một lượt: nộp xong là xong. Một lượt duy nhất biến một tai nạn kỹ thuật — micro để xa, ngoài phòng có tiếng, lạc đề ở giây thứ năm rồi biết nhưng đã lỡ — thành phép đo chính thức của một đứa trẻ, và phép đo ấy đi tiếp vào Learner Model lẫn báo cáo mentor.

Trần ba chứ không mở vô hạn, vì bài này là một phép ĐO. Cho nói lại không giới hạn thì learner sẽ đọc lại cùng một đoạn tới lúc trơn, và thứ đo được sau đó là trí nhớ chứ không phải năng lực nói. Ba lần đủ vá tai nạn, không đủ học thuộc.

Trần canh ở cả hai phía: màn hình giấu nút ghi âm khi hết lượt, và server đếm lại trước khi đọc thân yêu cầu (SPEAKING_MAX_TAKES trong production.ts). Một cổng chỉ nằm trong trình duyệt thì không phải cổng; và đếm trước khi đọc tệp để learner hết lượt không phải đẩy xong vài trăm KB mới nghe lời từ chối.

b. Learner chọn, máy không chọn hộ ​

Luật cũ — "lấy lượt mới nhất" — sai ở đúng trường hợp hay xảy ra nhất: learner nói lần hai để thử một cách mở bài khác, nghe lại rồi thấy lần một vẫn hơn. Máy không nghe được điều ấy.

Bước chọn không phải thủ tục đặt thêm vào cuối: nó buộc learner nghe lại chính mình ba lần rồi nói ra lần nào tốt hơn — tức là tự đánh giá, thứ mà không chỗ nào khác trong bài chẩn đoán hỏi tới.

Cột ielts_productions.chosen (migration 0257) mặc định 0, và ba chỗ đọc bảng đổi sang ORDER BY chosen DESC, created_at DESC: pathway.ts (câu hé lộ learner đọc), model.ts (band vào Learner Model), report.ts (báo cáo mentor, nay có thêm cờ chosen để mentor biết lượt nào là lời khai của chính learner). Chưa ai chọn thì mọi chosen bằng 0 và thứ tự rơi về đúng luật cũ, nên mọi dòng có trước 0257 giữ nguyên cách hiểu — không cần backfill.

POST /v1/learners/{id}/ielts-productions/speaking/{productionId}/choose ghi cả hai vế trong một câu lệnh (chosen = CASE WHEN id=?1 THEN 1 ELSE 0 END): hai câu — một bỏ chọn hết, một chọn dòng mới — có một khoảnh khắc ở giữa nơi learner không có lượt nào được chọn. Mệnh đề WHERE giữ đủ learner_id, skill, track; thiếu track thì một cú bấm ở đây bỏ chọn cả lượt luyện của thang ba bậc, cùng bảng mà khác việc. Id lạ trả 404 trước khi ghi, nếu không nó sẽ lặng lẽ bỏ chọn sạch cả ba lượt rồi trả về 200.

Màn nộp bài không còn tự rời trang sau khi nộp: việc của learner chưa hết — còn nghe lại rồi chọn.

c. Màn "Bài nói của con": nhóm theo việc, màu mang nghĩa ​

Bản §29 xếp mọi lượt nói thành một dãy thẻ giống hệt nhau, mỗi thẻ mang ba nhãn chữ đầy đủ ("Nhận xét lần ấy", "Một việc cho lần sau", "Lời con đã nói, viết ra chữ"). Ba chục lượt thành chín chục dòng nhãn lặp — mà chữ lặp thì mắt không đọc, nó lướt; thứ đáng đọc chìm trong thứ không đáng.

Ba phép sửa, theo đúng thứ tự quan trọng:

  1. Nhóm theo việc, không phải một dãy phẳng theo thời gian: bài chẩn đoán · thang ba bậc · bước nói của bộ bài. Đó đúng là ba việc khác nhau trong đầu learner, và một tiêu đề nhóm nói một lần thay cho ba chục nhãn lặp trên từng dòng.
  2. Màu mang nghĩa, không trang trí: mỗi nhóm một token màu (coral · ocean · sun) đứng ở vạch bên trái mỗi dòng. Liếc một cái là biết đang ở nhóm nào. Ba màu, hết — màu thứ tư là quay lại chỗ cũ, chỉ khác là bằng màu.
  3. Một dòng chữ mỗi lượt khi chưa mở: ngày, độ dài, và câu ghi nhận. Nhận xét đầy đủ cùng bản phiên âm gộp vào một chỗ mở ra, không phải hai — learner mở chúng cùng lúc, vì cùng một lý do.

Ranh giới hé lộ của §29 không đổi: learnerNotes vẫn lọc ở server, và trang này vẫn chỉ đọc thứ server đã lọc.

d. Còn mở ​

  • Trần ba lượt chỉ áp cho bài nói chẩn đoán. Thang ba bậc và bước nói của bộ bài vẫn nộp lại không giới hạn (chúng là bài luyện, không phải phép đo) — nhưng cũng chưa có đường chọn.
  • Bài viết chẩn đoán vẫn một lượt. Chủ dự án chỉ nói về bài nói, và một bài viết thì learner đã sửa được trước khi bấm nộp, nên nhu cầu khác hẳn.

59. IELTS Skills Check: bốn ô, một trang riêng, ba trạng thái (SRC-950, 22.09.2026) ​

59a. Số thứ tự nằm trong tiêu đề, không nằm ở dấu tích ​

Năm chặng vốn đã có position, nhưng màn hình chỉ vẽ nó vào ô tròn bên trái — và ô ấy đổi thành một nét check ngay khi chặng xong. Hậu quả đúng bằng ảnh chủ dự án gửi: một trang đã xong gần hết thì không còn con số nào, và năm chặng đọc ra như năm mục rời rạc chứ không phải một trình tự.

Nay số in trong chính tiêu đề (1. Goal), nên nó ở lại dù chặng xong hay chưa.

59b. Chặng Diagnosis còn hai dòng ​

TrướcSau
Quick CheckIELTS Knowledge Check
Reading & Listening CheckIELTS Skills Check → /ielts/setup/skills
Writing Sample(vào trang con)
Speaking Sample(vào trang con)

"Quick Check" nói bài ấy NHANH, trong khi điều learner cần biết là nó hỏi về cái gì: hiểu biết chung về kỳ thi, không phải năng lực tiếng Anh. Và "Quick" đứng cạnh "Skills Check" thì hai cái tên chỉ khác nhau ở tốc độ — tức là không nói được chúng khác nhau ở chỗ nào thật.

59c. Reading tách khỏi Listening, và đó là một đổi luật chứ không phải đổi nhãn ​

Nay:

  • POST /ielts-diagnostic?skills=reading dựng một lượt đo chỉ phần Reading (pickDiagnosticItems nhận danh sách kỹ năng; poolShortfall chỉ soi các kỹ năng được yêu cầu).
  • GET /ielts-assessment-brief?skills=reading trả lời giới thiệu khớp đúng bài ấy — số câu, số phút, và một câu giới hạn khác: một lượt đo một kỹ năng không so được kỹ năng ấy với ba kỹ năng kia trong cùng một lần ngồi.
  • Trạng thái từng ô đọc từ ielts_diagnostic_items.strand nối với assessment_sessions.status (readDiagnosticStrands), nên một lượt đo bốn kỹ năng cũ vẫn đánh dấu xong cả hai ô — đúng như nó phải thế: learner ấy ĐÃ làm phần Reading rồi.

59d. Ba trạng thái, và vì sao không phải một cờ done ​

not_checked · in_progress · checked. Cùng lý do SetupPhaseStatus ra đời ở §57: một learner mở bài rồi bỏ ngang mà màn hình nói "chưa kiểm" là xoá đi một việc họ đã làm thật. Writing và Speaking đọc theo bài đã nộp (ielts_productions), không theo phiên trắc nghiệm — một câu trắc nghiệm phần writing trong lượt đo cũ không phải một bài viết đã nộp.

59e. Xác nhận trước khi test, xem lại sau khi test ​

SkillCheckGate đứng trước mọi ô trắc nghiệm: chưa kiểm thì phải bấm "Start this check" mới vào bài (và trong bài còn một nấc giới thiệu nữa, SRC-719); đã kiểm thì mở ra là thấy kết quả — tỉ lệ đúng, số câu đã làm, câu nhận định của Learner Model — kèm dòng nói thẳng đây không phải band IELTS. Nút làm lại đứng sau kết quả, không thay chỗ nó.

59f. Chỗ dễ sai ​

  • Khoá việc trùng tên địa chỉ mạch luyện. reading, listening và skills đều là đoạn URL đã có nghĩa khác (/ielts/reading, /ielts/skills/reading). Nhánh legacy /ielts/<task> trong pathToRoute đứng trước, nên thiếu một dòng loại trừ là mạch luyện bị nuốt — e2e bắt đúng lỗi ấy ở lượt đầu. Ba ô kiểm chỉ tới được bằng địa chỉ thật, /ielts/setup/<task>.
  • /ielts/setup/assessment là link cũ, không được gãy. Nó vẫn mở bài bốn kỹ năng.
  • Trạng thái chặng. Việc thật của Diagnosis nằm trong bốn ô ở trang con, nên statusOf nhận thêm một dấu hiệu touched; thiếu nó thì learner đã kiểm xong Reading vẫn bị gọi là "Not started".

61. Chữ hướng dẫn của các bài check nói tiếng Việt (SRC-953, 22.09.2026) ​

61a. Đường ranh, và vì sao nó không mâu thuẫn với SRC-834/835 ​

Ở /ielts/**Thứ tiếng
Tên trang (Reading Check), tên kỹ năng, nhãn trạng thái (Not checked · In progress · Checked), nội dung đềTiếng Anh
Chữ Nemo GIẢI THÍCH bài: giới thiệu, giới hạn phép đo, dặn dò, tóm tắt kết quả, nhãn nútTiếng Việt

SRC-834/835 nói sân luyện tiếng Anh, với lý do: learner vào đây luyện một kỳ thi tiếng Anh, và một lớp dịch bọc quanh bài thi là lớp họ phải tự gỡ vào ngày thi. Lý do ấy áp cho thứ learner gặp trong phòng thi. Nó không áp cho Nemo khi Nemo đang nói VỀ bài thi.

Chỗ này quan trọng nhất ở đúng một câu: "Bài này KHÔNG cho ra band IELTS." Một learner band 5.0 đọc câu ấy bằng tiếng Anh sẽ hiểu lỗ chỗ, và một lời cảnh báo hiểu sai thì thà đừng cảnh báo — họ sẽ đem con số 17% đi so với mục tiêu du học của chính mình.

61b. Trình bày mượn khuôn trang luyện ​

Ba màn (cửa xác nhận · giới thiệu · làm bài) nay dùng đúng khuôn MicroExercise: cột max-w-3xl căn giữa, chữ cỡ đọc được với leading-8, lựa chọn là thẻ rộng hết cột (rounded-card border p-3.5), nút hành động là pill lớn. Trước đó chúng là text-sm dính mép trái của một trang full-width, đọc ra như phần chân của một biểu mẫu chứ không như một việc sắp ngồi xuống làm.

Vạch tiến độ chia đoạn thay cho dòng Question 3 / 6: một cái vạch nói "còn dài bao nhiêu" nhanh hơn mọi con số, và learner đang làm bài thì không nên phải đọc thêm chữ.

61c. Một thứ KHÔNG mượn ​

Trang luyện chấm ngay từng câu và mở lời giải. Bài đo thì không — và không phải vì tiếc công: hiện đúng/sai giữa chừng là làm hỏng chính phép đo (§ đầu diagnostic.ts). Thẻ lựa chọn ở bài đo vì thế chỉ có hai trạng thái, đã chọn và chưa chọn; không có màu đúng, không có gạch ngang sai.

133. Chẩn đoán 4 kỹ năng, mỗi kỹ năng một bài (SRC-1099, 28.09.2026) ​

Yêu cầu và mười quyết định: prd-ielts-diagnostic.

Dữ liệu (migration 0307): ielts_diag4_attempts là một lượt làm MỘT kỹ năng; items_json chụp lại đề kèm đáp án lúc bắt đầu, để kho câu có đổi sau đó thì lượt đã làm vẫn chấm đúng đề learner đã thấy. ielts_diag4_reports là ảnh chụp báo cáo, để xem lại lần cũ đúng như lúc ấy.

Nguồn câu: Reading lấy MỘT bài đọc đã publish có đủ 10 kỹ năng con và 30 câu trắc nghiệm, 3 câu đầu mỗi kỹ năng con. Listening lấy 3 đoạn nghe có đủ 5 kỹ năng con, mỗi đoạn 1 câu mỗi kỹ năng con. Chọn bài theo băm (learner, kỹ năng, số lượt) để lần làm lại gặp bài khác. Speaking/Writing lấy từ diagnosticBank/ (60 câu, không câu nào có đáp án là lựa chọn dài nhất - bài học từ P0 nội dung ở §132). Kho chưa đủ thì trả 503 thay vì phát một đề rỗng.

API (modules/ielts/diag4Routes.ts): GET /ielts-diag4 (trạng thái + báo cáo), POST /ielts-diag4/{skill}/start (làm tiếp lượt dở nếu có; 400 nếu chưa đủ 30 ngày), PUT /attempts/{id} (lưu dần), POST /attempts/{id}/submit, GET /reports/{id}. Đề phát ra không mang đáp án hay lời giải. Nộp dùng UPDATE ... WHERE submitted_at IS NULL để hai lượt nộp cùng lúc không chấm hai lần. Báo cáo sinh khi lượt MỚI NHẤT của cả bốn kỹ năng đều chưa thuộc báo cáo nào.

Chấm (diag4.ts, hàm thuần có test): bốn loại kết quả, mức Strong/Developing/Needs work, ba việc nên luyện trước (hiểu sai trước, rồi tỉ lệ đúng thấp nhất, bỏ qua kỹ năng con Strong).

Giao diện (apps/learn/src/ielts/Diagnostic.tsx): hub bốn thẻ, trang làm bài từng câu một, trang báo cáo; thẻ "Find your level" trên /ielts. Bài đo 6 câu cũ chưa gỡ khỏi Learning Setup ở vòng này: gỡ nó đụng tới luật requiredDiagnosisParts của cổng bốn bước, nên để thành việc riêng.

Mentor đọc báo cáo (SRC-1246, 05.10.2026, trả nợ của mục này): cổng Dolphin (mentors.nemo12.com), màn một learner, tab IELTS, khối đầu tiên "4-skill diagnostic". Khối ấy gọi đúng hai đường của learner (GET /v1/learners/{id}/ielts-diag4 và GET .../reports/{id}): canAccessLearner đã cho vai mentor đọc, nên không dựng một route /v1/mentor/... thứ hai trả cùng dữ liệu. Mentor thấy trạng thái bốn kỹ năng (đã nộp ngày nào, band ước lượng), danh sách báo cáo (mới nhất mở sẵn) và nội dung báo cáo: overall, bốn band, ba việc nên luyện trước, sub-skill từng kỹ năng, và chỗ hiểu sai kèm đáp án learner chọn. Chỉ đọc: cổng mentor không có nút bắt đầu, lưu hay nộp. Không import Diag4ReportView của learn vì nó gắn với router và chữ hướng dẫn của learn; phần thuần (apps/mentors/src/diag4.ts) có test riêng.

163. Báo cáo mẫu khi chưa làm đủ bài chẩn đoán (SRC-1217, 03.10.2026) ​

Chủ dự án 03.10.2026: learner mở báo cáo khi chưa làm đủ bốn bài chẩn đoán thì thấy một báo cáo MẪU, số liệu giả nhưng thông tin của chính learner, để hình dung báo cáo cuối cùng.

  • Trang: learn.nemo12.com/ielts/diagnostic/report (Diag4ReportPage). Có báo cáo thật thì không đổi gì. Chưa có thì trên cùng là thẻ "còn thiếu gì": trạng thái từng bài (Checked / In progress / Not checked) và MỘT nút chính đi tiếp bài đang dở (hoặc bài đầu chưa làm). Thẻ Report ở /ielts/diagnostic thêm link "Xem báo cáo mẫu".
  • Một bộ vẽ: Diag4ReportView vẽ cả báo cáo thật lẫn báo cáo mẫu, nên mẫu không thể lệch bố cục thật. Mẫu chỉ thêm: huy hiệu "Sample report" trên MỌI phần, nền sọc chìm và độ mờ nhẹ, dòng ngữ cảnh (tên, Goal ≈ band · ngày thi, trường + lớp), và tên mục "Focus first" không thành link.
  • Dữ liệu mẫu: apps/learn/src/ielts/diagnosticSample.ts, hàm thuần buildSampleReport(context, variant). Không fetch, không đồng hồ, không ngẫu nhiên: cùng đầu vào ra cùng báo cáo. Kiểu Diag4SampleReport mang sample: true; trang chỉ GỌI ĐỌC (ielts-diag4, ielts-goal, walk-entry), không ghi gì, không vào Evidence.
  • Ba biến thể, learner bấm qua lại: "Nếu gần mục tiêu", "Nếu một kỹ năng tụt lại" (Writing thấp hơn mục tiêu 2 band), "Nếu dưới mục tiêu". Band = mục tiêu learner (mặc định 6.5 khi chưa đặt) cộng bảng lệch cố định OFFSETS, kẹp 3..9, làm tròn nửa bậc.
  • Ngôn ngữ theo SRC-953: nhãn, tên kỹ năng, huy hiệu tiếng Anh; chữ giải thích và nhãn nút tiếng Việt. Trình đọc màn hình: vùng báo cáo có aria-label "Sample report, số liệu giả", mỗi huy hiệu có chữ ẩn "số liệu giả, không phải kết quả của bạn".
  • Ngoài phạm vi: báo cáo SAT chỉ mở theo id một bài đã nộp (không có trạng thái "chưa đủ"); Diagnosis Report trường học cố ý không có điểm số và không bịa danh sách (SDD-021 §4).
  • Kiểm: diagnosticSample.test.ts (dùng goal thật, tất định, cờ sample, ba câu chuyện khác nhau), e2e/ieltsDiagSample.spec.ts (chưa đủ bài: thấy mẫu có tên + CTA và không có lượt ghi; đủ bài: báo cáo thật không có huy hiệu; 375px không cuộn ngang).

165. Gap to Target: band theo tiêu chí cho Writing/Speaking, bậc cho Reading/Listening (SRC-1188, 02.10.2026) ​

Chủ dự án chốt 02.10.2026 cho trang learn.nemo12.com/ielts/gap. Luật 19.09.2026 (mục "Bằng chứng luyện tập KHÔNG đẩy band" ở §5b-bis) đứng nguyên: tỉ lệ đúng của bài luyện không bao giờ thành band, không có phép quy đổi tỉ lệ ra band ở bất cứ đâu.

  • Writing và Speaking có band thật theo từng tiêu chí (Writing: Task Response, Coherence and Cohesion, Lexical Resource, Grammatical Range and Accuracy; Speaking: Fluency and Coherence, Lexical Resource, Grammatical Range and Accuracy, Pronunciation chỉ khi dữ liệu có). Nguồn là band tiêu chí do ielts.production-feedback v2 ghi vào ielts_productions.ai_notes_json (§12g).
  • Luật gom: trung vị của tối đa 3 bài đã chấm gần nhất cho từng tiêu chí. Hai bài thì lấy trung bình làm tròn lên nửa bậc. Màn bày kèm số bài làm căn cứ và ngày của bài mới nhất. Trung vị để một lượt chấm lệch không kéo cả con số; ba bài để con số đi theo bài gần đây.
  • Bài nào được đếm: chỉ bài scored có mảng criteria hợp lệ. Bài chấm trước 19.09.2026 không có tiêu chí thì bỏ qua (không bịa từ band tổng, như §12g). ai_notes_json hỏng thì bỏ qua bài ấy. Bài chẩn đoán không được đếm, để trang này không thành cửa sau của luật hé lộ SRC-792 (kết quả chẩn đoán để dành cho buổi gặp mentor). Chỉ key và band rời khỏi worker; note_vi và các ô dành cho mentor thì không.
  • Nguồn thứ hai: phần Writing/Speaking của thi đầy đủ (chủ dự án chốt 04.10.2026). Bài chẩn đoán đứng ngoài nên bài luyện gần như chưa bao giờ mang band tiêu chí, và danh sách sẽ rỗng với hầu hết learner. Thi đầy đủ thì đã chấm từng tiêu chí bằng cùng prompt v2 và learner đã thấy các band ấy trên phiếu kết quả, nên đưa vào đây không hé thêm điều gì. Điều kiện đếm khớp đúng điều kiện route phiếu kết quả mở cho learner: lượt finished, phần đã nộp, đọc ielts_full_test_sections.result_json (subskills[{code, band}]; Pronunciation band: null bị bỏ). Hai nguồn gom chung theo ngày, luật trung vị 3 bài giữ nguyên, và mỗi tiêu chí trả thêm sources: {practice, full_test} để màn ghi rõ "từ 2 bài thi thử, 1 bài luyện".
  • Reading và Listening không có band. Hai kỹ năng ấy không có tiêu chí chấm, và thứ duy nhất có là tỉ lệ đúng của bài luyện, đúng thứ luật 19.09 cấm quy ra band. Trang bày bốn bậc của server (mastery.ts: Building, Getting there, Solid, Strong; dưới 8 câu là "Not checked"). Mốc 75% cũ ở client (lệch với 70% của server) đã gỡ; nút "Đóng chỗ hở lớn nhất" chọn kỹ năng con có bậc thấp nhất, tỉ lệ đúng thấp hơn phá hoà.
  • Trên màn có một câu tiếng Việt nói rõ hai điều này: band theo tiêu chí lấy từ bài đã chấm, còn Reading/Listening chỉ có bậc, không phải band IELTS.

API: thêm trường criteria vào GET /v1/learners/{learnerId}/ielts-skills/{skill} (đường learner đã gọi sẵn cho trang này, cùng cổng quyền canAccessLearner): mảng {key, band, pieces, latest_at, cluster, sources} với writing/speaking, null với reading/listening. cluster nối tiêu chí Writing với cụm kỹ năng con (migration 0260) để trang xếp kỹ năng con dưới tiêu chí của nó. Mã: workers/api/src/modules/ieltsSkills/criteria.ts; test: routes.test.ts khối "criteria".

Lịch sử quyết định ​

Từ mục 1. /ielts là một cổng, không phải một hub ​

Trước SRC-792, learn.nemo12.com/ielts không khớp route nào nên rơi về hub sáu school. Người tới vì IELTS phải tự tìm đường giữa Turtle, Shark, Octopus — tức là phải chọn một con vật trước khi được nói về kỳ thi mình đang lo.

Vòng 2 cùng ngày — một tính năng, một trang, một URL. Bản đầu nhét cả bốn bước vào một trang, mỗi bước mở ra tại chỗ; chủ dự án xem xong nói "lằng nhằng phức tạp quá". Đúng: một bước mở ra kéo theo cả card mục tiêu, biểu mẫu lời khai, bài quiz và hai ô nộp bài trong cùng một cột — cái stepper lẽ ra để nói còn mấy việc nữa lại thành chỗ chứa mọi việc.

Từ mục 9. Cổng SAT dùng lại đúng khuôn này (SRC-839, 2026-09-19) ​

Chỉ đạo chủ dự án 2026-09-19, kèm ảnh chụp learn.nemo12.com/sat: "làm lại toàn bộ trang này, tương tự như trang ielts". Ảnh ấy bày hub sáu school, vì /sat không khớp route nào — đúng cái hỏng mà §1 mô tả cho /ielts trước SRC-792, chỉ khác tên kỳ thi.

Từ mục 10. Khu IELTS mở cổng ra mắt sớm (SRC-843, 2026-09-19) ​

(Ghi hộ từ commit dac83a0f khi cổng SRC-596 đỏ trên main; phiên làm SRC-843 sửa lời nếu cần.)

Từ mục 33. Ba lượt nói chẩn đoán, và learner chọn lượt ưng nhất (SRC-890, 2026-09-20) ​

Chỉ đạo chủ dự án 20.09.2026: "Có thể đưa tối đa 3 lần bài nói chẩn đoán lên. Rồi cho phép lựa chọn bài nói mà mình thấy ưng nhất." — và, cùng ngày, về màn /ielts/recordings vừa dựng ở §29: "Màn hình này quá nhiều text cứ na ná nhau, cần chỉnh lại Information Architect và màu sắc cho dễ đọc thông tin."

Từ mục 59. IELTS Skills Check: bốn ô, một trang riêng, ba trạng thái (SRC-950, 22.09.2026) ​

Chỉ đạo chủ dự án 22.09.2026, kèm hai ảnh chụp /ielts/setup:

"Đánh số ở đầu các cụm, từ 1 tới 5. Ảnh 2, gồm "IELTS Check" (thay vì Quick Check), hoặc đổi tên thành gì đó mà Learner hiểu rằng "kiểm tra hiểu biết về IELTS nói chung". Rồi IELTS Skills Check (bạn có thể đổi tên). Click vào thì vào trang bên trong gồm 4 kỹ năng, có tiến độ check (chưa kiểm tra, đang làm dở, đã kiểm tra; đều là tiếng Anh): Reading Check, rồi tách Listening Check ra. Writing Check và cuối cùng là Speaking Check. Đó đều là các bài Diagnosis. Mọi bước, learner đều cần xác nhận, rồi mới đi tiếp, hoặc rồi mới test. Test rồi thì trong trang nhỏ đó, có thể xem lại được."

Trước đây hai kỹ năng ấy nằm chung một phiên assessment_sessions(kind='diagnostic') gồm 24 câu. Luật cũ ở requiredDiagnosisParts: chọn Reading là bị đòi cả skill_assessment, tức là ngồi hết sáu câu Listening cho một phép đo mình không xin.

Từ mục 61. Chữ hướng dẫn của các bài check nói tiếng Việt (SRC-953, 22.09.2026) ​

Chỉ đạo chủ dự án 22.09.2026, kèm bốn ảnh chụp: ba ảnh /ielts/setup/reading và một ảnh trang luyện /ielts/skills/reading/inference.

"Với ảnh 1, 2, 3, cần dùng tiếng Việt cho phần hướng dẫn, trình bày thoáng ra và đẹp đẹp như ảnh 4. Quiz cần trình bày như ảnh 4."

Ảnh 1 chụp đúng chỗ luật cũ gãy trong thực tế: một thẻ tiếng Anh (What this check found, 17% correct · 6 questions answered) có một dòng tiếng Việt lọt vào giữa (bài đo đúng 1/6) — câu nhận định do Learner Model sinh ra, vốn luôn tiếng Việt. Thẻ ấy chưa bao giờ thuần tiếng Anh được.