UNPKG

@ideal-photography/shared

Version:

Shared MongoDB and utility logic for Ideal Photography PWAs: users, products, services, bookings, orders/cart, galleries, reviews, notifications, campaigns, settings, audit logs, minimart items/orders, and push notification subscriptions.

186 lines (167 loc) 6.36 kB
import mongoose from 'mongoose'; // Import all models from shared/models directory import User from '../models/User.js'; import Admin from '../models/Admin.js'; import AdminInvite from '../models/AdminInvite.js'; import RefreshToken from '../models/RefreshToken.js'; import Equipment from '../models/Equipment.js'; import Booking from '../models/Booking.js'; import Review from '../models/Review.js'; import Campaign from '../models/Campaign.js'; import Notification from '../models/Notification.js'; import Order from '../models/Order.js'; import Wishlist from '../models/Wishlist.js'; import Transaction from '../models/Transaction.js'; import AuditLog from '../models/AuditLog.js'; import Settings from '../models/Settings.js'; import BookingWorkflow, { WorkflowInstance } from '../models/BookingWorkflow.js'; import MakeoverOffer from '../models/MakeoverOffer.js'; import StudioSession from '../models/StudioSession.js'; import MinimartItem from '../models/MinimartItem.js'; import Cart from '../models/SimpleCart.js'; import UserPushSubscription from '../models/UserPushSubscription.js'; import AdminPushSubscription from '../models/AdminPushSubscription.js'; // Database connection helper const connectDB = async (uri, options = {}) => { try { const defaultOptions = { maxPoolSize: 10, serverSelectionTimeoutMS: 5000, socketTimeoutMS: 45000, // Remove problematic options that aren't supported in this MongoDB driver version }; await mongoose.connect(uri, { ...defaultOptions, ...options }); console.log('✅ MongoDB connected successfully'); return mongoose.connection; } catch (error) { console.error('❌ MongoDB connection error:', error); throw error; } }; // Database initialization helper const initializeDB = async () => { try { // Create default settings if they don't exist const settingsCount = await Settings.countDocuments(); if (settingsCount === 0) { await Settings.createDefaults(); console.log('✅ Default settings created'); } // TODO: Temporarily disable index creation to avoid conflicts // Create indexes for all models // await Promise.all([ // User.createIndexes(), // Product.createIndexes(), // Booking.createIndexes(), // Service.createIndexes(), // Gallery.createIndexes(), // Review.createIndexes(), // Campaign.createIndexes(), // Notification.createIndexes(), // Order.createIndexes(), // AuditLog.createIndexes(), // Settings.createIndexes() // ]); // Seed first super admin if configured and none exists const hasAnyAdmin = await Admin.countDocuments(); const defaultUser = process.env.DEFAULT_ADMIN_USER; const defaultPass = process.env.DEFAULT_ADMIN_PASS; if (!hasAnyAdmin && defaultUser && defaultPass) { // Import permissions to get the correct permission values const { getPermissionsForRole } = await import('../constants/permissions.js'); const admin = await Admin.create({ username: String(defaultUser).trim(), password: String(defaultPass), role: 'super_admin', permissions: getPermissionsForRole('super_admin'), isVerified: true, isActive: true }); console.log(`✅ Seeded default super admin '${admin.username}'`); } // Ensure all existing admins have correct permissions (migration) await ensureCorrectPermissions(); console.log('✅ Database initialized (indexes skipped for development)'); } catch (error) { console.error('❌ Database initialization error:', error); throw error; } }; // Migration function to ensure all admins have correct permissions const ensureCorrectPermissions = async () => { try { const { getPermissionsForRole } = await import('../constants/permissions.js'); // Get all admins const admins = await Admin.find({}); for (const admin of admins) { const correctPermissions = getPermissionsForRole(admin.role); const missingPermissions = correctPermissions.filter(perm => !admin.permissions.includes(perm)); if (missingPermissions.length > 0) { console.log(`🔄 Migrating permissions for ${admin.role} ${admin.username}: adding ${missingPermissions.length} missing permissions`); admin.permissions = correctPermissions; await admin.save(); } } console.log('✅ Permission migration completed'); } catch (error) { console.error('❌ Permission migration error:', error); // Don't throw error - this is a migration, not critical for startup } }; export { mongoose, connectDB, initializeDB }; export const models = { User, Admin, AdminInvite, RefreshToken, Equipment, Booking, Review, Campaign, Notification, Order, Wishlist, Transaction, AuditLog, Settings, BookingWorkflow, WorkflowInstance, MakeoverOffer, StudioSession, MinimartItem, Cart, UserPushSubscription, AdminPushSubscription, }; // Convenience exports for common operations export const utils = { // Create audit log entry createAuditLog: (action, actor, target, result, details = {}) => { return AuditLog.create({ action, actor, target, result, details, category: details.category || 'technical' }); }, // Get setting value getSetting: (key, defaultValue = null) => { return Settings.get(key, defaultValue); }, // Set setting value setSetting: (key, value, changedBy, reason = '') => { return Settings.set(key, value, changedBy, reason); }, // Send notification sendNotification: async (notificationData) => { const notification = await Notification.create(notificationData); // TODO: Integrate with actual notification delivery system return notification; } };