Spaces:
Sleeping
Sleeping
| 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); |