Initial Commit

This commit is contained in:
Stefan Hardegger
2025-11-18 08:16:12 +01:00
parent 0331f54d31
commit 0bb7c4f5e6
4 changed files with 1360 additions and 1 deletions

391
CLAUDE.md Normal file
View 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!** 🎯

View 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
View 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
View File

@@ -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.