Files
english/Claude.md
2026-04-12 18:54:59 +07:00

14 KiB
Raw Blame History

Claude Project Context — English Learning App (TOEIC Focus)

File này 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. Last updated: Merged all decisions — Phase 1 scaffold done, Phase 24 planned


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 Roadmap: 4 phases — MVP → Auth & Progress → Speaking AI → Full TOEIC


Tech Stack

Frontend

Layer Tech Ghi chú
Framework React + Vite + TypeScript
Routing TanStack Router File-based, type-safe
Server state TanStack Query Fetch, cache, sync API data
Client state Zustand UI state + localStorage persist
Styling Tailwind CSS Desktop-first
UI Components shadcn/ui Dùng khi cần, không bắt buộc

Design System (từ Stitch export)

Token Value
Font Plus Jakarta Sans + Material Symbols Outlined
Primary #2563EB
Success #16A34A
Danger #DC2626
Background #F8FAFC
Card #FFFFFF
Border radius 1216px
Shadow soft, subtle

Responsive Layout

Breakpoint Layout
Desktop (1280px) Sidebar trái cố định (240px) + main content — LAYOUT CHÍNH
Tablet (768px) Sidebar thu gọn icon-only
Mobile (375px) Ẩn sidebar, hiện bottom navigation bar

Backend

Phase Tech Ghi chú
Phase 1 Supabase (PostgreSQL + Edge Functions + JS SDK) Tạm thời, migrate sau
Phase 2+ NestJS + PostgreSQL native Khi có traction

⚠️ Supabase chỉ dùng Phase 1. Schema PostgreSQL thiết kế chuẩn ngay từ đầu để migrate không đau.

AI

Layer Tech Ghi chú
Provider GLM (Z.ai API) Rẻ, OpenAI-compatible format
Endpoint open.bigmodel.cn/api/paas/v4
Model GLM-4 / GLM-4.7
Fallback OpenAI / Claude API Swap dễ vì API compatible
Gọi từ Supabase Edge Function (Phase 1) → NestJS service (Phase 2+) Giấu API key

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)

