Repository navigation
Expand file tree
/
Copy pathmodels.js
More file actions
98 lines (89 loc) · 3.6 KB
/
Copy pathmodels.js
File metadata and controls
98 lines (89 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import mongoose from 'mongoose'
function normalizeUserRole(role = 'staff') {
const normalized = String(role || 'staff').trim().toLowerCase()
return ['admin', 'principal', 'secretary', 'staff'].includes(normalized)
? normalized
: 'staff'
}
function getPriorityByRole(role = 'staff') {
const normalized = normalizeUserRole(role)
if (normalized === 'secretary') return 'highest'
if (normalized === 'principal') return 'high'
if (normalized === 'admin') return 'medium'
return 'low'
}
// User Schema
const UserSchema = new mongoose.Schema({
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
role: { type: String, enum: ['admin', 'principal', 'secretary', 'staff'], default: 'staff' },
name: { type: String, required: true },
// Whether bookings from this user should be auto-approved
autoApprove: { type: Boolean, default: false },
// Role-based priority category for user management display and policies.
priority: { type: String, enum: ['low', 'medium', 'high', 'highest'], default: 'low' },
department: String,
createdAt: { type: Date, default: Date.now }
})
UserSchema.pre('save', function(next) {
this.role = normalizeUserRole(this.role)
this.priority = getPriorityByRole(this.role)
next()
})
// Event Schema
const EventSchema = new mongoose.Schema({
title: { type: String, required: true },
description: { type: String, required: true },
date: { type: Date, required: true },
time: { type: String, required: true },
venue: { type: String, required: true },
eventType: { type: String, enum: ['Workshop', 'Seminar', 'Conference', 'Alumni Talk', 'Meeting', 'Competition', 'Cultural', 'Sports', 'Other', ''], default: '' },
image: String,
createdBy: { type: String, required: true },
createdAt: { type: Date, default: Date.now }
})
// Booking Schema
const BookingSchema = new mongoose.Schema({
bookingId: { type: String, unique: true },
venue: { type: String, required: true },
date: { type: Date, required: true },
time: { type: String, required: true },
duration: { type: Number, required: true, default: 1 }, // Duration in hours
attendees: { type: Number, required: true },
organizer: { type: String, required: true },
email: { type: String, required: true },
purpose: { type: String, required: true },
purposeCategory: {
type: String,
enum: ['Alumni Talk', 'Workshop', 'Seminar', 'Events', 'Other'],
default: 'Other'
},
status: {
type: String,
enum: ['pending', 'approved', 'rejected', 'cancelled'],
default: 'pending'
},
userRole: String,
priority: { type: Number, default: 1 },
originalVenue: String, // For moved bookings
movedReason: String, // Reason for venue change
venueCapacity: Number, // Capacity of selected venue
approvedBy: String, // Email of admin who approved
approvalDate: Date, // Date when approved
createdAt: { type: Date, default: Date.now },
updatedAt: { type: Date, default: Date.now }
})
BookingSchema.index({ venue: 1, date: 1, status: 1 })
BookingSchema.index({ email: 1, createdAt: -1 })
// Generate booking ID before saving
BookingSchema.pre('save', function(next) {
if (!this.bookingId) {
this.bookingId = 'BK' + Date.now() + Math.random().toString(36).substring(2, 6).toUpperCase()
}
this.updatedAt = new Date()
next()
})
// Use existing models if already compiled, otherwise compile new ones
export const User = mongoose.models.User || mongoose.model('User', UserSchema)
export const Event = mongoose.models.Event || mongoose.model('Event', EventSchema)
export const Booking = mongoose.models.Booking || mongoose.model('Booking', BookingSchema)