135 lines
3.1 KiB
JavaScript
135 lines
3.1 KiB
JavaScript
const { v4: uuidv4 } = require('uuid');
|
|
|
|
module.exports = (sequelize, DataTypes) => {
|
|
const QuizAnswer = sequelize.define('QuizAnswer', {
|
|
id: {
|
|
type: DataTypes.CHAR(36),
|
|
primaryKey: true,
|
|
defaultValue: () => uuidv4(),
|
|
allowNull: false,
|
|
comment: 'UUID primary key'
|
|
},
|
|
quizSessionId: {
|
|
type: DataTypes.CHAR(36),
|
|
allowNull: false,
|
|
field: 'quiz_session_id',
|
|
validate: {
|
|
notEmpty: {
|
|
msg: 'Quiz session ID is required'
|
|
},
|
|
isUUID: {
|
|
args: 4,
|
|
msg: 'Quiz session ID must be a valid UUID'
|
|
}
|
|
},
|
|
comment: 'Foreign key to quiz_sessions table'
|
|
},
|
|
questionId: {
|
|
type: DataTypes.CHAR(36),
|
|
allowNull: false,
|
|
field: 'question_id',
|
|
validate: {
|
|
notEmpty: {
|
|
msg: 'Question ID is required'
|
|
},
|
|
isUUID: {
|
|
args: 4,
|
|
msg: 'Question ID must be a valid UUID'
|
|
}
|
|
},
|
|
comment: 'Foreign key to questions table'
|
|
},
|
|
selectedOption: {
|
|
type: DataTypes.STRING(255),
|
|
allowNull: false,
|
|
field: 'selected_option',
|
|
validate: {
|
|
notEmpty: {
|
|
msg: 'Selected option is required'
|
|
}
|
|
},
|
|
comment: 'The option selected by the user'
|
|
},
|
|
isCorrect: {
|
|
type: DataTypes.BOOLEAN,
|
|
allowNull: false,
|
|
field: 'is_correct',
|
|
comment: 'Whether the selected answer was correct'
|
|
},
|
|
pointsEarned: {
|
|
type: DataTypes.INTEGER.UNSIGNED,
|
|
allowNull: false,
|
|
defaultValue: 0,
|
|
field: 'points_earned',
|
|
validate: {
|
|
min: {
|
|
args: [0],
|
|
msg: 'Points earned must be non-negative'
|
|
}
|
|
},
|
|
comment: 'Points earned for this answer'
|
|
},
|
|
timeTaken: {
|
|
type: DataTypes.INTEGER.UNSIGNED,
|
|
allowNull: false,
|
|
defaultValue: 0,
|
|
field: 'time_taken',
|
|
validate: {
|
|
min: {
|
|
args: [0],
|
|
msg: 'Time taken must be non-negative'
|
|
}
|
|
},
|
|
comment: 'Time taken to answer in seconds'
|
|
},
|
|
answeredAt: {
|
|
type: DataTypes.DATE,
|
|
allowNull: false,
|
|
defaultValue: DataTypes.NOW,
|
|
field: 'answered_at',
|
|
comment: 'When the question was answered'
|
|
}
|
|
}, {
|
|
tableName: 'quiz_answers',
|
|
timestamps: true,
|
|
underscored: true,
|
|
indexes: [
|
|
{
|
|
fields: ['quiz_session_id'],
|
|
name: 'idx_quiz_answers_session_id'
|
|
},
|
|
{
|
|
fields: ['question_id'],
|
|
name: 'idx_quiz_answers_question_id'
|
|
},
|
|
{
|
|
fields: ['quiz_session_id', 'question_id'],
|
|
unique: true,
|
|
name: 'idx_quiz_answers_session_question_unique'
|
|
},
|
|
{
|
|
fields: ['is_correct'],
|
|
name: 'idx_quiz_answers_is_correct'
|
|
},
|
|
{
|
|
fields: ['answered_at'],
|
|
name: 'idx_quiz_answers_answered_at'
|
|
}
|
|
]
|
|
});
|
|
|
|
// Associations
|
|
QuizAnswer.associate = (models) => {
|
|
QuizAnswer.belongsTo(models.QuizSession, {
|
|
foreignKey: 'quizSessionId',
|
|
as: 'quizSession'
|
|
});
|
|
QuizAnswer.belongsTo(models.Question, {
|
|
foreignKey: 'questionId',
|
|
as: 'question'
|
|
});
|
|
};
|
|
|
|
return QuizAnswer;
|
|
};
|