sanket3280/code-execution
0
1const mongoose = require('mongoose');2 3const ProblemSchema = new mongoose.Schema({4 title: {5 type: String,6 required: [true, 'Please provide a problem title'],7 unique: true,8 trim: true,9 maxlength: [100, 'Title cannot exceed 100 characters']10 },11 slug: {12 type: String,13 unique: true,14 lowercase: true,15 trim: true16 },17 description: {18 type: String,19 required: [true, 'Please provide a problem description']20 },21 difficulty: {22 type: String,23 required: [true, 'Please specify difficulty level'],24 enum: ['easy', 'medium', 'hard', 'Easy', 'Medium', 'Hard']25 },26 category: {27 type: String,28 required: [true, 'Please specify a category'],29 enum: [30 // Lowercase-hyphenated31 'array', 'string', 'linked-list', 'tree', 'graph', 'dynamic-programming', 'sorting', 'searching', 'math', 'stack', 'backtracking', 'heap', 'greedy', 'bit-manipulation', 'binary-search', 'sliding-window', 'two-pointers', 'trie', 'union-find', 'design', 'database', 'sql', 'geometry', 'recursion', 'simulation', 'counting', 'prefix-sum', 'monotonic-stack', 'topological-sort', 'segment-tree', 'binary-indexed-tree', 'dfs', 'bfs', 'hash-table', 'matrix', 'divide-and-conquer', 'other',32 // Title-case with spaces33 'Array', 'String', 'Linked List', 'Tree', 'Graph', 'Dynamic Programming', 'Sorting', 'Searching', 'Math', 'Stack', 'Backtracking', 'Heap', 'Greedy', 'Bit Manipulation', 'Binary Search', 'Sliding Window', 'Two Pointers', 'Trie', 'Union Find', 'Design', 'Database', 'SQL', 'Geometry', 'Recursion', 'Simulation', 'Counting', 'Prefix Sum', 'Monotonic Stack', 'Topological Sort', 'Segment Tree', 'Binary Indexed Tree', 'DFS', 'BFS', 'Hash Table', 'Matrix', 'Divide and Conquer', 'Other'34 ]35 },36 constraints: {37 type: mongoose.Schema.Types.Mixed, // Allow both string and array38 required: [true, 'Please provide constraints']39 },40 examples: [{41 input: {42 type: String,43 required: [true, 'Please provide example input']44 },45 output: {46 type: String,47 required: [true, 'Please provide example output']48 },49 explanation: {50 type: String51 }52 }],53 testCases: [{54 input: {55 type: String,56 required: [true, 'Please provide test case input']57 },58 output: {59 type: String,60 required: [true, 'Please provide test case output']61 },62 isHidden: {63 type: Boolean,64 default: false65 }66 }],67 // List of allowed languages for this problem (HackerEarth codes). If empty/missing, fallback to globally enabled languages68 allowedLanguages: [{ type: String }],69 solutionTemplate: {70 javascript: {71 type: String,72 default: '// Write your JavaScript solution here\n'73 },74 python: {75 type: String,76 default: '# Write your Python solution here\n'77 },78 java: {79 type: String,80 default: '// Write your Java solution here\n'81 },82 cpp: {83 type: String,84 default: '// Write your C++ solution here\n'85 }86 },87 timeLimit: {88 type: Number,89 default: 1000, // in milliseconds90 required: [true, 'Please specify time limit']91 },92 memoryLimit: {93 type: Number,94 default: 128, // in MB95 required: [true, 'Please specify memory limit']96 },97 submissionsCount: {98 type: Number,99 default: 0100 },101 successCount: {102 type: Number,103 default: 0104 },105 successRate: {106 type: Number,107 default: 0108 },109 tags: [{110 type: String111 }],112 createdBy: {113 type: mongoose.Schema.Types.Mixed, // Allow both ObjectId and string114 ref: 'User',115 required: true116 },117 createdAt: {118 type: Date,119 default: Date.now120 },121 questionNumber: {122 type: Number,123 required: true,124 unique: true125 },126 acceptsMultipleAnswers: {127 type: Boolean,128 default: false129 },130 verifierType: {131 type: String,132 enum: ['palindrome', 'array_any_order', 'array_membership', 'set_membership', 'custom', null],133 default: null134 },135 validationRules: {136 type: mongoose.Schema.Types.Mixed,137 default: {}138 }139});140 141// Pre-save middleware to normalize data and generate slug142ProblemSchema.pre('save', function(next) {143 // Generate slug from title if not provided144 if (!this.slug && this.title) {145 this.slug = this.title146 .toLowerCase()147 .replace(/[^a-z0-9]+/g, '-')148 .replace(/^-+|-+$/g, '');149 }150 151 // Normalize difficulty to lowercase152 if (this.difficulty) {153 this.difficulty = this.difficulty.toLowerCase();154 }155 156 // Normalize category to lowercase with hyphens157 if (this.category) {158 this.category = this.category.toLowerCase().replace(/\s+/g, '-');159 }160 161 // Convert constraints array to string if needed162 if (Array.isArray(this.constraints)) {163 this.constraints = this.constraints.join('\n');164 }165 166 next();167});168 169// Indexes for better query performance170ProblemSchema.index({ title: 1 }, { unique: true });171ProblemSchema.index({ slug: 1 }, { unique: true });172ProblemSchema.index({ questionNumber: 1 }, { unique: true });173ProblemSchema.index({ difficulty: 1 });174ProblemSchema.index({ category: 1 });175ProblemSchema.index({ tags: 1 });176ProblemSchema.index({ createdBy: 1 });177ProblemSchema.index({ createdAt: -1 });178 179// Compound indexes for common queries180ProblemSchema.index({ difficulty: 1, category: 1 });181ProblemSchema.index({ category: 1, difficulty: 1 });182 183// Text index for search184ProblemSchema.index({ title: 'text', description: 'text' });185 186module.exports = mongoose.model('Problem', ProblemSchema);