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
JavaScript
"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;