Sunschool’s concept tracking system tags every quiz question with specific concepts (e.g., “addition”, “fractions”, “plants”) and tracks performance on each concept individually. This enables precise identification of struggling areas and adaptive content recommendations.
Concepts are automatically extracted from question text and options:
Copy
Ask AI
// From server/services/quiz-tracking-service.ts:47export function extractConceptTags( question: QuizQuestion, subject: string): string[] { const text = `${question.text} ${question.options.join(' ')}`.toLowerCase(); const tags: Set<string> = new Set(); // Add subject as primary tag tags.add(subject.toLowerCase()); // Math concepts if (text.match(/\b(add|addition|plus|sum)\b/)) tags.add('addition'); if (text.match(/\b(subtract|subtraction|minus|difference)\b/)) tags.add('subtraction'); if (text.match(/\b(multiply|multiplication|times|product)\b/)) tags.add('multiplication'); if (text.match(/\b(divide|division|split|quotient)\b/)) tags.add('division'); if (text.match(/\b(fraction|half|quarter|third)\b/)) tags.add('fractions'); if (text.match(/\b(count|counting|number|how many)\b/)) tags.add('counting'); // Science concepts if (text.match(/\b(plant|plants|grow|seed|leaf)\b/)) tags.add('plants'); if (text.match(/\b(animal|animals|bird|fish|mammal)\b/)) tags.add('animals'); if (text.match(/\b(water|liquid|solid|gas|ice|steam)\b/)) tags.add('states-of-matter'); if (text.match(/\b(hot|cold|heat|temperature|warm)\b/)) tags.add('temperature'); if (text.match(/\b(light|dark|shadow|sun)\b/)) tags.add('light'); if (text.match(/\b(sound|hear|loud|quiet|noise)\b/)) tags.add('sound'); // Reading/Language concepts if (text.match(/\b(letter|alphabet|word|spell)\b/)) tags.add('letters'); if (text.match(/\b(read|reading|story|book)\b/)) tags.add('reading'); if (text.match(/\b(write|writing|sentence)\b/)) tags.add('writing'); if (text.match(/\b(rhyme|rhyming|sound)\b/)) tags.add('phonics'); // General cognitive skills if (text.match(/\b(color|red|blue|green|yellow)\b/)) tags.add('colors'); if (text.match(/\b(shape|circle|square|triangle)\b/)) tags.add('shapes'); if (text.match(/\b(big|small|large|tiny|size)\b/)) tags.add('size'); if (text.match(/\b(compare|same|different|similar)\b/)) tags.add('comparison'); return Array.from(tags);}
The system uses simple regex pattern matching. As the platform grows, this can be enhanced with NLP (Natural Language Processing) for more sophisticated concept detection.
Questions are hashed to detect duplicates and track repeated attempts:
Copy
Ask AI
// From server/services/quiz-tracking-service.ts:36export function hashQuestion(questionText: string): string { return crypto .createHash('sha256') .update(questionText.toLowerCase().trim()) .digest('hex');}
The same question asked multiple times will have the same hash. This allows the system to detect if a learner is seeing the same question repeatedly and track improvement.
CREATE TABLE quiz_answers ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), learner_id INTEGER NOT NULL, lesson_id TEXT NOT NULL, question_index INTEGER NOT NULL, question_text TEXT NOT NULL, question_hash TEXT NOT NULL, user_answer INTEGER NOT NULL, correct_answer INTEGER NOT NULL, is_correct BOOLEAN NOT NULL, concept_tags TEXT[] NOT NULL, answered_at TIMESTAMP DEFAULT NOW());CREATE INDEX idx_quiz_answers_learner ON quiz_answers(learner_id);CREATE INDEX idx_quiz_answers_concepts ON quiz_answers USING GIN(concept_tags);