обновил бэк закупок

This commit is contained in:
2025-10-18 11:30:18 +03:00
parent 2b5e5564c8
commit 599ccd1582
16 changed files with 1260 additions and 554 deletions

View File

@@ -0,0 +1,64 @@
const mongoose = require('mongoose')
const companySchema = new mongoose.Schema({
fullName: {
type: String,
required: true
},
shortName: String,
inn: {
type: String,
unique: true,
sparse: true
},
ogrn: String,
legalForm: String,
industry: String,
companySize: String,
website: String,
phone: String,
email: String,
slogan: String,
description: String,
foundedYear: Number,
employeeCount: String,
revenue: String,
legalAddress: String,
actualAddress: String,
bankDetails: String,
logo: String,
rating: {
type: Number,
default: 0,
min: 0,
max: 5
},
reviews: {
type: Number,
default: 0
},
ownerId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
platformGoals: [String],
productsOffered: String,
productsNeeded: String,
partnerIndustries: [String],
partnerGeography: [String],
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
}
})
// Индексы для поиска
companySchema.index({ fullName: 'text', shortName: 'text', description: 'text' })
companySchema.index({ industry: 1 })
companySchema.index({ rating: -1 })
module.exports = mongoose.model('Company', companySchema)

View File

@@ -0,0 +1,37 @@
const mongoose = require('mongoose')
const messageSchema = new mongoose.Schema({
threadId: {
type: String,
required: true,
index: true
},
senderCompanyId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company',
required: true
},
recipientCompanyId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company',
required: true
},
text: {
type: String,
required: true
},
read: {
type: Boolean,
default: false
},
timestamp: {
type: Date,
default: Date.now,
index: true
}
})
// Индекс для быстрого поиска сообщений потока
messageSchema.index({ threadId: 1, timestamp: -1 })
module.exports = mongoose.model('Message', messageSchema)

View File

@@ -0,0 +1,46 @@
const mongoose = require('mongoose')
const productSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
category: {
type: String,
required: true
},
description: {
type: String,
required: true,
minlength: 20,
maxlength: 500
},
type: {
type: String,
enum: ['sell', 'buy'],
required: true
},
productUrl: String,
companyId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company',
required: true
},
price: String,
unit: String,
minOrder: String,
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
}
})
// Индекс для поиска
productSchema.index({ companyId: 1, type: 1 })
productSchema.index({ name: 'text', description: 'text' })
module.exports = mongoose.model('Product', productSchema)

View File

@@ -0,0 +1,67 @@
const mongoose = require('mongoose')
const bcrypt = require('bcryptjs')
const userSchema = new mongoose.Schema({
email: {
type: String,
required: true,
unique: true,
lowercase: true,
trim: true,
match: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
},
password: {
type: String,
required: true,
minlength: 8
},
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
position: String,
phone: String,
companyId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Company'
},
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
}
})
// Хешировать пароль перед сохранением
userSchema.pre('save', async function(next) {
if (!this.isModified('password')) return next()
try {
const salt = await bcrypt.genSalt(10)
this.password = await bcrypt.hash(this.password, salt)
next()
} catch (error) {
next(error)
}
})
// Метод для сравнения паролей
userSchema.methods.comparePassword = async function(candidatePassword) {
return await bcrypt.compare(candidatePassword, this.password)
}
// Скрыть пароль при преобразовании в JSON
userSchema.methods.toJSON = function() {
const obj = this.toObject()
delete obj.password
return obj
}
module.exports = mongoose.model('User', userSchema)