Files
english/Claude.md
2026-04-12 01:06:31 +07:00

278 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 14 (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 (17)
/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 17)
- [ ] 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 critical bug sau 1 tuần beta
---
## Rủi ro đã nhận diện
| Rủi ro | Mức độ | Xử |
|---|---|---|
| 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 | do |
|---|---|
| Không 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 23 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, 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