🌱 Mầm Văn — Sơ đồ toàn bộ luồng đã làm

Mỗi nút ghi kèm file code + hàm (dòng nhỏ) · Kéo / chụm 2 ngón: di chuyển & phóng to · Bấm vào 1 nút: mọi thứ liên quan sẽ sáng lên · Bấm ra khoảng trống: bỏ chọn
xuất bản → báo bài mớibài nộp vào hàng đợi chấmAI tạo → nháp chờ duyệtduyệt xong mới vào kholấy câu hỏi từ khohuấn luyện gợi ý chấmđiểm chốt → kết quả của HSyêu cầu → hàng đợi GV duyệttừ chối → hoàn XP vào vícấp XP cho các bướccấp XP cho các bướccùng một hàm tính năng lựcdữ liệu nền cho phân tíchGV/Admin xem thử như HSAdmin đóng vai GVtạo bài liên kếtđiểm danh tính vào mốc mở rươngmở chi tiết để xử lýmở Studio từ Ngân hàngôn từ mục Cần ôn lạihiển thị % năng lực cho HS1. GIÁO VIÊN📁 screens/TeacherPortal.tsxƒ TeacherPortal · TeacherSidebar · TeacherTopbar1.1 Tổng quan📁 screens/teacher/TeacherOverviewScreen.tsx📁 analytics/metricsEngine.tsƒ TeacherOverviewScreen · computeOverviewMetricsChỉ tính học sinh thuộc lớp của GV đang đăngnhập (chốt phạm vi — hết lẫn học sinh lớpkhác)📁 screens/teacher/TeacherOverviewScreen.tsx📁 analytics/filterUtils.ts📁 analytics/metricsEngine.tsƒ filterStudents · computeOverviewMetricsThẻ chỉ số tổng quan lớp(computeOverviewMetrics)📁 analytics/metricsEngine.ts📁 screens/teacher/TeacherOverviewScreen.tsxƒ computeOverviewMetricsThời gian học tích cực theo ngày: tổng phút cảlớp + số học sinh tham gia từng ngày📁 analytics/engagementAnalytics.ts📁 screens/teacher/TeacherOverviewScreen.tsxƒ computeDailyALTPhân bổ Mastery theo 4 mức (%): Vững / Đangtiến bộ / Cần ôn lại / Chưa đủ dữ liệu📁 analytics/masteryAnalytics.ts📁 logic/mastery.tsƒ computeMasteryDistribution · calculateAllMasteryTiến độ hoàn thành theo chủ đề: tỉ lệ học sinhđã hoàn thành các bước học📁 analytics/engagementAnalytics.tsƒ computeTopicProgressListHọc sinh cần quan tâm(detectStudentsNeedingAttention) — hiện đúngTÊN lớp, không in mã UUID📁 analytics/metricsEngine.tsƒ detectStudentsNeedingAttentionGợi ý sư phạm tự động(generatePedagogicalInsights)📁 analytics/metricsEngine.tsƒ generatePedagogicalInsightsMọi số liệu tính từ dữ liệu thật — đã gỡ toànbộ số bịa thời demo📁 analytics/metricsEngine.ts📁 analytics/engagementAnalytics.ts📁 analytics/masteryAnalytics.ts1.2 Lớp & học sinh📁 screens/teacher/ClassesAndStudentsScreen.tsxƒ ClassesAndStudentsScreenTạo lớp mới (cảnh báo trùng tên + năm học)📁 screens/teacher/ClassesAndStudentsScreen.tsx📁 services/index.tsƒ handleCreateClass · classServiceThẻ lớp: sĩ số, hoạt động 7 ngày, nút Vào lớp📁 screens/teacher/ClassesAndStudentsScreen.tsxƒ ClassesAndStudentsScreenLưu trữ lớp — lớp đã lưu trữ không còn xuấthiện trong các ô chọn📁 screens/teacher/ClassesAndStudentsScreen.tsx📁 services/mock/mockRepositories.tsƒ handleUpdateClass · MockClassRepositoryTìm lớp theo tên📁 screens/teacher/ClassesAndStudentsScreen.tsxƒ ClassesAndStudentsScreenVào lớp → bảng học sinh của lớp📁 screens/teacher/ClassesAndStudentsScreen.tsx📁 components/teacher/AddStudentModal.tsxƒ ClassesAndStudentsScreen · AddStudentModalThêm học sinh thủ công: họ tên + lớp📁 components/teacher/AddStudentModal.tsxƒ handleSubmitManual · handleAddManualRowTên đăng nhập TỰ SINH xác định (số nhỏ nhấtchưa dùng) — hết cảnh trùng tên phải tự sửa📁 services/mock/credentialUtils.tsƒ generateUsername · removeVietnameseTonesMã HS TỰ SINH (HS0001, HS0002… số trống nhỏnhất); để trống là hệ thống tự cấp📁 services/mock/credentialUtils.tsƒ generateStudentCodeKhông còn trường Ngày sinh📁 components/teacher/AddStudentModal.tsx📁 screens/teacher/ClassesAndStudentsScreen.tsxNhập học sinh bằng Excel: xem trước; lỗithì báo rõ thay vì bảng trống im lặng📁 components/teacher/AddStudentModal.tsx📁 utils/excelUtils.tsƒ handleSubmitExcel · handleFileSelected downloadStudentTemplateExcelĐặt lại mật khẩu: GV TỰ ĐẶT mật khẩu mới(tối thiểu 6 ký tự) hoặc để trống để hệthống sinh ngẫu nhiên📁 screens/teacher/ClassesAndStudentsScreen.tsx📁 services/mock/credentialUtils.tsƒ handleResetPassword · generateFriendlyPasswordXóa học sinh — đọc lỗi DB thì báo thật,không báo thành công giả📁 screens/teacher/ClassesAndStudentsScreen.tsxƒ handleDeleteStudentĐã bỏ mục 'Danh sách học sinh' toàn cục — quảnlý học sinh nằm trong từng lớp📁 components/teacher/TeacherSidebar.tsx📁 screens/teacher/ClassesAndStudentsScreen.tsxƒ TeacherSidebar1.3 Nội dung học📁 screens/teacher/TeacherContentScreen.tsxƒ TeacherContentScreenCây chủ đề (khung trái)📁 components/teacher/content/TopicTreeSidebar.tsxƒ TopicTreeSidebarChủ đề: tạo / sửa / xóa — hộp thoại xácnhận giữa màn hình, cảnh báo số bài liênquan📁 components/teacher/content/TopicModal.tsx📁 screens/teacher/TeacherContentScreen.tsx📁 components/teacher/ui/ConfirmDialog.tsxƒ TopicModal · handleSubmit · handleDeleteTopic confirmDeleteTopic · ConfirmDialogMàu nhận diện nhuộm cả thẻ + viền; tiêu đề16px; nhãn trạng thái rút gọn không xuốngdòng ('Có sửa chưa đăng')📁 components/teacher/content/TopicTreeSidebar.tsx📁 components/teacher/content/StatusBadge.tsxƒ TopicTreeSidebar · StatusBadgeKéo–thả sắp xếp thứ tự chủ đề, lưu ngay📁 components/teacher/content/TopicTreeSidebar.tsx📁 screens/teacher/TeacherContentScreen.tsxƒ handleTopicDrop · handleReorderTopicsTạo chủ đề mới xong: tự chọn chủ đề + tựtạo nháp 'Bài giảng Video mới' + mở ngaytrình soạn video📁 screens/teacher/TeacherContentScreen.tsxƒ handleSaveTopic · createVideoDraftInTopicMỗi chủ đề chứa: Video / Lý thuyết / Bàiluyện tập / Bài kiểm tra / Bài tập về nhà📁 components/teacher/content/TopicTreeSidebar.tsxƒ TopicTreeSidebarNút '+ Tạo mới' (5 loại × tạo thủ công hoặcTạo với AI) và nút 'Thêm vào chủ đề' ởtrang chi tiết chủ đề📁 screens/teacher/TeacherContentScreen.tsxƒ handleCreateNewManual · handleOpenAiModalTrình soạn Video📁 components/teacher/content/VideoLessonEditor.tsxƒ VideoLessonEditor · handleSaveDraftNguồn video: tải lên / liên kết; thời lượng📁 components/teacher/content/VideoLessonEditor.tsx📁 services/supabase/storage.tsƒ handleFileSelect · LESSON_MEDIA_BUCKETCác ý trọng tâm (điểm tóm tắt) + tiểu mục📁 components/teacher/content/VideoLessonEditor.tsxƒ handleAddPoint · handleUpdatePoint handleDeletePoint · handleMovePointGắn 3 bài liên kết: Luyện tập / Kiểm tranhanh / Mastery Check — tạo mới ngay trongtrình soạn, ID được ghi ngược vào bài gốc📁 screens/teacher/TeacherContentScreen.tsx📁 components/teacher/content/VideoLessonEditor.tsxƒ handleCreateLinkedQuizQuay lại về trang chủ đề · Xem trước nhưhọc sinh · Lưu nháp · Cập nhật lên web họcsinh (xuất bản)📁 components/teacher/content/VideoLessonEditor.tsx📁 components/teacher/content/StudentPreviewModal.tsxƒ handleSaveDraft · StudentPreviewModalTrình soạn Lý thuyết📁 components/teacher/content/TheoryLessonEditor.tsxƒ TheoryLessonEditor · handleSaveDraftSoạn theo khối nội dung (tiêu đề / đoạnvăn…); thời gian đọc tối thiểu (giây)📁 components/teacher/content/TheoryLessonEditor.tsxƒ handleAddBlock · handleUpdateBlock handleDeleteBlock · handleMoveBlockGắn bài Luyện tập + bài Kiểm tra lý thuyết📁 screens/teacher/TeacherContentScreen.tsx📁 components/teacher/content/TheoryLessonEditor.tsxƒ handleCreateLinkedQuizQuay lại / Xem trước / Lưu nháp / Xuất bản📁 components/teacher/content/TheoryLessonEditor.tsx📁 components/teacher/content/StudentPreviewModal.tsxƒ handleSaveDraft · StudentPreviewModalTrình tạo Bài tập (QuizBuilder)📁 components/teacher/content/QuizBuilder.tsxƒ QuizBuilder · performSaveLoại bài: Luyện tập / Kiểm tra nhanh (7phút) / Mastery Check (15 phút) / BTVN (+20XP) / Đọc hiểu / Cuối kỳ📁 components/teacher/content/QuizBuilder.tsxƒ QUIZ_KIND_CONFIG · handleKindChangeSoạn câu hỏi: lấy từ Ngân hàng hoặc tạo mới📁 components/teacher/content/QuizBuilder.tsx📁 components/teacher/content/QuestionBankModal.tsxƒ handleImportFromBank · handleAddQuestion QuestionBankModalDọn đáp án khi xóa lựa chọn; chặn xuất bảnkhi đáp án không còn trong danh sách lựachọn📁 components/teacher/content/QuizBuilder.tsxƒ handleUpdateQuestion · handleDeleteQuestionNút Quay lại trở về ĐÚNG bài gốc (video/lýthuyết) đã tạo liên kết — không văng vềtrang chủ đề📁 screens/teacher/TeacherContentScreen.tsx📁 components/teacher/content/QuizBuilder.tsxƒ quizReturnTo · handleCreateLinkedQuizXuất bản (PublishModal)📁 components/teacher/content/PublishModal.tsxƒ PublishModal · handleConfirmChọn lớp áp dụng; tùy chọn thông báo họcsinh📁 components/teacher/content/PublishModal.tsxƒ handleToggleClass · handleConfirmCảnh báo: video chưa gắn bài luyện tập ·bài kiểm tra dưới 3 câu · bài đã có họcsinh làm📁 screens/teacher/TeacherContentScreen.tsxƒ handleOpenPublishModalForCurrentXuất bản xong: học sinh đúng lớp nhận thôngbáo bài mới (xem 2.10)📁 components/teacher/content/PublishModal.tsx📁 logic/studentNotifications.tsƒ handleConfirm · buildStudentNotificationsTrạng thái nội dung: Nháp / Đã xuất bản / Cósửa chưa đăng📁 components/teacher/content/StatusBadge.tsxƒ StatusBadge1.4 Ngân hàng câu hỏi📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ TeacherQuestionBankScreenKho ngân hàng: câu hỏi + video + lý thuyếttham chiếu📁 screens/teacher/TeacherQuestionBankScreen.tsx📁 services/index.tsƒ TeacherQuestionBankScreen · quizService4 dạng câu: Trắc nghiệm 1 đáp án / Chọn nhiềuđáp án / Điền vào ô trống / Tự luận (Rubric)📁 screens/teacher/TeacherQuestionBankScreen.tsx📁 types.tsƒ QuestionTypeTô sáng đáp án đúng — nhận cả 2 dạng lưu (chữcái & toàn văn)📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ TeacherQuestionBankScreenĐáp án điền khuyết được chuẩn hóa về dạng danhsách (gốc của lỗi không nộp được bài — đã vá)📁 services/supabase/supabaseRepositories.ts📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ normalizeAnswerForTypeBộ lọc dạng DANH SÁCH 3 nhóm, gập/mở được,tiêu đề hiện lựa chọn đang áp dụng📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ TeacherQuestionBankScreen1) Dạng học liệu📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ TeacherQuestionBankScreen2) Năng lực: Nhận biết / Thông hiểu / Phântích / Vận dụng📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ TeacherQuestionBankScreen3) Độ khó: Dễ / Trung bình / Khó📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ TeacherQuestionBankScreenThêm câu hỏi thủ công; xóa câu hỏi bằng hộpthoại xác nhận của app📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ handleSaveQuestionForm · handleOpenAddQuestionModal confirmDeleteQuestionTab Bản nháp (huy hiệu đếm số chờ duyệt)📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ readQuestionDraftSets · readTheoryDrafts QUESTION_DRAFT_PREFIX · THEORY_DRAFT_PREFIXBộ câu hỏi & lý thuyết do AI tạo mà chưaduyệt đều nằm ở đây📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ readQuestionDraftSets · readTheoryDraftsMở xem từng câu → tích chọn câu đạt → 'Đưavào Ngân hàng'; câu chưa chọn ở lại nháp📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ handlePushDraftQuestions handleReviewDraftInStudioXóa nháp có hỏi xác nhận📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ handleDeleteDraftNguyên tắc xuyên suốt: chưa duyệt thì chưavào Ngân hàng📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ readQuestionDraftSets · readTheoryDrafts QUESTION_DRAFT_PREFIX · THEORY_DRAFT_PREFIX1.5 Mầm AI Studio📁 components/teacher/ai/AiContentStudioModal.tsxƒ AiContentStudioModal3 panel kéo chỉnh độ rộng / thu thành thanhdọc 46px (lưu theo máy)📁 components/teacher/ai/AiContentStudioModal.tsxƒ AiContentStudioModal · onMovePanel 1: Nguồn tài liệu📁 components/teacher/ai/AiContentStudioModal.tsxƒ AiContentStudioModal · onMovePanel 2: Trò chuyện & tra cứu tài liệu📁 components/teacher/ai/AiContentStudioModal.tsxƒ AiContentStudioModal · onMovePanel 3: Xưởng tạo đầu ra📁 components/teacher/ai/AiContentStudioModal.tsxƒ AiContentStudioModal · onMoveTrợ lý trò chuyện 'Tôi là trợ lý Mầm AI' — tracứu trên tài liệu đã nạp (RAG)📁 components/teacher/ai/AiContentStudioModal.tsx📁 services/ai/AIService.tsƒ handleSendMessage · FormattedChatMessage · AIServiceTạo đầu ra theo CƠ CẤU LOẠI CÂU: 4 dòng sốlượng (Chọn 1 / Chọn nhiều / Điền khuyết / Tựluận), nút −/+ từng loại, tổng tự cộng, khóanút tạo khi tổng = 0📁 components/teacher/ai/AiContentStudioModal.tsxƒ handleGenerateDraftCơ cấu loại câu truyền thẳng vào prompt Gemini— loại để 0 thì không sinh câu loại đó📁 services/ai/GeminiAIService.tsƒ GeminiAIServiceSinh bằng Gemini (model AI-2.5-flash); khiGemini lỗi → bản dự phòng MockAI và BÁO RÕ'(Bản dự phòng — Gemini lỗi)', không giả danhAI thật📁 services/ai/GeminiAIService.ts📁 services/ai/index.ts📁 services/ai/MockAIService.tsƒ GeminiAIService · SmartAIService · getLastAiFallback MockAIServiceBộ câu hỏi AI → BẢN NHÁP BỀN: tự lưu (đóngxưởng / chuyển màn / tải lại trang vẫn còn);thanh BẢN NHÁP báo số câu + giờ lưu📁 components/teacher/ai/AiContentStudioModal.tsx📁 screens/teacher/TeacherQuestionBankScreen.tsxƒ handleGenerateDraft · QUESTION_DRAFT_PREFIX readQuestionDraftSetsDuyệt → Lưu vào Ngân hàng: chỉ lưu câu đã tíchchọn; tiêu đề 'Bộ câu hỏi: <chủ đề>', thờilượng = max(7 phút, số câu), XP = số câu × 5📁 components/teacher/ai/AiContentStudioModal.tsxƒ handleSaveReviewedQuestions · handleToggleDraftId handleToggleSelectAllDraftsLý thuyết AI → màn DUYỆT LÝ THUYẾT xem trướcđúng dạng học sinh sẽ đọc → ưng ý mới 'Lưu lýthuyết vào học liệu'; nháp lý thuyết cũng tựlưu bền📁 components/teacher/ai/AiContentStudioModal.tsxƒ handleApplyTheoryDraft · handleDiscardTheoryDraft1.6 Chấm bài📁 screens/teacher/TeacherGradingScreen.tsxƒ TeacherGradingScreenHàng đợi GOM THEO HỌC SINH — mỗi em đúng 1dòng (khử trùng bài theo nội dung + quy vềđúng 1 học sinh thật dù lệch định danh giữacác nguồn)📁 components/teacher/grading/GradingQueueTable.tsx📁 screens/teacher/TeacherGradingScreen.tsxƒ GradingQueueTableBảng 6 cột theo mẫu: Học sinh | Lớp | Chủ đềđã làm (x/y) | Bài chờ chấm (0 thì làm mờ) |Chờ lâu nhất (đỏ + '(quá hẹn)' khi quá 24 giờ)| Xem chi tiết📁 components/teacher/grading/GradingQueueTable.tsx📁 components/teacher/grading/StudentGradingDetail.tsxƒ GradingQueueTable · waitingHours · formatSubmittedAt2 thẻ thống kê: 'Cần chấm' (chờ chấm + đã cógợi ý AI, có nút lọc riêng gợi ý AI) · 'Chờ >24 giờ' (bấm → sắp xếp chờ lâu nhất lên đầu)📁 screens/teacher/TeacherGradingScreen.tsx📁 components/teacher/grading/GradingQueueTable.tsxƒ handleToolbarPickBộ lọc gộp 1 ô duy nhất: Trạng thái / Sắp xếp📁 components/teacher/grading/GradingQueueTable.tsxƒ handleToolbarPick'Chấm ngay' mở thẳng bài chờ lâu nhất chưachấm của em📁 screens/teacher/TeacherGradingScreen.tsxƒ TeacherGradingScreenXem chi tiết theo học sinh📁 components/teacher/grading/StudentGradingDetail.tsxƒ StudentGradingDetailThẻ 'Họ tên · Lớp' + thanh tổng kết: x/ybài kiểm tra đã làm, số bài chờ chấm, sốbài quá hạn, ĐTB, công tắc 'Chỉ hiện bàichưa chấm'📁 components/teacher/grading/StudentGradingDetail.tsxƒ StudentGradingDetailBài gom theo CHỦ ĐỀ: dòng nhóm '… – bài chờchấm: N' / '… – (Hoàn thành)'📁 components/teacher/grading/StudentGradingDetail.tsxƒ StudentGradingDetailCột Điểm hiện 'Gợi ý Xđ' cho bài AI đã gợiý📁 components/teacher/grading/StudentGradingDetail.tsx📁 utils/scoreFormat.tsƒ formatScoreMàn chấm bài (SplitGradingWorkspace)📁 components/teacher/grading/SplitGradingWorkspace.tsxƒ SplitGradingWorkspaceNội dung bài tự luận + thông tin bài / nănglực / chủ đề📁components/teacher/grading/SplitGradingWorkspace.tsxƒ SplitGradingWorkspace'Gợi ý chấm tự động bởi AI': điểm gợi ý làmtròn 1 chữ số thập phân; chưa có gợi ý thìkhông bịa số📁components/teacher/grading/SplitGradingWorkspace.tsx📁 services/ai/AIService.tsƒ handleAcceptAllAI · handleClearAI AIEssayGradingResult'Tiêu chí đánh giá & Chấm điểm': chấm theoRubric từng tiêu chí; gõ số thập phân / xóatrắng bình thường; Rubric không lưu khitổng trọng số ≠ 100📁components/teacher/grading/SplitGradingWorkspace.tsx📁 components/teacher/content/QuizBuilder.tsxƒ SplitGradingWorkspace · DEFAULT_ESSAY_RUBRICCâu nhận xét mẫu nhanh — bấm để chèn📁components/teacher/grading/SplitGradingWorkspace.tsxƒ SplitGradingWorkspaceChốt điểm → ghi đúng chủ đề / năng lực +nhật ký kiểm toán + thông báo cho học sinh(ở cả 2 kho dữ liệu)📁components/teacher/grading/SplitGradingWorkspace.tsx📁 screens/teacher/TeacherGradingScreen.tsxƒ handleFinalize · handleFinalizeGradingHuấn luyện AI (AiTrainingStudio): rubric + bàimẫu chấm để AI học cách gợi ý điểm📁 components/teacher/grading/AiTrainingStudio.tsxƒ AiTrainingStudio · handleSaveConfig · handleRunSandbox handleCloneRubricBài tự luận không bao giờ bị gán nhầm cho 'họcsinh đầu tiên' khi không tra được chủ nhân📁 screens/teacher/TeacherGradingScreen.tsx📁 services/supabase/supabaseRepositories.tsƒ SupabaseEssayRepository1.7 Quà tặng📁 screens/teacher/TeacherRewardsScreen.tsxƒ TeacherRewardsScreenHàng đợi yêu cầu đổi quà — số liệu thật (XPtuần / điểm danh / tên lớp tính từ state thật)📁 screens/teacher/TeacherRewardsScreen.tsx📁 services/index.tsƒ TeacherRewardsScreen · rewardServiceDuyệt / Từ chối / Trao / Mở — trạng tháiGIVEN/OPENED không bị ghi nhầm thành REJECTED(migration_003)📁 screens/teacher/TeacherRewardsScreen.tsx📁 components/teacher/rewards/RejectRewardModal.tsx📁 database/migration_003_reward_status.sqlƒ handleApprove · handleGive · RejectRewardModalTừ chối → HOÀN đầy đủ XP đã trừ vào TỔNG XPcủa học sinh (kể cả từ chối hàng loạt)📁 screens/teacher/TeacherRewardsScreen.tsx📁 services/mock/mockRepositories.ts📁 services/supabase/supabaseRepositories.tsƒ handleConfirmReject · MockRewardRepository SupabaseRewardRepositoryDuyệt / trao hàng loạt chỉ tính yêu cầu hợp lệ📁 screens/teacher/TeacherRewardsScreen.tsxƒ handleBatchApprove · handleBatchGiveXuất CSV theo đúng bộ lọc đang xem📁 screens/teacher/TeacherRewardsScreen.tsx📁 utils/exportUtils.tsƒ handleExportHistoryCSV · exportToCsvDanh mục quà GV tùy biến là nguồn dự phòng;giá XP chuẩn theo danh mục học sinh nhìn thấy📁 screens/teacher/TeacherRewardsScreen.tsx📁 components/teacher/rewards/RewardMilestoneModal.tsx📁 data/rewards.tsƒ handleSaveMilestone · RewardMilestoneModal REWARDS_CATALOG1.8 Phân tích📁 screens/teacher/TeacherAnalyticsScreen.tsxƒ TeacherAnalyticsScreenmetricsEngine: computeOverviewMetrics /detectStudentsNeedingAttention /generatePedagogicalInsights📁 analytics/metricsEngine.tsƒ computeOverviewMetrics · detectStudentsNeedingAttention generatePedagogicalInsightsPhổ điểm (Histogram): tính theo TỪNG HỌC SINH— điểm TB của mỗi em xếp vào đúng 1 dải; tổngcác cột luôn khớp sĩ số thật (đã sửa lỗi đếmtheo câu hỏi)📁 analytics/scoreAnalytics.ts📁 components/teacher/analytics/ScoreAnalyticsTab.tsxƒ computeScoreDistribution · ScoreAnalyticsTabBản đồ nhiệt năng lực (masteryAnalytics) ·Tương tác & chuyên cần (engagementAnalytics) ·Phân tích câu hỏi (questionAnalytics) · Hồ sơhọc sinh (studentProfileAnalytics)📁 analytics/masteryAnalytics.ts📁 analytics/engagementAnalytics.ts📁 analytics/questionAnalytics.ts📁 analytics/studentProfileAnalytics.tsƒ computeStudentTopicHeatmap · computeMasteryDistribution computeQuestionAnalytics · computeStudentProfileDataTên lớp tra theo danh sách thật ở cả 3 nơi —không in UUID, không bịa tên lớp📁 screens/teacher/TeacherAnalyticsScreen.tsx📁 analytics/filterUtils.tsƒ filterStudentsToàn bộ biểu đồ tính từ dữ liệu thật (điểmdanh, nhật ký XP, kết quả câu hỏi, bước đãhọc); tuần không có điểm thì để trống — hết sốbịa (13/18, 7.5đ, 82%, chuỗi 78→91%…)📁 analytics/scoreAnalytics.ts📁 analytics/masteryAnalytics.ts📁 analytics/engagementAnalytics.ts📁 analytics/questionAnalytics.ts1.9 Cài đặt📁 screens/teacher/TeacherSettingsScreen.tsxƒ TeacherSettingsScreenCấu hình ngưỡng XP — kiểm tra thứ tự ngưỡng,chặn giá trị 0 / trống trước khi lưu📁 screens/teacher/TeacherSettingsScreen.tsx📁 config.tsƒ handleSaveSettings · getEffectiveXpConfig · XP_CONFIGMô hình Mầm AI: chọn model Gemini; cảnh báoAPI Key đang lưu trong trình duyệt📁 screens/teacher/TeacherSettingsScreen.tsx📁 services/ai/index.tsƒ handleSaveAiConfig · handleTestAiConnection setGeminiApiKey · setGeminiModelĐổi mật khẩu: kiểm tra mật khẩu hiện tại + lưuthật📁 screens/teacher/TeacherSettingsScreen.tsxƒ handleChangePasswordCỡ chữ hiển thị (Chuẩn / Lớn 112% / Rất lớn125%) — phóng toàn cục theo đúng tỉ lệ📁 screens/teacher/TeacherSettingsScreen.tsx📁 config.tsƒ handleSaveSettings · getSavedSystemSettingsĐã gỡ khu vực 'Đặt lại dữ liệu demo' khỏi bảnkhách thật📁 screens/teacher/TeacherSettingsScreen.tsx📁 components/DevPanel.tsxƒ DevPanel2. HỌC SINH📁 App.tsx📁 components/Navbar.tsxƒ Navbar · NotificationBell2.1 Trang chủ📁 screens/HomeScreen.tsxƒ HomeScreenLời chào theo hồ sơ thật (đúng tên, đúng lớp)— học sinh mới bắt đầu TRẮNG, không thừa hưởngtiến độ mẫu📁 screens/HomeScreen.tsx📁 services/mock/seedData.tsƒ createFreshStudentStateChủ đề học kỳ này: thẻ cao đều nhau, chân thẻghim đáy ('X bài giảng · Vào học')📁 screens/HomeScreen.tsx📁 components/VideoCard.tsxƒ VideoCard · getVideoCardStatusĐiểm danh mỗi ngày (+2 XP)📁 screens/HomeScreen.tsx📁 App.tsx📁 logic/xpEngine.ts📁 config.tsƒ handleCheckInClick · handleAttendanceCheckIn · awardXP ATTENDANCE_CONFIGBiểu ngữ bài mới nhất chưa đọc + nút 'Vào làmngay'📁 logic/studentNotifications.ts📁 screens/HomeScreen.tsx📁 App.tsxƒ buildStudentNotifications · handleOpenNotificationGợi ý bài học tiếp theo📁 screens/HomeScreen.tsxƒ HomeScreenTiến độ năng lượng học tập hôm nay (phút họctích cực / trần XP ngày)📁 screens/HomeScreen.tsx📁 logic/useActiveLearningTimer.ts📁 logic/xpEngine.tsƒ useActiveLearningTimer · getCurrentDailyXpCapKhu Bài tập về nhà – Bài kiểm tra – Bài luyệntập📁 screens/HomeScreen.tsxƒ HomeScreenCần ôn lại (các chủ đề yếu)📁 screens/HomeScreen.tsx📁 logic/mastery.tsƒ calculateAllMasteryRương quà bí mật (gợi mở sang mục Đổi quà)📁 screens/HomeScreen.tsx📁 components/rewards/RewardTrack.tsxƒ RewardTrackXem trước Cây tri thức📁 screens/HomeScreen.tsx📁 components/GrowthTree.tsxƒ GrowthTree2.2 Học bài📁 screens/LearnScreen.tsxƒ LearnScreenDanh sách chủ đề → chọn bài Video hoặc Lýthuyết chi tiết📁 screens/LearnScreen.tsx📁 components/VideoCard.tsxƒ getVideoCardStatusHọc dở được khôi phục đúng bước đang học (khóabước ổn định — không bắt đầu lại từ bước 0)📁 screens/LearnScreen.tsx📁 screens/VideoLessonScreen.tsx📁 logic/studentStateUtils.tsƒ rolloverStudentState2.3 Luồng Video — tổng 48 XP📁 screens/VideoLessonScreen.tsx📁 config.tsƒ VideoLessonScreen · TOTAL_VIDEO_XPBước 1: Xem video đạt 80% → +5 XP📁 screens/VideoLessonScreen.tsx📁 logic/xpEngine.tsƒ handleProceedFromVideo · awardXPBước 2: Đọc lý thuyết tóm tắt (các ý trọngtâm) → +2 XP📁 screens/VideoLessonScreen.tsxƒ handleProceedFromSummaryBước 3: Bài luyện tập → +5 XP📁 screens/VideoLessonScreen.tsx📁 components/QuizRunner.tsxƒ handleCompleteQuizStep · QuizRunnerBước 4: Kiểm tra nhanh → +8 XP📁 screens/VideoLessonScreen.tsx📁 components/QuizRunner.tsxƒ handleCompleteQuizStep · QuizRunnerBước 5: Mastery Check → +8 XP📁 screens/VideoLessonScreen.tsx📁 components/QuizRunner.tsxƒ handleCompleteQuizStep · QuizRunnerBước 6: Hoàn thành toàn luồng → +20 XP📁 screens/VideoLessonScreen.tsx📁 config.tsƒ TOTAL_VIDEO_XP2.4 Luồng Lý thuyết chi tiết — tổng 41 XP📁 screens/TheoryLessonScreen.tsx📁 config.tsƒ TheoryLessonScreen · XP_CONFIGBước 1: Đọc hết khối nội dung (đủ thời gianđọc tối thiểu) + xác nhận đã hiểu → +10 XP📁 screens/TheoryLessonScreen.tsxƒ handleUnderstood · handleNotUnderstoodBước 2: Bài luyện tập sau lý thuyết → +5 XP📁 screens/TheoryLessonScreen.tsx📁 components/QuizRunner.tsxƒ handleCompleteTheoryQuiz · QuizRunnerBước 3: Bài kiểm tra lý thuyết 1 → +8 XP📁 screens/TheoryLessonScreen.tsx📁 components/QuizRunner.tsxƒ handleCompleteTheoryQuiz · QuizRunnerBước 4: Bài kiểm tra lý thuyết 2 → +8 XP📁 screens/TheoryLessonScreen.tsx📁 components/QuizRunner.tsxƒ handleCompleteTheoryQuiz · QuizRunnerBước 5: Hoàn thành toàn luồng → +10 XP (trướcđây bị thiếu — đã cộng đúng như cấu hình hứa)📁 screens/TheoryLessonScreen.tsx📁 config.tsƒ XP_CONFIG2.5 Làm bài (QuizRunner — dùng chung cho mọi loạibài)📁 components/QuizRunner.tsxƒ QuizRunner4 dạng câu: Chọn 1 đáp án / Chọn nhiều đáp án/ Điền vào ô trống / Tự luận📁 components/QuizRunner.tsx📁 types.tsƒ QuizRunner · QuestionTypeĐồng hồ đếm ngược theo thời lượng bài; HẾT GIỜTỰ NỘP phần đã làm (đã sửa lỗi nộp bài trống)📁 components/QuizRunner.tsxƒ handleSubmitFinalHộp xác nhận nộp bài: báo số câu chưa trả lời;chống nộp 2 lần📁 components/QuizRunner.tsxƒ handleSubmitScoring · handleSubmitFinalBài có câu điền khuyết không còn chết im lặngkhi nộp: đáp án được chuẩn hóa về dạng danhsách; lỗi lạ thì báo rõ + mở lại nút nộp đểnộp lại📁 components/QuizRunner.tsx📁 services/supabase/supabaseRepositories.tsƒ normalizeAnswerForTypeMàn hình KẾT QUẢ sau mỗi quiz: điểm /10, XPTHỰC NHẬN, xem lại từng câu với đúng câu hỏiđã làm (kể cả câu do GV/AI tạo)📁 components/QuizResult.tsx📁 components/QuizRunner.tsxƒ QuizResultCâu tự luận → tạo bài nộp mang đúng mã họcsinh → vào hàng đợi chấm của giáo viên📁 components/QuizRunner.tsx📁 services/index.ts📁 services/supabase/supabaseRepositories.tsƒ essayService · SupabaseEssayRepositoryBài tập về nhà hoàn thành → +20 XP📁 components/QuizRunner.tsx📁 logic/xpEngine.ts📁 config.tsƒ awardXP · XP_CONFIGÔn lại phần yếu: +3 XP khi nâng được điểm (tốiđa 1 lần / chủ đề)📁 components/QuizRunner.tsx📁 logic/xpEngine.tsƒ awardXP2.6 Cây tri thức — Vườn Văn Mầm Mục📁 screens/TreeScreen.tsx📁 components/GrowthTree.tsxƒ TreeScreen · GrowthTree6 giai đoạn theo số bước học đã hoàn thành📁 config.ts📁 components/GrowthTree.tsxƒ TREE_STAGES_CONFIG · GrowthTreeHạt mầm (0 bước)📁 config.ts📁 components/GrowthTree.tsxƒ TREE_STAGES_CONFIG · GrowthTreeNảy mầm (3 bước)📁 config.ts📁 components/GrowthTree.tsxƒ TREE_STAGES_CONFIG · GrowthTreeChồi non (8 bước)📁 config.ts📁 components/GrowthTree.tsxƒ TREE_STAGES_CONFIG · GrowthTreeCây con (18 bước)📁 config.ts📁 components/GrowthTree.tsxƒ TREE_STAGES_CONFIG · GrowthTreeCây ra hoa (32 bước)📁 config.ts📁 components/GrowthTree.tsxƒ TREE_STAGES_CONFIG · GrowthTreeCây kết trái (50 bước)📁 config.ts📁 components/GrowthTree.tsxƒ TREE_STAGES_CONFIG · GrowthTreeTưới nước: mỗi bước học tạo 'Nước tưới MầmMực' nuôi cây lớn📁 screens/TreeScreen.tsx📁 components/GrowthTree.tsxƒ handleWaterTree · handleLeafPress15 vị trí lá trên tán cây📁 components/GrowthTree.tsxƒ GrowthTree · TopicLeafData4 lá chính đầu tiên = 4 chủ đề đầu trongthứ tự khóa học (lá to, có nhãn tên)📁 components/GrowthTree.tsxƒ GrowthTree · TopicLeafDataTừ chủ đề thứ 5: hiện ở 11 'lá ẩn' còn lại(lá nhỏ hơn, rê chuột xem tên + %)📁 components/GrowthTree.tsxƒ GrowthTree · TopicLeafDataMàu lá: Hoàn thành ≥80% = xanh lá đậm · Đanghọc 50–79% = xanh biển · Cần ôn lại <50% =vàng · Chưa học = xám (có hàng chú thích)📁 components/GrowthTree.tsx📁 logic/mastery.tsƒ GrowthTree · calculateAllMasteryHiệu ứng NHẤP lá đã hoàn thành: lá lún xuốngnhư bị ấn vào tán cây + vòng sáng lan tỏa📁 components/GrowthTree.tsxƒ handleLeafPressMa trận năng lực: từng chủ đề × 4 năng lực📁 screens/TreeScreen.tsx📁 logic/mastery.tsƒ calculateAllMastery · calculateLevelMasteryHuy hiệu đạt được📁 screens/TreeScreen.tsx📁 data/mockData.tsƒ BADGES_CATALOG2.7 Kết quả học tập📁 screens/LearningResultsScreen.tsxƒ LearningResultsScreenThẻ tổng quan: Tổng XP tích lũy (+ XP hôm nay)· Huy hiệu đạt được — đã bỏ 2 thẻ 'Câu hỏi đãlàm' & 'Điểm trung bình'📁 screens/LearningResultsScreen.tsxƒ LearningResultsScreenĐiểm theo từng chủ đề📁 screens/LearningResultsScreen.tsx📁 logic/mastery.tsƒ calculateAllMastery4 thanh năng lực (%) + điểm trung bình +trạng thái: Đã hoàn thành / Đang học / Cầnôn lại / Chưa học📁 screens/LearningResultsScreen.tsx📁 logic/mastery.tsƒ calculateAllMasteryKhối chủ đề nhuộm nền + viền theo đúng màucủa chủ đề đó📁 screens/LearningResultsScreen.tsx📁 logic/mastery.tsƒ calculateAllMasteryBấm tên chủ đề → tới bài học📁 screens/LearningResultsScreen.tsx📁 logic/mastery.tsƒ calculateAllMasteryDùng chung hàm calculateAllMastery với Câytri thức — số liệu nhất quán📁 logic/mastery.tsƒ calculateAllMastery · calculateLevelMasteryBiểu đồ tiến bộ 6 tuần — dạng ĐƯỜNG MỐC TUẦN📁 screens/LearningResultsScreen.tsx📁 utils/scoreFormat.tsƒ LearningResultsScreen · ONE_WEEK · formatScoreMỗi mốc là vòng tròn chứa điểm trung bìnhcủa tuần; tuần này to nhất, viền cam nổibật📁 screens/LearningResultsScreen.tsx📁 utils/scoreFormat.tsƒ LearningResultsScreen · ONE_WEEK · formatScoreTuần chưa học hiện mốc xám 'Chưa học' thayvì biến mất📁 screens/LearningResultsScreen.tsx📁 utils/scoreFormat.tsƒ LearningResultsScreen · ONE_WEEK · formatScoreNhãn tuần dễ hiểu ('Tuần trước', '2 tuầntrước'…) + số câu đã làm dưới mỗi mốc📁 screens/LearningResultsScreen.tsx📁 utils/scoreFormat.tsƒ LearningResultsScreen · ONE_WEEK · formatScoreGóc phải thẻ: tổng số câu + điểm tuần này📁 screens/LearningResultsScreen.tsx📁 utils/scoreFormat.tsƒ LearningResultsScreen · ONE_WEEK · formatScoreThành tích & huy hiệu: toàn bộ danh mục, phânbiệt đã đạt / chưa đạt📁 screens/LearningResultsScreen.tsx📁 data/mockData.tsƒ BADGES_CATALOG2.8 Đổi quà📁 screens/RewardsScreen.tsxƒ RewardsScreenVí chi tiêu = TỔNG XP của tài khoản (vĩnh viễn— chỉ giảm khi xin quà); MỐC MỞ RƯƠNG xét theoXP TUẦN + số ngày điểm danh (quyết định chốtcủa chủ dự án)📁 screens/RewardsScreen.tsx📁 App.tsx📁 config.tsƒ handleRequestReward · CHEST_TIERS · getChestTierConfigCác rương theo cấu hình: Rương Hạt / Rương Lá/ Rương Hoa / Rương Vàng📁 config.ts📁 components/rewards/ChestCard.tsx📁 components/rewards/ChestIllustration.tsxƒ CHEST_TIERS · ChestCard · ChestIllustrationDanh mục quà thật (XP / ngày điểm danh yêucầu)📁 data/rewards.tsƒ REWARDS_CATALOGBookmark Mầm Mực thủ công — 280 XP · 4 ngày📁 data/rewards.tsƒ REWARDS_CATALOGQuyền chọn bài đọc cho cả lớp — 320 XP · 4ngày📁 data/rewards.tsƒ REWARDS_CATALOGBút mực xanh Giấy & Mực — 450 XP · 5 ngày📁 data/rewards.tsƒ REWARDS_CATALOGSổ tay Giấy & Mực bìa cứng — 650 XP · 5ngày📁 data/rewards.tsƒ REWARDS_CATALOGRương Vàng: Bút mài nét hoa & Bộ quà lưuniệm Mầm Văn — 750 XP · 6 ngày📁 data/rewards.tsƒ REWARDS_CATALOGNội dung quà thuộc loại 'secret' — học sinhkhông được biết trước bên trong có gì📁 types.ts📁 screens/RewardsScreen.tsxƒ RewardTierSecretGửi yêu cầu: TRỪ NGAY vào Tổng XP (ghideductedXp); chặn khi Tổng XP không đủ; chặngửi trùng khi đang có yêu cầu chưa bị từ chối📁 App.tsx📁 screens/RewardsScreen.tsxƒ handleRequestReward · handleConfirmClaimTrạng thái: Chờ duyệt → Được duyệt → Đã trao →Đã mở📁 components/rewards/RequestHistory.tsx📁 components/rewards/ChestOpeningModal.tsx📁 screens/RewardsScreen.tsxƒ RequestHistory · ChestOpeningModal · handleOpenChest handleCollectBị từ chối → HOÀN 100% XP đã trừ vào Tổng XP📁 App.tsx📁 services/mock/mockRepositories.ts📁 services/supabase/supabaseRepositories.tsƒ MockRewardRepository · SupabaseRewardRepository2.9 Hồ sơ📁 screens/ProfileScreen.tsxƒ ProfileScreenThông tin tài khoản học sinh📁 screens/ProfileScreen.tsxƒ ProfileScreenThẻ dưới chân thanh điều hướng: TỔNG XP tíchlũy là số chính, XP hôm nay ở dòng nhỏ bêndưới📁 components/Navbar.tsx📁 screens/ProfileScreen.tsxƒ NavbarCỡ chữ hiển thị (phóng toàn cục 112% / 125%)📁 screens/ProfileScreen.tsx📁 config.tsƒ getSavedSystemSettingsĐăng xuất — xóa sạch phiên, kể cả phiên đangđóng vai📁 App.tsx📁 screens/ProfileScreen.tsxƒ handleLogout2.10 Thông báo bài mới📁 logic/studentNotifications.tsƒ buildStudentNotificationsChuông thông báo trên thanh điều hướng (máytính + điện thoại) + huy hiệu đỏ đếm số chưađọc📁 components/Navbar.tsx📁 App.tsxƒ NotificationBell · handleMarkAllNotificationsReadDanh sách kiểu tin nhắn: loại bài + tiêu đề +chủ đề + thời gian; bấm vào là vào làm bài đóngay📁 logic/studentNotifications.ts📁 components/Navbar.tsxƒ formatRelativeTime · QUIZ_KIND_LABELS NotificationBellThông báo suy ra từ mốc xuất bản thật của nộidung: trong vòng 14 ngày, đúng lớp được giao📁 logic/studentNotifications.tsƒ buildStudentNotifications · FOURTEEN_DAYSTrạng thái đã đọc lưu THEO TÀI KHOẢN → đồng bộmọi thiết bị (thay cơ chế cũ chỉ lưu trên máygiáo viên)📁 logic/studentNotifications.ts📁 App.tsxƒ handleMarkAllNotificationsRead3. ADMIN📁 screens/admin/AdminPortal.tsxƒ AdminPortalQuản lý tài khoản giáo viên: danh sách, tạo mới(họ tên, tên đăng nhập, mật khẩu, liên hệ, ghichú), sửa thông tin📁 screens/admin/AdminPortal.tsxƒ CreateTeacherModal · EditTeacherModal · handleSubmitTạm khóa / Mở khóa tài khoản giáo viên📁 screens/admin/AdminPortal.tsxƒ handleToggleLockXóa tài khoản giáo viên📁 screens/admin/AdminPortal.tsxƒ handleConfirmDelete'Truy cập với tư cách Giáo viên này' — đóng vaiGV để hỗ trợ📁 screens/admin/AdminPortal.tsx📁 screens/TeacherPortal.tsxƒ AdminPortal · TeacherPortalTải lại danh sách · Đăng xuất khỏi Cổng Admin📁 screens/admin/AdminPortal.tsxƒ AdminPortalĐIỂM ĐANG CHỜ QUYẾT ĐỊNH: đăng nhập Admin vẫn làthông tin cứng trong mã nguồn (repo công khai) —phương án vá đã chuẩn bị, chờ chủ dự án duyệt📁 services/supabase/supabaseRepositories.ts📁 services/mock/mockRepositories.tsƒ SupabaseAuthRepository · MockAuthRepository4. HỆ THỐNG & DỮ LIỆU (dùng chung)📁 services/index.tsƒ useLiveQuery4.1 Đăng nhập & phiên📁 screens/LoginScreen.tsxƒ LoginScreen · handleLoginSubmit3 vai trò: Học sinh / Giáo viên / Admin — đăngnhập bằng tên đăng nhập + mật khẩu thật trongDB📁 screens/LoginScreen.tsx📁 types.tsƒ handleRoleSelect · RoleĐÃ XÓA cửa hậu mật khẩu phổ thông ở cả 2 khodữ liệu (trước đây mọi tài khoản vào được bằngmật khẩu mặc định, kể cả sau khi chủ tài khoảnđã đổi mật khẩu khác)📁 services/mock/mockRepositories.ts📁 services/supabase/supabaseRepositories.tsƒ MockAuthRepository · SupabaseAuthRepositoryLỗi đăng nhập báo rõ; không còn gợi ý mật khẩutrong thông báo lỗi📁 screens/LoginScreen.tsxƒ handleLoginSubmit'Xem góc Học sinh' cho GV/Admin: lưu phiêngốc, thanh cảnh báo cố định + nút 'Thoát xemthử' quay về đúng phiên📁 App.tsxƒ handleSwitchToStudentView · handleExitStudentPreviewĐăng xuất xóa cả phiên đóng vai — hết đườngleo quyền trở lại📁 App.tsxƒ handleLogoutBộ đếm giờ học tích cực chỉ chạy khi ngườidùng thật là học sinh📁 logic/useActiveLearningTimer.ts📁 App.tsxƒ useActiveLearningTimer4.2 Máy XP (xpEngine)📁 logic/xpEngine.tsƒ awardXPXP phẳng theo HOÀN THÀNH — không gắn với điểmsố (quyết định chốt của chủ dự án)📁 logic/xpEngine.ts📁 config.tsƒ awardXP · XP_CONFIGawardXP lật ngày / tuần theo GIỜ ĐỊA PHƯƠNG:ngày mới từ 00:00 giờ VN (đã sửa lỗi ngày UTCbắt đầu 07:00 khiến điểm danh 2 lần trong mộtbuổi sáng); khóa tuần theo thứ Hai📁 logic/xpEngine.ts📁 logic/studentStateUtils.tsƒ awardXP · getLocalTodayStr · getWeekKey rolloverStudentStateTrần XP ngày theo phút học tích cực: dưới 45phút → tối đa 130 XP · 45–90 phút → 150 XP ·quá 90 phút không cộng thêm (vẫn học bìnhthường)📁 logic/xpEngine.ts📁 config.tsƒ getCurrentDailyXpCap · XP_CONFIGTrần XP tuần: 900 XP — đạt trần hiện thông báonghỉ ngơi / tiếp tục nuôi Cây📁 config.ts📁 logic/xpEngine.tsƒ XP_CONFIG · getEffectiveXpConfigTách 'tiến độ học' khỏi 'đã trả XP'(xpAwardedSteps): học lúc chạm trần vẫn ghitiến độ cho Cây / Năng lực; hôm sau làm lạiđược trả XP đúng 1 lần — hết mất XP vĩnh viễn,hết lỗi 'từ ngày thứ 2 mọi lần cộng XP đều trảvề 0'📁 logic/studentStateUtils.ts📁 logic/xpEngine.ts📁 types.tsƒ countLearningSteps · xpAwardedSteps · awardXPThông báo XP hiển thị số THỰC NHẬN, kể cả khibị trần chặn📁 logic/xpEngine.tsƒ XPCalculationResult · awardXP4.3 Kho dữ liệu 2 lớp📁 services/supabase/client.ts📁 services/supabase/supabaseRepositories.tsƒ supabase · isSupabaseReadySupabase (PostgreSQL) là kho chính — 12 bảng:học sinh, giáo viên, lớp, chủ đề, video, lýthuyết, quiz, câu hỏi, bài nộp tự luận, statehọc sinh, yêu cầu quà…📁 services/supabase/client.ts📁 services/supabase/supabaseRepositories.tsƒ supabase · SupabaseContentRepositoryKho mock (localStorage) làm dự phòng khi mấtkết nối: đọc GỘP dữ liệu 2 nơi (bài nộp, họcsinh, lớp) để không bao giờ thất lạc dữ liệu📁 services/mock/mockRepositories.ts📁 services/supabase/payloadStore.tsƒ readStorage · writeStorage · bootstrapStorage readLocalList · writeLocalListCổng chặn ghi state: chỉ lưu sau khi stateTHẬT của đúng học sinh đã nạp xong — hết lỗistate mẫu (310 XP, huy hiệu sẵn) ghi đè lên DB📁 services/supabase/supabaseRepositories.ts📁 logic/studentStateUtils.tsƒ SupabaseAttemptRepository · rolloverStudentStateHọc sinh mới bắt đầu TRẮNG với hồ sơ thật(đúng tên + đúng lớp) ở cả 2 nhánh đọc state📁 services/mock/seedData.tsƒ createFreshStudentStateuseLiveQuery + eventBus: đồng bộ tức thời giữacác màn hình theo đúng khóa sự kiện (quiz /content / class…)📁 services/index.ts📁 services/mock/eventBus.tsƒ useLiveQuery · syncEventBus · SyncEventBusMigration chờ chủ dự án chạy trong SupabaseSQL Editor: 003 (trạng thái quà GIVEN/OPENED)+ 004 (cột payload giữ đủ trường câu hỏi) —app đang chạy chế độ tương thích an toàn tronglúc chờ📁 database/migration_003_reward_status.sql📁 database/migration_004_question_payload.sqlĐã sao lưu toàn bộ 12 bảng trước khi dọn dữliệu test: xóa 21 HS test + 15 bài nộp test;giữ lại hs001, 5 giáo viên, 4 lớp, toàn bộ nộidung thật (6 chủ đề, 97 câu hỏi, 33 quiz, 19video, 6 lý thuyết)📁 services/supabase/supabaseRepositories.ts📁 services/mock/mockRepositories.ts4.4 Giao diện & hiệu năng📁 components/teacher/ui/ConfirmDialog.tsxƒ ConfirmDialogMọi hộp thoại xác nhận dùng ConfirmDialog giữamàn hình (6 chỗ từng dùng hộp thoại mặc địnhcủa trình duyệt đã thay hết)📁 components/teacher/ui/ConfirmDialog.tsxƒ ConfirmDialogNút điều hướng tự nhả focus sau khi bấm — hếtvòng đen focus bám trên nút menu📁 components/Navbar.tsx📁 components/teacher/TeacherSidebar.tsxƒ Navbar · TeacherSidebarTải lười (React.lazy): gói JS ban đầu 2,37 MB→ ~0,79 MB; phần giáo viên (~1,08 MB) và thưviện biểu đồ (~0,39 MB) chỉ tải khi vào đúngkhu vực📁 App.tsx📁 screens/TeacherPortal.tsxƒ LearnScreen · TeacherPortalDevPanel (cộng XP / tự duyệt quà / tự chấm 9.0/ đặt lại dữ liệu demo) CHỈ có ở bảndevelopment — đã kiểm chứng bị loại khỏi góiproduction📁 components/DevPanel.tsx📁 App.tsxƒ DevPanel · handleResetData5. KHUNG ĐO NĂNG LỰC (từ sơ đồ gốc của chủdự án — đã có dữ liệu đỡ)📁 logic/mastery.tsƒ calculateAllMastery · calculateLevelMasteryMỗi lần làm bài xong, đo được từ học sinh: điểmtheo câu / chủ đề, năng lực, độ khó, tỉ lệ đúng,thời gian📁 components/QuizRunner.tsx📁 services/index.tsƒ QuizRunner · attemptService4 năng lực × dạng đo × độ khó📁 types.ts📁 logic/mastery.tsƒ SkillLevel · Difficulty · SKILL_METADATANhận biết → Trắc nghiệm — Dễ📁 types.ts📁 logic/mastery.tsƒ SkillLevel · Difficulty · SKILL_METADATAThông hiểu → Trắc nghiệm — Trung bình📁 types.ts📁 logic/mastery.tsƒ SkillLevel · Difficulty · SKILL_METADATAPhân tích → Trắc nghiệm — Khó · Tự luận chấmRubric — Khó📁 types.ts📁 logic/mastery.tsƒ SkillLevel · Difficulty · SKILL_METADATAVận dụng → Tự luận / viết văn (đoạn 5–7 câu,bài 150–200 chữ) chấm Rubric — Khó📁 types.ts📁 logic/mastery.tsƒ SkillLevel · Difficulty · SKILL_METADATABiểu thị khách quan: % thành thạo từng năng lựctheo chủ đề (calculateLevelMastery /calculateAllMastery) + trạng thái Vững / Đangtiến bộ / Cần ôn lại / Chưa học📁 logic/mastery.tsƒ calculateLevelMastery · calculateAllMasteryDữ liệu nền cho phân tích📁 analytics/engagementAnalytics.ts📁 analytics/questionAnalytics.tsƒ computeQuestionAnalyticsĐăng nhập & chuyên cần: có thường xuyên vàohọc không, ai ít đăng nhập (điểm danh + phúthọc tích cực theo ngày)📁 analytics/engagementAnalytics.tsƒ computeWeeklyAttendance · computeDailyALTNăng lực qua bài tập: kết quả từng câu gắnnăng lực + độ khó📁 analytics/questionAnalytics.ts📁 analytics/scoreAnalytics.tsƒ computeQuestionAnalytics · computeAvgScoreByTopicĐầu ra đã nối chung 1 hàm tính: Kết quả học tậpcủa học sinh · Ma trận năng lực ở Cây tri thức ·Phân tích của giáo viên📁 logic/mastery.ts📁 screens/LearningResultsScreen.tsx📁 screens/TreeScreen.tsx📁 screens/teacher/TeacherAnalyticsScreen.tsxƒ calculateAllMastery6. KIỂM CHỨNG & TRẠNG THÁI DỰ ÁN📁 docs/CHANGELOG.md📁 scripts/test_round2_logic.tsCổng TypeScript trong lệnh build (tsc --noEmit &&vite build): 18 lỗi type ban đầu → 0 lỗi📁 package.jsonƒ tscTest logic tự động scripts/test_round2_logic.ts:35/35 đạt (XP, lật ngày/tuần, đổi quà trừ TỔNG XP+ hoàn khi từ chối, sinh tên đăng nhập / mã HS)📁 scripts/test_round2_logic.tsĐợt 0–6 + QA vòng 2 + các đợt tinh chỉnh ngày18/10: đã đẩy nhánh dev (81c8bc1) và deployproduction https://mamvan.vercel.app📁 docs/CHANGELOG.mdCòn treo📁 docs/CHANGELOG.mdKiểm chứng trực tiếp luồng nộp bài bằng tàikhoản hs001 trên production (đang chờ nhập mậtkhẩu qua thẻ bảo mật)📁 docs/CHANGELOG.md📁 scripts/test_round2_logic.tsChủ dự án tự merge nhánh dev → main📁 docs/CHANGELOG.mdChạy migration 003 + 004 trong Supabase SQLEditor📁 database/migration_003_reward_status.sql📁 database/migration_004_question_payload.sql📁 docs/CHANGELOG.mdQuyết định vá đăng nhập Admin cứng trong mãnguồn📁 services/supabase/supabaseRepositories.ts📁 services/mock/mockRepositories.ts📁 docs/CHANGELOG.mdƒ SupabaseAuthRepository · MockAuthRepositoryĐổi mật khẩu database — đã thống nhất để sau📁 docs/CHANGELOG.md