Skip to content

SDD-038 · Home theo trạng thái và JourneyShell ​

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.

90. Hub chia làm hai cụm: đọc ở trên, bấm ở dưới (SRC-988, 22.09.2026) ​

Vì sao ranh giới ấy đáng vẽ ra. Trước bản này hai loại nội dung xen kẽ nhau: khối Learning Setup (một việc phải làm) đứng trên cùng, rồi ba thẻ số, rồi hai đường dẫn trôi nổi, rồi bốn kỹ năng. Mở trang ra là phải đọc lướt cả màn mới biết chỗ nào để XEM và chỗ nào để BẤM. Nay một đường kẻ và một dòng "What to do now" chia đúng hai loại ấy.

Learning Setup xuống cuối. Nó lên đầu ở SRC-945 vì khi ấy dashboard của người mới còn rỗng gần hết, nên khối dẫn đường là thứ duy nhất đáng đọc. Lý do đó hết hiệu lực từ khi dashboard có "This month" và "Small wins" - hai thẻ có nội dung ngay từ buổi học đầu tiên. Và với learner đã khai xong, một khối "còn hai việc" đứng trên cùng mỗi ngày là lời nhắc về việc họ đã làm rồi.

Live class và Leaderboard vào một thẻ có tên "Learn with others". Cùng khuôn với thẻ bốn kỹ năng ngay trên nó. Chúng đứng chung vì cùng một loại: đây là nơi learner gặp NGƯỜI KHÁC, không phải nơi họ luyện bài.

Thẻ bốn kỹ năng có tên "Practise a skill". Một thẻ bốn dòng không tiêu đề thì learner phải đọc hết bốn dòng mới đoán ra nó là cái gì.

Bỏ thẻ 12 tuần. Với learner mới nó là mười một cột trống cạnh một cột, và con số "0.3 a week on average" vừa đúng vừa vô dụng - nó chia công sức của một tuần cho mười hai. Nhịp đều đặn đã có thẻ "Am I showing up?" nói bằng bảy ô vuông của tuần này, tức là bằng thứ learner còn làm gì được với nó.

Ca e2e neo đúng cái ranh giới (mọi thứ để đọc nằm trên vạch, mọi thứ để bấm nằm dưới), vì thứ tự trên trang chủ là thứ trôi nhanh nhất: mỗi lần thêm một thẻ, người thêm đặt nó ở chỗ tiện nhất trong mã chứ không phải chỗ đúng trên màn.

Bổ sung cùng ngày: cụm hành động xếp hai cột từ lg trở lên - trái là "Practise a skill", phải là "Learn with others" chồng lên "Learning Setup". Xếp dọc như bản đầu thì nửa phải của màn rộng bỏ trống hoàn toàn, và learner phải cuộn qua ba thẻ chồng nhau để thấy hết một cụm mà mỗi thẻ chỉ có hai tới bốn dòng. Dưới lg vẫn một cột và việc luyện vẫn nằm trên: trên điện thoại thứ quan trọng nhất phải ở trên chứ không ở cạnh. Ca e2e đo toạ độ x, vì một lưới hỏng sẽ lặng lẽ xếp lại thành một cột.

Lượt chỉnh thứ hai cùng ngày, cho riêng thẻ Learning Setup:

· Rộng hết cột. Bản trước bó còn một phần ba màn (SRC-971) vì khi ấy nó đứng một mình dưới một dải trống. Nay nó nằm trong cột phải cạnh "Learn with others", nên một thẻ hẹp hơn thẻ trên nó đọc ra như một thẻ bị lỗi - và chính hai dòng bên trong bị cắt cụt thành "Lea…", "Learnin…".

· Luôn mở, bỏ hẳn nút gập (đảo lại SRC-940). Nút gập sinh ra khi khối này đứng TRÊN cả bốn kỹ năng và learner phải cuộn qua nó mỗi lần vào trang; từ khi nó xuống cuối cột phải thì cái giá ấy không còn, mà một khối hai dòng gập lại thì chỉ còn một dòng tiêu đề không nói gì. Khoá localStorage nhớ trạng thái gập bỏ theo: giữ một khoá đã hết người đọc là hẹn ngày ai đó tin vào nó.

· Việc đã xong chỉ còn một chấm tròn nhỏ, đặc, màu accent thay cho nhãn chữ "Done". Một việc đã xong không cần chiếm chỗ bằng chữ; thứ cần chữ là việc CHƯA xong, vì ở đó cái nhãn nói ra bước tiếp theo. Lời "Done" vẫn còn dưới dạng sr-only, nên dấu hiệu này không chỉ là màu.

92. Dashboard trang chủ hiện ngay, không chờ mười lăm giây (SRC-992, 22.09.2026) ​

Chủ dự án: ba thẻ trên cùng của /ielts "hiện nay hiển thị khá lâu, thường là sau 10-15 giây mới hiển thị", và phải xuống dưới một giây.

