---
url: https://docs.nemo12.com/intake/src-0500-0524.md
description: >-
  Sổ tiếp nhận nguồn yêu cầu SRC-0500 tới SRC-0524: mỗi dòng một nguồn, ngày
  nhận, tài liệu canonical đã ghi và trạng thái.
---

# Sổ nguồn SRC-0500 tới SRC-0524

Một mảnh của [sổ tiếp nhận](../intake.md). Chỉ CHÈN dòng bằng `node scripts/src-new.mjs`, không ghi đè cả file.

| ID | Ngày nhận | Nguồn | Canonical hóa vào | Trạng thái |
| --- | --- | --- | --- | --- |
| SRC-500 | 2026-08-21 | Rà soát 2026-08-22 sau khi đảo chiều nguồn dữ liệu: docs.nemo12.com build ĐỎ | VitePress chặn cả bản build khi có link chết, mà cây năng lực vừa chuyển vào docs lại trỏ sang các chùm bài luận chỉ có trên site Pearl (`/ideas/…`, `/mental-models/…`, `/decisions/…`, `/learning/…`). Hệ quả: một chùm bài luận thiếu chỗ đó làm SẬP toàn bộ docs.nemo12.com, tức đúng lúc docs vừa thành nguồn thì nó không xuất bản được. Khai `ignoreDeadLinks` theo TIỀN TỐ chứ không tắt kiểm link, để link gãy trong tài liệu quản trị vẫn đỏ như cũ | ✅ |
| SRC-501 | 2026-08-21 | Rà soát 2026-08-22: ba mảnh runtime vẫn chưa có trong docs | Xuất thêm vào `docs/knowledge/<môn>.md`: **1.109 cạnh tiên quyết** kèm câu vì sao từng cạnh, **sổ 1.587 lab** với cột Gắn node để dò lab mồ côi bằng mắt, và **chỉ mục kho câu hỏi theo node** (bao nhiêu câu, đang dùng bao nhiêu, khoảng độ khó). Kho câu cố ý chỉ vào docs dưới dạng CHỈ MỤC: đưa cả 15.575 câu vào vừa làm docs hết đọc được, vừa để lộ đáp án ra một trang công khai | ✅ |
| SRC-502 | 2026-08-21 | Rà soát 2026-08-22: 9 lab live vẫn không ghi được bằng chứng vì cây năng lực chưa có Unit nào phủ | Soạn nội dung để NHẬN chúng chứ không gắn bừa: Module mới **3.6 Yếu tố truyện, kịch và thơ** trong package Diễn giải của Ngữ văn (5 unit, nhận bối cảnh, xung đột, yếu tố kịch, lời thoại, nhạc tính thơ), cộng bốn unit lẻ: Trường từ vựng (Vốn từ mở rộng), Lắng nghe để người nói biết mình được nghe (nửa NGHE của mảng nói và nghe vốn đã có unit nói trước lớp), Miêu tả bằng lời (module Speak của Tiếng Anh, vì lab là kỹ năng nói), Phản ứng cho nhận electron (module Vì sao có liên kết của Hoá, vì redox là chuyển electron chứ không phải bài tính toán). Chạy `sync-tree-from-pearl` cho ba môn: 9 unit mới vào D1, **134+62+64 id cũ giữ nguyên** nên không mất câu hỏi hay bằng chứng nào. Lab live mồ côi: **9 → 0**. Agent còn phát hiện hai lỗi cũ ở `van/compose/writing-for-a-reader.md`: hai unit nằm sau mục IB và không được liệt kê ở trang Package (đã sửa), và hai unit trùng nội dung gần hết (chưa gộp, ghi lại để làm sau) | ✅ |
| SRC-503 | 2026-08-21 | Feedback UI 2026-08-22 (ảnh trang Mô phỏng): popover 🔥/⚡/vững bật GIỮA màn hình, cách chỗ bấm nửa trang — mọi popover phải mở ngay tại chỗ vừa click, và nút trong popover phải nhỏ lại để nội dung là thứ nổi lên | code: App.tsx XpBar (neo dưới cụm mini card), ProgressViews.tsx (popover thẻ bản đồ neo theo toạ độ click; popover xác nhận BẮT ĐẦU neo dưới nút, bỏ link Ở lại đây); modal giữa bài trong Learning.tsx giữ nguyên vì là điểm dừng có chủ đích | ✅ |
| SRC-504 | 2026-08-21 | CI trên main đỏ: 8 test e2e gãy sau khi phiên khác đổi bản đồ (SRC-499) và popover (SRC-503) mà không cập nhật test | Sửa TEST cho khớp luật mới chứ không sửa giao diện của phiên kia: bản đồ nay mặc định chỉ bày Package nên test nào chạm Module hay Unit phải mở sâu trước (gói thành một hàm `moBanDoToiUnit` khớp cả nhãn VI lẫn EN, để lần sau đổi mức xem chỉ phải sửa một chỗ); nhãn ngôi sao Focus đổi theo mức xem; popover xác nhận bỏ link "Ở lại đây" nên cách đóng nay là bấm LỚP PHỦ, và phải bấm vào góc lớp phủ chứ không phải giữa, vì giữa là chính popover. Test "Dashboard bày sẵn cả ba tầng" viết lại thành "mặc định chỉ Package, mở sâu mới tới Unit": luật cũ SRC-445 (một cách bày) vẫn đúng, cái đổi là bày TỚI ĐÂU | ✅ |
| SRC-505 | 2026-08-21 | Chủ dự án 2026-08-22 bác lập luận dung lượng của tôi: "three.js mà 150KB thì quá nhẹ, chỉ bằng một tấm ảnh. Dùng three.js cho lab vật lý, hoá học, sinh học. Cần sinh động hoá các lab, không chỉ three.js mà thư viện khác cũng OK" | Chủ dự án đúng và tôi ghi lại chỗ mình sai: Nemo12 cấm ảnh bitmap CHÍNH VÌ hình sinh từ tham số vừa nhẹ vừa học được nhiều hơn, nên lấy dung lượng ra chặn một engine tương tác thật là dùng sai chính nguyên tắc ấy. Đã làm: `Molecule3D` bi và que xoay được, nạp động (gói riêng 131KB nén), không asset ngoài, màu theo quy ước CPK, liên kết đôi vẽ thành thanh SONG SONG để learner đếm được bậc, máy thiếu WebGL thì nói ra một câu chứ không để trắng; archetype `molecule-3d` trong `lab_content.viz`; hai lab Hoá đã đổi sang (H₂O góc 104,5 độ với hai cặp electron chưa liên kết, CH₄ tứ diện), bản picker cũ giữ trong `viz_picker`. Ranh giới còn lại KHÔNG phải dung lượng mà là: 3D vào LAB chứ không vào hình câu hỏi (hình câu hỏi là thứ liếc rồi trả lời), và 3D phải kiếm được chỗ của nó (xoay được thì thấy thêm gì mà hình phẳng không nói nổi). Hàng chờ sinh động hoá tiếp ghi ở SDD-010 §11.2 | ✅ |
| SRC-506 | 2026-08-21 | Thảo luận với chủ dự án 2026-08-22 trong phiên Claude: cần cơ chế nâng mastery khi learner hổng vùng kiến thức — remediation loop (chẩn đoán xuống prerequisite gốc, baseline, bậc thang can thiệp, stopping rule, đo delta). Chủ dự án xác nhận làm spec | SDD-002 (mục mới Remediation Loop) + PRD-001 (REQ mới) | ✅ |
| SRC-507 | 2026-08-21 | Chạy theo thứ tự 1 → 4 → 2 — cổng chất lượng nội dung trước | Nội dung chỉ vào luồng học qua sàng lọc: seed nạp candidate, trigger D1 chặn published không hồ sơ, chấm bù cho kho cũ | ✅ |
| SRC-508 | 2026-08-21 | Trong Learner Model co can them evidence_count, trajectory, last_evidence_at vao tung node ko? | Moi node trong ban chup Learner Model mang theo evidence_count + trajectory + last_evidence_at, va giu MOI node co bang chung chu khong chi 5 strength + 5 gap; phan bi cat phai dem duoc bang nodes_omitted | ✅ |
| SRC-509 | 2026-08-21 | Chay theo thu tu 1 -> 4 -> 2 (viec 2: dien tap backup/restore) | Dot dien tap backup/restore phai kiem ca VAN TAY NOI DUNG chu khong chi dem dong, va phai chay lai moi khi schema doi dang ke | ✅ |
| SRC-510 | 2026-08-22 | Chủ dự án 2026-08-22: làm nốt cả 4 việc trong hàng chờ sinh động hoá lab (SDD-010 §11.2) | Bốn archetype mới trong engine khám phá, ba cái đầu CHẠY MÔ PHỎNG chứ không vẽ minh hoạ: `pendulum` (chu kỳ T = 2π√(L/g) tính thật, learner kéo dài dây rồi thấy chu kỳ đổi còn biên độ nhỏ thì không), `collision` (hai xe, đàn hồi hay mềm, giải từ bảo toàn động lượng), `circuit` (định luật Ôm, độ sáng bóng đèn tính từ dòng THẬT nên nối tiếp thì mọi bóng cùng mờ, song song thì sáng như một bóng, đúng chỗ learner hay nói ngược), `quadratic` (kéo a, b, c thấy parabol đổi hình, không cần thư viện nào). Test canh CON SỐ chứ không canh hình: mô phỏng vẽ đẹp mà ra số sai thì dạy sai, tệ hơn là không có mô phỏng | ✅ |
| SRC-511 | 2026-08-22 | Chủ dự án 2026-08-22, sau khi mở một lab Toán: "xem xong, tôi không hiểu nó xuất hiện ra để làm gì. Cần thêm một vùng thông tin mô tả về từng lab, dạng meta, để learner và mentor như tôi đọc xong còn hiểu về nó" | Đúng, và đó là lỗi thật: mọi lab vào thẳng câu hỏi, không chỗ nào nói vì sao nó tồn tại. Cột `objective_vi` có sẵn nhưng chỉ phủ 34/161 lab Toán và nó trả lời "lab dạy gì", không trả lời "vì sao có lab này". Migration 0068 thêm ba cột tách theo BA NGƯỜI ĐỌC khác nhau, cộng thời lượng: `why_vi` (mentor hỏi vì sao có lab), `notice_vi` (learner hỏi làm xong nhận ra gì), `mentor_vi` (phụ huynh hỏi nên hỏi lại con câu gì), `minutes`. Gộp ba câu thành một đoạn văn thì ai đọc cũng phải lọc qua phần không dành cho mình, và người bỏ cuộc trước nhất là learner. Vùng meta ĐÓNG SẴN sau nút "Lab này để làm gì?": learner tới đây để nghịch, mở sẵn thì đẩy chính cái lab xuống dưới màn hình | ✅ |
| SRC-512 | 2026-08-22 | Chủ dự án 2026-08-22, ba việc trên màn Toàn cảnh: (1) bấm thẻ 'con đã làm gần đây' thì popover bị CHE, cần popover có điều đáng tự hào, nút đi tiếp và nút đóng; (2) khu 'Việc hôm nay' quá nhiều chữ, muốn icon và 1-2 câu; (3) từ bản đồ không đi tới được Learning Experience và Assessment Experience của Unit; (4) cả màn hình phải làm learner thấy 'tôi hoàn thành nhiều việc, tới đích không xa' và bớt thứ gây nhiễu | Popover thẻ gần đây neo bằng `fixed` phủ toàn màn hình chứ không nằm trong thẻ (panel phải có khung riêng và có cuộn nên popover neo trong đó bị cắt, đúng lỗi trong ảnh); nội dung là MỘT câu khen đúng mức việc đã làm (đi hết Unit > quay lại nhiều lượt > mới bắt đầu, lấy từ hai con số `rounds` và `done` vốn đã tính sẵn ở truy vấn cockpit nhưng trước đây bỏ đi), cộng nút đóng và nút đi tiếp. Khu 'Việc hôm nay' còn ĐÚNG MỘT câu đổi vai theo trạng thái, bỏ ba dòng nói cùng một ý. Bản đồ: mọi popover đều có lối vào bài, Package và Module vào Unit đầu tiên của mình, vì từ SRC-499 mức xem mặc định chỉ bày Package nên trước đó không có đường nào dẫn vào. Panel phải: số 0 điểm hôm nay đổi thành lời mời, và ô 'đã vững' thêm dòng 'còn N unit nữa là tròn X' | ✅ |
| SRC-513 | 2026-08-22 | Chủ dự án 2026-08-22, trang Kế hoạch: đổi 76 ngày thành tuần làm tròn; vẽ chart hay diagram cho vui mắt vì màn hình quá nhiều chữ; và "với Giai đoạn 1, tôi cần biết cụ thể LT, DS, SH là gì, không được phép viết tắt" | 76 là con số đúng mà vô dụng: không ai lập kế hoạch theo ngày lẻ, và số lớn đọc ra cảm giác xa vời; nay là **11 tuần**, khớp luôn đơn vị các chặng bên dưới đang dùng. Thêm **dải đường đi**: mỗi chặng một khúc dài theo số tuần, khúc đang đi tô đậm, nhìn một cái là biết đang ở đâu thay vì đọc hai dòng rồi tự cộng trong đầu. Viết tắt sửa từ GỐC ở server: truy vấn kế hoạch nay join sang bảng `strands` lấy `name_vi`, vì mã strand là chuyện nội bộ của dữ liệu, phụ huynh và learner không có cách nào tra ra nó nghĩa là gì | ✅ |
| SRC-514 | 2026-08-22 | Chủ dự án 2026-08-22 hỏi cơ chế Diagnosis: có ứng xử khác theo lớp không, phủ rộng nhiều package hay mỗi package một test riêng | Câu hỏi chạm đúng một chỗ MÃ ĐANG CHẠY LỆCH KHỎI THIẾT KẾ đã chốt. SDD-021 §3.1 nói bài đo mở đầu trải rộng mỗi Package 2-3 câu và độ khó xuất phát lấy từ LỚP trong hồ sơ; mã thật thì `ORDER BY grade, level LIMIT 15`, tức 15 node DỄ NHẤT của môn, **giống hệt nhau cho mọi learner**. Đo thật trên Toán: cả 15 câu đều lớp 1 tới 3, kể cả với learner lớp 9. Hậu quả không phải kém tối ưu mà là sai mục đích: bài đo sinh ra để khỏi bắt learner học lại thứ đã biết, nhưng learner lớp 9 đúng hết mấy câu lớp 1 rồi hệ vẫn mù về mọi thứ từ lớp 4 trở lên; và ấn tượng đầu tiên là 'chỗ này không dành cho mình'. Vá bằng `pickDiagnostic` tách riêng để test được: xếp theo KHOẢNG CÁCH tới lớp learner (cùng khoảng cách thì ưu tiên câu DƯỚI lớp, vì đo là để tìm nền hổng chứ không phải thử xem vượt tới đâu), lấy vòng tròn qua các Package nên không Package nào nuốt hết chỗ, và bỏ luôn strand đang ẩn khỏi giao diện. Đo lại trên dữ liệu thật: lớp 9 nay nhận câu lớp 8-10, lớp 5 nhận lớp 2-6, cả năm Package đều có mặt | ✅ |
| SRC-515 | 2026-08-22 | Chủ dự án 2026-08-22: "mọi người đều quan tâm việc TÔI CẦN KHÁM TOÀN DIỆN, để biết tôi hổng ở những đâu một cách nhanh nhất. Có thể là một bài 15 câu, nhưng adaptive. Và vẫn cần dùng thông tin lớp mấy hiện tại" | Mười lăm câu tĩnh không trả lời được câu đó: chúng chỉ nói learner làm đúng mấy câu quanh lớp mình, không nói TRẦN nằm ở đâu. Muốn biết hổng từ đâu thì phải đi TÌM RANH GIỚI, và tìm bằng ba câu mỗi Package chính là tìm kiếm nhị phân: câu 1 hỏi ngay tại lớp hiện tại; câu 2 đúng thì nhảy LÊN 2 lớp, sai thì lùi XUỐNG 2 lớp; câu 3 đã có cả mốc đúng lẫn mốc sai thì hỏi ngay GIỮA để khép khoảng, chưa có thì đi tiếp cùng hướng 4 lớp. Năm Package, 15 câu, kết quả là một câu đọc được cho từng mảng: **vững tới lớp 7, hổng từ lớp 8**. Bài đo nay ra câu theo ĐỢT qua `POST /v1/diagnostic/{id}/next`, server CHẤM chứ không tin client, vì nếu client tự khai đúng sai thì mở tab thứ hai là lái được cả bài đo về vùng dễ; trạng thái phiên ở cột mới `adaptive_json` (migration 0069). Cố ý KHÔNG dùng IRT ở vòng này: IRT cần ngân hàng câu đã hiệu chỉnh độ khó, còn thứ đang có là LỚP của node, một thang thô nhưng có thật; dùng thang thô cho đúng việc còn hơn một mô hình đẹp chạy trên tham số bịa. Thiếu lớp trong hồ sơ thì lùi về bài tĩnh trải rộng của SRC-514 | ✅ |
| SRC-516 | 2026-08-22 | Chủ dự án 2026-08-22: làm nốt hai việc còn treo của bài đo — bày kết quả theo mảng, và cho engine chọn bài dùng lớp hiện tại | **Màn kết quả khám**: bài đo trước đây chấm xong là nhảy thẳng vào trang học, tức learner làm 15 câu rồi không được biết mình vừa được kết luận gì, đúng câu hỏi lớn nhất của người đi khám. Nay dừng lại một màn: mỗi mảng một dòng, nói bằng lời chứ không bằng điểm ("Vững tới lớp 7. Cần vá từ lớp 8"), kèm TÊN mảng chứ không phải mã. Không xếp hạng, không phần trăm, không so với ai: bài đo sinh ra để chỉ chỗ bắt đầu, một con số tổng chỉ làm learner tự chấm điểm mình. Chi tiết kỹ thuật đáng nhớ: phải giữ kết quả bằng `useRef` song song với state, vì hàm chấm chạy ngay trong cùng một tick với `setState` nên đọc state thì màn kết quả không bao giờ hiện. **Chọn bài theo lớp**: chiến lược nền móng nay thử CỬA SỔ HẸP (lớp G-3 tới G) trước rồi mới nới ra toàn môn. Learner lớp 9 chưa có bằng chứng nào mà được mời học "Đếm, gộp và tách" của lớp 1 thì đọc ra đúng một câu: chỗ này không dành cho mình. Đo trên dữ liệu thật: cùng một Unit chặn 10 Unit khác, learner lớp 9 nay nhận bản lớp 6 thay vì bản lớp 1. Cửa sổ chỉ là ưu tiên chứ không phải bộ lọc cứng, môn chưa có nội dung ở khoảng đó thì câu thứ hai vẫn tìm được bài | ✅ |
| SRC-517 | 2026-08-22 | Chủ dự án 2026-08-22: thêm card ở panel phải chứa tên learner và đang học lớp mấy; click thì expand ra năm sinh, tuổi hiện nay suy ra từ năm sinh, và 3 nguyện vọng thi vào chuyên gì trường gì | Dữ liệu đã có sẵn cả (`learners.birth_date`, `grade`, bảng `learner_exam_targets` với `priority`), nên không thêm endpoint nào, chỉ dựng thẻ. Ba quyết định trình bày: mặt thẻ CHỈ tên và lớp, vì đó là hai thứ trả lời câu "hệ có nhớ mình là ai không", phần còn lại là hồ sơ mà hồ sơ thì learner không cần nhìn mỗi ngày; tuổi SUY RA từ năm sinh chứ không lưu thành cột, vì lưu tuổi là lưu một con số sẽ sai sau đúng một năm và không ai nhớ đi sửa; nguyện vọng chỉ tải khi learner MỞ thẻ, vì panel phải hiện ở mọi trang mà đây là dữ liệu gần như không đổi | ✅ |
| SRC-518 | 2026-08-22 | Chủ dự án 2026-08-22: trang Hồ sơ tách ra 3 cụm, mỗi cụm một card riêng — cụm 1 thông tin chung với ngày sinh format DD.MM.YYYY, cụm 2 trường và lớp hiện tại cùng tỉnh thành, cụm 3 các nguyện vọng tối đa 3 gồm tên trường và lớp chuyên hoặc lớp chọn | Vì sao tách thật chứ không chỉ kẻ thêm đường ngang: ba cụm đổi theo BA NHỊP khác nhau. Tên và ngày sinh gần như không bao giờ đổi; trường lớp đổi mỗi năm một lần; nguyện vọng đổi suốt năm cuối cấp, có khi vài lần một tháng. Gộp một form thì mỗi lần sửa nguyện vọng lại phải lướt qua và có nguy cơ chạm nhầm vào ngày sinh, nên nay MỖI CỤM có công tắc sửa riêng. Hai cụm đầu vẫn dùng chung `PATCH /profile` (endpoint đòi đủ năm trường) nên mỗi cụm gửi cả năm trường lấy từ state: tách ở giao diện, không tách ở hợp đồng dữ liệu. Cụm nguyện vọng nhập được ngay tại chỗ, trần BA vì nguyện vọng thứ tư trở đi thì thứ tự ưu tiên hết nghĩa và kế hoạch học cũng không đuổi theo nổi bốn đích; bỏ một nguyện vọng là đánh dấu `dropped` chứ không xoá dòng, vì kế hoạch đã từng chạy theo đích đó và xoá sạch là mất luôn lý do vì sao mấy tuần trước hệ xếp bài như vậy | ✅ |
| SRC-519 | 2026-08-22 | Chủ dự án 2026-08-23: thêm link Khai ngay ở card learner tại panel phải | Thẻ Về con ở panel phải chỉ ĐỌC, không sửa được gì, nên khi nó nói Chưa khai năm sinh hoặc Chưa đặt nguyện vọng nào thì learner đọc xong cũng không biết khai ở đâu — dòng chữ trở thành lời trách chứ không phải lời mời. Nay mở thẻ ra mà còn thiếu thì có link Khai ngay đưa thẳng sang trang Hồ sơ. Link CHỈ hiện khi thật sự thiếu: hồ sơ đủ rồi mà vẫn để một lời mời đứng đó thì thành nhiễu, trái luật tối giản SRC-048. Điều kiện thiếu tính cả nguyện vọng, nhưng chỉ sau khi thẻ đã mở, vì danh sách nguyện vọng chỉ tải lúc mở thẻ nên trước đó rỗng không có nghĩa là chưa đặt | ✅ |
| SRC-520 | 2026-08-23 | Chỉ đạo: **bổ sung 2 mentor** — Phan Minh Thông (cựu học sinh Chuyên Lý, Chuyên Tiền Giang) và Phan Quốc Việt (cựu học sinh Chuyên Toán, Chu Văn An, **sinh năm 1997**); thẻ mentor **chỉ để lại ảnh, tên, và dòng "cựu học sinh chuyên…"**; **tạo trang riêng cho từng mentor ở `mentors/{slug}`** | [SDD-019 §7b + §8](../architecture/sdd-019-mentor-albums.md). Migration `0070` thêm `mentor_profiles.slug` (UNIQUE, cho phép NULL) — cột riêng chứ không sinh tại chỗ từ tên, vì tên có dấu, có người trùng tên, và link đã gửi đi phải sống lâu hơn một lần sửa tên hiển thị. `GET /v1/public/mentors/{slug}` + khai vào allowlist của `authCoverage.test.ts` kèm lý do (test này chặn đúng lúc: route public mới mà không khai là đỏ). `Team.tsx`: thẻ rút từ **bốn tầng chữ xuống ba thứ** — bỏ dòng trường·lớp·năm màu cam (nó lặp gần nguyên văn phần đầu headline ngay dưới nó) và bỏ cụm badge môn; cả thẻ thành link tới trang riêng. Thêm `MentorPage`: trường·lớp·năm quay lại dạng cặp nhãn/giá trị vì đây là chỗ người ta **kiểm chứng**, cộng môn dạy và tiểu sử. **Dữ liệu:** 5 mentor đều published, `alumni_verified=1` (chủ dự án xác nhận). **CHƯA có năm tốt nghiệp của 2 người mới** — 1997 là năm SINH của Phan Quốc Việt, không suy ra được năm tốt nghiệp, và cổng `publishBlockers` vẫn coi đó là thiếu; đã ghi vào `alumni_note` (cột nội bộ) và nêu lại cho chủ dự án. Kiểm: 703 test xanh (api 507 + web/learn 196), typecheck + lint sạch, QG-001 PASS 103 docs. *(Lưu ý khảo cổ: toàn bộ thay đổi của SRC-520 bị một phiên song song cuốn vào commit `da364fd` — commit đó mang thông điệp về trang Hồ sơ (SRC-521), không nhắc gì tới mentor. Tìm mã nguồn theo dòng này chứ đừng tìm theo thông điệp commit.)* | 🔵 xong, chờ 2 năm tốt nghiệp |
| SRC-521 | 2026-08-23 | Chủ dự án 2026-08-23 (ảnh trang Hồ sơ): hai button Sửa thông tin chung và Sửa trường lớp cần nhỏ lại, hiện chiều ngang quá dài; header của ba card cần ở một section phía trên tách với section phía dưới trong mỗi card; card nguyện vọng chỉ hiện chỗ nhập khi click vào button, mặc định chỉ hiển thị các nguyện vọng hiện tại | Ba chỉnh này cùng một ý: trang Hồ sơ là trang để ĐỌC, sửa là việc thỉnh thoảng. Nút Sửa kéo hết chiều ngang mang sức nặng thị giác của nút hành động chính, mời bấm vào một việc mà đa số lần vào trang không ai cần làm; nay nút co lại cỡ nhỏ và nép về phải, nút Huỷ và Lưu trong form cũng vậy. Tiêu đề mỗi card tách thành BĂNG RIÊNG có đường kẻ ngăn: ba card xếp dọc thì mắt cần một mốc rõ để biết card mới bắt đầu ở đâu, một dòng chữ nhỏ trôi trên nội dung không đủ làm mốc. Ô nhập nguyện vọng giấu sau nút vì form mở sẵn dưới danh sách là một việc chưa xong đang nằm đó, trong khi ba nguyện vọng đã đặt nghĩa là xong rồi | ✅ |
| SRC-522 | 2026-08-23 | Chủ dự án 2026-08-23: đang chưa thêm được Nguyện vọng, và thêm được hay không thì vẫn chưa thấy message nào trên màn hình để biết; ảnh cột phải cho thấy card Con đã làm gần đây đang đè lên popover | Hai lỗi độc lập. MỘT: API GET exam-targets trả THẲNG một mảng trong data, còn POST trả {targets, onboarding}; client đọc r.targets cho cả hai nên GET luôn ra undefined — thêm nguyện vọng thật ra CÓ vào D1 nhưng danh sách vẫn rỗng và bộ đếm vẫn 0/3, trông y hệt thêm không được. Đáng nói hơn: e2e vẫn xanh vì bản mock tự viết theo hình dạng SAI, tức là test đang hợp thức hoá bug thay vì bắt nó; nay mock trả mảng đúng như API thật và việc chuẩn hoá đặt ở một chỗ trong api.ts. Thêm câu xác nhận có role=status cho cả thêm lẫn bỏ — im lặng sau một hành động là để người dùng tự đoán. HAI: popover bị card sau đè không phải do thiếu z-index mà do theme sâu cho .n12-card một backdrop-filter, thứ tự mở một stacking context riêng nên mọi z-index bên trong card bị nhốt lại; phải nâng CHÍNH card lên z-50 khi popover mở | ✅ |
| SRC-523 | 2026-08-23 | Chủ dự án 2026-08-23 (ảnh nemo12.com): thứ tự hiển thị mentor là Đắc, Phan Quốc Việt, Hồng, Minh Thông, cuối cùng Hồng Hà; headline hiển thị Cựu học sinh Chuyên Hàn trên một dòng và THPT Chuyên Ngữ trên dòng khác. Kèm theo: Đặng Tuyết Hồng đồng hành ở môn AI và Ngữ Văn, Phan Quốc Việt ở môn Toán, Hồng Hà ở môn Tiếng Anh và IELTS | Ba thay đổi. THỨ TỰ: mọi hồ sơ đều để display_order mặc định 100 nên thứ tự thực tế rơi về full_name, tức bảng chữ cái tiếng Việt quyết định ai đứng đầu trang chủ; đó là thứ tự của máy chứ không phải của người, mà trang giới thiệu đội ngũ thì gặp ai trước là một lựa chọn biên tập. Đánh số cách nhau 10 để chèn người vào giữa không phải đánh số lại cả bảng. HAI DÒNG: mọi headline theo cùng một khuôn LỚP CHUYÊN trước phẩy TRƯỜNG sau phẩy, nên bẻ tại dấu phẩy đầu tiên là chỗ ngắt trùng đúng chỗ ý nghĩa đổi; để nguyên một dòng thì trình duyệt cắt theo bề rộng cột và ở cột hẹp nó cắt giữa tên trường thành hai mảnh không mảnh nào đọc thành ý. MÔN: subjects_json cũ chép theo lớp chuyên ngày xưa, mà lớp chuyên hồi phổ thông và môn nay họ đồng hành là hai chuyện khác nhau; môn nay bày ngay trên thẻ vì đó là thứ người đọc đang đi tìm khi lướt danh sách, và mã môn được đổi sang tên tiếng Việt thay vì bày thẳng korean hay ielts như trang hồ sơ đang làm | ✅ |
| SRC-524 | 2026-08-23 | Chủ dự án 2026-08-23 (ảnh lab Góc và ảnh trang Toàn cảnh): chuyển vị trí đỉnh của góc ra giữa, hiện đang hơi nghiêng về bên trái; khi 90 độ thì vòng cung da cam nên biến thành góc vuông; ảnh 3 có đoạn text thừa ở trên cùng | Đoạn text thừa là một ghi chú mã nguồn tôi viết ở SRC-522: trong phần con của JSX thì /\* … */ KHÔNG phải comment, nó là chữ, nên nguyên dòng ghi chú kèm mã SRC đã lên tới production ở đầu trang Toàn cảnh. Không cổng nào bắt được vì không test nào đọc chữ thừa trên trang; nay có một test quét ba trang chính, chặn cả /* lẫn chuỗi SRC- rò ra mặt trang. Về lab Góc: đỉnh mới là chỗ mắt nhìn vào để đọc một góc nên nó phải là tâm bố cục, đặt ở x=150 thay vì x=60 thì ở 180° hai cạnh trải đều hai bên. Đủ 90° thì cung tròn đổi thành dấu vuông vì đó là quy ước hình học chứ không phải trang trí: cung nói góc nào đó, ô vuông nói đúng 90°, vẽ cung ở 90° là bỏ mất đúng điều lab muốn learner nhận ra. Nhân tiện bỏ dòng số đo dưới hình vì khung chỉ cao 160 nên nó nằm ngoài vùng nhìn thấy, số đo đã có ở nhãn thanh kéo | ✅ |
