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.

185 lines (184 loc) • 7.29 kB
"use strict"; /** * @moduleName: QuizResult Entity Model * @version: 1.0.0 * @since: 2025-07-22 * @lastUpdated: 2025-07-22 * @projectSummary: TypeORM entity model for quiz attempt results with score calculation and timing * @techStack: TypeORM, TypeScript, Decorators, Computed Properties * @dependency: typeorm, reflect-metadata * @interModuleDependency: ./Quiz, ./Result * @requirementsTraceability: * {@link Requirements.REQ_DATA_002} (Append-Only Results Storage) * @briefDescription: Quiz attempt result entity with user information, scoring, timing, and individual question results * @contributors: Jorge the Database Architect * @vulnerabilitiesAssessment: * - User identification stored securely * - Score calculation methods validated * - Timing data for analytics * - Cascade delete for result cleanup */ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var QuizResult_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.QuizResult = void 0; const typeorm_1 = require("typeorm"); const Quiz_1 = require("./Quiz"); const Result_1 = require("./Result"); let QuizResult = QuizResult_1 = class QuizResult { // Computed properties get percentage() { return this.totalQuestions > 0 ? Math.round((this.correctAnswers / this.totalQuestions) * 100) : 0; } get averageTimePerQuestion() { return this.totalQuestions > 0 && this.totalTimeSpent ? Math.round(this.totalTimeSpent / this.totalQuestions) : 0; } get grade() { const percentage = this.percentage; if (percentage >= 90) return 'A'; if (percentage >= 80) return 'B'; if (percentage >= 70) return 'C'; if (percentage >= 60) return 'D'; return 'F'; } // Helper methods calculateScore() { if (this.results) { this.totalQuestions = this.results.length; this.correctAnswers = this.results.filter(r => r.isCorrect).length; this.incorrectAnswers = this.totalQuestions - this.correctAnswers; this.score = this.percentage; this.totalTimeSpent = this.results.reduce((sum, r) => sum + (r.timeSpent || 0), 0); } } markCompleted() { this.isCompleted = true; this.status = 'completed'; this.completedAt = new Date(); this.calculateScore(); } toJSON() { var _a, _b; return { id: this.id, quizId: this.quizId, userId: this.userId, userName: this.userName, score: this.score, totalQuestions: this.totalQuestions, correctAnswers: this.correctAnswers, incorrectAnswers: this.incorrectAnswers, totalTimeSpent: this.totalTimeSpent, isCompleted: this.isCompleted, status: this.status, percentage: this.percentage, grade: this.grade, averageTimePerQuestion: this.averageTimePerQuestion, startedAt: this.startedAt, completedAt: this.completedAt, quiz: (_a = this.quiz) === null || _a === void 0 ? void 0 : _a.toJSON(), results: (_b = this.results) === null || _b === void 0 ? void 0 : _b.map(r => r.toJSON()), metadata: this.metadata, }; } // Static factory method static create(data) { const quizResult = new QuizResult_1(); quizResult.quizId = data.quizId; quizResult.userId = data.userId; quizResult.userName = data.userName; quizResult.status = 'in_progress'; quizResult.isCompleted = false; return quizResult; } }; exports.QuizResult = QuizResult; __decorate([ (0, typeorm_1.PrimaryGeneratedColumn)('uuid'), __metadata("design:type", String) ], QuizResult.prototype, "id", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'uuid' }), __metadata("design:type", String) ], QuizResult.prototype, "quizId", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }), __metadata("design:type", String) ], QuizResult.prototype, "userId", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'varchar', length: 255, nullable: true }), __metadata("design:type", String) ], QuizResult.prototype, "userName", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'float', default: 0 }), __metadata("design:type", Number) ], QuizResult.prototype, "score", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'integer', default: 0 }), __metadata("design:type", Number) ], QuizResult.prototype, "totalQuestions", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'integer', default: 0 }), __metadata("design:type", Number) ], QuizResult.prototype, "correctAnswers", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'integer', default: 0 }), __metadata("design:type", Number) ], QuizResult.prototype, "incorrectAnswers", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'integer', nullable: true }), __metadata("design:type", Number) ], QuizResult.prototype, "totalTimeSpent", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'boolean', default: false }), __metadata("design:type", Boolean) ], QuizResult.prototype, "isCompleted", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'varchar', length: 50, default: 'in_progress' }), __metadata("design:type", String) ], QuizResult.prototype, "status", void 0); __decorate([ (0, typeorm_1.Column)({ type: 'json', nullable: true }), __metadata("design:type", Object) ], QuizResult.prototype, "metadata", void 0); __decorate([ (0, typeorm_1.CreateDateColumn)(), __metadata("design:type", Date) ], QuizResult.prototype, "startedAt", void 0); __decorate([ (0, typeorm_1.UpdateDateColumn)(), __metadata("design:type", Date) ], QuizResult.prototype, "completedAt", void 0); __decorate([ (0, typeorm_1.ManyToOne)(() => Quiz_1.Quiz, quiz => quiz.results, { eager: true, }), (0, typeorm_1.JoinColumn)({ name: 'quizId' }), __metadata("design:type", Quiz_1.Quiz) ], QuizResult.prototype, "quiz", void 0); __decorate([ (0, typeorm_1.OneToMany)(() => Result_1.Result, result => result.quizResult, { cascade: true, eager: false, }), __metadata("design:type", Array) ], QuizResult.prototype, "results", void 0); exports.QuizResult = QuizResult = QuizResult_1 = __decorate([ (0, typeorm_1.Entity)('quiz_results') ], QuizResult);