From 6cc97bb2b82c016da01e5d58e8d6b0b41de75f70 Mon Sep 17 00:00:00 2001 From: Phongxuan123 <158146102+Phongxuan123@users.noreply.github.com> Date: Sat, 25 Jul 2026 08:33:38 +0700 Subject: [PATCH] =?UTF-8?q?docs:=20th=C3=AAm=20b=E1=BA=A3n=20=C4=91?= =?UTF-8?q?=E1=BA=B7c=20t=E1=BA=A3=20t=E1=BB=95ng=20h=E1=BB=A3p=20to=C3=A0?= =?UTF-8?q?n=20d=E1=BB=B1=20=C3=A1n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tổng hợp docs/SPECIFICATION.md từ code thực tế (schema.prisma, seed.ts, componentRegistry, package.json...) và các tài liệu kỹ thuật sẵn có, bao gồm cả phần non-tech (mục tiêu sản phẩm, chương trình học Triết học Mác - Lênin, tính năng theo góc nhìn người dùng) lẫn tech (kiến trúc, stack, mô hình dữ liệu, hệ thống lesson flow, API, deploy, giới hạn hiện tại). Thêm liên kết từ README gốc trỏ tới tài liệu này. --- README.md | 1 + docs/SPECIFICATION.md | 481 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 482 insertions(+) create mode 100644 docs/SPECIFICATION.md diff --git a/README.md b/README.md index 7c6d75b..177b5c1 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ This repository should be read from the current code first. Historical proposal Start here: +- [Full project specification (Vietnamese)](docs/SPECIFICATION.md) - complete tech + non-tech spec: product goals, curriculum, features, architecture, data model, ops, in one document. - [Project overview](docs/PROJECT_OVERVIEW.md) - current architecture, modules, data model, and major flows. - [API reference](docs/API.md) - current endpoint inventory generated from controller inspection; use Swagger `/docs` for live schemas. - [Lesson components](docs/LESSON_COMPONENTS.md) - detailed `lessonFlow`, `lessonMedia`, renderer, validator, progress, and authoring contract. diff --git a/docs/SPECIFICATION.md b/docs/SPECIFICATION.md new file mode 100644 index 0000000..c5130f0 --- /dev/null +++ b/docs/SPECIFICATION.md @@ -0,0 +1,481 @@ +# Bản đặc tả dự án PhiloMind + +Tài liệu này tổng hợp toàn bộ thông tin về dự án PhiloMind — từ mục tiêu sản phẩm, đối tượng người dùng, nội dung học thuật, đến kiến trúc kỹ thuật, mô hình dữ liệu và quy trình vận hành. Đây là bản đặc tả tổng hợp (master spec); với chi tiết kỹ thuật sâu hơn từng mảng, xem thêm các tài liệu chuyên biệt liệt kê ở [Tài liệu liên quan](#tài-liệu-liên-quan). + +Cập nhật lần cuối: 2026-07-24. + +--- + +## Mục lục + +1. [Tổng quan sản phẩm](#1-tổng-quan-sản-phẩm) +2. [Đối tượng người dùng & vai trò](#2-đối-tượng-người-dùng--vai-trò) +3. [Nội dung học thuật (chương trình học)](#3-nội-dung-học-thuật-chương-trình-học) +4. [Tính năng theo góc nhìn người dùng](#4-tính-năng-theo-góc-nhìn-người-dùng) +5. [Kiến trúc hệ thống](#5-kiến-trúc-hệ-thống) +6. [Stack công nghệ](#6-stack-công-nghệ) +7. [Cấu trúc thư mục monorepo](#7-cấu-trúc-thư-mục-monorepo) +8. [Mô hình dữ liệu (Prisma/PostgreSQL)](#8-mô-hình-dữ-liệu-prismapostgresql) +9. [Hệ thống Lesson Flow (bài học dạng component)](#9-hệ-thống-lesson-flow-bài-học-dạng-component) +10. [Backend API](#10-backend-api) +11. [Frontend học viên (Learner)](#11-frontend-học-viên-learner) +12. [Admin Portal](#12-admin-portal) +13. [AI, TTS & tích hợp bên thứ ba](#13-ai-tts--tích-hợp-bên-thứ-ba) +14. [Xác thực & phân quyền](#14-xác-thực--phân-quyền) +15. [Thiết kế UI/UX](#15-thiết-kế-uiux) +16. [Vận hành & triển khai (DevOps)](#16-vận-hành--triển-khai-devops) +17. [Kiểm thử & chất lượng](#17-kiểm-thử--chất-lượng) +18. [Quy trình phát triển & cộng tác](#18-quy-trình-phát-triển--cộng-tác) +19. [Giới hạn hiện tại & định hướng](#19-giới-hạn-hiện-tại--định-hướng) +20. [Tài liệu liên quan](#tài-liệu-liên-quan) + +--- + +## 1. Tổng quan sản phẩm + +**PhiloMind** là một nền tảng học tập được hỗ trợ bởi AI, chuyển đổi một giáo trình triết học truyền thống (dạng văn bản tuyến tính, khô khan) thành một **hành trình học tập có hướng dẫn** (guided journey), giàu tính tương tác và đa giác quan. + +Nội dung học thuật hiện tại của hệ thống là **"Triết học Mác – Lênin"** — môn học đại cương bắt buộc trong chương trình giáo dục đại học tại Việt Nam. Toàn bộ kiến trúc component/kỹ thuật, tuy vậy, được thiết kế trung lập theo môn học (subject-agnostic): bất kỳ giáo trình nào cũng có thể được số hoá theo cùng một mô hình `Course → Chapter → ConceptNode → lessonFlow`. + +### Vấn đề sản phẩm giải quyết + +- Giáo trình triết học lý luận truyền thống thường dài, trừu tượng, khó tạo động lực tự học. +- Người học khó tự đánh giá mình đã hiểu đúng khái niệm hay chưa, thiếu phản hồi tức thời. +- Ôn tập ngắn hạn trước kỳ thi thường không tạo trí nhớ dài hạn. +- Thiếu môi trường để rèn tư duy phản biện (một kỹ năng cốt lõi của triết học) ngoài lớp học truyền thống. + +### Cách PhiloMind giải quyết + +- **Hành trình học có cấu trúc**: giáo trình được chẻ nhỏ thành các `ConceptNode` (đơn vị học tập nguyên tử), sắp xếp theo `Chapter`, hiển thị dưới dạng sơ đồ tư duy (mindmap) trực quan hoá lộ trình. +- **Bài học tương tác đa dạng component**: mỗi `ConceptNode` không phải một trang văn bản, mà là một chuỗi (`lessonFlow`) gồm nhiều loại hoạt động — hội thoại dẫn truyện, video, trắc nghiệm, kéo-thả phân loại, ghép cặp, lắp ráp chuỗi nhân quả, mảnh ghép kiến thức, dòng thời gian, mini-game trí nhớ... — giữ người học chủ động thay vì đọc thụ động. +- **Tranh luận Socratic với AI**: học viên luyện phản biện tư duy bằng cách tranh luận trực tiếp với AI đóng vai người phản biện. +- **Thẻ ghi nhớ ngắt quãng (Spaced Repetition/SM-2)**: hệ thống flashcard tự tính lịch ôn tập tối ưu để kiến thức đi vào trí nhớ dài hạn. +- **Podcast hội thoại do AI tổng hợp**: học viên có thể nghe lại nội dung dưới dạng audio (text-to-speech) khi không tiện đọc. +- **PhilosoFUN**: nội dung giải trí nhẹ nhàng (video) liên quan triết học, giảm áp lực học thuật. + +--- + +## 2. Đối tượng người dùng & vai trò + +| Vai trò | Mô tả | Quyền hạn chính | +|---|---|---| +| **Học viên (student)** | Người dùng cuối, thường là sinh viên đang học môn Triết học Mác – Lênin | Học bài, làm quiz, ôn flashcard, tranh luận với AI, nghe podcast, bình luận, gửi phản hồi (feedback) | +| **Quản trị viên (admin)** | Ban giảng huấn/vận hành nội dung | Toàn quyền CRUD: khoá học, chương, node bài học (soạn `lessonFlow` dạng JSON), flashcard, quiz, chủ đề tranh luận, video PhilosoFUN, quản lý người dùng, xem toàn bộ phản hồi/feedback | + +Vai trò được lưu trong field `User.role` (`"student"` mặc định, `"admin"` cho quản trị), gán quyền qua `RolesGuard` + decorator `@Roles("admin")` ở backend. + +--- + +## 3. Nội dung học thuật (chương trình học) + +Khoá học seed mặc định: **"Triết học Mác – Lênin"**, chia thành các chương (`Chapter`), mỗi chương chứa nhiều node khái niệm (`ConceptNode`): + +### Chương 1 — Triết học và vai trò của triết học trong đời sống xã hội +- Khái niệm triết học +- Nguồn gốc của triết học (nhận thức + xã hội) +- Đối tượng của triết học trong lịch sử +- Triết học — hạt nhân lý luận của thế giới quan +- Vấn đề cơ bản của triết học +- Biện chứng và siêu hình +- Sự ra đời và phát triển (của triết học Mác – Lênin) +- Đối tượng và chức năng +- Vai trò trong đời sống xã hội + +### Chương 2 — Chủ nghĩa duy vật biện chứng +- Vật chất và ý thức +- Phép biện chứng duy vật +- Lý luận nhận thức +- Quan niệm về phạm trù vật chất & Cuộc cách mạng khoa học tự nhiên (khủng hoảng vật lý) +- Phương thức tồn tại của vật chất & Tính thống nhất vật chất +- Nguồn gốc, bản chất và kết cấu của ý thức +- Mối quan hệ giữa vật chất và ý thức +- Hai loại hình biện chứng và phép biện chứng duy vật +- Hai nguyên lý cơ bản của phép biện chứng duy vật +- Các cặp phạm trù cơ bản +- Ba quy luật cơ bản +- Quan niệm về nhận thức trong lịch sử triết học +- Nguồn gốc, bản chất và các giai đoạn nhận thức +- Thực tiễn và vai trò của thực tiễn đối với nhận thức +- Quan điểm của CNDVBC về chân lý + +### Chương 3 — Chủ nghĩa duy vật lịch sử +- Hình thái kinh tế – xã hội +- Sản xuất vật chất; biện chứng lực lượng sản xuất – quan hệ sản xuất +- Cơ sở hạ tầng và kiến trúc thượng tầng +- Nguồn gốc giai cấp; đấu tranh giai cấp +- Nhà nước và cách mạng xã hội +- Bản chất con người; quần chúng và lãnh tụ + +### Nội dung bổ trợ +- Trắc nghiệm tổng hợp theo từng chương (`Quiz`) + đề thi thử tổng hợp. +- Tài liệu PDF: giáo trình đầy đủ, giáo trình từng chương, bản tóm tắt chi tiết từng chương (`Document`). +- Chủ đề tranh luận Socratic có sẵn (`DebateTopic`): "Chủ nghĩa Duy vật vs Chủ nghĩa Duy tâm", "Giá trị thặng dư trong kỷ nguyên số & AI", "Ý thức và Trí tuệ nhân tạo (AI)"... +- Mini-game khởi động (`Warmup`) gắn theo từng node: "Kính lọc cuộc đời" (phân loại thế giới quan), "Từ sấm sét đến quy luật", "Hai mảnh ghép khai sinh triết học", "Nhìn hình đoán khái niệm", "Mẩu chuyện triết học kinh điển". + +Dữ liệu bài học đã chuyển đổi sang dạng component được lưu ở `data/lesson_components/*.json` (nguồn seed cho các lesson đã publish); script `backend/prisma/reseed_lessons.ts` dùng để nạp lại DB từ các file này. + +--- + +## 4. Tính năng theo góc nhìn người dùng + +### 4.1. Trang chủ (`/`) +Dashboard tổng quan: banner giới thiệu, các tính năng cốt lõi, mốc lịch sử triết học, lối vào nhanh các mục chính. + +### 4.2. Sơ đồ bài học / Hành trình (`/lessons`) +- Hiển thị toàn bộ khoá học dưới dạng **sơ đồ tư duy tương tác** (mindmap, dùng React Flow), thể hiện quan hệ chương → node. +- Node bị khoá (`locked`) cho đến khi node trước hoàn thành; mở khoá tuần tự (`available` → `in_progress` → `completed`). +- Mở một node sẽ chuyển sang **trình phát bài học toàn màn hình** (Flow Lesson Player). + +### 4.3. Trình phát bài học (Flow Lesson Player) +Bố cục 2 cột khoá cứng 50/50: +- **Cột trái**: media trung tâm (video/hình ảnh) + thanh milestone. +- **Cột phải**: nội dung tương tác hiện tại (component đang active trong `lessonFlow`). +- **Thanh tiến trình** phía trên: các bước trong bài học dưới dạng pill có thể bấm để nhảy tới (nếu đã mở khoá), cuộn ngang mượt, nhãn tự động rút gọn. +- Nút "Học lại bài này từ đầu" để reset tiến trình. +- Nhiều **loại component tương tác** khác nhau xen kẽ nhau trong một bài học (xem mục 9). + +### 4.4. Khu luyện tập (`/practice`) +- **Flashcard ôn tập**: thuật toán lặp ngắt quãng kiểu SM-2 (`ease` 1-4, tính lại `interval`/`nextReview`), ôn theo "đến hạn hôm nay" hoặc theo từng chương. +- **Ghép cặp (Shinkei)**: mini-game trí nhớ lật thẻ ghép cặp khái niệm. +- **Quiz tổng hợp**: trắc nghiệm/ghép cặp/tự luận/phân tích/theo hình ảnh theo từng chương hoặc đề thi thử. + +### 4.5. Góc tranh luận (`/debate`) +- Tranh luận Socratic với AI theo **kịch bản có sẵn** (`DebateTopic`) hoặc theo **khái niệm bài học** (`ConceptNode`). +- AI đóng vai người phản biện, đặt câu hỏi truy vấn sâu để thử thách lập luận của học viên (throttle 5 request/phút để chống lạm dụng). +- Lịch sử tranh luận được lưu trọn vẹn (`Debate.transcript`). + +### 4.6. PhilosoFUN (`/philosofun`) +Thư viện video giải trí/minh hoạ triết học ngắn, không gắn với tiến trình học chính thức. + +### 4.7. Tài liệu (`/docs`) +Kho tài liệu PDF tham khảo (giáo trình đầy đủ, tóm tắt từng chương) do admin tải lên. + +### 4.8. Cài đặt (`/settings`) +Tuỳ chỉnh cá nhân (theme sáng/tối, tuỳ chọn mở khoá toàn bộ nội dung ở chế độ dev cho việc kiểm thử). + +### 4.9. Bình luận & phản hồi +- Học viên có thể bình luận trực tiếp trên từng node bài học (`Comment`). +- Gửi phản hồi chung về sản phẩm qua form khảo sát (`Feedback`), admin xem toàn bộ danh sách. + +--- + +## 5. Kiến trúc hệ thống + +Monorepo 4 dịch vụ độc lập, giao tiếp qua REST API: + +```mermaid +flowchart LR + Learner["Learner frontend\nReact + Vite"] --> API["Backend API\nNestJS"] + Admin["Admin portal\nReact + Vite"] --> API + API --> DB["PostgreSQL\n(qua Prisma)"] + API --> Supabase["Supabase\nAuth + Storage"] + API --> LLM["LLM tương thích OpenAI\n(mặc định OpenRouter)"] + API --> TTS["TTS worker\nFastAPI + Kokoro ONNX"] + TTS --> API +``` + +- **PostgreSQL** (qua Prisma) là nguồn dữ liệu chính thức (system of record). +- **Supabase** dùng cho Auth (đăng nhập bên thứ ba) và Storage (lưu file/ảnh/video); có cơ chế fallback lưu local/mock khi chưa cấu hình Supabase. +- **LLM** (mặc định qua OpenRouter, tương thích chuẩn OpenAI) phục vụ tính năng tranh luận Socratic; có nội dung fallback khi chưa cấu hình API key thật, để demo local vẫn chạy được. +- **TTS worker** (FastAPI + Kokoro ONNX) tổng hợp giọng đọc cho podcast, tách thành dịch vụ riêng để không chặn backend chính khi xử lý audio. + +--- + +## 6. Stack công nghệ + +| Thành phần | Công nghệ chính | Phiên bản tiêu biểu | +|---|---|---| +| Backend API | NestJS, TypeScript, Prisma ORM | NestJS ^11, Prisma ^5.7, TypeScript ^5.1 | +| Database | PostgreSQL (image có pgvector cho local dev) | PostgreSQL 15 | +| Learner frontend | React, Vite, Tailwind CSS, TanStack Query (React Query), React Router | React ^18.3, Vite ^7.3, Tailwind ^3.4 | +| Admin frontend | React, Vite, Tailwind CSS | React ^18.3, Vite ^7.3 | +| Kéo-thả tương tác | `@dnd-kit/core` + `@dnd-kit/sortable` | ^6.3 | +| Sơ đồ tư duy | React Flow | — | +| TTS worker | FastAPI, Kokoro ONNX (onnxruntime), soundfile | FastAPI ≥0.109 | +| Auth | JWT (Passport), Google ID token, Supabase JWT | Passport ^0.7 | +| Rate limiting | `@nestjs/throttler` | ^6.5 | +| Testing | Vitest (frontend/admin), Jest/NestJS test runner (backend) | — | +| CI/CD | GitHub Actions | — | +| Container hoá | Docker, `docker-compose.yml` cho local stack | — | +| Hosting production | Hugging Face Spaces (backend + TTS worker), Vercel (frontend học viên, dựa theo domain `philo-mind-tau.vercel.app` quan sát trong quá trình vận hành) | — | + +--- + +## 7. Cấu trúc thư mục monorepo + +``` +PhiloMind/ +├── backend/ NestJS REST API, Prisma schema, seed scripts, tích hợp AI/TTS/storage +│ ├── prisma/ schema.prisma, seed.ts, sql/reseed_lessons_manual.sql +│ └── src/ +│ ├── auth/ JWT strategy, guard, role guard/decorator +│ ├── users/ đăng nhập local/Google/Supabase, CRUD user, feedback +│ ├── courses/ course, chapter, concept node, journey, lesson flow, progress, comment, document, podcast, upload +│ ├── flashcards/ due card, review SM-2, CRUD, bulk import +│ ├── quizzes/ CRUD quiz, lọc theo node +│ ├── debate/ phiên tranh luận Socratic (theo topic hoặc theo node) qua AIService +│ ├── philosofun/ CRUD video giải trí +│ ├── ai/ client tương thích OpenAI, có fallback khi không có API key +│ ├── tts/ proxy sang TTS worker + upload Supabase/local +│ ├── supabase/ client Supabase + storage helper (có mock fallback) +│ └── database/ Prisma client wrapper (chuẩn hoá URL pooler, giới hạn concurrency) +├── frontend/ Learner React app (journey mindmap, lesson player, quiz, debate, flashcard, settings) +│ └── src/pages/lesson/ Toàn bộ hệ thống chơi bài học dạng flow + component +├── admin/ Admin React app (CRUD nội dung & người dùng) +├── tts_worker/ FastAPI speech worker trả về audio WAV +├── data/lesson_components/ File JSON nội dung bài học đã chuyển đổi (nguồn seed) +├── docs/ Tài liệu kỹ thuật hiện hành (file này + các tài liệu chuyên biệt) +├── scripts/ Tiện ích kiểm tra sức khoẻ hệ thống/tích hợp +└── .github/workflows/ CI + workflow deploy Hugging Face (backend, TTS worker) +``` + +--- + +## 8. Mô hình dữ liệu (Prisma/PostgreSQL) + +### Sơ đồ quan hệ cốt lõi + +``` +User 1---* Course 1---* Chapter 1---* ConceptNode 1---* Flashcard + | | (tự tham chiếu: |---1 Podcast + | | parentChapter/subChapters) |---* Warmup + |---* Progress *---1 ConceptNode |---* Comment + |---* Debate *---1 ConceptNode (hoặc *---1 DebateTopic) |---* Quiz + |---* FlashcardReview *---1 Flashcard |---* Debate + |---* Comment |---* Progress + |---* Feedback +``` + +### Danh mục model + +| Model | Vai trò | Trường đáng chú ý | +|---|---|---| +| `User` | Định danh học viên/admin | `role` (`student`/`admin`), `streak`, quan hệ tới progress/debates/reviews/feedbacks/comments/courses | +| `Course` | Container chứa chương và tài liệu | `title`, `description`, thuộc về 1 `User` (chủ sở hữu nội dung) | +| `Chapter` | Cấu trúc phân cấp có thứ tự | `orderIndex`, `parentChapterId` (tự tham chiếu để hỗ trợ chương con) | +| `ConceptNode` | **Đơn vị học tập trung tâm** | `lessonFlow` (JSON), `lessonMedia` (JSON), `lessonType` (mặc định `"flow"`), `contentReady`, `lessonStatus` (`draft`/`published`/`archived`), `difficulty`, `timeToRead`, `videoUrl`, `orderIndex` | +| `Progress` | Trạng thái học của từng user với từng node | `status`, `lessonCompleted`, `activeComponentId`, `currentComponentIndex`, `completedComponentIds` (JSON), `componentResults` (JSON) — unique theo (`userId`, `nodeId`) | +| `Flashcard` / `FlashcardReview` | Nội dung thẻ ghi nhớ + lịch sử ôn tập | `ease` (1-4), `interval` (ngày), `nextReview` | +| `Podcast` | Audio + transcript cho 1 node | `audioUrl`, `transcript` (JSON mảng `{time, speaker, text}`) — quan hệ 1-1 với `ConceptNode` | +| `DebateTopic` / `Debate` | Chủ đề tranh luận tái sử dụng + phiên tranh luận của user | `transcript` (JSON mảng tin nhắn); `Debate` có thể gắn với `nodeId` hoặc `topicId` | +| `Warmup` | Hoạt động khởi động ngắn trước bài học | `type` (`image-guess`/`story`), `blanks`, `answer`, `options`, `correctIndex` | +| `Quiz` | Nội dung quiz/game độc lập | `type` (`mcq`/`matching`/`essay`/`image`/`analysis`), `questions` (JSON) | +| `Comment` | Bình luận theo node | `role` để phân biệt bình luận của học viên/admin | +| `Document` | Tham chiếu file PDF/tài liệu | `status` (`parsing`/`completed`/`failed`) | +| `Feedback` | Phản hồi sản phẩm từ người dùng | `content` | +| `Philosofun` | Metadata video giải trí | `videoUrl` | + +Chi tiết đầy đủ từng field: xem `backend/prisma/schema.prisma`. + +--- + +## 9. Hệ thống Lesson Flow (bài học dạng component) + +Đây là phần lõi khác biệt nhất của sản phẩm: mỗi `ConceptNode` không chứa văn bản tĩnh mà chứa **`lessonFlow`** — một mảng JSON có thứ tự các "component" (bước học), mỗi bước là một loại hoạt động tương tác riêng biệt. + +### Nguyên tắc hoạt động +- `lessonFlow`: mảng JSON các bước học cấp cao nhất; mỗi bước có `id` (duy nhất toàn flow, kể cả bên trong nhóm), `type`, `config`, tuỳ chọn `title`, `linkedMediaId`, `completionRule`. +- `lessonMedia`: mảng media tuỳ chọn cho cột giữa (video/hình ảnh), độc lập với `lessonFlow` nhưng có thể liên kết qua `linkedMediaId`. +- Bài học chỉ mở được cho học viên khi **đồng thời** `contentReady === true` **và** `lessonStatus === "published"` — cả ở UI lẫn API backend (chặn cứng, không chỉ ẩn UI). +- `component_group`: gom nhiều component con (ví dụ hội thoại + câu hỏi) thành **một hoạt động học liền mạch** về mặt trải nghiệm người dùng — không hiển thị khái niệm kỹ thuật "group" cho học viên. + +### Danh mục loại component hỗ trợ + +| Loại | Trải nghiệm học viên | +|---|---| +| `component_group` | Nhóm nhiều component con thành một hoạt động liền mạch | +| `dialogue` | Hội thoại dẫn truyện giữa các nhân vật (bong bóng chat kiểu đám mây) | +| `media` | Xác nhận đã xem/đọc media (video/ảnh) | +| `markdown` | Đọc nội dung văn bản định dạng | +| `target_matching` / `map_target_matching` | Kéo-thả khớp mục vào đích (kể cả đích có toạ độ trên bản đồ/hình ảnh) | +| `category_sorting` | Phân loại thẻ vào đúng nhóm | +| `mindmap_reveal` | Mở khoá dần các thẻ khái niệm trên bản đồ tư duy toả tia | +| `mcq` | Trắc nghiệm 1 câu, phản hồi sai chỉ chớp đỏ tạm thời rồi tự reset | +| `quiz_sequence` | Chuỗi nhiều câu trắc nghiệm | +| `multi_select` | Câu hỏi nhiều đáp án đúng | +| `matching_columns` | Ghép cột trái–phải (hỗ trợ nhiều-tới-một) | +| `true_false` | Câu hỏi đúng/sai | +| `sequence_sorting` / `chain_sorting` | Sắp xếp thứ tự/chuỗi nhân quả (chọn theo số thứ tự, kiểm tra trực tiếp, không lộ đáp án) | +| `knowledge_piece` | Thẻ "mảnh ghép kiến thức" ngắn, hiệu ứng bay vào milestone khi thu thập | +| `progression_spiral` | Mở dần các mốc trên một mặt xoắn ốc/tiến trình | +| `timeline_explorer` | Khám phá các giai đoạn lịch sử, có trạng thái đã xem lưu lại | +| `hotspot_gallery` | Mở các điểm nóng trên ảnh/thẻ để đọc chi tiết | +| `shinkei_matching` | Mini-game trí nhớ lật thẻ ghép cặp 2 cột | +| `final_summary` | Màn hình tổng kết hoàn thành bài học | +| `fill_in_blanks` | Điền/chọn từ khoá còn thiếu trong đoạn văn | + +### Vòng đời runtime +1. Admin soạn/sửa `lessonFlow` (dạng JSON) trong `/nodes` của admin portal. +2. Backend validate cấu trúc bằng `NodeSchemaValidator` trước khi lưu. +3. Học viên mở `/lessons?lesson=` → `useJourney` tải lộ trình → `useNodeDetails` tải chi tiết node. +4. `FlowLessonPlayer` chuẩn hoá flow, dựng danh sách media, chọn vị trí tiếp tục (resume), render layout 2 cột. +5. `RightInteractive` chọn renderer tương ứng từ `componentRegistry` theo `type`. +6. Hoàn thành mỗi component gọi `PATCH /api/courses/nodes/:nodeId/component-progress`. +7. Hoàn thành component cuối cùng gọi `POST /api/courses/nodes/:nodeId/complete` → backend đánh dấu hoàn thành node và mở khoá node tiếp theo. + +Đặc tả chi tiết từng loại component, cấu trúc JSON, quy tắc ảnh inline, ví dụ mẫu: xem [`LESSON_COMPONENTS.md`](LESSON_COMPONENTS.md). + +--- + +## 10. Backend API + +Base URL local: `http://localhost:3001/api` (health check `/` và `/health` nằm ngoài prefix `/api`). Swagger sống tại `/docs` khi `NODE_ENV !== "production"` hoặc `ENABLE_SWAGGER=true`. + +### Nhóm endpoint chính + +| Nhóm | Mô tả | +|---|---| +| Auth & Users | Đăng ký/đăng nhập local, Google, Supabase; CRUD user (admin); feedback | +| Courses/Chapters/Nodes/Documents/Files | CRUD khoá học/chương/node; roadmap hành trình; chi tiết node; tiến trình cấp node & cấp component; upload file/ảnh/video | +| Warmups & Comments | CRUD warmup theo node; bình luận theo node | +| Podcasts & TTS | CRUD podcast; tổng hợp audio preview (throttled) | +| Flashcards | Thẻ đến hạn, submit review, CRUD, bulk import | +| Quizzes | CRUD quiz, lọc theo node | +| Debate | Chủ đề tranh luận, gửi tin nhắn tranh luận (throttled), quản trị phiên tranh luận | +| Philosofun | CRUD video | + +Quy tắc xác thực: endpoint công khai chỉ có các entrypoint auth; phần lớn API yêu cầu JWT; thao tác tạo/sửa/xoá và một số danh sách/chi tiết yêu cầu vai trò admin. Endpoint gửi tin nhắn tranh luận và tổng hợp podcast bị giới hạn 5 request/phút/route để chống lạm dụng. + +Danh sách endpoint đầy đủ theo method/path/auth: xem [`API.md`](API.md). + +--- + +## 11. Frontend học viên (Learner) + +| Route | Chức năng | +|---|---| +| `/` | Dashboard trang chủ | +| `/practice` | Khu luyện tập (flashcard/ghép cặp/quiz) | +| `/practice/shinkei/:id` | Mini-game trí nhớ ghép cặp | +| `/debate` | Góc tranh luận Socratic | +| `/lessons` | Sơ đồ hành trình + trình phát bài học | +| `/philosofun` | Video giải trí | +| `/docs` | Tài liệu tham khảo trong app | +| `/settings` | Cài đặt người dùng | +| `/login`, `/register` | Xác thực | +| `/quiz/matching/:id`, `/quiz/analysis/:id`, `/quiz/essay/:id`, `/quiz/mcq/:id`, `/image-quiz/:id` | Các route quiz chuyên biệt | + +Các thành phần dữ liệu quan trọng: `services/api.js` (fetch wrapper gắn JWT), `services/queryKeys.js` (khoá React Query tập trung), `hooks/useJourney.js`, `hooks/useNodeDetails.js`, `hooks/useMutations.js`. + +--- + +## 12. Admin Portal + +| Route | Chức năng | +|---|---| +| `/login` | Đăng nhập admin | +| `/` | Dashboard | +| `/users` | Quản lý người dùng | +| `/courses` | Quản lý khoá học | +| `/nodes` | Soạn chương/node, `lessonFlow` (JSON), upload media, warmup, flashcard, quiz, podcast, tài liệu | +| `/practice` | Quản lý nội dung luyện tập | +| `/debates` | Quản lý chủ đề/phiên tranh luận | +| `/philosofun` | Quản lý video | + +`/nodes` (`admin/src/pages/Nodes.jsx`) là khu vực thao tác phức tạp nhất: `lessonFlow` hiện được soạn trực tiếp dưới dạng JSON thô — validation phía backend là hàng rào chính ngăn dữ liệu sai cấu trúc được lưu. + +--- + +## 13. AI, TTS & tích hợp bên thứ ba + +- **AI (tranh luận Socratic)**: `AIService` gọi một LLM tương thích chuẩn OpenAI (mặc định trỏ tới OpenRouter, model mặc định `meta-llama/llama-3-70b-instruct:free`). Khi không cấu hình `OPENAI_API_KEY`, hệ thống dùng nội dung fallback để demo local vẫn hoạt động được. +- **TTS (podcast)**: backend `TTSService` gọi sang `tts_worker` (FastAPI + Kokoro ONNX) để tổng hợp giọng đọc từ văn bản, kết quả audio được lưu qua Supabase Storage hoặc local/mock storage. +- **Supabase**: dùng cho Auth (đăng nhập bên thứ ba, đối chiếu JWT) và Storage (ảnh, video, audio). Có cơ chế mock/local fallback khi chưa cấu hình để không chặn phát triển local. +- **Google OAuth**: đăng nhập bằng Google ID token, backend xác thực và map vào `User` nội bộ. + +--- + +## 14. Xác thực & phân quyền + +- 3 phương thức đăng nhập: local (email/mật khẩu), Google ID token, Supabase JWT — tất cả quy về một JWT nội bộ do backend phát hành. +- `JwtAuthGuard` bảo vệ phần lớn endpoint; `RolesGuard` + `@Roles("admin")` bảo vệ thao tác quản trị. +- Một số endpoint cho phép chủ sở hữu (owner) hoặc admin (ví dụ xem thông tin user). +- Học viên không thể truy cập nội dung `draft`/chưa `contentReady` dù có JWT hợp lệ — chặn ở cả tầng API, không chỉ tầng UI. + +--- + +## 15. Thiết kế UI/UX + +Nguyên tắc sản phẩm: +- Làm cho triết học "có cấu trúc, dễ điều hướng, dễ thảo luận" — giảm tải nhận thức thay vì thêm chi tiết trang trí. +- Luôn cho học viên thấy ngữ cảnh học tập trước khi vào nội dung sâu. +- Ưu tiên hành động tiếp theo rõ ràng, tránh tiến trình ẩn. +- Không để lộ thuật ngữ schema kỹ thuật (như "component group") cho học viên. +- Màn hình admin: dày đặc thao tác, tối ưu vận hành; màn hình học viên: dẫn dắt, phản chiếu. +- Bố cục trình phát bài học: khoá cứng 2 cột 50/50 (không cho kéo–thả resize, tránh vỡ layout), media bên trái, hoạt động học bên phải. +- Bảng màu chính: tông teal-blue sáng (`primary` palette trong Tailwind config), hỗ trợ đầy đủ sáng/tối (`dark` class + biến CSS). + +Chi tiết & quy ước UI đầy đủ: xem [`DESIGN_SYSTEM.md`](DESIGN_SYSTEM.md). + +--- + +## 16. Vận hành & triển khai (DevOps) + +### Local development +```bash +cp .env.example .env +docker compose up --build +``` +Cổng mặc định: Frontend `3000`, Backend `3001`, Admin `3002`, TTS worker `8000`, PostgreSQL `5432`. + +### Biến môi trường quan trọng (backend) +`DATABASE_URL`, `JWT_SECRET`, `GOOGLE_CLIENT_ID`, `ALLOWED_ORIGINS`, `ENABLE_SWAGGER`, `SUPABASE_URL`/`SUPABASE_ANON_KEY`/`SUPABASE_SERVICE_ROLE_KEY`, `OPENAI_API_KEY`/`OPENAI_API_BASE_URL`/`LLM_MODEL`, `TTS_WORKER_URL`, cùng nhóm biến pool Prisma (`PRISMA_CONNECTION_LIMIT`, `DB_QUERY_CONCURRENCY`...). + +### Triển khai production +| Workflow | Trigger | Đích | +|---|---|---| +| `ci.yml` | Push/PR vào `main`/`master` | Test + build backend/frontend/admin | +| `deploy_backend.yml` | Thay đổi trong `backend/` | Hugging Face Space `Cuong2004/PhiloMind` | +| `deploy_tts.yml` | Thay đổi trong `tts_worker/` | Hugging Face Space `Cuong2004/PhiloMind_TTSworker` | + +Backend lắng nghe cổng `7860` khi chạy trên Hugging Face Spaces (biến `SPACE_ID`), ngược lại dùng `PORT`/`3001`. Frontend học viên deploy qua Vercel. + +**Lưu ý vận hành đã rút ra thực tế**: dự án dùng `prisma db push` (không dùng migration lịch sử) — mỗi khi `schema.prisma` thay đổi (thêm cột), cần chạy `db push` lên DB production, nếu không backend sẽ lỗi `P2022` (cột không tồn tại) và toàn bộ API trả về lỗi, gây cảm giác "mất kết nối database" dù bản chất là lệch schema. + +Checklist bảo mật & smoke-test sau deploy đầy đủ: xem [`OPERATIONS.md`](OPERATIONS.md). + +--- + +## 17. Kiểm thử & chất lượng + +```bash +cd backend && npm run test -- --runInBand +cd frontend && npm run test -- --run && npm run build +cd admin && npm run test -- --run && npm run build +``` +CI (GitHub Actions) chạy test + build verification cho cả 3 app con ở mỗi push/PR vào `main`/`master`. + +--- + +## 18. Quy trình phát triển & cộng tác + +- Quy trình chuẩn cho mọi thay đổi code: **Issue → Pull Request → Review/Merge** trên GitHub, kèm build + test xanh trước khi merge. +- Nhánh chính: `main`. +- Author commit chuẩn hoá theo tài khoản GitHub thật của người thực hiện thay đổi (không dùng AI co-author trên các commit hướng tới lịch sử đóng góp công khai). +- Nội dung bài học được author bởi ban giảng huấn qua admin portal (JSON `lessonFlow`) hoặc qua các file JSON trong `data/lesson_components/` rồi reseed vào DB. + +--- + +## 19. Giới hạn hiện tại & định hướng + +Những điểm hạn chế/nợ kỹ thuật đã biết tại thời điểm viết tài liệu: + +- **Soạn bài học vẫn ở dạng JSON thô** trong admin portal (`Nodes.jsx`) — chưa có trình soạn thảo trực quan (visual editor) cho `lessonFlow`; rủi ro nhập sai cấu trúc phụ thuộc hoàn toàn vào validator backend. +- **Không có lịch sử migration Prisma** (dùng `db push` trực tiếp) — thuận tiện cho tốc độ phát triển nhưng đòi hỏi kỷ luật vận hành cao khi đổi schema trên production để tránh lệch schema DB thực. +- **Biến môi trường frontend vẫn giữ tiền tố `REACT_APP_*`** dù runtime đã chuyển sang Vite (kế thừa từ giai đoạn dùng Create React App). +- **`lessonMedia` cấp node** được backend/player hỗ trợ nhưng admin UI hiện chủ yếu vẫn nhúng media như component `media` bên trong `lessonFlow` thay vì dùng field riêng. +- Một số component bài học (đặc biệt các loại tương tác kéo-thả/scale cao) từng gặp lỗi hiển thị ở tỉ lệ scale màn hình lớn do CSS `overflow-hidden` lồng sai vị trí — đã rà soát và vá, nhưng cần lưu ý khi thêm component mới. + +--- + +## Tài liệu liên quan + +| Tài liệu | Nội dung | +|---|---| +| [`PROJECT_OVERVIEW.md`](PROJECT_OVERVIEW.md) | Kiến trúc, module, mô hình dữ liệu, luồng chính (bản gốc, tiếng Anh) | +| [`API.md`](API.md) | Danh mục endpoint đầy đủ theo method/path/auth | +| [`LESSON_COMPONENTS.md`](LESSON_COMPONENTS.md) | Đặc tả chi tiết `lessonFlow`/`lessonMedia`, từng loại component, ví dụ JSON | +| [`OPERATIONS.md`](OPERATIONS.md) | Biến môi trường, setup local, pooling Supabase/Postgres, deploy, bảo mật, smoke-test | +| [`DESIGN_SYSTEM.md`](DESIGN_SYSTEM.md) | Nguyên tắc UX/UI, quy ước layout, accessibility | +| [`PROPOSED_COMPONENTS.md`](PROPOSED_COMPONENTS.md) | Đề xuất loại component mới đang xem xét | +| `backend/README.md`, `frontend/README.md`, `admin/README.md`, `tts_worker/README.md` | Tài liệu riêng từng service |