diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..470548b --- /dev/null +++ b/CLAUDE.md @@ -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` 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!** 🎯 diff --git a/HANZI-LEARNING-APP-SPECIFICATION.md b/HANZI-LEARNING-APP-SPECIFICATION.md new file mode 100644 index 0000000..24ca8f5 --- /dev/null +++ b/HANZI-LEARNING-APP-SPECIFICATION.md @@ -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 }` + +### 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. \ No newline at end of file diff --git a/PROJECT-NAMING.md b/PROJECT-NAMING.md new file mode 100644 index 0000000..dfd74b9 --- /dev/null +++ b/PROJECT-NAMING.md @@ -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.** diff --git a/README.md b/README.md index cfd9113..84c2d27 100644 --- a/README.md +++ b/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.