Skip to content

Sổ nguồn SRC-0450 tới SRC-0474 ​

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

IDNgày nhậnNguồnCanonical hóa vàoTrạng thái
SRC-4502026-08-21Chỉ đạo: trang giới thiệu (referral) riêng ở marlins (bố mẹ giới thiệu bố mẹ) và learn (learner giới thiệu learner); người giới thiệu nhận 15% số tiền người mới trả, người được giới thiệu giảm 15%; bên learn thì 15% cộng vào tài khoản onlineREQ-GRW-01; migration 0064_referrals.sql (referral_codes · referral_attributions · referral_rewards); module referral + GET /v1/referral/me, POST /v1/referral/claim (14 test, phần lớn canh chống gian lận); ReferralPanel.tsx canonical dùng chung, marlins #/gioi-thieu + tab, learn /gioi-thieu + nút navbar; useReferralClaim bắt ?ref= cất localStorage rồi ghi công SAU đăng nhập (link mời đi qua Google OAuth nên query string mất). Chưa làm được phần tiền: Q-015 đã chốt phase 1 không có cổng thanh toán và Q-014 chưa có bảng giá, nên quyền lợi nằm ở trạng thái pending, amount_minor để NULL và màn hình nói thẳng "chưa có khoản nào được chốt"🔵
SRC-4512026-08-21Chỉ đạo: so sánh SPA vs "mỗi page một URL" để gửi URL trang đang làm cho người khác; sau khi nghe phân tích → "Làm cả 3"Kết luận: hai thứ độc lập — SPA vẫn có URL thật được (learn đã vậy); giữ SPA, thêm địa chỉ hoá bằng History API cho cả ba app còn lại. coral: từ KHÔNG có routing (tab trong useState, URL luôn là coral.nemo12.com) → /{school}/{subject}/{tab}[/{id}], deep link cho lesson đang rà và đề đang xem; localStorage hạ xuống vai trò "lần trước làm ở đâu" (replaceState, không đẩy lịch sử). marlins + dolphin: hash → đường dẫn thật, hình dạng route giữ nguyên từng chữ nên mọi nhánh parse không đổi; link cũ #/… đã gửi cho bố mẹ vẫn sống nhờ replaceState lần tải đầu. dolphin thêm /learner/:id — mentor đang xem hồ sơ một Nemo nay gửi được đúng chỗ đó, kèm màn "không thấy learner (link cũ)" thay vì lặng lẽ nhảy về danh sách. Ba worker đã có not_found_handling: single-page-application nên F5 không 404. Kiểm: round-trip 8/8 đường dẫn coral, mô phỏng redirect link cũ đúng 2/2, 483/483 test, build cả ba sạch✅
SRC-4522026-08-21Feedback Coral (ảnh panel học thử): công thức toán hiện thô $x + y = 52$ — cần vẽ. Sau đó: "vẫn như cũ, và vá luôn đi"Copy MathText.tsx (KaTeX, cú pháp $…$ — SRC-219/244/249) từ learn sang coral, nối vào panel học thử Data Quality (đề + đáp án + misconception), Học liệu và màn xem đề. Deploy đầu FAIL ở npm ci (Missing: katex@0.18.4 from lock file) nên bản vá không lên — commit apps/coral/package.json mà quên package-lock.json ở gốc; đã sync lock và pin ^0.16.11 trùng learn thay vì ^0.18.4 npm tự chọn: hai major khác nhau trong một monorepo nghĩa là người rà và học sinh thấy công thức vẽ khác nhau. Kiểm: npm ci sạch trên bản sao lock; chạy splitMath trên dữ liệu thật của bài trong ảnh → 8/8 đáp án tách đúng công thức. (Dòng intake lần đầu ghi ở SRC-448, rồi SRC-450, đều bị commit của phiên song song ghi đè mất — ghi lại ở đây.)✅
SRC-4532026-08-21Feedback UI (ảnh màn Học vượt): bỏ dòng "Đúng ít nhất 9/10 câu là vượt được cả unit. Sai từ hai câu trở lên thì làm lại từ đầu."; chuyển cụm "Quá dễ · Quá khó · Báo cáo" xuống dưới cùng màn hình, một khu riênglearn Learning.tsx: dòng luật học vượt rời khỏi màn (luật server giữ nguyên — đứng dưới tiêu đề nó là câu đe trước khi làm bài; trượt thì màn kết quả nói, đúng lúc thông tin có ích); ba lối phản hồi tách khỏi hàng Skip/i thành khu riêng ở đáy, căn giữa, có đường kẻ ngăn — chúng nói về chất lượng câu hỏi, không thuộc hàng điều khiển của lượt làm✅
SRC-4542026-08-21Chỉ đạo (ảnh màn làm bài): "với riêng một số tài khoản có quyền Quality Control hoặc Tester, trong mỗi câu hỏi cần thêm một vùng để đánh giá câu hỏi đó (câu hỏi sai, câu trả lời bị sai…), và cuối cùng lấy các dữ liệu đó đi nâng cấp từng câu hỏi, từng đáp án"Quyền cấp theo email ở server (shared/qcEmails.ts, khuôn QUEUE_EXPLAIN_EMAILS): practice/start trả cờ qc, client chỉ bày vùng khi server nói có, và report từ tài khoản QC mang nhãn "QC báo" (server tự tra email — client tự xưng không có tác dụng). Vùng đánh giá bày sẵn theo TỪNG câu với sáu nhãn tách theo chỗ-cần-sửa: Câu hỏi sai · Đáp án sai · Nhiều đáp án đúng · Giải thích sai · Đề khó hiểu · Chính tả (ba reason mới: question_wrong, multiple_correct, explanation_wrong). Đường dữ liệu đi nâng cấp DÙNG LẠI hạ tầng SRC-365: content_reports + content_review_queue + sàng lọc máy tự rút câu hỏng, đổ về "Việc đang chờ" của Coral (SRC-447) nơi từng câu sửa qua candidate version✅
SRC-4552026-08-21Hỏi (ảnh app.chuyenchon.com/lab): "labs môn Toán từ chuyenchon đã đưa sang nemo12 chưa, link tới từng lab thế nào, từ Unit đã tới được lab chưa, còn unit nào thiếu lab?"Đã sang từ đợt migrate SDD-010: 71 lab chuyenchon môn Toán trong D1, nhưng chỉ 52 live — 19 lab nằm draft từ đợt migrate, có nội dung đầy đủ (stepper/parametric/picker, 2 check/lab) mà không ai chạm tới được. Bật cả 19 lên live: mỗi unit chỉ một lab live (idx_labs_one_per_unit) nên trong nhóm trùng tên unit, lab chính giữ unit, 5 lab còn lại live với unit=NULL — vào nhóm "Lab khác" của Thư viện (đúng luật SRC-167: lab không gắn bài vẫn chạm tới được). Link: mỗi lab một URL learn.nemo12.com/{school}/labs/math/{id} (REQ-LAB-12, slug SRC-216). Từ Unit: cây B1-B5 0 unit thiếu lab; lab gắn vào Unit qua cột unit nên bấm từ Đường học tới thẳng✅
SRC-4562026-08-21Feedback UI (2 ảnh lab "Số & trục số"): (1) "chỉnh lại toàn bộ dự đoán của các lab, learner ko cần typing nữa — chỉ chọn 1 trong 4 phương án"; (2) chỉnh MÀU các graph minh hoạ; (3) các bước dữ liệu không đè lên nhau nữa — "mỗi bước tách rời, cách nhau xa xa cho thoáng, bước sau bổ sung thêm vào bên dưới"(1) Soạn tay 4 phương án cho 191 lab còn bắt gõ (Toán 70 · Văn 51 · Anh 49 · Lý-Hoá-Sinh 21; nhiễu là nhầm lẫn thật của học sinh, cổng canh nhãn SRC-421 chạy lúc nạp) — file nguồn scripts/lab-predict-choices.json + seed-lab-predict-choices.mjs; LabPlayer bỏ hẳn ô gõ chữ, lab không có phương án thì bỏ qua bước đoán; đo lại: 0 lab live còn bắt gõ. (2) Palette DIAGRAM của hình khám phá từng pha hex cho NỀN TRẮNG (trục #5A6B78 chìm trên nước sẫm — đúng lỗi REQ-VIS-09) — trỏ toàn bộ về token --fig-* của theme theo luật SRC-353. (3) Đảo SRC-389 theo chỉ đạo mới: các bước/ý quan sát nay XẾP CHỒNG, mỗi bước một card viền riêng cách nhau rộng, bước mới bổ sung xuống dưới và mang viền sáng để mắt vẫn biết nhìn đâu✅
SRC-4572026-08-21Chỉ đạo: sửa để chạy nhiều phiên song song không đè nhau nữa (sau hai sự cố: SRC-448/450 bị lấy trùng, dòng intake bị ghi đè mất)scripts/src-new.mjs cấp số nguyên tử (khoá mkdir, số = max đang có +1 nên không tin con trỏ, đọc lại ngay trước khi ghi, rename nguyên tử) · QG-001 thêm bất biến trùng số + con trỏ phải đi trước max · scripts/check-no-clobber.mjs chặn commit làm MẤT dòng SRC/REQ có trong HEAD (cờ NEMO12_ALLOW_LEDGER_DELETE=1 khi cố ý) · hook .githooks/pre-commit chạy hai kiểm tra cho mọi commit đụng docs/ · luật ghi vào CLAUDE.md + skill intake. Kiểm: 8 tiến trình cấp số đồng thời ra 8 số liên tiếp không mất dòng; thử tạo dòng trùng → QG-001 FAIL đúng; thử xoá dòng → hook chặn commit đúng✅
SRC-4582026-08-21Chỉ đạo: "chỉnh tương tự cho các lab của các môn còn lại"; và feedback (ảnh trang Labs): "UI trang danh sách labs nhìn xấu quá, chán quá. Cái nào nhìn cũng như cái nào"Đo lại: live labs của cả 11 môn đã 0 lab bắt gõ từ SRC-456 (sửa ở tầng dùng chung nên ăn mọi môn); phần "còn lại" thật là 20 lab draft Văn+Anh bị bỏ quên từ đợt migrate — soạn nốt 4 phương án, bật live theo tiền lệ SRC-455 (unit trống thì giữ, kẹt/không có thì vào nhóm "Lab khác"). Sửa kèm 2 bug tự gây: bytes phải bằng LENGTH() của chính SQLite (đếm bằng JS lệch trên tiếng Việt — audit bắt được), và thư viện: mỗi lab nay mang một con vật biển riêng băm từ id (12 emoji, deterministic — lab quen mặt lần nào mở cũng đúng con ấy), thẻ dọc hình-trước-chữ-sau, lưới 4 cột. SRC-227 (mặt thẻ chỉ hình + tên) giữ nguyên hiệu lực✅
SRC-4592026-08-21Feedback (2 ảnh): (1) chip "Con đã làm gần đây" cần kèm "x giờ y phút trước"; (2) "learner làm 1 lần, thấy màu xanh và nghĩ ôi tôi đã ổn rồi" trong khi confidence rất thấp — cần chỉ số thôi thúc làm thêm vài lượt mỗi unit(1) RecentUnit mang updated_at sẵn có trong truy vấn, client thêm vnAgo() vào bộ vnTime dùng chung 5 bản sao (quá 30 ngày thì trả ngày cụ thể — "47 ngày trước" bắt người đọc làm toán). (2) Độ chắc vẽ THẲNG vào ô mức vững: unit có sure = MIN confidence của phần đã đo (MIN chứ không trung bình — một node mới chạm một lần là cả unit chưa chắc); confidence < 0.65 thì ô chỉ có viền màu, ruột rỗng — chính cái ô rỗng là lời mời làm thêm; popover nói câu cụ thể "Mới đo 1 lượt — ô còn RỖNG vì chưa chắc con nhớ lâu. Làm thêm vài lượt nữa là ô đặc lại"✅
SRC-4602026-08-21Feedback (ảnh lab "Số & trục số"): "với trục số, learner cần được phép kéo TRỰC TIẾP vào điểm trên trục số (như hiện nay là kéo trên một progress bar khác)"Hình number-line của engine khám phá nhận Pointer Events trên chính SVG: chạm/kéo đâu trên trục thì điểm nhảy về giá trị nguyên gần đó (setPointerCapture nên kéo trượt ra ngoài vẫn bám), quầng mờ quanh điểm nói "chỗ này cầm được" không cần chữ; thanh trượt rời bên dưới bỏ — hai hình cùng nói một giá trị mà phải thao tác ở hình kia là bắt trẻ tự dựng cầu nối trong đầu. Bàn phím/trình đọc màn hình vẫn chỉnh được qua input ẩn (sr-only) + role="slider" trên SVG✅
SRC-4612026-08-21Feedback (ảnh Dashboard chế độ EN): "còn nhiều từ tiếng Việt trên màn hình này khi đang ở chế độ EN" — panel phải (MÔN HỌC · Toán · HÔM NAY · ĐÃ VỮNG) và link "Con đang ở đâu"XpBar nối vào công tắc VI/EN như mọi nhãn khác (nhãn qua t(), tooltip theo lang, tên môn dùng bảng dịch có sẵn — "Toán" → "Maths"); link "Con đang ở đâu →" theo lang trong card Mastery. Panel phải hiện trên MỌI trang nên sót ở đây là sót ở khắp nơi✅
SRC-4622026-08-21Feedback (ảnh panel phải): trong "Con đã làm gần đây", mốc "x giờ y phút trước" đưa xuống dòng dưới và mờ hơn; các cụm hai dòng cách nhau raChip đổi sang khối hai dòng full-width: tên đậm ở trên, mốc thời gian dòng dưới cỡ 11px mờ 70%; danh sách xếp dọc gap-2 — tên và mốc chen một dòng thì chip dài ngắn lổn nhổn, mắt không quét dọc được✅
SRC-4632026-08-21Feedback (2 ảnh: popover Unit + trang Pearl): popover bỏ "2/2 bài đã học · Vững"; thay bằng tóm tắt kiểu Pearl "học xong unit này tôi có thể…" + tối đa 3 ý (Bằng chứng đạt · Hiểu lầm thường gặp · Knowledge node), "nội dung này hầu như đã có sẵn trong Pearl"; làm tương tự cho Module CardsMigration 0065 thêm unit_evidence + unit_misconception vào skill_nodes (phi chuẩn hoá như i_will); sync-iwill-from-pearl.mjs bóc thêm hai đoạn "Bằng chứng đạt." và "Hiểu lầm thường gặp." ngay dưới câu I-will của từng Unit. Danh sách Knowledge node KHÔNG cần cột: nó là tên các node của Unit, client ghép từ dữ liệu đã có; Module ghép tương tự bằng tên các Unit của nó. Popover Unit/Module bỏ dòng đếm (con số đã nằm trên thẻ — nhắc lại là chiếm chỗ của thứ learner cần: bài này đòi gì, hay vấp ở đâu); Package giữ dòng đếm✅
SRC-4642026-08-21Sự cố lộ ra khi làm SRC-463: cột mới báo "no such column" trên production dù deploy-api xanhNguyên nhân gốc: bước áp migration trong deploy-api.yml chỉ chạy khi dispatch tay (04929dd — để token deploy không cần quyền D1), push thường chỉ deploy code. Hệ quả: 0064_referrals và 0065 nằm PENDING nhiều giờ mà không ai biết. Xử lý: dispatch deploy-api qua GitHub (đúng luật cấm wrangler thẳng), áp cả hai; migrations/README sửa lại con trỏ số (0038 → 0066, lệch từ lâu) và ghi thành luật: merge migration xong PHẢI dispatch deploy-api rồi kiểm migrations list --remote ra "No migrations to apply"✅
SRC-4652026-08-21Chỉ đạo "làm nốt đi" — mảnh cuối còn treo từ SRC-445/446: IELTS và SAT chuẩn hoá theo Pearl kiểu Tin học (Pearl đã có đủ trang chuẩn do phiên song song soạn)Cây mới trong D1: IELTS I1-I5 và SAT SA1-SA5 (mỗi môn 64 unit · 19 module); strand kỹ-năng-đề-thi cũ vào HIDDEN_STRANDS như tiền lệ (câu và lab cũ nằm im theo node); i_will/evidence/misconception sync từ Pearl. Nội dung soạn mới cho cây: 768 câu (6 câu/node, đáp án rải 187/194/197/190), 128 lab picker (nhắm hiểu lầm/bẫy chấm của từng unit), graph 80 + 78 cạnh có lý do (IELTS 15 cạnh xuyên Package), file nguồn trong repo. Đo cuối: cả hai môn 64/64 unit đủ lab, 0 unit dưới sàn câu, AUDIT sạch✅
SRC-4662026-08-21Feedback (ảnh lab trục số): trục cần mũi tên hai đầu thể hiện "còn rất nhiều nữa"; số 0 và vạch của nó khác màu cho khác biệtHình number-line của engine khám phá: mũi tên hai đầu cùng màu trục; vạch 0 cao hơn, dày hơn và mang màu đối tượng chính (aqua --fig-a1), nhãn 0 to đậm cùng màu — 0 là mốc quy chiếu của cả trục, cùng màu mọi vạch thì mắt phải tự đếm lại từ nhãn mỗi lần định vị. Ăn cho mọi lab dùng trục số ở mọi môn✅
SRC-4672026-08-21Feedback (ảnh vùng Kiểm định chất lượng): "toàn option về câu hỏi sai, đáp án sai… mà ko có cái option nào thể hiện sự tích cực cả. Ví dụ câu hỏi hay, các option trả lời hay"Thêm hàng KHEN đứng trước hàng lỗi: "👍 Câu hỏi hay" (good_question) và "👍 Bộ đáp án hay" (good_options), viền seafoam. Lời khen về content_reports để Coral biết khuôn nào đáng nhân bản, và cố ý KHÔNG vào content_review_queue — hàng đó là danh sách việc phải sửa, nhét lời khen vào là người xử lý phải bấm qua từng lời khen để tìm lỗi thật✅
SRC-4682026-08-21Feedback (ảnh trang Kế hoạch): "cột giữa, cần ẩn đi 80% thông tin, cần thì click vào nó mới mở thêm ra"Trang Kế hoạch mặc định chỉ còn card đích (số ngày + chip chặng + phút/ngày); ba khu "Tuần này con làm gì" · "Chặng đường" · "Kế hoạch đã đổi gì" gấp thành ba dòng tiêu đề kèm số đếm, bấm mới mở, mỗi lúc một khu (accordion — cùng luật SRC-126)✅
SRC-4692026-08-21Bug (ảnh bài Học vượt Ngữ văn): đề hiện nguyên "Từ ăn trong…" — markdown thô lọt vào chữ learner đọc25 chỗ (22 prompt · 2 options · 1 misconception, chủ yếu Ngữ văn) bị bọc ** từ một đợt soạn — màn làm bài không render markdown nên learner thấy nguyên hoa thị. Bóc sạch bằng REPLACE trên D1; chặn tái phát ở HAI cổng: seed-items-from-json.mjs từ chối câu còn ** ngay lúc nạp, và audit-data.mjs thêm mục "markdown thô trong prompt/options" (câu vào production dưới dạng dữ liệu nên phải canh bằng máy)✅
SRC-4702026-08-21Chỉ đạo (ảnh Dashboard): "lessons nào mới làm xong thì hiển thị để learners có cảm giác ôi tôi làm xong nhiều thứ thế — nhiều icons thể hiện done, done, done"Panel phải thêm card "Xong hôm nay": mỗi Experience hoàn thành trong ngày là một dấu ✓ tròn seafoam (tối đa 12, tên bài ở tooltip + 3 tên gần nhất mờ bên dưới); endpoint /xp trả kèm done_today (chỉ completed — bài trượt không nằm trong khu ăn mừng). Chỉ dựng khi CÓ gì để mừng — khu ăn mừng rỗng là lời chê✅
SRC-4712026-08-21Feedback (ảnh Dashboard): "Mức vững" → "Em học chắc tới đâu?", bỏ dòng phụ; card Mức vững, Package card và Module card đều cần phần trên tách phần dưới bằng đường kẻ nối liền hai mép (kiểu header của card); hai link "vì sao là việc này" và "con đang ở đâu" đưa vào popover của dấu i nhỏCả ba tầng card cùng một khuôn: header (tên + dải ô) có border-b liền hai mép, thân card bên dưới. Tên card lớn thành câu hỏi của learner. "Vì sao lại là việc này" mở bằng dấu i tròn nhỏ trong card Việc hôm nay; "Con đang ở đâu →" vào popover dấu i ở header card Mức vững (kèm một câu giải thích ô đặc/ô rỗng)✅
SRC-4722026-08-21Feedback (ảnh màn chờ Học vượt): "chỉnh lại các text cho ngắn gọn, cả button nữa — dài dòng quá"Câu báo cooldown rút từ hai mệnh đề dài thành "Thử lại sau 3 giờ. Giờ con cứ học đường thường nhé." (≥60 phút thì nói bằng GIỜ — "180 phút nữa" bắt trẻ làm toán); tiêu đề "Chưa mở lúc này" → "Chờ chút đã"; nút "← Xem toàn cảnh" → "← Toàn cảnh"✅
SRC-4732026-08-21Feedback (ảnh Dashboard): căn giữa "Em học chắc tới đâu?" và đưa dải ô lên TRÊN dòng chữ đóHeader card căn giữa, dải mức vững nằm trên tên — hình trước chữ sau (luật SRC-048), và cùng thứ tự đọc với thẻ Package/Module ngay bên dưới, nên mắt không phải đổi cách đọc khi xuống tầng; dấu i neo góc phải header✅
SRC-4742026-08-21Feedback (ảnh Dashboard): bỏ card "MÔN HỌC · Toán" ở panel phải; đổi tiêu đề card giữa thành "Em học chắc môn Toán tới đâu?"Tên môn chuyển vào chính câu hỏi của card (lấy từ payload overview, không chép bảng tên thứ hai ở client) — nói một lần ở đúng chỗ mắt đang nhìn thay vì hai lần; card "Môn học" ở panel phải gỡ, XpBar không còn cần prop subject✅