/** * Interactive CRUD Testing Script * * This script demonstrates CRUD operations with MongoDB and the Candidate model * It will: * 1. Connect to MongoDB * 2. Allow you to create, read, update and delete candidate records * 3. Display the results in a formatted way */ require('dotenv').config(); const mongoose = require('mongoose'); const readline = require('readline'); const { cyan, green, yellow, red, bold } = require('colorette'); const MONGODB_URI = process.env.MONGODB_URI || 'mongodb://localhost:27017/candidate-portal'; // Create readline interface const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); // Candidate Schema const CandidateSchema = new mongoose.Schema( { name: { type: String, required: true }, email: { type: String, required: true, unique: true }, phone: String, visaStatus: { type: String, enum: ['H1B', 'Green Card', 'OPT', 'CPT', 'Citizen', 'Other'] }, location: String, openToRelocate: Boolean, experience: String, technology: String, skills: [String], currentStatus: String, status: String, marketingStartDate: Date, dayRecruiter: String, nightRecruiter: String, notes: String, hotlisted: Boolean }, { timestamps: true } ); // Main async function async function main() { try { console.log(cyan('šŸ”Œ Connecting to MongoDB...')); // Connect to MongoDB await mongoose.connect(MONGODB_URI, { bufferCommands: false, serverSelectionTimeoutMS: 5000, }); console.log(green('āœ… Connected to MongoDB successfully!')); // Define the model const Candidate = mongoose.model('Candidate', CandidateSchema); // Display menu and handle user input await showMenu(Candidate); } catch (error) { console.error(red('āŒ Error:'), error); } } // Show menu async function showMenu(Candidate) { console.log('\n' + bold(cyan('===== CANDIDATE CRUD OPERATIONS ====='))); console.log(cyan('1. Create a new candidate')); console.log(cyan('2. List all candidates')); console.log(cyan('3. Find a candidate by email')); console.log(cyan('4. Update a candidate')); console.log(cyan('5. Delete a candidate')); console.log(cyan('6. Exit')); rl.question(bold('\nEnter your choice (1-6): '), async (choice) => { switch (choice) { case '1': await createCandidate(Candidate); break; case '2': await listCandidates(Candidate); break; case '3': await findCandidate(Candidate); break; case '4': await updateCandidate(Candidate); break; case '5': await deleteCandidate(Candidate); break; case '6': console.log(yellow('šŸ‘‹ Goodbye!')); await mongoose.disconnect(); rl.close(); return; default: console.log(red('āŒ Invalid choice. Please try again.')); await showMenu(Candidate); break; } }); } // Create a new candidate async function createCandidate(Candidate) { console.log('\n' + bold(cyan('===== CREATE NEW CANDIDATE ====='))); const candidate = { name: await askQuestion('Enter name: '), email: await askQuestion('Enter email: '), phone: await askQuestion('Enter phone (optional): '), visaStatus: await askQuestion('Enter visa status (H1B, Green Card, OPT, CPT, Citizen, Other): ') || 'OPT', location: await askQuestion('Enter location (optional): '), technology: await askQuestion('Enter technology (optional): '), experience: await askQuestion('Enter experience (optional): '), openToRelocate: (await askQuestion('Open to relocate? (y/n): ')).toLowerCase() === 'y' }; try { const result = await Candidate.create(candidate); console.log(green('āœ… Candidate created successfully!')); console.log(formatCandidate(result)); } catch (error) { console.error(red('āŒ Error creating candidate:'), error.message); } await continuePrompt(Candidate); } // List all candidates async function listCandidates(Candidate) { console.log('\n' + bold(cyan('===== LIST ALL CANDIDATES ====='))); try { const limit = parseInt(await askQuestion('Enter limit (default 10): ') || '10'); const candidates = await Candidate.find().limit(limit); if (candidates.length === 0) { console.log(yellow('āš ļø No candidates found.')); } else { console.log(green(`Found ${candidates.length} candidates:`)); candidates.forEach((candidate, index) => { console.log(`\n${bold(cyan(`Candidate #${index + 1}:`))} ${bold(candidate.name)}`); console.log(formatCandidate(candidate)); }); } } catch (error) { console.error(red('āŒ Error listing candidates:'), error.message); } await continuePrompt(Candidate); } // Find a candidate by email async function findCandidate(Candidate) { console.log('\n' + bold(cyan('===== FIND CANDIDATE BY EMAIL ====='))); const email = await askQuestion('Enter email to search: '); try { const candidate = await Candidate.findOne({ email }); if (!candidate) { console.log(yellow(`āš ļø No candidate found with email: ${email}`)); } else { console.log(green('āœ… Candidate found:')); console.log(formatCandidate(candidate)); } } catch (error) { console.error(red('āŒ Error finding candidate:'), error.message); } await continuePrompt(Candidate); } // Update a candidate async function updateCandidate(Candidate) { console.log('\n' + bold(cyan('===== UPDATE CANDIDATE ====='))); const email = await askQuestion('Enter email of candidate to update: '); try { const candidate = await Candidate.findOne({ email }); if (!candidate) { console.log(yellow(`āš ļø No candidate found with email: ${email}`)); } else { console.log(green('āœ… Current candidate information:')); console.log(formatCandidate(candidate)); console.log('\nEnter new values (or leave blank to keep current value):'); const updates = {}; updates.name = await askQuestion(`Name (${candidate.name}): `) || candidate.name; updates.phone = await askQuestion(`Phone (${candidate.phone}): `) || candidate.phone; updates.location = await askQuestion(`Location (${candidate.location}): `) || candidate.location; updates.technology = await askQuestion(`Technology (${candidate.technology}): `) || candidate.technology; updates.experience = await askQuestion(`Experience (${candidate.experience}): `) || candidate.experience; const relocateAnswer = await askQuestion(`Open to relocate? (y/n) (current: ${candidate.openToRelocate ? 'yes' : 'no'}): `); if (relocateAnswer) { updates.openToRelocate = relocateAnswer.toLowerCase() === 'y'; } const hotlistAnswer = await askQuestion(`Hotlisted? (y/n) (current: ${candidate.hotlisted ? 'yes' : 'no'}): `); if (hotlistAnswer) { updates.hotlisted = hotlistAnswer.toLowerCase() === 'y'; } const updated = await Candidate.findByIdAndUpdate( candidate._id, { $set: updates }, { new: true, runValidators: true } ); console.log(green('\nāœ… Candidate updated successfully!')); console.log(formatCandidate(updated)); } } catch (error) { console.error(red('āŒ Error updating candidate:'), error.message); } await continuePrompt(Candidate); } // Delete a candidate async function deleteCandidate(Candidate) { console.log('\n' + bold(cyan('===== DELETE CANDIDATE ====='))); const email = await askQuestion('Enter email of candidate to delete: '); try { const candidate = await Candidate.findOne({ email }); if (!candidate) { console.log(yellow(`āš ļø No candidate found with email: ${email}`)); } else { console.log(red('āš ļø You are about to delete the following candidate:')); console.log(formatCandidate(candidate)); const confirm = await askQuestion('Are you sure you want to delete this candidate? (y/n): '); if (confirm.toLowerCase() === 'y') { await Candidate.findByIdAndDelete(candidate._id); console.log(green('āœ… Candidate deleted successfully!')); } else { console.log(yellow('āš ļø Deletion cancelled.')); } } } catch (error) { console.error(red('āŒ Error deleting candidate:'), error.message); } await continuePrompt(Candidate); } // Helper to format candidate for display function formatCandidate(candidate) { return ` ID: ${candidate._id} Name: ${candidate.name} Email: ${candidate.email} Phone: ${candidate.phone || 'N/A'} Visa Status: ${candidate.visaStatus || 'N/A'} Location: ${candidate.location || 'N/A'} Open to Relocate: ${candidate.openToRelocate ? 'Yes' : 'No'} Experience: ${candidate.experience || 'N/A'} Technology: ${candidate.technology || 'N/A'} Hotlisted: ${candidate.hotlisted ? 'Yes' : 'No'} Created: ${candidate.createdAt ? new Date(candidate.createdAt).toLocaleString() : 'N/A'} Updated: ${candidate.updatedAt ? new Date(candidate.updatedAt).toLocaleString() : 'N/A'} `; } // Helper to ask a question and get an answer function askQuestion(question) { return new Promise(resolve => { rl.question(question, resolve); }); } // Continue prompt async function continuePrompt(Candidate) { await askQuestion('\nPress Enter to continue...'); await showMenu(Candidate); } // Run the program main().catch(console.error);