-- 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+
CREATE TABLE users (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email       TEXT UNIQUE NOT NULL,
  name        TEXT NOT NULL,
  password    TEXT NOT NULL,          -- hashed
  created_at  TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE user_progress (
  id            UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id       UUID REFERENCES users(id),
  type          TEXT,                 -- test | vocab | writing
  reference_id  UUID,
  data          JSONB,
  created_at    TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE writing_submissions (
  id          UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id     UUID REFERENCES users(id),
  content     TEXT NOT NULL,
  feedback    JSONB,
  created_at  TIMESTAMPTZ DEFAULT now()
);

TypeScript Interfaces

interface Question {
  id: string
  part: number
  type: string
  content: string
  options: string[]
  answer: string
  explanation: string
  audioUrl?: string
  imageUrl?: string
}

interface VocabWord {
  id: string
  word: string
  phonetic: string
  meaningVi: string
  topic: 'business' | 'office' | 'travel' | 'finance' | 'hr' | 'marketing'
  example: string
}

interface TestResult {
  testId: string
  part: number
  score: number
  total: number
  duration: number
  answers: { questionId: string; selected: string; correct: boolean }[]
  completedAt: Date
}

interface WritingFeedback {
  score: string
  grammar: string[]
  vocabulary: string[]
  structure: string
  improvedVersion: string
  summary: string
}

// Phase 2+
interface User {
  id: string
  email: string
  name: string
  createdAt: Date
}

Cấu trúc thư mục

src/
├── routes/
│   ├── index.tsx              ← Trang chủ (/)
│   ├── toeic/
│   │   ├── index.tsx          ← Chọn Part (/toeic)
│   │   ├── part.$partId.tsx   ← Config số câu (/toeic/part/$partId)
│   │   ├── session.tsx        ← Làm bài (/toeic/session)
│   │   └── result.tsx         ← Kết quả + đáp án (/toeic/result)
│   ├── writing.tsx            ← AI Writing Checker (/writing)
│   ├── vocab.tsx              ← Flashcard (/vocab)
│   └── auth/                  ← Phase 2
│       ├── login.tsx          ← Đăng nhập (/auth/login)
│       └── register.tsx       ← Đăng ký (/auth/register)
├── components/
│   ├── layout/
│   │   ├── Sidebar.tsx        ← Desktop sidebar
│   │   └── BottomNav.tsx      ← Mobile bottom nav
│   ├── QuestionCard.tsx
│   ├── FlashCard.tsx
│   ├── WritingFeedback.tsx
│   ├── ProgressRing.tsx
│   └── Timer.tsx
├── store/
│   ├── testStore.ts           ← Zustand: trạng thái bài thi
│   ├── vocabStore.ts          ← Zustand: flashcard progress (persist localStorage)
│   └── authStore.ts           ← Zustand: user session (Phase 2)
├── hooks/
│   ├── useQuestions.ts        ← TanStack Query
│   ├── useVocab.ts            ← TanStack Query
│   └── useWritingCheck.ts     ← TanStack Mutation → Edge Function
├── lib/
│   └── supabase.ts            ← Supabase client init
└── utils/
    └── rateLimiter.ts         ← Rate limit 3 lần/ngày/IP (localStorage)

Supabase Edge Function — AI Writing Checker

// supabase/functions/writing-check/index.ts
import { serve } from "https://deno.land/std/http/server.ts"

serve(async (req) => {
  const { content } = await req.json()

  const response = await fetch("https://open.bigmodel.cn/api/paas/v4/chat/completions", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${Deno.env.get("GLM_API_KEY")}`,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      model: "glm-4",
      messages: [
        {
          role: "system",
          content: `You are an expert English writing evaluator for TOEIC/IELTS.
Evaluate the writing and return ONLY valid JSON:
{
  "score": "estimated band score",
  "grammar": ["error + fix"],
  "vocabulary": ["suggestion"],
  "structure": "feedback in Vietnamese",
  "improved_version": "rewritten version",
  "summary": "overall feedback in Vietnamese"
}`
        },
        { role: "user", content }
      ]
    })
  })

  const data = await response.json()
  const result = JSON.parse(data.choices[0].message.content)
  return new Response(JSON.stringify(result), {
    headers: { "Content-Type": "application/json" }
  })
})

Roadmap — 4 Phases


PHASE 1 — MVP (Hiện tại) 🚧

Mục tiêu: Ra sản phẩm web dùng thử không cần login, validate market

Stack: React + Vite + TypeScript + TanStack + Zustand + Tailwind + Supabase + GLM

Tính năng:

  • Luyện đề TOEIC mini test theo từng Part (Part 17)
  • Chọn số câu: 10 / 20 / full part, có đếm giờ
  • Submit → xem điểm + đáp án + giải thích tiếng Việt
  • Lịch sử kết quả + thống kê điểm yếu theo Part (localStorage)
  • AI Writing Checker (GLM, 3 lần/ngày/IP, không cần login)
  • Flashcard từ vựng TOEIC (6 chủ đề, localStorage progress)

Không có:

  • Auth / login
  • Progress sync server
  • Thanh toán
  • Flutter / mobile app
  • Full mock test

Timeline: 5 tuần

Done khi:

  • ≥ 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

PHASE 2 — Auth & Progress

Mục tiêu: Giữ chân user, sync progress server-side, hiểu behavior trước khi monetize

Trigger: Phase 1 có traction — 200+ MAU hoặc feedback tích cực

Stack thay đổi:

  • Migrate Supabase → NestJS + PostgreSQL native
  • Thêm Redis cho cache + session

Guest Access (chưa đăng ký):

  • Xem preview 1 bài test dạng read-only (thấy câu hỏi, không làm được)
  • Không cho submit đáp án, không xem kết quả
  • Hiện modal "Đăng ký để luyện thi" khi cố tương tác
  • Flashcard: xem vài card đầu, bị chặn sau đó
  • AI Writing: không dùng được, hiện CTA đăng ký

Auth — Đăng ký:

  • Form: Tên + Email + Password (chỉ 3 field)
  • Không xác thực email, không OTP, không confirm
  • Đăng ký xong → redirect home luôn

Auth — Đăng nhập:

  • Email + Password
  • Redirect về trang trước hoặc home

Sau khi đăng nhập:

  • Làm bài không giới hạn
  • Progress sync server-side: lịch sử thi, từ vựng, writing submissions
  • Dashboard cá nhân: streak, biểu đồ điểm, điểm yếu theo Part
  • AI Writing: 10 lần/ngày

Không có ở Phase 2:

  • Xác thực email
  • Quên mật khẩu
  • Google / Zalo OAuth
  • Flutter / mobile app
  • Thanh toán / freemium
  • Notification

PHASE 3 — Speaking AI

Mục tiêu: Tăng differentiation, cover kỹ năng Speaking cho IELTS/TOEIC

Trigger: Phase 2 ổn định, user quay lại đều đặn

Tính năng:

  • AI Speaking Coach: record giọng → AI chấm phát âm + so sánh native speaker
  • Luyện IELTS Speaking Part 1/2/3 (mock interview với AI)
  • Shadow reading: nghe → lặp lại → AI so sánh độ chính xác
  • Pronunciation scoring có điểm số và progress chart

Tech mới:

  • Speech-to-text: Whisper API hoặc Google Speech-to-Text
  • Text-to-speech: native audio
  • WebRTC / MediaRecorder API (web)

PHASE 4 — Full TOEIC Mock Test

Mục tiêu: Platform luyện TOEIC toàn diện chuẩn ETS

Trigger: Phase 3 xong, cần nội dung premium

Tính năng:

  • Full TOEIC test chuẩn ETS: 200 câu, 120 phút
  • Audio Listening chuẩn cho Part 14
  • Auto-score: tính điểm 10990 theo bảng quy đổi ETS
  • Phân tích chi tiết: điểm mạnh/yếu từng Part, so sánh lần trước
  • Bộ đề theo năm: ETS 2023, 2024, Actual Test...
  • Đếm ngược đến ngày thi + lịch ôn tập gợi ý

Quyết định kiến trúc quan trọng

Quyết định Lý do
Không auth Phase 1 Giảm scope, validate market trước
Email only Phase 2, không OAuth Đơn giản nhất để build, OAuth Phase 3+
Không xác thực email Phase 2 MVP — giảm friction đăng ký tối đa
Chỉ 3 field đăng ký (tên/email/pass) Friction thấp nhất, đủ để identify user
Guest chỉ xem preview, không làm được Buộc đăng ký để dùng, giúp thu thập user data
Không thanh toán Phase 2 Hiểu behavior trước khi charge tiền
Không Flutter Phase 2 Web đã responsive, mobile app khi có traction rõ ràng
Supabase tạm Phase 1 Ra nhanh hơn 23 tuần, schema chuẩn để migrate sau
GLM thay OpenAI/Claude Rẻ hơn, OpenAI-compatible, swap dễ
Desktop-first (không mobile-first) Target TOEIC learner hay dùng máy tính
TanStack Query + Zustand Server state tách biệt client state rõ ràng
localStorage Phase 1 Đủ cho MVP, không cần backend phức tạp
NestJS Phase 2 Supabase đủ để validate, NestJS khi scale
Speaking AI Phase 3 Cần infra ổn định trước khi làm realtime audio
Full mock test Phase 4 Cần content team + audio, không phải tech problem

Conventions

  • Ngôn ngữ: Tiếng Việt cho UI người dùng, English cho code/comments/type names
  • Giải thích đáp án: Luôn bằng tiếng Việt
  • AI feedback: Nhận xét tổng thể tiếng Việt, ví dụ sửa tiếng Anh
  • Desktop-first: Design và test trên 1280px trước, mobile sau
  • YAGNI / KISS: Không build thứ chưa cần, từng Phase giải quyết từng vấn đề
  • Schema chuẩn ngay từ đầu: Dù dùng Supabase, PostgreSQL schema phải production-ready

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 nếu cần
Latency GLM từ VN cao 🟡 TB Benchmark thực tế, cache response nếu cần
User mất progress (localStorage Phase 1) 🟡 TB Chấp nhận Phase 1, auth Phase 2 giải quyết
Bản quyền đề TOEIC crawl 🟡 TB Seed nhanh, thay bằng nội dung tự soạn dần
Supabase free tier limit 🟢 Thấp 500MB đủ Phase 1, migrate trước khi hit limit
Audio quality Phase 4 🟡 TB Budget cho studio recording hoặc TTS premium