Ba nguyên nhân, xếp theo mức đóng góp.

Một: mỗi lần mở trang chủ, worker kéo TOÀN BỘ kho bài đọc và bài nghe về.loadGlossaries đọc mọi bài đã phát hành của một kỹ năng, kèm trọn body_json của từng bài, và endpoint ielts-effort gọi nó hai lần. Tất cả chừng ấy byte chỉ để tính một dòng: "You met 26 new words this week." Đây là loại hỏng tệ nhất trong các loại hỏng về tốc độ, vì cái giá lớn lên theo KHO chứ không theo learner: mỗi bài soạn thêm làm trang chủ của mọi learner chậm thêm một chút, và trên máy người viết mã thì kho chỉ có vài bài nên không ai thấy gì. Nay nó chỉ hỏi những bài learner ĐÃ LÀM - vài chục thay vì cả kho - và bài đọc không kéo body_json nữa vì từ vựng của bài đọc nằm trong extra_json. Hai lượt đọc cũng chạy song song thay vì nối đuôi.

Hai: năm câu hỏi, năm lượt gửi. Promise.all năm câu SQL nghe như song song, nhưng D1 nằm sau một lượt gọi mạng: năm gói tin đi, năm gói tin về, và trang chờ gói chậm nhất. c.env.DB.batch gộp cả năm vào một gói. Hai câu safeIelts ở lại ngoài batch có chủ ý: chúng đọc bảng của module khác và ĐƯỢC PHÉP không tồn tại, còn batch chạy cả chùm trong một giao dịch nên một bảng thiếu sẽ kéo đổ cả bốn câu kia theo.

Ba: khối dashboard không vẽ gì trong lúc chờ. EffortDashboard trả null tới khi dữ liệu về, nên thứ learner nhìn thấy đầu tiên là một khoảng trống - kể cả khi lượt gọi chỉ mất vài trăm mili giây. Nay nó vẽ ngay bằng số của lần mở trước (lastSeen.ts, localStorage), rồi thay bằng số thật khi lượt gọi về. Cái giá phải nói rõ: trong một nhịp vẽ, learner có thể thấy con số của hôm qua - chẳng hạn chuỗi ngày chưa kịp đứt. Đổi lại họ thấy dashboard thay vì thấy khoảng trống. Vì vậy bộ nhớ ấy CHỈ dùng cho số liệu nỗ lực: không dùng cho quyền truy cập, số lượt còn lại hay tiền, nơi sai một nhịp là sai thật.

