const mongoose = require('mongoose'); const feedbackSchema = new mongoose.Schema({ userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, comment: { type: String, required: true, trim: true }, rating: { type: Number, min: 1, max: 5 }, createdAt: { type: Date, default: Date.now } }); const voteSchema = new mongoose.Schema({ userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, rank: { type: Number, enum: [1, 2, 3], // 1 = 1st place, 2 = 2nd place, 3 = 3rd place required: true }, createdAt: { type: Date, default: Date.now } }); const submissionSchema = new mongoose.Schema({ sourceTextId: { type: mongoose.Schema.Types.ObjectId, ref: 'SourceText', required: true }, userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, username: { type: String, required: true }, groupNumber: { type: Number, min: 1, max: 8, required: function() { // Group number is required for tutorial tasks, optional for other submissions return this.sourceTextId && this.sourceTextId.category === 'tutorial'; } }, targetCulture: { type: String, required: true }, targetLanguage: { type: String, required: true }, transcreation: { type: String, required: true }, explanation: { type: String, required: true }, culturalAdaptations: [{ type: String }], isAnonymous: { type: Boolean, default: true }, status: { type: String, enum: ['draft', 'submitted', 'reviewed', 'approved', 'rejected'], default: 'submitted' }, difficulty: { type: String, enum: ['beginner', 'intermediate', 'advanced'], default: 'intermediate' }, votes: [voteSchema], feedback: [{ userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, comment: String, createdAt: { type: Date, default: Date.now } }], createdAt: { type: Date, default: Date.now }, updatedAt: { type: Date, default: Date.now } }); // Calculate score based on votes (1st place = 3 points, 2nd place = 2 points, 3rd place = 1 point) submissionSchema.methods.calculateScore = function() { return this.votes.reduce((total, vote) => { const points = 4 - vote.rank; // 1st = 3 points, 2nd = 2 points, 3rd = 1 point return total + points; }, 0); }; // Get vote count by rank submissionSchema.methods.getVoteCountByRank = function() { const counts = { 1: 0, 2: 0, 3: 0 }; this.votes.forEach(vote => { counts[vote.rank]++; }); return counts; }; // Update score before saving submissionSchema.pre('save', function(next) { this.score = this.calculateScore(); this.updatedAt = Date.now(); next(); }); // Index for efficient querying submissionSchema.index({ sourceTextId: 1, targetCulture: 1, status: 1, createdAt: -1 }); module.exports = mongoose.model('Submission', submissionSchema);