Class_generator/src/DRS/progress-items/VocabularyDiscoveryItem.js
StillHammer 13f6d30e86 Implement robust progress system with ultra-strict validation
**Core Architecture:**
- StrictInterface: Base class with visual error enforcement (red screen, sound, shake)
- ProgressItemInterface: Strict contract requiring 4 methods (validate, serialize, getWeight, canComplete)
- Implementation validation at startup - app refuses to start if methods missing

**Progress Items (8 types with realistic weights):**
- VocabularyDiscoveryItem (1pt) - Passive word exposure, no prerequisites
- VocabularyMasteryItem (1pt) - Active flashcards, requires discovery
- PhraseItem (6pts, 3x vocab) - Requires vocabulary mastery
- DialogItem (12pts, 6x vocab) - Complex, requires vocabulary mastery
- TextItem (15pts, 7.5x vocab) - Most complex, requires vocabulary mastery
- AudioItem (12pts, 6x vocab) - Requires vocabulary mastery
- ImageItem (6pts, 3x vocab) - Requires vocabulary discovered
- GrammarItem (6pts, 3x vocab) - Requires vocabulary discovered

**Realistic Progress Calculation:**
- 1 vocab word = 2 points total (discovery + mastery)
- Other items weighted 3x-7.5x heavier for realistic progression
- Example: 171 vocab (342pts) + 75 phrases (450pts) + 6 dialogs (72pts) + 3 texts (45pts) = 909 total points
- Discovering all words = 38% progress (not 76%)

**Services:**
- ContentProgressAnalyzer: Scans chapter content, creates progress items, calculates total weight
- ProgressTracker: Manages state, tracks completion, saves progress to server
- ImplementationValidator: Validates all implementations at startup

**Integration:**
- Application.js validates ALL item implementations before startup
- Missing methods trigger full-screen red error with impossible-to-ignore UI
- Sound alert + screen shake in dev mode

**Pedagogical Flow Enforced:**
Discovery (passive) → Mastery (active) → Application (context)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-07 15:26:42 +08:00

67 lines
1.7 KiB
JavaScript

/**
* VocabularyDiscoveryItem - Progress item for vocabulary discovery (passive exposure)
* Weight: 1 point
* Prerequisites: None
*/
import ProgressItemInterface from '../interfaces/ProgressItemInterface.js';
class VocabularyDiscoveryItem extends ProgressItemInterface {
constructor(word, data) {
super(
ProgressItemInterface.TYPES.VOCABULARY_DISCOVERY,
`vocab-discover-${word}`,
{ word, ...data }
);
this.word = word;
this.data = data;
}
/**
* Validate item data
* @override
*/
validate() {
if (!this.word || typeof this.word !== 'string') {
throw new Error(`VocabularyDiscoveryItem: Invalid word - ${this.word}`);
}
if (!this.data) {
throw new Error(`VocabularyDiscoveryItem: Missing data for word - ${this.word}`);
}
return true;
}
/**
* Serialize to JSON
* @override
*/
serialize() {
return {
...this._getBaseSerialization(),
word: this.word,
data: this.data
};
}
/**
* Get item weight
* @override
*/
getWeight() {
return ProgressItemInterface.WEIGHTS['vocabulary-discovery'];
}
/**
* Check if can be completed (no prerequisites for discovery)
* @override
*/
canComplete(userProgress) {
// Discovery has no prerequisites - can always be completed
// But shouldn't be completed if already discovered
const discovered = userProgress.discoveredWords || [];
return !discovered.includes(this.word);
}
}
export default VocabularyDiscoveryItem;