106 lines
2.3 KiB
JavaScript
106 lines
2.3 KiB
JavaScript
const mongoose = require('mongoose');
|
|
|
|
const userSchema = new mongoose.Schema({
|
|
name: {
|
|
type: String,
|
|
required: [true, 'Name ist erforderlich'],
|
|
trim: true
|
|
},
|
|
address: {
|
|
type: String,
|
|
required: [true, 'Adresse ist erforderlich'],
|
|
trim: true
|
|
},
|
|
phone: {
|
|
type: String,
|
|
required: [true, 'Telefonnummer ist erforderlich'],
|
|
trim: true
|
|
},
|
|
landline: {
|
|
type: String,
|
|
default: null,
|
|
trim: true
|
|
},
|
|
email: {
|
|
type: String,
|
|
default: null,
|
|
trim: true,
|
|
lowercase: true
|
|
},
|
|
passwordHash: {
|
|
type: String,
|
|
default: null
|
|
},
|
|
type: {
|
|
type: String,
|
|
required: [true, 'Typ ist erforderlich']
|
|
},
|
|
available: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
gps: {
|
|
lat: {
|
|
type: Number,
|
|
min: [-90, 'Latitude muss zwischen -90 und 90 liegen'],
|
|
max: [90, 'Latitude muss zwischen -90 und 90 liegen']
|
|
},
|
|
lng: {
|
|
type: Number,
|
|
min: [-180, 'Longitude muss zwischen -180 und 180 liegen'],
|
|
max: [180, 'Longitude muss zwischen -180 und 180 liegen']
|
|
}
|
|
},
|
|
photo: {
|
|
type: String,
|
|
default: null
|
|
},
|
|
// Soft delete fields
|
|
deleted: {
|
|
type: Boolean,
|
|
default: false,
|
|
index: true
|
|
},
|
|
deletedAt: {
|
|
type: Date,
|
|
default: null
|
|
},
|
|
deletedBy: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: 'Admin',
|
|
default: null
|
|
},
|
|
// Drohnenführer invite token for initial password setup
|
|
inviteToken: {
|
|
type: String,
|
|
default: null,
|
|
select: false
|
|
},
|
|
inviteTokenExpiry: {
|
|
type: Date,
|
|
default: null,
|
|
select: false
|
|
}
|
|
}, {
|
|
timestamps: true
|
|
});
|
|
|
|
// Indexes for performance
|
|
userSchema.index({ available: 1 });
|
|
userSchema.index({ type: 1 });
|
|
userSchema.index({ 'gps.lat': 1, 'gps.lng': 1 });
|
|
// Compound index for combined queries (available + type + sorting by name)
|
|
userSchema.index({ available: 1, type: 1, name: 1 });
|
|
// Text index for search functionality
|
|
userSchema.index({ name: 'text', address: 'text' });
|
|
|
|
// Query middleware - automatically exclude deleted documents
|
|
userSchema.pre(/^find/, function(next) {
|
|
// Only filter if not explicitly requesting deleted items
|
|
if (!this.getOptions().includeDeleted) {
|
|
this.where({ deleted: { $ne: true } });
|
|
}
|
|
next();
|
|
});
|
|
|
|
module.exports = mongoose.model('User', userSchema); |