297 lines
9.3 KiB
JavaScript
297 lines
9.3 KiB
JavaScript
/**
|
|
* 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);
|