- Fix WebSocket server to properly broadcast logs to all connected clients - Integrate professional logging system with real-time WebSocket interface - Add network status indicator with DigitalOcean Spaces connectivity - Implement AWS Signature V4 authentication for private bucket access - Add JSON content loader with backward compatibility to JS modules - Restore navigation breadcrumb system with comprehensive logging - Add multiple content formats: JSON + JS with automatic discovery - Enhance top bar with logger toggle and network status indicator - Remove deprecated temp-games module and clean up unused files 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
384 lines
15 KiB
Markdown
384 lines
15 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## Project Overview
|
||
|
||
Interactive English learning platform for children (8-9 years old) built as a modular Single Page Application. The system provides 9 different educational games that work with various content modules through a flexible architecture.
|
||
|
||
## Key Architecture Patterns
|
||
|
||
### Core System Flow
|
||
1. **AppNavigation** (`js/core/navigation.js`) - Central SPA navigation controller
|
||
2. **ContentScanner** (`js/core/content-scanner.js`) - Auto-discovers available content modules
|
||
3. **GameLoader** (`js/core/game-loader.js`) - Dynamically loads game and content modules
|
||
4. **Content Engine** (`js/core/content-engine.js`) - Processes and adapts content for games
|
||
|
||
### Module Loading System
|
||
- Games and content are loaded dynamically via `GameLoader.loadGame(gameType, contentType)`
|
||
- All modules register themselves on global objects: `window.GameModules` and `window.ContentModules`
|
||
- Content is discovered automatically by `ContentScanner` scanning `js/content/` directory
|
||
- **JSON Content Support**: New JSON-first architecture with backward compatibility to JS modules
|
||
- **JSON Content Loader**: `js/core/json-content-loader.js` transforms JSON content to legacy game format
|
||
- **Offline-First Loading**: Content loads from local files first, with DigitalOcean Spaces fallback
|
||
- Games follow consistent constructor pattern: `new GameClass({ container, content, onScoreUpdate, onGameEnd })`
|
||
|
||
### URL-Based Navigation
|
||
- Single HTML file (`index.html`) handles all navigation via URL parameters
|
||
- Routes: `?page=home|games|levels|play&game=<gameType>&content=<contentType>`
|
||
- Browser back/forward supported through `popstate` events
|
||
- Navigation history maintained in `AppNavigation.navigationHistory`
|
||
- Breadcrumb navigation with clickable path elements
|
||
- **Top Bar**: Fixed header with app title and permanent network status indicator
|
||
- **Network Status**: Real-time connectivity indicator (🟢 Online / 🟠Connecting / 🔴 Offline)
|
||
- Keyboard shortcuts (ESC = go back)
|
||
|
||
## Content Module Format
|
||
|
||
### Rich Content Schema (New Architecture)
|
||
|
||
Content modules support rich, multimedia educational content with optional properties. The system adapts games and exercises based on available content features:
|
||
|
||
```javascript
|
||
window.ContentModules.ModuleName = {
|
||
name: "Display Name",
|
||
description: "Description text",
|
||
difficulty: "easy|medium|hard|beginner|intermediate|advanced",
|
||
language: "chinese|english|french|spanish", // Target learning language
|
||
hskLevel: "HSK1|HSK2|HSK3|HSK4|HSK5|HSK6", // Chinese proficiency level
|
||
|
||
// Rich vocabulary with optional multimedia
|
||
vocabulary: {
|
||
"word_or_character": {
|
||
translation: "English translation",
|
||
prononciation: "pronunciation guide", // Optional: pronunciation guide
|
||
type: "noun|verb|adjective|greeting|number", // Word classification
|
||
pronunciation: "audio/word.mp3", // Optional: audio file
|
||
difficulty: "HSK1|HSK2|...", // Optional: individual word difficulty
|
||
strokeOrder: ["stroke1", "stroke2"], // Optional: character writing order
|
||
examples: ["example sentence 1"], // Optional: usage examples
|
||
grammarNotes: "special usage rules" // Optional: grammar context
|
||
}
|
||
// OR simple format for basic content:
|
||
// "word": "simple translation"
|
||
},
|
||
|
||
// Grammar rules and explanations
|
||
grammar: {
|
||
topic_name: {
|
||
title: "Grammar Rule Title",
|
||
explanation: "Detailed explanation",
|
||
examples: [
|
||
{ chinese: "䏿–‡ä¾‹å<C3A5>", english: "English example", prononciation: "zhÅ<68>ng wén lì zi" }
|
||
],
|
||
exercises: [/* grammar-specific exercises */]
|
||
}
|
||
},
|
||
|
||
// Audio content with/without text
|
||
audio: {
|
||
withText: [
|
||
{
|
||
title: "Audio Lesson Title",
|
||
audioFile: "audio/lesson1.mp3",
|
||
transcript: "Full text transcript",
|
||
translation: "English translation",
|
||
timestamps: [{ time: 5.2, text: "specific segment" }] // Optional
|
||
}
|
||
],
|
||
withoutText: [
|
||
{
|
||
title: "Listening Challenge",
|
||
audioFile: "audio/challenge1.mp3",
|
||
questions: [
|
||
{ question: "What did they say?", type: "ai_interpreted" }
|
||
]
|
||
}
|
||
]
|
||
},
|
||
|
||
// Poetry and cultural content
|
||
poems: [
|
||
{
|
||
title: "Poem Title",
|
||
content: "Full poem text",
|
||
translation: "English translation",
|
||
audioFile: "audio/poem1.mp3", // Optional
|
||
culturalContext: "Historical background"
|
||
}
|
||
],
|
||
|
||
// Fill-in-the-blank exercises
|
||
fillInBlanks: [
|
||
{
|
||
sentence: "I _____ to school every day",
|
||
options: ["go", "goes", "going", "went"], // Multiple choice options
|
||
correctAnswer: "go",
|
||
explanation: "Present tense with 'I'"
|
||
},
|
||
{
|
||
sentence: "The weather is _____ today",
|
||
type: "open_ended", // AI-interpreted answers
|
||
acceptedAnswers: ["nice", "good", "beautiful", "sunny"],
|
||
aiPrompt: "Evaluate if answer describes weather positively"
|
||
}
|
||
],
|
||
|
||
// Sentence correction exercises
|
||
corrections: [
|
||
{
|
||
incorrect: "I are happy today",
|
||
correct: "I am happy today",
|
||
explanation: "Use 'am' with pronoun 'I'",
|
||
type: "grammar_correction"
|
||
}
|
||
],
|
||
|
||
// Reading comprehension with AI evaluation
|
||
comprehension: [
|
||
{
|
||
text: "Long reading passage...",
|
||
questions: [
|
||
{
|
||
question: "What is the main idea?",
|
||
type: "ai_interpreted",
|
||
evaluationPrompt: "Check if answer captures main theme"
|
||
},
|
||
{
|
||
question: "Multiple choice question?",
|
||
type: "multiple_choice",
|
||
options: ["A", "B", "C", "D"],
|
||
correctAnswer: "B"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
|
||
// Matching exercises (connect lines between columns)
|
||
matching: [
|
||
{
|
||
title: "Match Words to Meanings",
|
||
leftColumn: ["apple", "book", "car"],
|
||
rightColumn: ["苹果", "书", "车"],
|
||
correctPairs: [
|
||
{ left: "apple", right: "苹果" },
|
||
{ left: "book", right: "书" },
|
||
{ left: "car", right: "车" }
|
||
]
|
||
}
|
||
],
|
||
|
||
// Standard content (backward compatibility)
|
||
sentences: [{ english: "...", chinese: "...", prononciation: "..." }],
|
||
texts: [{ title: "...", content: "...", translation: "..." }],
|
||
dialogues: [{ conversation: [...] }]
|
||
};
|
||
```
|
||
|
||
### JSON Content Format (New Architecture)
|
||
|
||
The platform now supports JSON content files for easier editing and maintenance:
|
||
|
||
```json
|
||
{
|
||
"name": "Content Name",
|
||
"description": "Content description",
|
||
"difficulty": "easy|medium|hard",
|
||
"vocabulary": {
|
||
"word": {
|
||
"translation": "French translation",
|
||
"prononciation": "pronunciation guide",
|
||
"type": "noun|verb|adjective"
|
||
}
|
||
},
|
||
"sentences": [
|
||
{
|
||
"english": "English sentence",
|
||
"chinese": "Chinese translation",
|
||
"prononciation": "pronunciation"
|
||
}
|
||
],
|
||
"grammar": { /* grammar rules */ },
|
||
"audio": { /* audio content */ },
|
||
"exercises": { /* exercise definitions */ }
|
||
}
|
||
```
|
||
|
||
**JSON Content Loader Features:**
|
||
- Automatic transformation from JSON to legacy game format
|
||
- Backward compatibility with existing JavaScript content modules
|
||
- Support for all rich content features (vocabulary, grammar, audio, exercises)
|
||
- Offline-first loading with cloud fallback
|
||
|
||
### Content Adaptivity System
|
||
|
||
The platform automatically adapts available games and exercises based on content richness:
|
||
|
||
**Content Analysis:**
|
||
- System scans each content module for available features
|
||
- Generates compatibility scores for each game type
|
||
- Recommends optimal learning activities
|
||
- Handles graceful degradation when content is incomplete
|
||
|
||
**Adaptive Game Selection:**
|
||
- **Rich vocabulary** → Enable advanced matching games, pronunciation practice
|
||
- **Audio files present** → Enable listening exercises, pronunciation challenges
|
||
- **Grammar rules** → Enable correction exercises, structured lessons
|
||
- **Fill-in-blanks data** → Enable cloze tests with multiple choice or AI evaluation
|
||
- **Minimal content** → Fall back to basic vocabulary games
|
||
|
||
**Missing Content Handling:**
|
||
- Display helpful messages: "Add audio files to enable pronunciation practice"
|
||
- Suggest content enrichment opportunities
|
||
- Gracefully disable incompatible game modes
|
||
- Provide content creation tools for missing elements
|
||
|
||
**Example Adaptive Behavior:**
|
||
```javascript
|
||
// Content with only basic vocabulary
|
||
{ vocabulary: { "hello": "ä½ å¥½" } }
|
||
→ Enable: Basic matching, simple quiz
|
||
→ Disable: Audio practice, grammar exercises
|
||
→ Suggest: "Add pronunciation guide and audio for pronunciation practice"
|
||
|
||
// Rich multimedia content
|
||
{ vocabulary: { "hello": { translation: "ä½ å¥½", prononciation: "nÇ<6E> hÇŽo", pronunciation: "audio/hello.mp3" } } }
|
||
→ Enable: All vocabulary games, audio practice, pronunciation scoring
|
||
→ Unlock: Advanced difficulty levels, speed challenges
|
||
```
|
||
|
||
## Game Module Format
|
||
|
||
Game modules must export to `window.GameModules` with this pattern:
|
||
```javascript
|
||
class GameName {
|
||
constructor({ container, content, onScoreUpdate, onGameEnd }) {
|
||
this.container = container;
|
||
this.content = content;
|
||
this.onScoreUpdate = onScoreUpdate;
|
||
this.onGameEnd = onGameEnd;
|
||
}
|
||
|
||
start() { /* Initialize game */ }
|
||
destroy() { /* Cleanup */ }
|
||
restart() { /* Reset game state */ }
|
||
}
|
||
|
||
window.GameModules = window.GameModules || {};
|
||
window.GameModules.GameName = GameName;
|
||
```
|
||
|
||
## Configuration System
|
||
|
||
- **Main config**: `config/games-config.json` - defines available games and content
|
||
- **Environment config**: `js/core/env-config.js` - DigitalOcean Spaces configuration and offline settings
|
||
- **Content discovery**: Automatic scanning of both `.js` and `.json` content files
|
||
- Games can be enabled/disabled via `games.{gameType}.enabled`
|
||
- **Cloud Integration**: DigitalOcean Spaces endpoint configuration for remote content
|
||
- **Offline-First Strategy**: Local content prioritized, remote fallback with timeout protection
|
||
- UI settings, scoring rules, and feature flags also in main config
|
||
|
||
## Development Workflow
|
||
|
||
### Running the Application
|
||
Open `index.html` in a web browser - no build process required. All modules load dynamically.
|
||
|
||
### Adding New Games
|
||
1. Create `js/games/{game-name}.js` with proper module export
|
||
2. Add game configuration to `config/games-config.json`
|
||
3. Update `AppNavigation.getDefaultConfig()` if needed
|
||
|
||
### Adding New Content
|
||
**Option 1: JSON Format (Recommended)**
|
||
1. Create `js/content/{content-name}.json` with proper JSON structure
|
||
2. Content will be auto-discovered and loaded via JSON Content Loader
|
||
3. Easier to edit and maintain than JavaScript files
|
||
|
||
**Option 2: JavaScript Format (Legacy)**
|
||
1. Create `js/content/{content-name}.js` with proper module export
|
||
2. Add filename to `ContentScanner.contentFiles` array
|
||
3. Content will be auto-discovered on next app load
|
||
|
||
### Content Creation Tool
|
||
- Built-in content creator at `js/tools/content-creator.js`
|
||
- Accessible via "Créateur de Contenu" button on home page
|
||
- Generates properly formatted content modules
|
||
|
||
## Key Files by Function
|
||
|
||
**Navigation & Loading:**
|
||
- `js/core/navigation.js` - SPA navigation controller (452 lines)
|
||
- `js/core/game-loader.js` - Dynamic module loading (336 lines)
|
||
- `js/core/content-scanner.js` - Auto content discovery (376 lines)
|
||
|
||
**Content Processing:**
|
||
- `js/core/content-engine.js` - Content processing engine (484 lines)
|
||
- `js/core/content-factory.js` - Exercise generation (553 lines)
|
||
- `js/core/content-parsers.js` - Content parsing utilities (484 lines)
|
||
- `js/core/json-content-loader.js` - JSON to legacy format transformation
|
||
- `js/core/env-config.js` - Environment and cloud configuration
|
||
|
||
**Game Implementations:**
|
||
- `js/games/whack-a-mole.js` - Standard version (623 lines)
|
||
- `js/games/whack-a-mole-hard.js` - Difficult version (643 lines)
|
||
- `js/games/memory-match.js` - Memory pairs game (403 lines)
|
||
- `js/games/quiz-game.js` - Quiz system (354 lines)
|
||
- `js/games/fill-the-blank.js` - Sentence completion (418 lines)
|
||
- `js/games/text-reader.js` - Guided text reading (366 lines)
|
||
- `js/games/adventure-reader.js` - RPG-style adventure (949 lines)
|
||
|
||
## Important Implementation Details
|
||
|
||
### Scoring System
|
||
- Games call `this.onScoreUpdate(score)` to update display
|
||
- Final scores saved to localStorage with key pattern: `score_{gameType}_{contentType}`
|
||
- Best scores tracked and displayed in game-end modal
|
||
- Points per correct answer, malus per error, speed bonus
|
||
- Score history and achievement badges
|
||
|
||
### Content Compatibility
|
||
- `ContentScanner` evaluates content compatibility with each game type
|
||
- Compatibility scoring helps recommend best content for each game
|
||
- Games should handle various content formats gracefully
|
||
|
||
### Memory Management
|
||
- `GameLoader.cleanup()` called before loading new games
|
||
- Games should implement `destroy()` method for proper cleanup
|
||
- Previous game instances must be cleaned up to prevent memory leaks
|
||
|
||
### Error Handling
|
||
- Content loading errors logged but don't crash the application
|
||
- Fallback mechanisms for missing content or games
|
||
- User-friendly error messages via `Utils.showToast()`
|
||
|
||
## Design Guidelines
|
||
|
||
### Visual Design Principles
|
||
- Modern, clean design optimized for children (8-9 years old)
|
||
- Large, tactile buttons (minimum 44px for touch interfaces)
|
||
- High contrast colors for accessibility
|
||
- Smooth, non-aggressive animations
|
||
- Emoji icons combined with text labels
|
||
|
||
### Color Palette
|
||
- **Primary**: Blue (#3B82F6) - Trust, learning
|
||
- **Secondary**: Green (#10B981) - Success, validation
|
||
- **Accent**: Orange (#F59E0B) - Energy, attention
|
||
- **Error**: Red (#EF4444) - Clear error indication
|
||
- **Neutral**: Gray (#6B7280) - Text, backgrounds
|
||
|
||
### Accessibility Features
|
||
- Full keyboard navigation support
|
||
- Alternative text for all images
|
||
- Adjustable font sizes
|
||
- High contrast mode compatibility
|
||
- Screen reader friendly markup
|
||
|
||
### Responsive Design
|
||
- Mobile/tablet adaptation
|
||
- Touch-friendly interface
|
||
- Portrait/landscape orientation support
|
||
- Fluid layouts that work on various screen sizes
|
||
- **Fixed Top Bar**: App title and network status always visible
|
||
- **Network Status**: Automatic hiding of status text on mobile devices
|
||
- **Content Margin**: Proper spacing to accommodate fixed header |