new procurement

This commit is contained in:
2025-10-23 09:49:04 +03:00
parent 99127c42e2
commit a6065dd95c
22 changed files with 1588 additions and 409 deletions

View File

@@ -0,0 +1,58 @@
const mongoose = require('mongoose');
const buyProductSchema = new mongoose.Schema({
companyId: {
type: String,
required: true,
index: true
},
name: {
type: String,
required: true
},
description: {
type: String,
required: true,
minlength: 10,
maxlength: 1000
},
quantity: {
type: String,
required: true
},
unit: {
type: String,
default: 'шт'
},
files: [{
id: String,
name: String,
url: String,
type: String,
size: Number,
uploadedAt: {
type: Date,
default: Date.now
}
}],
status: {
type: String,
enum: ['draft', 'published'],
default: 'published'
},
createdAt: {
type: Date,
default: Date.now,
index: true
},
updatedAt: {
type: Date,
default: Date.now
}
});
// Индексы для оптимизации поиска
buyProductSchema.index({ companyId: 1, createdAt: -1 });
buyProductSchema.index({ name: 'text', description: 'text' });
module.exports = mongoose.model('BuyProduct', buyProductSchema);

View File

@@ -1,4 +1,4 @@
const mongoose = require('mongoose')
const mongoose = require('mongoose');
const companySchema = new mongoose.Schema({
fullName: {
@@ -8,7 +8,6 @@ const companySchema = new mongoose.Schema({
shortName: String,
inn: {
type: String,
unique: true,
sparse: true
},
ogrn: String,
@@ -46,6 +45,10 @@ const companySchema = new mongoose.Schema({
productsNeeded: String,
partnerIndustries: [String],
partnerGeography: [String],
verified: {
type: Boolean,
default: false
},
createdAt: {
type: Date,
default: Date.now
@@ -54,11 +57,14 @@ const companySchema = new mongoose.Schema({
type: Date,
default: Date.now
}
})
}, {
collection: 'companies',
minimize: false
});
// Индексы для поиска
companySchema.index({ fullName: 'text', shortName: 'text', description: 'text' })
companySchema.index({ industry: 1 })
companySchema.index({ rating: -1 })
companySchema.index({ fullName: 'text', shortName: 'text', description: 'text' });
companySchema.index({ industry: 1 });
companySchema.index({ rating: -1 });
module.exports = mongoose.model('Company', companySchema)
module.exports = mongoose.model('Company', companySchema);

View File

@@ -1,4 +1,4 @@
const mongoose = require('mongoose')
const mongoose = require('mongoose');
const messageSchema = new mongoose.Schema({
threadId: {
@@ -29,9 +29,9 @@ const messageSchema = new mongoose.Schema({
default: Date.now,
index: true
}
})
});
// Индекс для быстрого поиска сообщений потока
messageSchema.index({ threadId: 1, timestamp: -1 })
messageSchema.index({ threadId: 1, timestamp: -1 });
module.exports = mongoose.model('Message', messageSchema)
module.exports = mongoose.model('Message', messageSchema);

View File

@@ -1,4 +1,4 @@
const mongoose = require('mongoose')
const mongoose = require('mongoose');
const productSchema = new mongoose.Schema({
name: {
@@ -22,25 +22,36 @@ const productSchema = new mongoose.Schema({
},
productUrl: String,
companyId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company',
required: true
type: String,
required: true,
index: true
},
price: String,
unit: String,
minOrder: String,
createdAt: {
type: Date,
default: Date.now
default: Date.now,
index: true
},
updatedAt: {
type: Date,
default: Date.now
}
})
});
// Индекс для поиска
productSchema.index({ companyId: 1, type: 1 })
productSchema.index({ name: 'text', description: 'text' })
productSchema.index({ companyId: 1, type: 1 });
productSchema.index({ name: 'text', description: 'text' });
module.exports = mongoose.model('Product', productSchema)
// Transform _id to id in JSON output
productSchema.set('toJSON', {
transform: (doc, ret) => {
ret.id = ret._id;
delete ret._id;
delete ret.__v;
return ret;
}
});
module.exports = mongoose.model('Product', productSchema);

View File

@@ -0,0 +1,58 @@
const mongoose = require('mongoose');
const reviewSchema = new mongoose.Schema({
companyId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company',
required: true,
index: true
},
authorCompanyId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company',
required: true
},
authorName: {
type: String,
required: true
},
authorCompany: {
type: String,
required: true
},
rating: {
type: Number,
required: true,
min: 1,
max: 5
},
comment: {
type: String,
required: true,
minlength: 10,
maxlength: 1000
},
date: {
type: Date,
default: Date.now
},
verified: {
type: Boolean,
default: true
},
createdAt: {
type: Date,
default: Date.now,
index: true
},
updatedAt: {
type: Date,
default: Date.now
}
});
// Индексы для оптимизации поиска
reviewSchema.index({ companyId: 1, createdAt: -1 });
reviewSchema.index({ authorCompanyId: 1 });
module.exports = mongoose.model('Review', reviewSchema);

View File

@@ -1,5 +1,5 @@
const mongoose = require('mongoose')
const bcrypt = require('bcryptjs')
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema({
email: {
@@ -37,31 +37,37 @@ const userSchema = new mongoose.Schema({
type: Date,
default: Date.now
}
})
}, {
collection: 'users',
minimize: false,
toObject: { versionKey: false }
});
userSchema.set('toObject', { virtuals: false, versionKey: false });
// Хешировать пароль перед сохранением
userSchema.pre('save', async function(next) {
if (!this.isModified('password')) return next()
if (!this.isModified('password')) return next();
try {
const salt = await bcrypt.genSalt(10)
this.password = await bcrypt.hash(this.password, salt)
next()
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
next();
} catch (error) {
next(error)
next(error);
}
})
});
// Метод для сравнения паролей
userSchema.methods.comparePassword = async function(candidatePassword) {
return await bcrypt.compare(candidatePassword, this.password)
}
return await bcrypt.compare(candidatePassword, this.password);
};
// Скрыть пароль при преобразовании в JSON
userSchema.methods.toJSON = function() {
const obj = this.toObject()
delete obj.password
return obj
}
const obj = this.toObject();
delete obj.password;
return obj;
};
module.exports = mongoose.model('User', userSchema)
module.exports = mongoose.model('User', userSchema);