# Claude Project Context — English Learning App (TOEIC Focus) > File này dùng để cung cấp context đầy đủ cho Claude khi làm việc với dự án. > Cập nhật file này mỗi khi có quyết định kiến trúc mới. --- ## Tổng quan dự án **Loại sản phẩm**: Web app học tiếng Anh / luyện thi TOEIC & IELTS cho người dùng Việt Nam **Target users**: Sinh viên, người đi làm tại Việt Nam cần TOEIC, IELTS, hoặc học tiếng Anh tổng quát **Focus chính**: TOEIC (mở rộng market), sau đó IELTS **Giai đoạn hiện tại**: Phase 1 — MVP, validate market --- ## Mục tiêu Phase 1 - Ra sản phẩm web dùng thử được, **không cần đăng nhập** - Validate 2 tính năng cốt lõi: luyện đề TOEIC + AI writing checker - Test xem có người dùng thật, có traction không - **Không over-engineer** — Supabase tạm thời, đổi sau nếu có traction --- ## Tech Stack ### Frontend | Layer | Tech | Ghi chú | |---|---|---| | Framework | **React** (Vite) | | | Routing | **TanStack Router** | Type-safe routing | | Server state | **TanStack Query** | Fetch, cache, sync API data | | Client state | **Zustand** | UI state, localStorage sync | | Styling | **Tailwind CSS** | Mobile-first | | UI Components | **shadcn/ui** | Dùng khi cần, không bắt buộc | ### Backend (Phase 1 — tạm thời) | Layer | Tech | Ghi chú | |---|---|---| | Database | **Supabase** (PostgreSQL managed) | Free tier, migrate sau | | API | **Supabase JS SDK** | Gọi thẳng từ React | | Server functions | **Supabase Edge Functions** (Deno) | Xử lý AI API call, giấu key | > ⚠️ **Supabase chỉ dùng Phase 1** để ra sản phẩm nhanh. > Phase 2 migrate sang **NestJS + PostgreSQL native** khi có traction. > Schema PostgreSQL thiết kế chuẩn ngay từ đầu để migrate không đau. ### Backend (Phase 2 — kế hoạch) | Layer | Tech | |---|---| | Framework | **NestJS** | | ORM | **Prisma** hoặc **TypeORM** | | Database | **PostgreSQL** (self-hosted) | | Auth | **JWT** + Google OAuth + Zalo OAuth | | Mobile | **Flutter** (iOS + Android) | ### AI | Layer | Tech | Ghi chú | |---|---|---| | Provider | **GLM (Z.ai API)** — `open.bigmodel.cn` | Rẻ, OpenAI-compatible | | Model | **GLM-4** hoặc **GLM-4.7** | Test chất lượng chấm writing | | Fallback | OpenAI / Claude API | Nếu GLM không đủ chất lượng | > GLM API tương thích OpenAI format → swap provider không cần đổi code. ### Deploy | Layer | Tech | |---|---| | Frontend | **Self-hosted server** (có sẵn) | | Backend | **Self-hosted server** (có sẵn) | | Database | Supabase Cloud (Phase 1) → self-hosted PostgreSQL (Phase 2) | --- ## Database Schema (PostgreSQL — Phase 1) ```sql -- Câu hỏi TOEIC CREATE TABLE questions ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), part INT NOT NULL, -- 1 đến 7 type TEXT, -- photo, q&a, incomplete_sentence, etc. content TEXT NOT NULL, -- nội dung câu hỏi / đoạn văn options JSONB, -- ["A. ...", "B. ...", "C. ...", "D. ..."] answer TEXT NOT NULL, -- "A" explanation TEXT, -- giải thích đáp án bằng tiếng Việt audio_url TEXT, -- Part 1–4 (listening) image_url TEXT, -- Part 1 (photos) created_at TIMESTAMPTZ DEFAULT now() ); -- Từ vựng TOEIC CREATE TABLE vocab ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), word TEXT NOT NULL, phonetic TEXT, -- /wɜːrd/ meaning_vi TEXT NOT NULL, -- nghĩa tiếng Việt topic TEXT NOT NULL, -- business | office | travel | finance | hr | marketing example TEXT, -- câu ví dụ tiếng Anh created_at TIMESTAMPTZ DEFAULT now() ); -- Phase 2 sẽ thêm: users, user_progress, writing_submissions, test_sessions ``` --- ## API Design ### Supabase SDK (Phase 1) ```typescript // Lấy câu hỏi theo Part supabase.from('questions').select('*').eq('part', 1).limit(10) // Lấy từ vựng theo chủ đề supabase.from('vocab').select('*').eq('topic', 'business') ``` ### Supabase Edge Functions ``` POST /functions/v1/writing-check Body : { content: string } Return : { score: string, // band score ước tính grammar: string[], // lỗi ngữ pháp + gợi ý sửa vocabulary: string[], // nhận xét từ vựng structure: string, // nhận xét bố cục (tiếng Việt) improved_version: string, // bài viết lại tốt hơn summary: string // tổng nhận xét (tiếng Việt) } ``` --- ## Cấu trúc thư mục (React) ``` src/ ├── pages/ │ ├── Home.tsx ← Landing page + CTA │ ├── ToeicPractice.tsx ← Chọn Part để luyện │ ├── TestSession.tsx ← Làm bài (timer + câu hỏi) │ ├── TestResult.tsx ← Kết quả + giải thích đáp án │ ├── WritingChecker.tsx ← AI Writing Checker │ └── Vocabulary.tsx ← Flashcard từ vựng ├── components/ │ ├── QuestionCard.tsx │ ├── FlashCard.tsx │ ├── WritingFeedback.tsx │ ├── ProgressBar.tsx │ └── Timer.tsx ├── hooks/ │ ├── useQuestions.ts ← TanStack Query: fetch questions │ ├── useVocab.ts ← TanStack Query: fetch vocab │ └── useWritingCheck.ts ← TanStack Mutation: gọi Edge Function ├── store/ │ ├── testStore.ts ← Zustand: trạng thái bài thi │ └── vocabStore.ts ← Zustand: progress flashcard (sync localStorage) ├── lib/ │ └── supabase.ts ← Supabase client init └── utils/ └── rateLimiter.ts ← Rate limit AI Writing (3 lần/ngày/IP, localStorage) ``` --- ## Routes (TanStack Router) ``` / ← Landing page /toeic ← Chọn Part (1–7) /toeic/part/$partId ← Config bài thi (số câu) /toeic/session ← Làm bài /toeic/result ← Kết quả + đáp án /writing ← AI Writing Checker /vocab ← Flashcard (filter theo topic) ``` --- ## Tính năng Phase 1 (đã chốt) ### ✅ 1. Luyện đề TOEIC - Mini test theo từng Part (Part 1 → Part 7) - Chọn số câu: 10 / 20 / full part - Làm bài có đếm giờ - Submit → xem điểm + đáp án đúng/sai + giải thích tiếng Việt - Lịch sử kết quả lưu **localStorage** (Zustand persist) - Thống kê điểm yếu theo Part ### ✅ 2. AI Writing Checker (Core Differentiator) - Nhập bài writing tự do (TOEIC email, IELTS task, general) - Gọi GLM qua Supabase Edge Function (API key an toàn) - Feedback JSON: band score, lỗi ngữ pháp, từ vựng, cấu trúc, bài mẫu - Rate limit: **3 lần / ngày / IP** (không cần login) - Hiển thị feedback có highlight, dễ đọc trên mobile ### ✅ 3. Flashcard Từ vựng TOEIC - 6 chủ đề: Business, Office, Travel, Finance, HR, Marketing - Mỗi card: từ + phiên âm + nghĩa Việt + câu ví dụ - Flip card animation - Đánh dấu: Đã thuộc / Cần ôn - Progress lưu localStorage (Zustand persist) - Filter theo chủ đề --- ## Tính năng KHÔNG có ở Phase 1 | Tính năng | Khi nào có | |---|---| | Đăng nhập / Auth | Phase 2 | | Progress sync server | Phase 2 | | Flutter mobile app | Phase 2 | | NestJS backend | Phase 2 | | Full TOEIC mock test | Phase 2 | | Thanh toán | Phase 2 | | Speaking / Pronunciation AI | Phase 3+ | | Cộng đồng / Forum | Phase 3+ | | Lớp học / Giáo viên | Phase 3+ | --- ## Timeline Phase 1 (5 tuần) | Tuần | Công việc | |---|---| | **1** | Setup Supabase schema + seed đề TOEIC (≥50 câu/part) + React + Vite + Tailwind + TanStack + Zustand | | **2** | UI luyện đề: chọn Part → làm bài → kết quả + giải thích | | **3** | Supabase Edge Function + GLM API → AI Writing Checker + rate limit | | **4** | Flashcard UI + Zustand persist + mobile polish + landing page | | **5** | Bug fix + test mobile thật + deploy lên server + beta ~20 người | --- ## Definition of Done — Phase 1 - [ ] ≥ 50 câu hỏi mỗi Part (Part 1–7) - [ ] AI Writing Checker phản hồi < 5 giây - [ ] Không lỗi hiển thị trên Chrome mobile - [ ] 20+ người dùng thật đã dùng thử - [ ] Không có critical bug sau 1 tuần beta --- ## Rủi ro đã nhận diện | Rủi ro | Mức độ | Xử lý | |---|---|---| | Content đề TOEIC chất lượng thấp (crawl) | 🔴 Cao | Crawl ít + clean kỹ, tự soạn dần để thay thế | | GLM chấm writing không đủ tin cậy | 🟡 TB | Test prompt kỹ, fallback OpenAI-compatible nếu cần | | Latency GLM từ VN cao | 🟡 TB | Benchmark thực tế tuần 3 | | User mất progress (localStorage) | 🟡 TB | Chấp nhận ở MVP, auth Phase 2 giải quyết | | Bản quyền đề TOEIC crawl | 🟡 TB | Dùng để seed nhanh, thay bằng nội dung tự soạn | --- ## Quyết định kiến trúc quan trọng | Quyết định | Lý do | |---|---| | Không có Auth Phase 1 | Giảm scope, user dùng thử không cần tạo tài khoản | | Supabase thay NestJS tạm | Ra nhanh hơn 2–3 tuần, schema chuẩn để migrate sau | | GLM thay OpenAI/Claude | Rẻ hơn đáng kể, API compatible, đủ để test | | Web-only, không Flutter | Tập trung 1 platform, Flutter Phase 2 reuse API | | TanStack Query + Zustand | TanStack cho server state, Zustand cho client/local state | | localStorage cho progress | Đủ cho MVP, không cần backend phức tạp | --- ## Conventions - **Ngôn ngữ**: Tiếng Việt cho UI người dùng, English cho code/comments - **Giải thích đáp án**: Luôn bằng tiếng Việt - **AI feedback**: Mix Việt-Anh (nhận xét tổng thể tiếng Việt, ví dụ sửa tiếng Anh) - **Mobile-first**: Test trên màn hình 375px trước, desktop sau - **YAGNI / KISS**: Không build thứ chưa cần, Phase 1 xong mới nghĩ Phase 2