UNPKG

mcp-quiz-server

Version:

🧠 AI-Powered Quiz Management via Model Context Protocol (MCP) - Create, manage, and take quizzes directly from VS Code, Claude, and other AI agents.

201 lines (200 loc) • 6.28 kB
"use strict"; /** * @fileoverview Question Answered Domain Event * @version 1.0.0 * @since 2025-07-29 * @lastUpdated 2025-07-29 * @module QuestionAnsweredEvent Domain Event * @description Domain event fired when a user answers a specific question * @contributors Claude Code Agent * @dependencies DomainEvent base class * @requirements REQ-ARCH-001 (Clean Architecture Domain Layer) * @testCoverage Unit tests for event creation and serialization */ Object.defineProperty(exports, "__esModule", { value: true }); exports.QuestionAnsweredEvent = void 0; const DomainEvent_1 = require("./DomainEvent"); /** * Question Answered Event * * @description Domain event that signals a user has answered a specific question. * This event can trigger immediate feedback, progress updates, * analytics collection, or adaptive learning algorithms. * * @example * ```typescript * const event = new QuestionAnsweredEvent( * 'question-123', * 'Option A', * 'Option B', * false, * 2, * 'user-456' * ); * ``` * * @since 2025-07-29 * @author Claude Code Agent * @requirements REQ-ARCH-001 (Clean Architecture Domain Layer) */ class QuestionAnsweredEvent extends DomainEvent_1.DomainEvent { constructor(questionId, userAnswer, correctAnswer, isCorrect, pointsEarned, userId, responseTimeMs) { super('QuestionAnswered', 1); this.questionId = questionId; this.userAnswer = userAnswer; this.correctAnswer = correctAnswer; this.isCorrect = isCorrect; this.pointsEarned = pointsEarned; this.userId = userId; this.responseTimeMs = responseTimeMs; } /** * Get the aggregate ID (Question ID) that this event relates to */ getAggregateId() { return this.questionId; } /** * Get event payload for serialization */ getEventData() { return { questionId: this.questionId, userId: this.userId, isCorrect: this.isCorrect, pointsEarned: this.pointsEarned, responseTimeMs: this.responseTimeMs, // Note: We don't include actual answers for privacy/security hasAnswer: !!this.userAnswer, }; } /** * Business Logic Methods */ /** * Get points earned as a percentage of possible points */ get pointsPercentage() { if (this.pointsEarned === 0) return 0; // Assuming correct answer would have earned the same points return this.isCorrect ? 100 : 0; } /** * Check if response was quick (business rule: under 10 seconds) */ get isQuickResponse() { if (!this.responseTimeMs) return false; return this.responseTimeMs < 10000; // 10 seconds } /** * Check if response was slow (business rule: over 60 seconds) */ get isSlowResponse() { if (!this.responseTimeMs) return false; return this.responseTimeMs > 60000; // 60 seconds } /** * Get response speed category */ get responseSpeed() { if (!this.responseTimeMs) return 'unknown'; if (this.responseTimeMs < 3000) return 'very_fast'; if (this.responseTimeMs < 10000) return 'fast'; if (this.responseTimeMs < 30000) return 'normal'; if (this.responseTimeMs < 60000) return 'slow'; return 'very_slow'; } /** * Get confidence indicator based on correctness and speed */ get confidenceIndicator() { if (this.isCorrect && this.isQuickResponse) return 'high'; if (this.isCorrect && !this.isSlowResponse) return 'medium'; if (!this.isCorrect && this.isQuickResponse) return 'low'; // Wrong but fast = guessing return 'medium'; } /** * Check if this answer suggests the user might need help */ get suggestsNeedForHelp() { // Wrong answer with slow response suggests confusion return !this.isCorrect && this.isSlowResponse; } /** * Check if this answer suggests expertise/mastery */ get suggestsMastery() { // Correct answer with quick response suggests mastery return this.isCorrect && this.isQuickResponse; } /** * Get learning pattern indicators */ get learningPatterns() { const patterns = []; if (this.suggestsMastery) patterns.push('mastery'); if (this.suggestsNeedForHelp) patterns.push('needs_help'); if (!this.isCorrect && this.isQuickResponse) patterns.push('hasty'); if (this.isCorrect && this.isSlowResponse) patterns.push('methodical'); return patterns; } /** * Check if this event should trigger immediate feedback */ get shouldTriggerFeedback() { // Always provide feedback for incorrect answers // Provide feedback for slow correct answers (reinforcement) return !this.isCorrect || this.isSlowResponse; } /** * Get feedback priority level */ get feedbackPriority() { if (!this.isCorrect) return 'high'; if (this.isSlowResponse) return 'medium'; return 'low'; } /** * Check if this should update user analytics */ get shouldUpdateAnalytics() { return true; // All question answers contribute to analytics } /** * Get analytics weight (importance of this answer for learning analytics) */ get analyticsWeight() { // Incorrect answers have higher weight for learning analytics if (!this.isCorrect) return 2.0; if (this.suggestsMastery) return 1.5; return 1.0; } /** * String representation for logging */ toString() { const correctness = this.isCorrect ? 'correctly' : 'incorrectly'; const speed = this.responseTimeMs ? ` in ${this.responseTimeMs}ms` : ''; return `QuestionAnswered: User ${this.userId} answered question ${this.questionId} ${correctness}${speed}`; } } exports.QuestionAnsweredEvent = QuestionAnsweredEvent;