Cổng giữ chỗ. read.test.ts gác phép lọc (lọc đúng bài, và bảng từ sau khi lọc y như khi đọc cả kho). Trong routes.test.ts có một ca nghe lén mọi câu SQL mà endpoint gửi xuống D1 và đòi câu hỏi về ielts_content_items phải mang mệnh đề IN (. Ca ấy đo CÂU HỎI GỬI ĐI chứ không đo kết quả, vì một bản quay lại đọc cả kho vẫn trả về đúng từng con số - chỉ chậm dần theo số bài đã soạn, và không có gì đỏ để ai nhận ra.

Một lỗi phát hiện kèm theo. Bản giả D1 trong runlog.testkit.ts hiện thực batch bằng cách gọi run() cho mọi câu, mà run() ném hết dòng đọc được đi - nên mã gộp câu đọc vào batch chạy đúng trên D1 thật nhưng nhận mảng rỗng trong test. Đúng cái bẫy mà đoạn đầu chính file ấy cảnh báo. Đã sửa để bản giả bám hợp đồng thật: đọc thì trả dòng, ghi thì trả số dòng đã đổi.

128. Trang kỹ năng tối giản và thanh trên có số liệu (SRC-1083, 27.09.2026) ​

  • "Where am I strong?" bớt một nửa element: bỏ nhãn "Sub-skill breakdown", câu mô tả, câu tiếng Việt về task type, ô khoá "Practise by task type", số thứ tự và mũi tên mỗi dòng; còn tiêu đề, dấu "?", tên sub-skill, vạch mastery và nhãn bậc. Nút "By task type" của Reading chỉ hiện khi đã mở.
  • Ba ô dashboard thành ô số liệu nhỏ, không viền, nền mờ: nhãn, dấu "?", con số và một hình cao đúng 32px ở cả ba ô; bỏ dòng chú thích dưới đáy. Khác hẳn thẻ hành động phía dưới. Áp cho cả bốn trang kỹ năng vì chúng dùng chung SkillStatusCard.
  • Video ở trang Listening và Reading hiện sẵn trình phát, căn giữa, khoảng thoáng trên dưới (IeltsClip shown).
  • "In the exam · The four parts" của Listening chuyển xuống dải dưới cùng, cùng dòng với "Exam practice" (ExamPracticeBand questionTitle).
  • Thanh trên luôn có band Overall mục tiêu và số ngày còn lại tới ngày thi; ở bốn trang kỹ năng thêm "phút hôm nay / chuẩn ngày · phần trăm" (NavStats trong Shell.tsx, đọc goal và effort một lần mỗi phiên trang). Ẩn trên màn hẹp. Ảnh đại diện cạnh tên đã bỏ; tên kèm dấu ▾ là nút mở menu.
  • Hai ca e2e kiểm thiết kế cũ (số thứ tự dòng, ảnh đại diện) sửa theo thiết kế mới.

126c. Speak together nói tiếng Anh đơn giản toàn bộ (SRC-1084, 27.09.2026) ​

Chủ dự án: đưa ô mã ra một góc (panel bên phải), bỏ nhãn "chọn 1 trong 3 cách hỏi", bỏ chỉ dẫn tiếng Việt và thay bằng tiếng Anh cực kỳ đơn giản cho học sinh 10 tuổi; trên các trang này không có tiếng Việt. Đây là ngoại lệ của SRC-953 cho /ielts/speaking/pair/**, cùng hàng với Learner Profile, Membership, Learning Plan (SRC-1019); đã thêm vào CLAUDE.md.

  • Ô mã phòng, link mời, trạng thái bạn cùng cặp, đồng hồ và "Leave room" nằm ở panel phải, dính khi cuộn.
  • Bối cảnh chỉ còn bản tiếng Anh; cụm từ bỏ bản dịch; gợi ý lượt 3-4 dùng hint_en mới (60 câu, tối đa 10 từ). Lỗi từ máy chủ (tiếng Việt) được thay bằng câu tiếng Anh đơn giản phía giao diện.

126d. Ảnh minh hoạ cho 12 tình huống (SRC-1085, 27.09.2026) ​

  • PairScene.tsx: mỗi tình huống một ảnh SVG vẽ trong code, hai người (một nam tóc ngắn áo xanh, một nữ tóc dài váy đỏ) đứng giữa một không gian riêng: bảng "Hello!" ở lớp, phòng khách, bàn ăn, công viên, giá quần áo, biển chỉ đường, trời mưa, kệ sách, trường học, bãi biển, điện thoại, lịch. Đồ vật đặt ở hai bên để không đè lên người.
  • Trang danh sách: mỗi thẻ là ảnh, rồi số thứ tự và tên; bỏ dòng mô tả.
  • Trang bài: ảnh hiện ngay dưới tiêu đề; "Useful phrases" thành một thẻ, mỗi cụm một ô.

134. Home /ielts theo khuôn trang kỹ năng, bớt 50% chữ (SRC-1101, 28.09.2026) ​

Chủ dự án: NavBar và dashboard ở bốn trang kỹ năng đã ổn, áp sang Home; Home giảm một nửa chữ và element.

  • NavBar: Home dùng cùng NavStats của ielts/Shell.tsx (Free days left, Target, days left, phút hôm nay), bỏ logo và ảnh avatar, chỉ còn chữ NEMO IELTS và tên. NavStats nhận learnerId qua prop vì Home đứng ngoài AuthProvider của mạch trang kỹ năng.
  • Dashboard: ba thẻ dùng chung StatCard của trang kỹ năng (nhãn, một con số, một hình cao 32px, không dòng chú thích). Chi tiết từng kỹ năng của This month, chuỗi ngày và các câu khen còn lại chuyển vào dấu "?": đọc khi cần, không liếc mỗi ngày.
  • Bỏ: link video 1 phút, vạch kẻ ngang; thẻ Next up gọn một hàng, bỏ nhãn hành trình và câu lý do (lý do nằm trong title của tên việc).

145. Rà mobile toàn bộ /ielts/** và /speaking/** (SRC-1135, 29.09.2026) ​

Cổng thường trực apps/learn/e2e/mobileAudit.spec.ts (chạy trong bộ e2e thường, khoảng 1,3 phút): 73 URL, một URL cho mỗi loại route của src/ielts/router.ts ở cả gốc /ielts và /speaking, cộng các trang tài khoản nằm ngoài router (/ielts, learner-profile, membership, learning-plan, settings, referral). Mỗi URL mở ở 375x812 và 320x640, cuộn hết trang một lượt (khối FadeIn chỉ hiện khi lọt vào tầm nhìn), rồi kiểm:

  • không cuộn ngang (scrollWidth <= innerWidth + 1);
  • không phần tử nào lòi ra ngoài khung, trừ khi nằm trong một hộp tự cuộn hoặc tự cắt (overflow-x auto, scroll, hidden);
  • nút và link ở thanh trên, link dạng nút: cao ít nhất 40px (vùng bấm mở rộng bằng after:-inset-* được tính);
  • chữ đọc liền (p, li, td, dd có từ 30 ký tự) ít nhất 14px;
  • không lỗi console.

Ảnh chụp cả trang của từng URL nằm ở test-results/mobile/. Ba endpoint mà mock chung trả {} (kho từ theo cụm, trang một dạng câu hỏi, trạng thái chẩn đoán 4 kỹ năng) và catalog khoá học được giả đúng hình trong e2e/mobileMocks.ts.

Đã sửa:

TrangLỗiSửa
/ieltsThẻ Next up rộng hơn khung ở 320px, trang cuộn ngang 3pxCard đặt lại flex-row; nhãn và tên việc chiếm cả dòng dưới sm
/ielts/learning-plan, /ielts/settings (chế độ sửa band)Nút −/+ đè ra ngoài mép ô bandLưới band một cột dưới sm, nút 40px
/speaking, /ielts/speaking/pairHàng "Next session" bóp ngày giờ thành một cột hẹpNhãn xuống dòng riêng dưới sm
/speaking/sessionsHàng buổi học bóp tên và ngàyKhối tên chiếm cả dòng dưới sm
/ielts/leaderboardTên bị cắt còn "Bà...", chip YOU còn "Y..."Tên được xuống dòng, "+N Nemo" chuyển xuống dưới tên dưới sm
/ielts/skills/<kỹ năng>/<năng lực>Ô bậc cắt "5 Việt + 5 Anh"Ô cao hơn và cho hai dòng dưới sm
/ielts/reading/<cụm>/passages/<n>Lề trái quá rộng, bài đọc chỉ còn khoảng 180px ở 320pxPadding và khoảng cách cột số đoạn nhỏ lại dưới sm
Thanh trên của mọi trangLink vệt đường dẫn 16px, nút hướng dẫn 36px, nút tài khoản 20pxVùng bấm 40px (padding trên link inline nên không đổi bố cục)
Nhiều trangChip lọc cụm, tab Upcoming/Week/Month, nút Report, Skip, "← IELTS", "Learning Setup →", "Skip the tour", link mở videoCao 40px
Bài nghe, bài đọc, bài tậpChấm câu hỏi 10px, vạch tiến độ 6px; chấm đầu bị cắt vòng viềnVùng bấm 20x40px bằng pseudo-element, hàng chấm lùi vào 4px
Bài nghe, trang dạng câu hỏi ĐọcChữ hướng dẫn 12px14px

Chưa sửa, có lý do: thanh trên của sân luyện xuống hai dòng ở 320px (vệt đường dẫn một dòng, nút một dòng) là thiết kế stackOnMobile đã chọn, không phải lỗi; thẻ hướng dẫn (Tour) che một phần thẻ bên dưới là hành vi của tour.

160. Home /ielts sinh từ Learner State + Stage, chế độ test cho chủ dự án (SRC-1186, 02.10.2026) ​

Chỉ đạo chủ dự án 02.10.2026: Home của learn.nemo12.com/ielts không còn là một bảng nhiều khối mà là MỘT khối "WHAT TO DO NOW", sinh từ Learner State + Stage. Đường ống: State + Stage + Learner Model + Evidence -> Recommendation -> Next Best Action -> Home UI.

Năm State, 22 Stage (apps/learn/src/ielts/learnerState.ts, hằng STAGES):

StateCâu hỏi của learnerStage
DiscoverMình bắt đầu từ đâu?Welcome, Set Goal, Diagnostic, Diagnostic Complete
DiagnosedMình nên học gì?Understand Result, Understand Gap, Review Roadmap, Start Learning
LearningTiếp theo mình làm gì?Plan, Learn, Practice, Feedback, Review, Reassess
Needs AttentionCó gì đang không ổn?Falling Behind, Stuck, Needs Review, Overloaded
ReadyTiếp theo là gì?Milestone Achieved, Confirm Readiness, Full Assessment, Set Next Goal

Suy ra từ dữ liệu có sẵn, không thêm bảng, không thêm API. homeSignals.ts gọi các đường đọc đã có: ielts-goal (mục tiêu, mốc), ielts-effort (có lịch sử chưa, phút theo ngày 30 ngày, điểm hiện tại), ielts-learning-plan (đã lưu kế hoạch chưa), ielts-diag4 (trạng thái bốn bài chẩn đoán, báo cáo mới nhất) và ielts-skills/{skill} x4 (mastery từng kỹ năng con, tỉ lệ đúng trước/nay). Một đường hỏng thì tín hiệu ấy thành "không có", không thành trang trắng. Hàm deriveLearnerState thuần, có test.

Thứ tự ưu tiên: (1) chưa có mục tiêu: Welcome; chưa luyện gì: Set Goal / Diagnostic / Diagnostic Complete; (2) đạt mục tiêu: Set Next Goal; vừa đạt mốc: Milestone Achieved; (3) Needs Attention, chỉ khi đã luyện: Falling Behind, Overloaded, Stuck, Needs Review; rồi Ready theo bằng chứng luyện: Full Assessment, Confirm Readiness; (4) có báo cáo mà chưa luyện: Review Roadmap (chưa lưu kế hoạch) / Start Learning; (5) vòng Learning: Review, Reassess, Plan, Feedback, Learn, Practice.

Ngưỡng (hằng có tên trong learnerState.ts):

HằngGiá trịNghĩa
FALLING_BEHIND_DAYS7Falling Behind: 7 ngày trở lên không học
STUCK_ATTEMPTS x ITEMS_PER_ATTEMPT3 x 5Stuck: 15 câu trở lên trên một kỹ năng con, vẫn bậc đầu, đúng dưới STUCK_RATE = 50%
OVERLOADED_OPEN7Overloaded: 7 kỹ năng con đã mở mà chưa lên bậc
NEEDS_REVIEW_ITEMS12Needs Review: 12 câu sai trở lên trên kỹ năng con đúng dưới REVIEW_RATE = 70%
REVIEW_ITEMS5Review (trong vòng Learning): 5 câu sai trở lên
LEARN_MIN_ITEMS5Learn khi kỹ năng con trọng tâm còn dưới 5 câu, sau đó Practice
REASSESS_DAYS30Reassess: báo cáo chẩn đoán cũ từ 30 ngày
DIAGNOSTIC_FRESH_DAYS2Diagnostic Complete: báo cáo trong 2 ngày và chưa luyện
READY_ACCURACY / FULL_TEST_ACCURACY75% / 85%Confirm Readiness (từ hai kỹ năng) / Full Assessment (cả bốn), mỗi kỹ năng ít nhất READY_MIN_ITEMS = 20 câu
MILESTONE_RECENT_DAYS14Milestone Achieved: mốc có ngày trong khoảng 14 ngày và điểm hiện tại đã chạm

Xấp xỉ có chủ ý: "3 lần luyện" của Stuck đếm bằng số câu (5 câu một lượt) vì mastery không trả lịch sử theo lượt; "việc đang mở" là kỹ năng con đã làm mà chưa lên bậc. Understand Result và Understand Gap không suy ra riêng được (không có dấu vết learner đã mở báo cáo), nên learner thật đi Diagnostic Complete -> Review Roadmap -> Start Learning; hai stage ấy xem được qua chế độ test.

Chữ learner đọc: tiếng Anh siêu đơn giản (ngoại lệ của SRC-953, ghi ở CLAUDE.md). Không bao giờ hiện chữ "State" hay "Stage" cho learner. Mỗi stage đúng MỘT nút accent, trỏ vào route có thật (/ielts/diagnostic, /ielts/diagnostic/report, /ielts/learning-plan, /ielts/{skill}, /ielts/tests, /ielts/settings, /ielts/profile). Welcome giữ dữ liệu cũ: chọn band rồi Continue ghi vào ielts-goal như form Goal (bốn kỹ năng cùng band, ngày thi mặc định +180 ngày, sửa ở Settings).

Các khối cũ của Home (dashboard, Next up, bốn kỹ năng, Find your level, Build your base, Learn with others, Learning Setup) nằm dưới nút "See more", gập sẵn; không xoá trang nào. Tour của hub chỉ chạy khi đã mở.

Chế độ test (HomeTestPanel.tsx): chỉ hiện với email đăng nhập dac2205@gmail.com. Nút "Test" góc phải dưới mở bảng có hai ô chọn (State rồi Stage) và ô mô tả tiếng Việt (nghĩa của State, câu hỏi của learner, mục tiêu UI và ưu tiên UI của Stage). Lựa chọn lưu ở localStorage (bọc try/catch), nút "Về trạng thái thật" xoá nó. Khi đang ép stage, Home không truyền hàm ghi nào, nên không có gì ghi vào dữ liệu học thật. Không có lượt gọi server nào riêng cho chế độ test nên không có gì để gác ở server. Tài khoản thiếu dữ liệu cho stage bị ép thì hiện số mẫu (SAMPLE_FACTS) kèm nhãn "sample data", chỉ trong chế độ test.

Kiểm: apps/learn/src/ielts/learnerState.test.tsx (mọi ngưỡng, và render tĩnh cả 22 stage: đúng một CTA, href thuộc danh sách route thật, không chữ "STATE:/STAGE:", không dấu tiếng Việt, không em dash).

166. Trang chủ /ielts thành sáu hành trình trong ba tầng (SRC-1249, 05.10.2026) ​

Chỉ đạo chủ dự án 05.10.2026: dựng lại toàn bộ trang chủ sau đăng nhập learn.nemo12.com/ielts quanh 6 hành trình của learner, mỗi hành trình trả lời một câu hỏi tự nhiên của họ, xếp thành 3 tầng thành một luồng dọc có đánh số, cùng khuôn với www.nemo12.com/ielts/consider (SRC-1248): vòng số bên trái, đường nối dọc, thẻ bo tròn có tiêu đề và một dòng trạng thái.

TầngHành trìnhCâu hỏiTrang
A. Find my path1 Discover My LevelMình đang ở đâu?/ielts/level
2 Set My GoalMình cần bao nhiêu điểm?/ielts/goal
3 Build My PlanMình phải học thế nào?/ielts/learning-plan (giữ nguyên, tiếng Anh đơn giản SRC-1019)
B. Make progress4 Learn & PracticeHôm nay mình học gì?/ielts/today
5 Check My ProgressMình có tiến bộ không?/ielts/progress
C. Get better6 Get UnstuckSao mình mãi không lên?/ielts/unstuck

Luật của hub. Mỗi thẻ hiện MỘT dòng trạng thái thật (vd. Band 6.0 · đo ngày 20.09.2026, Target 7.5 · còn 438 ngày, Chưa có kế hoạch); vòng số tô đặc khi đầu ra của hành trình đã có. Đúng MỘT thẻ sáng lên và mang nút chính duy nhất của màn: hành trình đầu tiên của tầng A còn thiếu đầu ra; xong tầng A thì một stage Needs Attention (SRC-1186) đưa sang Get Unstuck; không thì Learn & Practice nếu hôm nay chưa học, còn lại Check My Progress. Bấm thẻ là sang trang của hành trình.

Nguồn dữ liệu, không thêm endpoint. Mọi dòng đọc từ loadHomeSignals (SRC-1186): ielts-goal, ielts-effort (phút hôm nay, chuẩn phút/ngày, 7 ngày, 12 tuần), ielts-learning-plan, trạng thái chẩn đoán 4 kỹ năng cùng danh sách báo cáo và báo cáo mới nhất, bốn trang kỹ năng (mastery, tỉ lệ đúng). Luật suy ra nằm trong apps/learn/src/ielts/journeys/model.ts, thuần, có test.

Trạng thái trống trung thực. Thiếu dữ liệu thì dòng nói thiếu (Chưa đo trình độ, Chưa có lịch sử luyện tập, Chưa có số phút hôm nay) và bước trống chỉ tới việc sinh ra dữ liệu ấy. Get Unstuck chỉ kết luận về một kỹ năng nhỏ khi nó có ít nhất 15 câu trả lời (3 lượt x 5 câu, cùng ngưỡng STUCK_ATTEMPTS của SRC-1186); dưới ngưỡng ấy trang nói "Chưa đủ dữ liệu để chẩn đoán" và mời luyện thêm hoặc đo lại, không dựng một phép dò giả.

Trang hành trình bọc, không viết lại. Mỗi trang là một luồng bước đánh số cùng khuôn; phần việc thật vẫn là màn có sẵn: bài chẩn đoán và báo cáo, /ielts/gap, /ielts/settings, bộ chọn band (Welcome), thẻ "What to do now" cùng bảng test của chủ dự án, Next up, các khối luyện cũ (bốn kỹ năng, chẩn đoán, ngữ pháp, học cùng người khác, Learning Setup) nay mở sẵn ở /ielts/today, và các thẻ công sức ở /ielts/progress. Nút "See more" và thẻ "What to do now" trên hub đã bỏ.

Ngôn ngữ. Tên tầng, tên hành trình, tên bước, tên kỹ năng: tiếng Anh. Câu hỏi, dòng trạng thái, lời dặn và nhãn nút hành động: tiếng Việt (SRC-953).

Luật bố cục chủ dự án 06.10.2026 (mẫu chung: Guided Journey §9): mọi trang learn.nemo12.com/ielts/** có NavBar mà menu là sáu journey của §166, thanh bước ngay dưới nêu tên từng bước của journey đang đứng, và Status Card góc trên phải thay hàng chip.

NavBar. NEMO IELTS (về /ielts; là chữ khi đang ở /ielts) · Set My Goal · Discover My Level · Build My Plan · Learn & Practice · Check My Progress · Get Unstuck · trợ giúp · tài khoản. Sáu tab chương trình cũ (Roadmap, Curriculum, Methodology, Outcomes, Resources, Tuition, phần lớn trỏ sang nemo12.com) và lưới chương trình đã rời /ielts. Journey của một trang đọc từ đường dẫn (journeyOfPath): /ielts/diagnostic/** và /ielts/gap thuộc Discover My Level, /ielts/settings thuộc Set My Goal, /ielts/learning-plan thuộc Build My Plan, /ielts/profile thuộc Check My Progress, mọi trang luyện (kỹ năng, đề, ngữ pháp, từ vựng, live, speaking pair...) thuộc Learn & Practice. Hub và ba trang tài khoản (learner-profile, membership, referral) không thuộc journey nào: chúng hiện journey KẾ TIẾP (nextJourney, luật §166).

Thanh bước. Tên và luật "xong" của từng bước ở MỘT chỗ (journeySteps trong apps/learn/src/ielts/journeys/model.ts); luồng đánh số của trang hành trình đọc cùng định nghĩa ấy.

JourneyBước
Set My GoalTarget band → Test date → Gap → Next step
Discover My LevelStart → Diagnostic → Results → Understand my gaps → Next step
Build My PlanTarget → Current level → Monthly plan → First session (bước trỏ tới trang tạo ra đầu vào ấy)
Learn & PracticeREADING → LISTENING → WRITING → SPEAKING (mỗi pill mở trang kỹ năng ấy, SRC-1321)
Check My ProgressThis week → Accuracy by skill → Study hours, 12 weeks → Level checks → Leaderboard → Stuck?
Get UnstuckEnough data? → Diagnosis → What to do → Recheck

Năm journey, menu thu gọn (SRC-1300, chủ dự án 08.10.2026). NavBar còn năm mục tên ngắn: 1 Goal · 2 My Level · 3 Plan · 4 Learn · 5 Progress, mặc định gập về mục hiện tại, bấm thì mở ngang. Get Unstuck rời menu và hub (tầng C bỏ), thành bước cuối "Stuck?" của Check My Progress (This week → Accuracy by skill → Study hours, 12 weeks → Level checks → Stuck?); /ielts/unstuck giữ URL và thuộc Progress (journeyOfPath trả progress/stuck). Không còn dấu tick trên NavBar và hàng bước. Thiết kế: guided-journey §9x.

Learn gọn lại (chủ dự án 09.10.2026). Bước 4 Learn chỉ còn việc luyện: bốn kỹ năng (Reading, Listening, Writing, Speaking) và thẻ "Build your base" (Grammar, Full tests). "What to do now" và "Next up" gộp thành MỘT thẻ "What to do now" chỉ thẳng một kỹ năng để luyện hôm nay, một nút chính (pickTodaySkill trong journeys/JourneyPages.tsx: kỹ năng đang kẹt, rồi focus của Learner State, rồi kỹ năng đầu tiên chưa luyện, cuối cùng là Reading). Thẻ chỉ báo "Band x.x reached" khi đã có band ĐO ĐƯỢC (báo cáo chẩn đoán): bản cũ nói "You reached 6.0" trong khi Status Card ghi "Not measured yet", vì mốc đọc band ước tính. Panel Test của chủ dự án vẫn ép được stage để xem thẻ cũ. Các lối vào dời chỗ, không mất: Speak together và Live class thành hai ô "Practise with people" trên trang Speaking; Leaderboard thành bước "Leaderboard" của Progress (/ielts/leaderboard thuộc Progress trong journeyOfPath); Diagnostic chỉ còn ở bước 2 My Level. Thẻ Next up (JourneyNextUp) vẫn ở trang hồ sơ squid. Test: e2e/ieltsDashboard.spec.ts (lối vào ở chỗ mới), e2e/smoke.spec.ts, e2e/ieltsHomeNow.spec.ts.

Menu luôn mở, Learn luôn nổi, hàng 2 của Learn là bốn kỹ năng (SRC-1321, chủ dự án 10.10.2026). Đảo phần "menu thu gọn" của SRC-1300: NavBar cấp 1 luôn hiện đủ năm mục, không gập, không bấm để mở (featured + tags của JourneyNavBar, collapsible không còn dùng ở /ielts). Mục 4 Learn luôn là pill tô bg-accent-deep chữ trắng ở MỌI trang, kể cả khi đang ở journey khác, vì đó là đường chính; đang ở chính Learn thì thêm vòng viền đậm. Bốn mục kia là tag nhỏ (viền mảnh, chữ 14px nhẹ), vùng bấm vẫn cao 40px nhờ phần đệm quanh tag; tag của trang hiện tại có viền đậm + chữ đậm, khác hẳn kiểu tô của Learn. Ở 375px menu xuống dòng thay vì cuộn ngang, nên cả năm mục luôn trong tầm nhìn. Hàng 2 (hàng bước) giữ nguyên ở mọi journey; riêng Learn, hàng 2 thành bốn kỹ năng READING, LISTENING, WRITING, SPEAKING, mỗi pill mở /ielts/<skill> (journeySteps("today")). Pill sáng khi learner ở trang kỹ năng ấy hoặc một trang luyện dưới nó (journeyOfPath trả step = kỹ năng của đoạn đường thứ hai); ở /ielts/today, Grammar, Full tests, Live... không pill nào sáng, vì thẻ kỹ năng của trang đã nói kỹ năng nên luyện. Status Card ẩn trên trang luyện như cũ (practice của journeyOfPath).

Trang /ielts/today gọn còn khoảng một nửa: h1 (bỏ dòng phụ), MỘT thẻ kỹ năng với một dòng ngắn "Khoảng 10 phút." và một nút chính. Bỏ hai bước đánh số "What to do now", "Choose what to practise", bỏ thẻ "Practise a skill" (bốn kỹ năng đã là hàng 2), nhãn "Start here", nút ?, và tour "Four skills, in order" đi cùng thẻ ấy. Cột phải: Status Card ba dòng (Target, Level now, Today), dưới nó khối "Build your base" (Grammar n/180, Full tests; LearnBaseLinks trong IeltsPathway.tsx), rồi Learning Setup khi còn việc (SRC-945). Đo bằng Playwright 1280px, vùng nội dung + cột phải: 67 phần tử (chữ, icon, nút, link) và 169 từ trước, 26 phần tử và 51 từ sau (-61%, -70%), nút/link 18 xuống 7. Test: e2e/ieltsJourneyShell.spec.ts (năm mục luôn hiện, Learn có lớp tô, tag 40px, hàng kỹ năng sáng đúng trang), e2e/ieltsHomeNow.spec.ts (không bước đánh số, Grammar/Full tests ở cột phải, ngân sách ≤34 phần tử, ≤85 từ), e2e/smoke.spec.ts, e2e/ieltsAuditPass4.spec.ts.

Bước hiện tại là bước của chính trang (vd. /ielts/diagnostic/report là Results), nếu không thì bước chưa xong đầu tiên. Trên trang hành trình, bấm một bước là cuộn tới thẻ #step-<key>; ở trang khác là mở trang hành trình ở đúng thẻ ấy. Dòng "Journey n of 6" và link "← Your IELTS path" đầu trang hành trình đã bỏ.

Status Card (ieltsStatusRows): Membership (Free: N days left / Free trial ended / Member), Target (Band x.x hoặc Not set yet), Test date (N days left), Level now (band của báo cáo chẩn đoán gần nhất hoặc Not measured yet), Today (phút/chuẩn · %). Nhãn tiếng Anh (nhãn trạng thái, SRC-834). Dữ liệu từ một lượt loadHomeSignals mỗi lần xem trang, dùng chung với trang hành trình (journeys/signalsStore.ts), cộng ielts-membership.

Không link thoát ra khỏi cụm /ielts. Đã gỡ, mỗi chỗ một dòng:

ChỗLink cũNay
Thanh trên (ProgramMenu)Roadmap, Curriculum, Methodology, Outcomes, Resources, Tuition sang nemo12.com/ielts/...menu sáu journey
Thanh trênlưới chương trình /programs (cả bản điện thoại)bỏ
Thanh trênnút Zalo (ZaloLink, khi có link nhóm)bỏ ở /ielts
Menu tài khoản (cả hai mạch)"What's new" sang nemo12.com/ielts/whats-newbỏ ở /ielts, /speak giữ
Màn mời đăng nhập"← Back to Nemo12" sang nemo12.combỏ
Chân trangnemo12.com và bốn icon mạng xã hộimột dòng "© năm NEMO IELTS", không link
Learning Plan, Share my planlink www.nemo12.com/ielts/learning-plans/<slug>chữ để chép
Speaking pair, thẻ ngữ pháp"See the NEMO GRAMMAR lesson" sang /grammar/...bỏ
Speaking pair, "Why speaking practice works"sáu link nguồn nghiên cứu ra ngoàitên nguồn + tên miền bằng chữ (/speak giữ link)

✍️ Giữ lại, chờ chủ dự án quyết: nút Join on Zoom của buổi live (Live.tsx) và buổi Speak (SpeakSchedule.tsx, SpeakRegister.tsx). Đó là cách duy nhất để vào buổi học, không phải lối sang nơi khác; bỏ đi là learner không dự được buổi.

Test. apps/learn/e2e/ieltsJourneyShell.spec.ts: menu sáu journey theo thứ tự, journey của trang sáng, hub trỏ journey kế; thanh có tên đủ các bước và đúng một bước hiện tại; Status Card 3-5 dòng, hàng chip đã rời thanh trên; mọi a[href] trên hơn 40 trang /ielts (và màn mời đăng nhập) nằm dưới /ielts; 375px không cuộn ngang, bước hiện tại trong tầm nhìn, Status Card dưới thanh; bàn phím đi được menu. Unit: journeys/model.test.ts.

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

Từ mục 90. Hub chia làm hai cụm: đọc ở trên, bấm ở dưới (SRC-988, 22.09.2026) ​

Chỉ đạo: tách "cụm dashboard" ở trên khỏi "cụm hành động" ở dưới; Learning Setup xuống dưới; gom Live class và Leaderboard vào một thẻ và cũng đưa xuống dưới; thẻ bốn kỹ năng phải có tên; bỏ thẻ "Hours a week, last 12 weeks".

Từ mục 128. Trang kỹ năng tối giản và thanh trên có số liệu (SRC-1083, 27.09.2026) ​

Chủ dự án gửi năm ảnh trang Listening:

Từ mục 145. Rà mobile toàn bộ /ielts/** và /speaking/** (SRC-1135, 29.09.2026) ​

Chỉ đạo chủ dự án 29.09.2026: rà mọi trang learn.nemo12.com/ielts và /speaking, đảm bảo mobile-friendly. Learn nằm sau đăng nhập Google nên việc rà chạy bằng Playwright trên bản build thật với API giả.