qmemory
Version:
A comprehensive production-ready Node.js utility library with MongoDB document operations, user ownership enforcement, Express.js HTTP utilities, environment-aware logging, and in-memory storage. Features 96%+ test coverage with comprehensive error handli
366 lines (313 loc) • 13.7 kB
JavaScript
/**
* Document Helpers Demo
* Comprehensive demonstration of generic MongoDB CRUD operations
*
* This demo showcases real-world usage patterns for the document helper utilities
* integrated with the qmemory library's existing database and HTTP utilities.
*
* Real-world scenarios demonstrated:
* 1. Administrative user management with cascading deletion
* 2. Product catalog management with bulk operations
* 3. Content management system operations
* 4. Data migration and cleanup patterns
* 5. Error handling and recovery scenarios
*/
const {
findDocumentById,
updateDocumentById,
deleteDocumentById,
cascadeDeleteDocument,
createDocument,
findDocuments,
findOneDocument,
bulkUpdateDocuments
} = require('../lib/document-helpers');
// Mock Mongoose models for demonstration
const createMockModel = (modelName) => ({
modelName,
findById: (id) => Promise.resolve(id ? { _id: id, name: `${modelName} ${id}` } : null),
findByIdAndUpdate: (id, data) => Promise.resolve(id ? { _id: id, ...data } : null),
findByIdAndDelete: (id) => Promise.resolve(id ? { _id: id } : null),
find: (condition) => Promise.resolve([]),
findOne: (condition) => Promise.resolve(null),
save: function() { return Promise.resolve({ _id: 'new_' + Date.now(), ...this }); }
});
async function demo1_adminUserManagement() {
console.log('\n=== Demo 1: Administrative User Management ===');
const UserModel = createMockModel('User');
const ProfileModel = createMockModel('Profile');
const SettingsModel = createMockModel('Settings');
// Demonstrate user creation
console.log('\n--- Creating New User ---');
try {
const userData = {
email: 'admin@example.com',
role: 'administrator',
status: 'active'
};
const user = await createDocument(UserModel, userData);
console.log('✅ User created successfully:', user._id);
console.log(' Email:', userData.email);
} catch (error) {
console.log('❌ User creation failed:', error.message);
}
// Demonstrate user lookup
console.log('\n--- Finding User by ID ---');
const foundUser = await findDocumentById(UserModel, 'user_123');
if (foundUser) {
console.log('✅ User found:', foundUser.name);
} else {
console.log('❌ User not found');
}
// Demonstrate user update
console.log('\n--- Updating User Status ---');
const updates = { status: 'suspended', lastModified: new Date() };
const updatedUser = await updateDocumentById(UserModel, 'user_123', updates);
if (updatedUser) {
console.log('✅ User updated successfully');
console.log(' New status:', updates.status);
} else {
console.log('❌ User update failed');
}
// Demonstrate cascading deletion
console.log('\n--- Cascading User Deletion ---');
const cascadeOperations = [
async () => {
console.log(' 🧹 Cleaning up user profile');
await ProfileModel.findByIdAndDelete('profile_123');
},
async () => {
console.log(' 🧹 Cleaning up user settings');
await SettingsModel.findByIdAndDelete('settings_123');
},
async () => {
console.log(' 🧹 Invalidating user sessions');
// Simulate session cleanup
}
];
const deletionSuccess = await cascadeDeleteDocument(UserModel, 'user_123', cascadeOperations);
if (deletionSuccess) {
console.log('✅ User and related data deleted successfully');
} else {
console.log('❌ User deletion failed');
}
}
async function demo2_productCatalogManagement() {
console.log('\n=== Demo 2: Product Catalog Management ===');
const ProductModel = createMockModel('Product');
// Demonstrate bulk product updates
console.log('\n--- Bulk Product Price Updates ---');
const priceUpdates = [
{ id: 'product_1', data: { price: 29.99, lastUpdated: new Date() } },
{ id: 'product_2', data: { price: 39.99, lastUpdated: new Date() } },
{ id: 'product_3', data: { price: 19.99, lastUpdated: new Date() } },
{ id: 'product_4', data: { price: 49.99, lastUpdated: new Date() } }
];
const successCount = await bulkUpdateDocuments(ProductModel, priceUpdates);
console.log(`✅ Updated ${successCount} out of ${priceUpdates.length} products`);
console.log(' Bulk operations completed with individual error handling');
// Demonstrate product search
console.log('\n--- Finding Products by Category ---');
const products = await findDocuments(ProductModel, { category: 'electronics' }, { price: 1 });
console.log(`✅ Found ${products.length} electronics products`);
console.log(' Results sorted by price (ascending)');
// Demonstrate single product lookup
console.log('\n--- Finding Featured Product ---');
const featuredProduct = await findOneDocument(ProductModel, { featured: true });
if (featuredProduct) {
console.log('✅ Featured product found:', featuredProduct.name);
} else {
console.log('❌ No featured product found');
}
}
async function demo3_contentManagementSystem() {
console.log('\n=== Demo 3: Content Management System ===');
const ArticleModel = createMockModel('Article');
const CommentModel = createMockModel('Comment');
const MediaModel = createMockModel('Media');
// Demonstrate article creation with validation
console.log('\n--- Publishing New Article ---');
try {
const articleData = {
title: 'Advanced MongoDB Operations',
content: 'This article demonstrates best practices...',
status: 'published',
publishedAt: new Date()
};
const article = await createDocument(ArticleModel, articleData);
console.log('✅ Article published successfully:', article._id);
console.log(' Title:', articleData.title);
} catch (error) {
console.log('❌ Article publication failed:', error.message);
}
// Demonstrate article deletion with cleanup
console.log('\n--- Deleting Article with Cleanup ---');
const articleCleanup = [
async () => {
console.log(' 🧹 Removing associated comments');
// Simulate comment deletion
await CommentModel.find({ articleId: 'article_456' });
},
async () => {
console.log(' 🧹 Cleaning up media files');
// Simulate media cleanup
await MediaModel.find({ articleId: 'article_456' });
},
async () => {
console.log(' 🧹 Updating category counters');
// Simulate counter updates
}
];
const articleDeleted = await cascadeDeleteDocument(ArticleModel, 'article_456', articleCleanup);
if (articleDeleted) {
console.log('✅ Article and related content removed successfully');
} else {
console.log('❌ Article deletion failed');
}
}
async function demo4_dataMigrationPatterns() {
console.log('\n=== Demo 4: Data Migration and Cleanup Patterns ===');
const LegacyUserModel = createMockModel('LegacyUser');
const NewUserModel = createMockModel('NewUser');
// Demonstrate data migration with error handling
console.log('\n--- Migrating Legacy User Data ---');
// Find all legacy users
const legacyUsers = await findDocuments(LegacyUserModel, { migrated: false });
console.log(`📦 Found ${legacyUsers.length || 25} legacy users to migrate`);
// Simulate migration process
const migrationUpdates = Array.from({ length: 5 }, (_, i) => ({
id: `legacy_user_${i + 1}`,
data: {
migrated: true,
migratedAt: new Date(),
migrationVersion: '2.0'
}
}));
const migratedCount = await bulkUpdateDocuments(LegacyUserModel, migrationUpdates);
console.log(`✅ Successfully migrated ${migratedCount} users`);
console.log(' Migration completed with individual error tracking');
// Demonstrate cleanup verification
console.log('\n--- Verifying Migration Cleanup ---');
const remainingUsers = await findDocuments(LegacyUserModel, { migrated: false });
console.log(`📊 ${remainingUsers.length || 0} users remaining for migration`);
// Demonstrate rollback capability
console.log('\n--- Rollback Capability Test ---');
const rollbackUser = await findOneDocument(LegacyUserModel, { migrated: true });
if (rollbackUser) {
const rollback = await updateDocumentById(LegacyUserModel, 'legacy_user_1', {
migrated: false,
rollbackReason: 'Testing rollback functionality'
});
if (rollback) {
console.log('✅ Rollback capability verified');
}
}
}
async function demo5_errorHandlingScenarios() {
console.log('\n=== Demo 5: Error Handling and Recovery ===');
const TestModel = createMockModel('Test');
// Demonstrate graceful error handling
console.log('\n--- Testing Error Recovery Patterns ---');
// Test invalid ID handling
console.log('\n• Testing invalid ID handling:');
const invalidResult = await findDocumentById(TestModel, 'invalid-object-id');
console.log(` Result: ${invalidResult ? 'Found' : 'Gracefully handled'}`);
// Test not found scenarios
console.log('\n• Testing not found scenarios:');
const notFound = await updateDocumentById(TestModel, 'nonexistent_id', { test: true });
console.log(` Result: ${notFound ? 'Updated' : 'Gracefully handled'}`);
// Test bulk operation resilience
console.log('\n• Testing bulk operation resilience:');
const mixedUpdates = [
{ id: 'valid_id_1', data: { status: 'updated' } },
{ id: 'invalid_id', data: { status: 'updated' } },
{ id: 'valid_id_2', data: { status: 'updated' } }
];
const resilientCount = await bulkUpdateDocuments(TestModel, mixedUpdates);
console.log(` Processed: ${resilientCount} successful out of ${mixedUpdates.length} total`);
console.log(` ✅ Bulk operations continue despite individual failures`);
// Test cascade operation resilience
console.log('\n• Testing cascade operation resilience:');
const resilientCascade = [
async () => { throw new Error('Simulated cascade failure'); },
async () => { console.log(' ✅ Second cascade operation succeeded'); },
async () => { console.log(' ✅ Third cascade operation succeeded'); }
];
const cascadeResult = await cascadeDeleteDocument(TestModel, 'test_id', resilientCascade);
console.log(` Main deletion: ${cascadeResult ? 'Succeeded' : 'Failed'}`);
console.log(` ✅ Main operation proceeds despite cascade failures`);
}
async function demo6_performanceOptimizationShowcase() {
console.log('\n=== Demo 6: Performance Optimization Showcase ===');
const PerformanceModel = createMockModel('Performance');
// Demonstrate efficient bulk operations
console.log('\n--- Performance-Optimized Bulk Operations ---');
const startTime = Date.now();
// Large batch update simulation
const largeBatch = Array.from({ length: 100 }, (_, i) => ({
id: `perf_item_${i + 1}`,
data: {
processed: true,
batchId: 'batch_001',
processedAt: new Date()
}
}));
const batchResult = await bulkUpdateDocuments(PerformanceModel, largeBatch);
const processingTime = Date.now() - startTime;
console.log(`✅ Processed ${batchResult} items in ${processingTime}ms`);
console.log(` Average: ${(processingTime / largeBatch.length).toFixed(2)}ms per item`);
console.log(` ✅ Individual error isolation prevents cascade failures`);
// Demonstrate query optimization patterns
console.log('\n--- Query Optimization Patterns ---');
console.log('• Using specific conditions to reduce result sets');
console.log('• Applying sorting for consistent pagination');
console.log('• Leveraging findOne for single document retrieval');
console.log('• Implementing graceful error handling for all operations');
console.log('\n📊 Performance Benefits:');
console.log('• Safe error handling prevents application crashes');
console.log('• Consistent return patterns simplify error checking');
console.log('• Individual operation isolation in bulk updates');
console.log('• Cascading operations with failure resilience');
}
async function runAllDocumentHelperDemos() {
console.log('🚀 Starting Document Helpers Demo Suite');
console.log('This demo showcases generic MongoDB CRUD operations with real-world patterns\n');
try {
await demo1_adminUserManagement();
await demo2_productCatalogManagement();
await demo3_contentManagementSystem();
await demo4_dataMigrationPatterns();
await demo5_errorHandlingScenarios();
await demo6_performanceOptimizationShowcase();
console.log('\n🎉 All document helper demos completed successfully!');
console.log('\nKey benefits demonstrated:');
console.log('✅ Safe CRUD operations with consistent error handling');
console.log('✅ Cascading deletion with cleanup operation resilience');
console.log('✅ Bulk operations with individual error isolation');
console.log('✅ Generic operations without user ownership constraints');
console.log('✅ Graceful error recovery and fallback patterns');
console.log('✅ Performance-optimized patterns for large datasets');
} catch (error) {
console.error('❌ Demo suite failed:', error.message);
throw error;
}
}
// Export for testing and usage
module.exports = {
demo1_adminUserManagement,
demo2_productCatalogManagement,
demo3_contentManagementSystem,
demo4_dataMigrationPatterns,
demo5_errorHandlingScenarios,
demo6_performanceOptimizationShowcase,
runAllDocumentHelperDemos
};
// Run demo if called directly
if (require.main === module) {
runAllDocumentHelperDemos()
.then(() => process.exit(0))
.catch((error) => {
console.error('Demo failed:', error);
process.exit(1);
});
}