Initial Commit
This commit is contained in:
391
CLAUDE.md
Normal file
391
CLAUDE.md
Normal file
@@ -0,0 +1,391 @@
|
||||
# Instructions for Claude Code
|
||||
|
||||
## Critical: Specification Adherence
|
||||
|
||||
**YOU MUST READ AND FOLLOW THE SPECIFICATION DOCUMENT FIRST.**
|
||||
|
||||
Before implementing ANY feature, you MUST:
|
||||
1. Read the relevant section in `HANZI-LEARNING-APP-SPECIFICATION.md`
|
||||
2. Follow the specification EXACTLY as written
|
||||
3. Do NOT make up alternatives or "improvements" without explicit approval
|
||||
4. Do NOT skip steps or combine milestones without explicit approval
|
||||
5. Do NOT change the technology stack
|
||||
6. Do NOT modify the data models without approval
|
||||
|
||||
**The specification is the single source of truth. Deviations require explicit user approval.**
|
||||
|
||||
---
|
||||
|
||||
## Project Overview
|
||||
|
||||
This is **MemoHanzi** (记汉字 - "Remember Hanzi"), a self-hosted Hanzi (Chinese character) learning application using spaced repetition (SM-2 algorithm).
|
||||
|
||||
**Tech Stack (DO NOT CHANGE):**
|
||||
- Next.js 16 with TypeScript and App Router
|
||||
- PostgreSQL 18 with Prisma ORM
|
||||
- NextAuth.js v5 for authentication
|
||||
- Tailwind CSS for styling
|
||||
- Docker Compose for deployment with Nginx reverse proxy
|
||||
- Vitest for unit/integration tests
|
||||
- Playwright for E2E tests
|
||||
|
||||
**Key Files to Reference:**
|
||||
- `/HANZI-LEARNING-APP-SPECIFICATION.md` - Complete specification (READ THIS FIRST)
|
||||
- Note: Project name is **MemoHanzi**, use `memohanzi` for directory/database names
|
||||
- `/prisma/schema.prisma` - Database schema (once created)
|
||||
- `/src/actions/*` - Server Actions
|
||||
- `/src/lib/learning/sm2.ts` - SM-2 algorithm (critical implementation)
|
||||
|
||||
---
|
||||
|
||||
## Implementation Rules
|
||||
|
||||
### Rule 1: Follow the Milestones Sequentially
|
||||
|
||||
The specification defines 12 milestones (weeks). You MUST:
|
||||
- Complete milestones in order (1 → 2 → 3 → ...)
|
||||
- Finish all tasks in a milestone before moving to the next
|
||||
- Ask for approval before starting each new milestone
|
||||
- Report completion status for each milestone
|
||||
|
||||
**Current Milestone:** 1
|
||||
|
||||
### Rule 2: Database Schema is Fixed
|
||||
|
||||
The Prisma schema in the specification is FINAL. You MUST:
|
||||
- Implement the schema EXACTLY as specified
|
||||
- Include ALL models: Language, Hanzi, HanziForm, HanziTranscription, HanziMeaning, HanziHSKLevel, HanziPOS, HanziClassifier, User, UserPreference, Account, Session, VerificationToken, Collection, CollectionItem, UserHanziProgress, LearningSession, SessionReview
|
||||
- Include ALL enums: UserRole, CharacterDisplay, Difficulty
|
||||
- Include ALL fields and relations as specified
|
||||
- Do NOT add extra fields without approval
|
||||
- Do NOT simplify or "optimize" the schema
|
||||
|
||||
### Rule 3: SM-2 Algorithm Must Be Exact
|
||||
|
||||
The SM-2 algorithm implementation is critical. You MUST:
|
||||
- Use the EXACT formulas from Section 5 of the specification
|
||||
- Initial values: easeFactor=2.5, interval=1, consecutiveCorrect=0
|
||||
- Implement correct answer logic EXACTLY as specified
|
||||
- Implement incorrect answer logic EXACTLY as specified
|
||||
- Implement card selection algorithm EXACTLY as specified
|
||||
- Write comprehensive unit tests (90%+ coverage)
|
||||
|
||||
**Do NOT:**
|
||||
- Use a different spaced repetition algorithm
|
||||
- "Improve" or "simplify" the algorithm
|
||||
- Skip any calculation steps
|
||||
|
||||
### Rule 4: Server Actions Only (No REST API)
|
||||
|
||||
All data operations use Next.js Server Actions. You MUST:
|
||||
- Implement Server Actions as specified in Section 4
|
||||
- Return the standard `ActionResult<T>` type
|
||||
- Validate with Zod schemas
|
||||
- Check authentication/authorization
|
||||
- Use `revalidatePath()` after mutations
|
||||
- Do NOT create REST API endpoints (except for NextAuth)
|
||||
|
||||
### Rule 5: Follow the UI/UX Specification
|
||||
|
||||
Page structure is defined in Section 6. You MUST:
|
||||
- Create pages at the EXACT routes specified
|
||||
- Implement the specified components
|
||||
- Use the specified layouts (mobile-first, responsive)
|
||||
- Include ALL specified features per page
|
||||
- Do NOT create pages not in the specification
|
||||
|
||||
### Rule 6: Testing is Mandatory
|
||||
|
||||
For each feature you implement:
|
||||
- Write unit tests for business logic (70% coverage minimum)
|
||||
- Write integration tests for Server Actions
|
||||
- Write E2E tests for critical user flows
|
||||
- All tests must pass before moving to next milestone
|
||||
|
||||
### Rule 7: Security Requirements are Non-Negotiable
|
||||
|
||||
You MUST implement ALL security measures:
|
||||
- Password hashing with bcrypt (10 rounds) and salt
|
||||
- NextAuth.js session management
|
||||
- Middleware for route protection
|
||||
- Role-based access control in Server Actions
|
||||
- Input validation with Zod (client AND server)
|
||||
- No sensitive data in logs or error messages
|
||||
- Follow the security checklist in Section 11
|
||||
|
||||
### Rule 8: Docker Configuration is Fixed
|
||||
|
||||
Use the EXACT Docker setup from Section 10:
|
||||
- Three containers: nginx, app, postgres
|
||||
- PostgreSQL 18 (not other versions)
|
||||
- Nginx for reverse proxy with rate limiting
|
||||
- Do NOT change the docker-compose.yml structure without approval
|
||||
|
||||
---
|
||||
|
||||
## When You're Unsure
|
||||
|
||||
If you encounter ANY of these situations:
|
||||
|
||||
❌ The specification is unclear
|
||||
❌ You think there's a better approach
|
||||
❌ You want to add a feature not in the spec
|
||||
❌ You want to change the tech stack
|
||||
❌ You want to simplify something
|
||||
❌ You're not sure how to implement something
|
||||
|
||||
**STOP and ASK THE USER first. Do NOT proceed with assumptions.**
|
||||
|
||||
---
|
||||
|
||||
## Milestone Checklist Template
|
||||
|
||||
Before claiming a milestone is complete, verify:
|
||||
|
||||
**Milestone [N]: [Name]**
|
||||
- [ ] All tasks from specification completed
|
||||
- [ ] Code follows specification exactly
|
||||
- [ ] No deviations from specified approach
|
||||
- [ ] Tests written and passing
|
||||
- [ ] Codebase builds with docker compose
|
||||
- [ ] Security requirements met
|
||||
- [ ] Documentation updated
|
||||
- [ ] User approval obtained
|
||||
|
||||
---
|
||||
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
### ❌ DON'T DO THIS:
|
||||
|
||||
1. **"I'll use a simpler data model"** → NO. Use the exact schema specified.
|
||||
2. **"I'll implement REST API instead of Server Actions"** → NO. Server Actions only.
|
||||
3. **"I'll use a different algorithm"** → NO. SM-2 as specified.
|
||||
4. **"I'll skip tests for now"** → NO. Tests are mandatory.
|
||||
5. **"I'll use Next.js 15 instead"** → NO. Next.js 16 as specified.
|
||||
6. **"I'll combine these two milestones"** → NO. Follow the sequence.
|
||||
7. **"I'll add this nice feature"** → NO. Only spec features in MVP.
|
||||
|
||||
### ✅ DO THIS:
|
||||
|
||||
1. Read the specification section before implementing
|
||||
2. Ask for clarification if unclear
|
||||
3. Implement exactly as specified
|
||||
4. Write tests as you go
|
||||
5. Report progress and completion
|
||||
6. Ask before deviating
|
||||
7. Don't be overly friendly
|
||||
|
||||
---
|
||||
|
||||
## Startup Checklist
|
||||
|
||||
When starting implementation:
|
||||
|
||||
1. [ ] Read the complete specification document
|
||||
2. [ ] Confirm understanding of the tech stack
|
||||
3. [ ] Confirm understanding of the milestone approach
|
||||
4. [ ] Ask user which milestone to start with
|
||||
5. [ ] Review that milestone's tasks in detail
|
||||
6. [ ] Begin implementation following the specification
|
||||
|
||||
---
|
||||
|
||||
## Data Import Reference
|
||||
|
||||
When implementing import (Milestone 3), remember:
|
||||
|
||||
**HSK JSON Source:** https://github.com/drkameleon/complete-hsk-vocabulary/
|
||||
|
||||
**Required Fields:**
|
||||
- simplified (required)
|
||||
- forms[].traditional (required)
|
||||
- forms[].transcriptions.pinyin (required)
|
||||
- forms[].meanings[] (required, at least one)
|
||||
|
||||
**Optional Fields:**
|
||||
- radical, level[], frequency, pos[], classifiers[]
|
||||
- Additional transcriptions (numeric, wadegiles, etc.)
|
||||
|
||||
**CSV Format:**
|
||||
```
|
||||
simplified,traditional,pinyin,meaning,hsk_level,radical,frequency,pos,classifiers
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## SM-2 Algorithm Quick Reference
|
||||
|
||||
**CRITICAL: Use these EXACT formulas**
|
||||
|
||||
### On Correct Answer:
|
||||
```javascript
|
||||
if (consecutiveCorrect === 0) {
|
||||
interval = 1
|
||||
} else if (consecutiveCorrect === 1) {
|
||||
interval = 6
|
||||
} else {
|
||||
interval = Math.round(interval * easeFactor)
|
||||
}
|
||||
easeFactor = easeFactor + 0.1
|
||||
consecutiveCorrect++
|
||||
nextReviewDate = now + interval days
|
||||
```
|
||||
|
||||
### On Incorrect Answer:
|
||||
```javascript
|
||||
interval = 1
|
||||
consecutiveCorrect = 0
|
||||
nextReviewDate = now + 1 day
|
||||
easeFactor = Math.max(1.3, easeFactor - 0.2)
|
||||
```
|
||||
|
||||
**Test this thoroughly with unit tests!**
|
||||
|
||||
---
|
||||
|
||||
## Progress Reporting Format
|
||||
|
||||
When reporting progress, use this format:
|
||||
|
||||
```
|
||||
## Milestone [N] Progress
|
||||
|
||||
**Status:** [In Progress / Completed / Blocked]
|
||||
|
||||
**Completed Tasks:**
|
||||
- [x] Task 1
|
||||
- [x] Task 2
|
||||
|
||||
**In Progress:**
|
||||
- [ ] Task 3 (50% done)
|
||||
|
||||
**Remaining:**
|
||||
- [ ] Task 4
|
||||
- [ ] Task 5
|
||||
|
||||
**Questions/Issues:**
|
||||
- [List any blockers or questions]
|
||||
|
||||
**Deviations from Spec:**
|
||||
- [List any deviations - should be NONE without approval]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Naming Conventions
|
||||
|
||||
Follow these conventions:
|
||||
- Server Actions: `src/actions/[domain].ts` (e.g., `auth.ts`, `learning.ts`)
|
||||
- Components: `src/components/[category]/[ComponentName].tsx`
|
||||
- Tests: Co-located with source as `[filename].test.ts`
|
||||
- E2E tests: `e2e/[feature].spec.ts`
|
||||
|
||||
---
|
||||
|
||||
## Prisma Workflow
|
||||
|
||||
When working with the database:
|
||||
|
||||
```bash
|
||||
# Create migration
|
||||
npx prisma migrate dev --name descriptive_name
|
||||
|
||||
# Generate Prisma Client (after schema changes)
|
||||
npx prisma generate
|
||||
|
||||
# Seed database
|
||||
npx prisma db seed
|
||||
|
||||
# View data
|
||||
npx prisma studio
|
||||
```
|
||||
|
||||
**IMPORTANT:** Never edit migration files manually after they're created.
|
||||
|
||||
---
|
||||
|
||||
## Testing Commands
|
||||
|
||||
```bash
|
||||
# Unit tests
|
||||
npm run test:unit
|
||||
|
||||
# Integration tests
|
||||
npm run test:integration
|
||||
|
||||
# E2E tests
|
||||
npm run test:e2e
|
||||
|
||||
# All tests
|
||||
npm run test:ci
|
||||
|
||||
# Watch mode (during development)
|
||||
npm run test:watch
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# Communication Guidelines
|
||||
|
||||
## Avoid Sycophantic Language
|
||||
- **NEVER** use phrases like "You're absolutely right!", "You're absolutely correct!", "Excellent point!", or similar flattery
|
||||
- **NEVER** validate statements as "right" when the user didn't make a factual claim that could be evaluated
|
||||
- **NEVER** use general praise or validation as conversational filler
|
||||
- **NEVER** state that the code works now or a fix has been successfully implemented without building and verifying it first
|
||||
|
||||
## Appropriate Acknowledgments
|
||||
Use brief, factual acknowledgments only to confirm understanding of instructions:
|
||||
- "Got it."
|
||||
- "Ok, that makes sense."
|
||||
- "I understand."
|
||||
- "I see the issue."
|
||||
|
||||
These should only be used when:
|
||||
1. You genuinely understand the instruction and its reasoning
|
||||
2. The acknowledgment adds clarity about what you'll do next
|
||||
3. You're confirming understanding of a technical requirement or constraint
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Inappropriate (Sycophantic)
|
||||
User: "Yes please."
|
||||
Assistant: "You're absolutely right! That's a great decision."
|
||||
|
||||
User: "Let's remove this unused code."
|
||||
Assistant: "Excellent point! You're absolutely correct that we should clean this up."
|
||||
|
||||
### ✅ Appropriate (Brief Acknowledgment)
|
||||
User: "Yes please."
|
||||
Assistant: "Got it." [proceeds with the requested action]
|
||||
|
||||
User: "Let's remove this unused code."
|
||||
Assistant: "I'll remove the unused code path." [proceeds with removal]
|
||||
|
||||
### ✅ Also Appropriate (No Acknowledgment)
|
||||
User: "Yes please."
|
||||
Assistant: [proceeds directly with the requested action]
|
||||
|
||||
## Rationale
|
||||
- Maintains professional, technical communication
|
||||
- Avoids artificial validation of non-factual statements
|
||||
- Focuses on understanding and execution rather than praise
|
||||
- Prevents misrepresenting user statements as claims that could be "right" or "wrong"
|
||||
|
||||
---
|
||||
|
||||
## Final Reminder
|
||||
|
||||
**The specification document is LAW.**
|
||||
|
||||
If something in this CLAUDE.md file conflicts with the specification, the specification wins.
|
||||
|
||||
When in doubt:
|
||||
1. Check the specification
|
||||
2. If still unclear, ASK THE USER
|
||||
3. Do NOT make assumptions
|
||||
4. Do NOT deviate without approval
|
||||
|
||||
Your goal is to implement the specification accurately, not to improve it or take shortcuts.
|
||||
|
||||
**Good luck, and stick to the spec!** 🎯
|
||||
594
HANZI-LEARNING-APP-SPECIFICATION.md
Normal file
594
HANZI-LEARNING-APP-SPECIFICATION.md
Normal file
@@ -0,0 +1,594 @@
|
||||
# MemoHanzi - Implementation Specification
|
||||
|
||||
**Version:** 1.0
|
||||
**Status:** Ready for Implementation
|
||||
**Target:** Claude Code
|
||||
**Application Name:** MemoHanzi (记汉字 - "Remember Hanzi")
|
||||
|
||||
---
|
||||
|
||||
## Quick Start Summary
|
||||
|
||||
**What:** MemoHanzi is a self-hosted web app for learning Chinese characters (hanzi) using spaced repetition (SM-2 algorithm)
|
||||
|
||||
**Tech Stack:**
|
||||
- Next.js 16 (TypeScript, App Router, Server Actions)
|
||||
- PostgreSQL 18 + Prisma ORM
|
||||
- NextAuth.js v5 for authentication
|
||||
- Docker Compose deployment with Nginx reverse proxy
|
||||
- Tailwind CSS, React Hook Form, Zod validation, Recharts
|
||||
|
||||
**MVP Timeline:** 10-12 weeks
|
||||
|
||||
---
|
||||
|
||||
## 1. Core Features (MVP)
|
||||
|
||||
### User Features
|
||||
- ✅ Registration/Login with email & password
|
||||
- ✅ Create and manage personal hanzi collections
|
||||
- ✅ Browse and use global HSK-level collections
|
||||
- ✅ Learning sessions with 4-choice pinyin quiz
|
||||
- ✅ SM-2 spaced repetition algorithm
|
||||
- ✅ Progress tracking & statistics dashboard
|
||||
- ✅ Search hanzi database (by character, pinyin, meaning)
|
||||
- ✅ User preferences (language, display options, learning settings)
|
||||
|
||||
### Admin Features
|
||||
- ✅ Import hanzi data (JSON/CSV from HSK vocabulary source)
|
||||
- ✅ Manage global collections
|
||||
- ✅ User management (roles, activation)
|
||||
|
||||
---
|
||||
|
||||
## 2. System Architecture
|
||||
|
||||
### Deployment Stack
|
||||
```
|
||||
[Nginx Reverse Proxy:80/443]
|
||||
↓ HTTPS/Rate Limiting/Caching
|
||||
[Next.js App:3000]
|
||||
↓ Prisma ORM
|
||||
[PostgreSQL:5432]
|
||||
```
|
||||
|
||||
### Project Structure
|
||||
```
|
||||
memohanzi/
|
||||
├── src/
|
||||
│ ├── app/ # Next.js App Router
|
||||
│ │ ├── (auth)/ # Login, register
|
||||
│ │ ├── (app)/ # Dashboard, learn, collections, hanzi, progress, settings
|
||||
│ │ └── (admin)/ # Admin pages
|
||||
│ ├── actions/ # Server Actions (auth, collections, hanzi, learning, etc.)
|
||||
│ ├── components/ # React components
|
||||
│ ├── lib/ # Utils (SM-2 algorithm, parsers, validation)
|
||||
│ └── types/ # TypeScript types
|
||||
├── prisma/
|
||||
│ └── schema.prisma # Database schema
|
||||
├── docker/
|
||||
│ ├── Dockerfile
|
||||
│ └── nginx.conf
|
||||
└── docker-compose.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Database Schema (Prisma)
|
||||
|
||||
### Core Models
|
||||
|
||||
**Language** - Stores supported translation languages
|
||||
- Fields: code (ISO 639-1), name, nativeName, isActive
|
||||
|
||||
**Hanzi** - Base hanzi information
|
||||
- Fields: simplified (unique), radical, frequency
|
||||
- Relations: forms, hskLevels, partsOfSpeech, userProgress, collectionItems
|
||||
|
||||
**HanziForm** - Traditional variants
|
||||
- Fields: hanziId, traditional, isDefault
|
||||
- Relations: transcriptions, meanings, classifiers
|
||||
|
||||
**HanziTranscription** - Multiple transcription types
|
||||
- Fields: formId, type (pinyin/numeric/wadegiles/etc), value
|
||||
|
||||
**HanziMeaning** - Multi-language meanings
|
||||
- Fields: formId, languageId, meaning, orderIndex
|
||||
|
||||
**HanziHSKLevel** - HSK level tags
|
||||
- Fields: hanziId, level (e.g., "new-1", "old-3")
|
||||
|
||||
**HanziPOS** - Parts of speech
|
||||
- Fields: hanziId, pos (n/v/adj/etc)
|
||||
|
||||
**HanziClassifier** - Measure words
|
||||
- Fields: formId, classifier
|
||||
|
||||
### User & Auth Models
|
||||
|
||||
**User**
|
||||
- Fields: email, password (hashed), name, role (USER/ADMIN/MODERATOR), isActive
|
||||
- Relations: collections, hanziProgress, preferences, sessions
|
||||
|
||||
**UserPreference**
|
||||
- Fields: preferredLanguageId, characterDisplay (SIMPLIFIED/TRADITIONAL/BOTH), transcriptionType, cardsPerSession, dailyGoal, removalThreshold, allowManualDifficulty
|
||||
|
||||
**Account, Session, VerificationToken** - NextAuth.js standard models
|
||||
|
||||
### Learning Models
|
||||
|
||||
**Collection**
|
||||
- Fields: name, description, isGlobal, createdBy, isPublic
|
||||
- Relations: items (CollectionItem join table)
|
||||
|
||||
**CollectionItem** - Join table
|
||||
- Fields: collectionId, hanziId, orderIndex
|
||||
|
||||
**UserHanziProgress** - Tracks learning per hanzi
|
||||
- Fields: userId, hanziId, correctCount, incorrectCount, consecutiveCorrect
|
||||
- SM-2 fields: easeFactor (default 2.5), interval (default 1), nextReviewDate
|
||||
- Manual override: manualDifficulty (EASY/MEDIUM/HARD/SUSPENDED)
|
||||
|
||||
**LearningSession** - Track study sessions
|
||||
- Fields: userId, startedAt, endedAt, cardsReviewed, correctAnswers, incorrectAnswers, collectionId
|
||||
- Relations: reviews (SessionReview)
|
||||
|
||||
**SessionReview** - Individual card reviews
|
||||
- Fields: sessionId, hanziId, isCorrect, responseTime
|
||||
|
||||
---
|
||||
|
||||
## 4. Server Actions API
|
||||
|
||||
All actions return: `{ success: boolean, data?: T, message?: string, errors?: Record<string, string[]> }`
|
||||
|
||||
### Authentication (`src/actions/auth.ts`)
|
||||
- `register(email, password, name)` - Create account
|
||||
- `login(email, password)` - Authenticate
|
||||
- `logout()` - End session
|
||||
- `updatePassword(current, new)` - Change password
|
||||
- `updateProfile(name, email, image)` - Update user
|
||||
|
||||
### Collections (`src/actions/collections.ts`)
|
||||
- `createCollection(name, description, isPublic)` - New collection
|
||||
- `updateCollection(id, data)` - Modify (owner/admin only)
|
||||
- `deleteCollection(id)` - Remove (owner/admin only)
|
||||
- `getCollection(id)` - Get with hanzi
|
||||
- `getUserCollections()` - List user's collections
|
||||
- `getGlobalCollections()` - List HSK collections
|
||||
- `addHanziToCollection(collectionId, hanziIds[])` - Add hanzi
|
||||
- `removeHanziFromCollection(collectionId, hanziId)` - Remove hanzi
|
||||
|
||||
### Hanzi (`src/actions/hanzi.ts`)
|
||||
- `searchHanzi(query, hskLevel?, limit, offset)` - Search database (public)
|
||||
- `getHanzi(id)` - Get details (public)
|
||||
- `getHanziBySimplified(char)` - Lookup by character (public)
|
||||
|
||||
### Learning (`src/actions/learning.ts`)
|
||||
- `startLearningSession(collectionId?, cardsCount)` - Begin session, returns cards
|
||||
- `submitAnswer(sessionId, hanziId, selected, correct, time)` - Record answer, updates SM-2
|
||||
- `endSession(sessionId)` - Complete, return summary
|
||||
- `getDueCards()` - Get counts (now, today, week)
|
||||
- `updateCardDifficulty(hanziId, difficulty)` - Manual override
|
||||
- `removeFromLearning(hanziId)` - Stop learning card
|
||||
|
||||
### Progress (`src/actions/progress.ts`)
|
||||
- `getUserProgress(dateRange?)` - Overall stats & charts
|
||||
- `getHanziProgress(hanziId)` - Individual hanzi stats
|
||||
- `getLearningSessions(limit?)` - Session history
|
||||
- `getStatistics()` - Dashboard stats
|
||||
- `resetHanziProgress(hanziId)` - Reset card
|
||||
|
||||
### Preferences (`src/actions/preferences.ts`)
|
||||
- `getPreferences()` - Get settings
|
||||
- `updatePreferences(data)` - Update settings
|
||||
- `getAvailableLanguages()` - List languages
|
||||
|
||||
### Admin (`src/actions/admin.ts`)
|
||||
- `createGlobalCollection(name, description, hskLevel)` - HSK collection
|
||||
- `importHanzi(fileData, format)` - Bulk import (JSON/CSV)
|
||||
- `getImportHistory()` - Past imports
|
||||
- `getUserManagement(page, pageSize)` - List users
|
||||
- `updateUserRole(userId, role)` - Change role
|
||||
- `toggleUserStatus(userId)` - Activate/deactivate
|
||||
|
||||
---
|
||||
|
||||
## 5. SM-2 Algorithm Implementation
|
||||
|
||||
### Initial Values
|
||||
- easeFactor: 2.5
|
||||
- interval: 1 day
|
||||
- consecutiveCorrect: 0
|
||||
|
||||
### On Correct Answer
|
||||
```javascript
|
||||
if (consecutiveCorrect === 0) {
|
||||
interval = 1
|
||||
} else if (consecutiveCorrect === 1) {
|
||||
interval = 6
|
||||
} else {
|
||||
interval = Math.round(interval * easeFactor)
|
||||
}
|
||||
|
||||
easeFactor = easeFactor + 0.1 // Can adjust based on quality
|
||||
consecutiveCorrect++
|
||||
nextReviewDate = now + interval days
|
||||
```
|
||||
|
||||
### On Incorrect Answer
|
||||
```javascript
|
||||
interval = 1
|
||||
consecutiveCorrect = 0
|
||||
nextReviewDate = now + 1 day
|
||||
easeFactor = Math.max(1.3, easeFactor - 0.2)
|
||||
```
|
||||
|
||||
### Card Selection
|
||||
1. Query: `WHERE nextReviewDate <= now AND userId = currentUser`
|
||||
2. Apply manual difficulty (SUSPENDED = exclude, HARD = priority, EASY = depriority)
|
||||
3. Sort: nextReviewDate ASC, incorrectCount DESC, consecutiveCorrect ASC
|
||||
4. Limit to user's cardsPerSession
|
||||
5. If not enough, add new cards from collections
|
||||
|
||||
### Wrong Answer Generation
|
||||
- Select 3 random incorrect pinyin from same HSK level
|
||||
- Ensure no duplicates
|
||||
- Randomize order (Fisher-Yates shuffle)
|
||||
|
||||
---
|
||||
|
||||
## 6. UI/UX Pages
|
||||
|
||||
### Public
|
||||
- `/` - Landing page
|
||||
- `/login` - Login form
|
||||
- `/register` - Registration form
|
||||
|
||||
### Authenticated
|
||||
- `/dashboard` - Due cards, progress widgets, recent activity, quick start
|
||||
- `/learn/[collectionId]` - Learning session with cards
|
||||
- `/collections` - List all collections (global + user's)
|
||||
- `/collections/[id]` - Collection detail, hanzi list, edit
|
||||
- `/collections/new` - Create collection
|
||||
- `/hanzi` - Search hanzi (filters, pagination)
|
||||
- `/hanzi/[id]` - Hanzi detail (all transcriptions, meanings, etc)
|
||||
- `/progress` - Charts, stats, session history
|
||||
- `/settings` - User preferences
|
||||
|
||||
### Admin
|
||||
- `/admin/collections` - Manage global collections
|
||||
- `/admin/hanzi` - Manage hanzi database
|
||||
- `/admin/import` - Import data (JSON/CSV upload)
|
||||
- `/admin/users` - User management
|
||||
|
||||
### Key UI Components
|
||||
- **LearningCard**: Large hanzi, 4 pinyin options in 2x2 grid, progress bar
|
||||
- **AnswerFeedback**: Green/red feedback, show correct answer, streak, removal suggestion
|
||||
- **CollectionCard**: Name, count, progress, quick actions
|
||||
- **DashboardWidgets**: Due cards, daily progress, streak, recent activity
|
||||
- **Charts**: Activity heatmap, accuracy line chart, HSK breakdown bar chart
|
||||
|
||||
### Design
|
||||
- Mobile-first responsive
|
||||
- Dark mode support
|
||||
- Tailwind CSS
|
||||
- Keyboard shortcuts (1-4 for answers, Space to continue)
|
||||
- WCAG 2.1 AA accessibility
|
||||
|
||||
---
|
||||
|
||||
## 7. Data Import Formats
|
||||
|
||||
### HSK JSON (from github.com/drkameleon/complete-hsk-vocabulary)
|
||||
```json
|
||||
{
|
||||
"simplified": "爱好",
|
||||
"radical": "爫",
|
||||
"level": ["new-1", "old-3"],
|
||||
"frequency": 4902,
|
||||
"pos": ["n", "v"],
|
||||
"forms": [{
|
||||
"traditional": "愛好",
|
||||
"transcriptions": {
|
||||
"pinyin": "ài hào",
|
||||
"numeric": "ai4 hao4"
|
||||
},
|
||||
"meanings": ["to like; hobby"],
|
||||
"classifiers": ["个"]
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
### CSV Format
|
||||
```csv
|
||||
simplified,traditional,pinyin,meaning,hsk_level,radical,frequency,pos,classifiers
|
||||
爱好,愛好,ài hào,"to like; hobby",new-1,爫,4902,"n,v",个
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Testing Strategy
|
||||
|
||||
### Unit Tests (70% coverage target)
|
||||
- **SM-2 algorithm** - All calculation paths
|
||||
- **Card selection logic** - Sorting, filtering, limits
|
||||
- **Parsers** - JSON/CSV parsing, error handling
|
||||
- **Validation schemas** - Zod schemas
|
||||
|
||||
### Integration Tests (80% of Server Actions)
|
||||
- Auth actions with database
|
||||
- Learning flow (start session, submit answers, end session)
|
||||
- Collection CRUD
|
||||
- Import process
|
||||
|
||||
### E2E Tests (Critical paths)
|
||||
- Complete learning session
|
||||
- Create collection and add hanzi
|
||||
- Search hanzi
|
||||
- Admin import
|
||||
- Auth flow
|
||||
|
||||
**Tools:** Vitest (unit/integration), Playwright (E2E)
|
||||
|
||||
---
|
||||
|
||||
## 9. Development Milestones
|
||||
|
||||
### Week 1: Foundation
|
||||
- Setup Next.js 16 project
|
||||
- Configure Prisma + PostgreSQL
|
||||
- Setup Docker Compose
|
||||
- Create all data models
|
||||
- Configure NextAuth.js
|
||||
|
||||
### Week 2: Authentication
|
||||
- Registration/login pages
|
||||
- Middleware protection
|
||||
- User preferences
|
||||
- Integration tests
|
||||
|
||||
### Week 3-4: Data Import
|
||||
- Admin role middleware
|
||||
- HSK JSON parser
|
||||
- CSV parser
|
||||
- Import UI and actions
|
||||
- Test with real HSK data
|
||||
|
||||
### Week 5: Collections
|
||||
- Collections CRUD
|
||||
- Add/remove hanzi
|
||||
- Global HSK collections
|
||||
|
||||
### Week 5: Hanzi Search
|
||||
- Search page
|
||||
- Filters (HSK level)
|
||||
- Hanzi detail view
|
||||
- Pagination
|
||||
|
||||
### Week 6: SM-2 Algorithm
|
||||
- Implement algorithm
|
||||
- Card selection logic
|
||||
- Progress tracking
|
||||
- Unit tests (90%+ coverage)
|
||||
|
||||
### Week 7-8: Learning Interface
|
||||
- Learning session pages
|
||||
- Card component
|
||||
- Answer submission
|
||||
- Feedback UI
|
||||
- Session summary
|
||||
- Keyboard shortcuts
|
||||
- E2E tests
|
||||
|
||||
### Week 9: Dashboard & Progress
|
||||
- Dashboard widgets
|
||||
- Progress page
|
||||
- Charts (Recharts)
|
||||
- Statistics calculations
|
||||
|
||||
### Week 10: UI Polish
|
||||
- Responsive layouts
|
||||
- Mobile navigation
|
||||
- Dark mode
|
||||
- Loading/empty states
|
||||
- Toast notifications
|
||||
- Accessibility improvements
|
||||
|
||||
### Week 11: Testing & Docs
|
||||
- Complete test coverage
|
||||
- E2E tests for all critical flows
|
||||
- README and documentation
|
||||
- Security audit
|
||||
|
||||
### Week 12: Deployment
|
||||
- Production environment
|
||||
- Docker deployment
|
||||
- SSL certificates
|
||||
- Database backup
|
||||
- Import HSK data
|
||||
- Final testing
|
||||
|
||||
---
|
||||
|
||||
## 10. Docker Configuration
|
||||
|
||||
### docker-compose.yml
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
ports: ["80:80", "443:443"]
|
||||
volumes:
|
||||
- ./docker/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./docker/ssl:/etc/nginx/ssl:ro
|
||||
depends_on: [app]
|
||||
|
||||
app:
|
||||
build: .
|
||||
expose: ["3000"]
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://memohanzi_user:password@postgres:5432/memohanzi_db
|
||||
- NEXTAUTH_URL=https://yourdomain.com
|
||||
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
|
||||
postgres:
|
||||
image: postgres:18-alpine
|
||||
environment:
|
||||
POSTGRES_USER: memohanzi_user
|
||||
POSTGRES_PASSWORD: password
|
||||
POSTGRES_DB: memohanzi_db
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U hanzi_user"]
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
```bash
|
||||
# .env.local
|
||||
DATABASE_URL="postgresql://memohanzi_user:password@localhost:5432/memohanzi_db"
|
||||
NEXTAUTH_URL="http://localhost:3000"
|
||||
NEXTAUTH_SECRET="generate-with-openssl-rand-base64-32"
|
||||
NODE_ENV="development"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. Security Checklist
|
||||
|
||||
- [ ] Passwords hashed with bcrypt (10 rounds)
|
||||
- [ ] Session tokens httpOnly, sameSite
|
||||
- [ ] CSRF protection (NextAuth.js)
|
||||
- [ ] Rate limiting (Nginx)
|
||||
- [ ] Input validation (Zod, server-side)
|
||||
- [ ] SQL injection prevented (Prisma)
|
||||
- [ ] XSS prevention (React escaping)
|
||||
- [ ] HTTPS enforced (Nginx)
|
||||
- [ ] Secure headers (Nginx)
|
||||
- [ ] Role-based access enforced server-side
|
||||
- [ ] No sensitive data in logs
|
||||
- [ ] Environment variables for secrets
|
||||
|
||||
---
|
||||
|
||||
## 12. Phase 2 Features
|
||||
|
||||
1. **Additional Languages** - Multi-language support for meanings
|
||||
2. **Learning Modes** - Radical identification, hanzi-to-meaning, meaning-to-hanzi, tone practice
|
||||
3. **Autocomplete Data** - Auto-fill missing hanzi info from APIs
|
||||
4. **User Suggestions** - Allow users to report/suggest corrections
|
||||
|
||||
---
|
||||
|
||||
## 13. Phase 3 Ideas
|
||||
|
||||
- Writing practice (stroke order validation)
|
||||
- Social features (public collections, sharing)
|
||||
- Gamification (streaks, badges, leaderboards)
|
||||
- Mobile apps (React Native)
|
||||
- Audio pronunciation
|
||||
- Example sentences
|
||||
- Advanced SRS algorithms
|
||||
|
||||
---
|
||||
|
||||
## 14. Quick Reference Commands
|
||||
|
||||
**Development:**
|
||||
```bash
|
||||
# Start
|
||||
docker-compose up
|
||||
npm run dev
|
||||
|
||||
# Database
|
||||
npx prisma migrate dev
|
||||
npx prisma db seed
|
||||
npx prisma studio
|
||||
|
||||
# Testing
|
||||
npm run test
|
||||
npm run test:e2e
|
||||
```
|
||||
|
||||
**Production:**
|
||||
```bash
|
||||
# Deploy
|
||||
docker-compose up -d --build
|
||||
|
||||
# Monitor
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 15. Success Criteria (MVP)
|
||||
|
||||
**Technical:**
|
||||
- [ ] All tests passing (70%+ coverage)
|
||||
- [ ] Can import complete HSK vocabulary (5000+ hanzi)
|
||||
- [ ] Page load <2s
|
||||
- [ ] Learning session responsive (<100ms)
|
||||
- [ ] Mobile responsive
|
||||
|
||||
**Functional:**
|
||||
- [ ] Complete learning session works end-to-end
|
||||
- [ ] SM-2 algorithm calculates correctly
|
||||
- [ ] Progress tracking accurate
|
||||
- [ ] Collections management works
|
||||
- [ ] Search works efficiently
|
||||
|
||||
**User Experience:**
|
||||
- [ ] Can learn 20+ cards in 5-10 minutes
|
||||
- [ ] Interface intuitive
|
||||
- [ ] Daily use sustainable
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Priority Order
|
||||
1. Authentication (foundational)
|
||||
2. Data import (need data)
|
||||
3. Collections (organize learning)
|
||||
4. Search (browse data)
|
||||
5. Learning algorithm (core logic)
|
||||
6. Learning interface (user interaction)
|
||||
7. Progress tracking (motivation)
|
||||
8. Polish & deploy
|
||||
|
||||
### Critical Paths to Test
|
||||
1. Register → Login → Create Collection → Add Hanzi → Start Learning → Complete Session → View Progress
|
||||
2. Admin → Import HSK Data → Create Global Collection → User uses global collection
|
||||
3. Search Hanzi → View Detail → Add to Collection → Learn
|
||||
|
||||
### Key Implementation Files
|
||||
- `prisma/schema.prisma` - All data models
|
||||
- `src/lib/learning/sm2.ts` - SM-2 algorithm
|
||||
- `src/lib/learning/card-selector.ts` - Card selection
|
||||
- `src/lib/import/hsk-parser.ts` - Parse HSK JSON
|
||||
- `src/actions/learning.ts` - Learning Server Actions
|
||||
- `src/app/(app)/learn/[collectionId]/page.tsx` - Learning UI
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- **HSK Data Source**: https://github.com/drkameleon/complete-hsk-vocabulary
|
||||
- **Next.js Docs**: https://nextjs.org/docs
|
||||
- **Prisma Docs**: https://www.prisma.io/docs
|
||||
- **NextAuth Docs**: https://authjs.dev
|
||||
- **SM-2 Algorithm**: https://www.supermemo.com/en/archives1990-2015/english/ol/sm2
|
||||
|
||||
---
|
||||
|
||||
**This specification is complete and ready for implementation with Claude Code.**
|
||||
|
||||
Start with Milestone 1 (Week 1: Foundation) and proceed sequentially through the milestones.
|
||||
147
PROJECT-NAMING.md
Normal file
147
PROJECT-NAMING.md
Normal file
@@ -0,0 +1,147 @@
|
||||
# MemoHanzi - Project Naming Conventions
|
||||
|
||||
## Application Name
|
||||
**MemoHanzi** (记汉字)
|
||||
- **Meaning:** "Remember Hanzi" or "Memorize Hanzi"
|
||||
- **Chinese:** 记汉字
|
||||
- **Pronunciation:** Jì Hànzì
|
||||
|
||||
## Usage Guidelines
|
||||
|
||||
### Display Names (User-Facing)
|
||||
- **Full name:** MemoHanzi
|
||||
- **Tagline:** "Remember Hanzi, effortlessly"
|
||||
- **Description:** Spaced repetition for Chinese characters
|
||||
|
||||
### Technical Names (Code/Infrastructure)
|
||||
|
||||
**Project Directory:**
|
||||
```
|
||||
memohanzi/
|
||||
```
|
||||
|
||||
**Database:**
|
||||
- Database name: `memohanzi_db`
|
||||
- Database user: `memohanzi_user`
|
||||
|
||||
**Connection String:**
|
||||
```
|
||||
postgresql://memohanzi_user:password@localhost:5432/memohanzi_db
|
||||
```
|
||||
|
||||
**Docker Container Names:**
|
||||
- nginx: `memohanzi-nginx`
|
||||
- app: `memohanzi-app`
|
||||
- postgres: `memohanzi-postgres`
|
||||
|
||||
**NPM Package Name (if publishing):**
|
||||
```json
|
||||
{
|
||||
"name": "memohanzi",
|
||||
"description": "Self-hosted spaced repetition app for learning Chinese characters"
|
||||
}
|
||||
```
|
||||
|
||||
**Domain Names:**
|
||||
- Primary: memohanzi.com
|
||||
- Alternative: memohanzi.io / memohanzi.app
|
||||
|
||||
**Email Domains (Development):**
|
||||
- Admin: admin@memohanzi.local
|
||||
- Test user: user@memohanzi.local
|
||||
|
||||
### Code/Variable Naming
|
||||
|
||||
**Constants:**
|
||||
```typescript
|
||||
const APP_NAME = "MemoHanzi"
|
||||
const APP_NAME_CN = "记汉字"
|
||||
const APP_TAGLINE = "Remember Hanzi, effortlessly"
|
||||
```
|
||||
|
||||
**Environment Variables:**
|
||||
```bash
|
||||
NEXTAUTH_URL="https://memohanzi.com"
|
||||
DATABASE_URL="postgresql://memohanzi_user:password@localhost:5432/memohanzi_db"
|
||||
```
|
||||
|
||||
**File Names:**
|
||||
- Use lowercase with hyphens: `memohanzi-config.ts`
|
||||
- Or camelCase for TypeScript: `memohanziConfig.ts`
|
||||
|
||||
## Branding (Future Reference)
|
||||
|
||||
### Logo Concepts
|
||||
- Focus on the concept of memory/remembering
|
||||
- Incorporate Chinese character elements
|
||||
- Clean, modern design
|
||||
|
||||
### Color Palette Suggestions
|
||||
- **Primary:** Red (#E63946) - Traditional Chinese color, attention/memory
|
||||
- **Secondary:** Blue (#457B9D) - Trust, learning, calmness
|
||||
- **Accent:** Gold (#FFD60A) - Achievement, success
|
||||
- **Background:** White/Light gray - Clarity, simplicity
|
||||
|
||||
### Typography
|
||||
- **Hanzi Display:** Noto Sans CJK SC (Google Fonts)
|
||||
- **English UI:** Inter or System fonts
|
||||
- **Headings:** Bold, clean sans-serif
|
||||
|
||||
## Consistency Rules
|
||||
|
||||
1. **Always capitalize "MemoHanzi"** in user-facing content
|
||||
2. **Always use lowercase "memohanzi"** in code/technical contexts
|
||||
3. **Use "Hanzi" not "hanzi"** when referring to characters in documentation
|
||||
4. **Include Chinese characters (记汉字)** in about/landing pages
|
||||
5. **Never use "Hanzi Learning App"** as the name (old placeholder)
|
||||
|
||||
## Examples
|
||||
|
||||
### ✅ Correct Usage
|
||||
|
||||
**User-facing:**
|
||||
- "Welcome to MemoHanzi!"
|
||||
- "MemoHanzi helps you remember Hanzi effortlessly"
|
||||
- "Start learning with MemoHanzi (记汉字)"
|
||||
|
||||
**Technical:**
|
||||
```typescript
|
||||
// File: src/lib/memohanziConfig.ts
|
||||
export const config = {
|
||||
appName: "MemoHanzi",
|
||||
dbName: "memohanzi_db"
|
||||
}
|
||||
```
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
app:
|
||||
container_name: memohanzi-app
|
||||
```
|
||||
|
||||
### ❌ Incorrect Usage
|
||||
|
||||
**Don't:**
|
||||
- "Welcome to memohanzi!" (lowercase in UI)
|
||||
- "MemoHanzi_DB" (mixed case in technical)
|
||||
- "Hanzi Learning App" (old name)
|
||||
- "Memo-Hanzi" or "Memo Hanzi" (hyphenated or separated)
|
||||
|
||||
## README/Documentation Template
|
||||
|
||||
```markdown
|
||||
# MemoHanzi (记汉字)
|
||||
|
||||
**Remember Hanzi, effortlessly**
|
||||
|
||||
MemoHanzi is a self-hosted web application for learning Chinese characters (Hanzi)
|
||||
using spaced repetition (SM-2 algorithm).
|
||||
|
||||
## Features
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**This file should be referenced whenever naming anything in the project.**
|
||||
229
README.md
229
README.md
@@ -1,2 +1,229 @@
|
||||
# memohanzi
|
||||
# MemoHanzi - Implementation Package
|
||||
|
||||
Welcome! This package contains everything needed to implement MemoHanzi (记汉字 - "Remember Hanzi"), a self-hosted Chinese character learning application.
|
||||
|
||||
## 📦 What's Included
|
||||
|
||||
### 1. **HANZI-LEARNING-APP-SPECIFICATION.md** (Main Spec)
|
||||
Complete technical specification including:
|
||||
- ✅ System architecture
|
||||
- ✅ Complete database schema (Prisma)
|
||||
- ✅ All Server Actions API
|
||||
- ✅ SM-2 algorithm implementation
|
||||
- ✅ UI/UX specifications
|
||||
- ✅ Testing strategy
|
||||
- ✅ 12-week milestone plan
|
||||
- ✅ Docker configuration
|
||||
- ✅ Phase 2 & 3 roadmaps
|
||||
|
||||
### 2. **CLAUDE.md** (Instructions for Claude Code)
|
||||
Strict implementation guidelines to prevent deviation from spec:
|
||||
- Critical rules for following the specification
|
||||
- Milestone approach
|
||||
- Common mistakes to avoid
|
||||
- Progress reporting format
|
||||
|
||||
### 3. **PROJECT-NAMING.md** (Naming Conventions)
|
||||
All naming conventions for the MemoHanzi project:
|
||||
- Application naming (display vs technical)
|
||||
- Database naming
|
||||
- Code conventions
|
||||
- Branding guidelines
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### For Claude Code:
|
||||
1. Read `CLAUDE.md` first
|
||||
2. Read `HANZI-LEARNING-APP-SPECIFICATION.md`
|
||||
3. Read `PROJECT-NAMING.md` for naming conventions
|
||||
4. Start with Milestone 1 (Week 1: Foundation)
|
||||
|
||||
### For Human Developers:
|
||||
1. Read `HANZI-LEARNING-APP-SPECIFICATION.md` - this is your blueprint
|
||||
2. Check `PROJECT-NAMING.md` for naming consistency
|
||||
3. Follow the 12-week milestone plan
|
||||
4. Use the testing strategy throughout
|
||||
|
||||
## 📋 Project Overview
|
||||
|
||||
**Name:** MemoHanzi (记汉字)
|
||||
**Tagline:** Remember Hanzi, effortlessly
|
||||
**Type:** Self-hosted web application
|
||||
**Purpose:** Learn Chinese characters using spaced repetition (SM-2 algorithm)
|
||||
|
||||
**Tech Stack:**
|
||||
- Next.js 16 (TypeScript, App Router)
|
||||
- PostgreSQL 18 + Prisma
|
||||
- NextAuth.js v5
|
||||
- Docker Compose + Nginx
|
||||
- Tailwind CSS
|
||||
|
||||
**Timeline:** 10-12 weeks for MVP
|
||||
|
||||
## 🎯 Key Features (MVP)
|
||||
|
||||
**For Users:**
|
||||
- Learn Hanzi with spaced repetition
|
||||
- Multiple choice pinyin quiz (4 options)
|
||||
- Create custom collections or use HSK levels
|
||||
- Track progress with charts and statistics
|
||||
- Search complete Hanzi database
|
||||
|
||||
**For Admins:**
|
||||
- Import HSK vocabulary (JSON/CSV)
|
||||
- Manage global collections
|
||||
- User administration
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
memohanzi/ # Your project root
|
||||
├── src/
|
||||
│ ├── app/ # Next.js App Router
|
||||
│ ├── actions/ # Server Actions
|
||||
│ ├── components/ # React components
|
||||
│ ├── lib/ # Utils (SM-2, parsers, etc)
|
||||
│ └── types/ # TypeScript types
|
||||
├── prisma/
|
||||
│ └── schema.prisma # Database schema
|
||||
├── docker/
|
||||
│ ├── Dockerfile
|
||||
│ └── nginx.conf
|
||||
├── docker-compose.yml
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 🔑 Critical Implementation Notes
|
||||
|
||||
### 1. Follow the Specification EXACTLY
|
||||
The specification is the single source of truth. Do not deviate without approval.
|
||||
|
||||
### 2. Implement Milestones Sequentially
|
||||
Complete Week 1 → Week 2 → Week 3... in order.
|
||||
|
||||
### 3. SM-2 Algorithm is Critical
|
||||
Use the EXACT formulas provided in Section 5 of the spec.
|
||||
|
||||
### 4. Testing is Mandatory
|
||||
Write tests as you implement. Target: 70%+ coverage.
|
||||
|
||||
### 5. Database Schema is Fixed
|
||||
Implement ALL models exactly as specified in the Prisma schema.
|
||||
|
||||
## 📊 Development Milestones
|
||||
|
||||
| Week | Milestone | Focus |
|
||||
|------|-----------|-------|
|
||||
| 1 | Foundation | Setup project, Docker, Prisma schema |
|
||||
| 2 | Authentication | User registration, login, preferences |
|
||||
| 3-4 | Data Import | Admin imports HSK data (JSON/CSV) |
|
||||
| 5 | Collections | User collections + global HSK collections |
|
||||
| 5 | Hanzi Search | Search interface and detail views |
|
||||
| 6 | SM-2 Algorithm | Core learning algorithm + tests |
|
||||
| 7-8 | Learning UI | Learning session interface |
|
||||
| 9 | Dashboard | Progress tracking and visualizations |
|
||||
| 10 | UI Polish | Responsive design, dark mode |
|
||||
| 11 | Testing & Docs | Complete test coverage |
|
||||
| 12 | Deployment | Production deployment + data import |
|
||||
|
||||
## 🎨 Naming Conventions
|
||||
|
||||
**User-Facing:**
|
||||
- Always: "MemoHanzi" (capitalized)
|
||||
- Tagline: "Remember Hanzi, effortlessly"
|
||||
- Include Chinese: 记汉字
|
||||
|
||||
**Technical:**
|
||||
- Directory: `memohanzi/`
|
||||
- Database: `memohanzi_db`
|
||||
- User: `memohanzi_user`
|
||||
- Container: `memohanzi-app`, `memohanzi-postgres`
|
||||
|
||||
See `PROJECT-NAMING.md` for complete guidelines.
|
||||
|
||||
## 📚 Data Source
|
||||
|
||||
HSK Vocabulary: https://github.com/drkameleon/complete-hsk-vocabulary/
|
||||
|
||||
This repository contains comprehensive HSK (Chinese proficiency test) vocabulary data that will be imported into MemoHanzi.
|
||||
|
||||
## 🔐 Security Highlights
|
||||
|
||||
- ✅ Passwords hashed with bcrypt
|
||||
- ✅ NextAuth.js session management
|
||||
- ✅ HTTPS via Nginx
|
||||
- ✅ Rate limiting
|
||||
- ✅ Input validation (Zod)
|
||||
- ✅ SQL injection prevention (Prisma)
|
||||
|
||||
## 🧪 Testing Strategy
|
||||
|
||||
- **Unit Tests (70%):** Business logic, SM-2 algorithm, parsers
|
||||
- **Integration Tests (20%):** Server Actions, database operations
|
||||
- **E2E Tests (10%):** Critical user flows
|
||||
|
||||
**Tools:** Vitest (unit/integration), Playwright (E2E)
|
||||
|
||||
## 📖 Additional Resources
|
||||
|
||||
- **Next.js Docs:** https://nextjs.org/docs
|
||||
- **Prisma Docs:** https://www.prisma.io/docs
|
||||
- **NextAuth Docs:** https://authjs.dev
|
||||
- **SM-2 Algorithm:** https://www.supermemo.com/en/archives1990-2015/english/ol/sm2
|
||||
|
||||
## 🎯 Success Criteria (MVP)
|
||||
|
||||
**Technical:**
|
||||
- [ ] All tests passing (70%+ coverage)
|
||||
- [ ] Can import complete HSK vocabulary
|
||||
- [ ] Page load <2s
|
||||
- [ ] Mobile responsive
|
||||
|
||||
**Functional:**
|
||||
- [ ] Complete learning session works end-to-end
|
||||
- [ ] SM-2 algorithm accurate
|
||||
- [ ] Progress tracking working
|
||||
- [ ] Collections management functional
|
||||
- [ ] Search efficient
|
||||
|
||||
**User Experience:**
|
||||
- [ ] Can learn 20+ cards in 5-10 minutes
|
||||
- [ ] Interface intuitive
|
||||
- [ ] Daily use sustainable
|
||||
|
||||
## 🚦 Getting Started Checklist
|
||||
|
||||
Before beginning implementation:
|
||||
|
||||
- [ ] Read complete specification document
|
||||
- [ ] Understand the tech stack
|
||||
- [ ] Review the milestone approach
|
||||
- [ ] Check naming conventions
|
||||
- [ ] Set up development environment
|
||||
- [ ] Confirm understanding of SM-2 algorithm
|
||||
|
||||
## 💡 Important Reminders
|
||||
|
||||
1. **Read the spec before implementing anything**
|
||||
2. **Ask questions if anything is unclear**
|
||||
3. **Don't make up alternatives or "improvements"**
|
||||
4. **Write tests as you go**
|
||||
5. **Follow the milestone sequence**
|
||||
6. **Use consistent naming (check PROJECT-NAMING.md)**
|
||||
|
||||
## 📞 Next Steps
|
||||
|
||||
**For Claude Code:**
|
||||
Start by saying: "I've read CLAUDE.md and HANZI-LEARNING-APP-SPECIFICATION.md. Ready to begin Milestone 1: Project Foundation."
|
||||
|
||||
**For Human Developers:**
|
||||
1. Set up your development environment
|
||||
2. Create project directory: `memohanzi/`
|
||||
3. Begin Milestone 1 tasks
|
||||
4. Reference the specification frequently
|
||||
|
||||
---
|
||||
|
||||
**Good luck building MemoHanzi! 🎯**
|
||||
|
||||
记汉字 - Remember Hanzi, effortlessly.
|
||||
|
||||
Reference in New Issue
Block a user