149 lines
3.4 KiB
JavaScript
149 lines
3.4 KiB
JavaScript
const mongoose = require('mongoose');
|
||
|
||
const UserSchema = new mongoose.Schema({
|
||
telegramId: {
|
||
type: String,
|
||
required: true,
|
||
unique: true
|
||
},
|
||
username: {
|
||
type: String,
|
||
required: true
|
||
},
|
||
firstName: String,
|
||
lastName: String,
|
||
photoUrl: String,
|
||
bio: {
|
||
type: String,
|
||
default: '',
|
||
maxlength: 300
|
||
},
|
||
role: {
|
||
type: String,
|
||
enum: ['user', 'moderator', 'admin'],
|
||
default: 'user'
|
||
},
|
||
followers: [{
|
||
type: mongoose.Schema.Types.ObjectId,
|
||
ref: 'User'
|
||
}],
|
||
following: [{
|
||
type: mongoose.Schema.Types.ObjectId,
|
||
ref: 'User'
|
||
}],
|
||
settings: {
|
||
whitelist: {
|
||
noFurry: { type: Boolean, default: false },
|
||
onlyAnime: { type: Boolean, default: false },
|
||
// Скрыть контент 18+
|
||
noNSFW: { type: Boolean, default: false },
|
||
// Скрыть гомосексуальный контент
|
||
noHomo: { type: Boolean, default: true }
|
||
},
|
||
searchPreference: {
|
||
type: String,
|
||
enum: ['furry', 'anime'],
|
||
default: 'furry'
|
||
}
|
||
},
|
||
// Предпочитаемые теги для ленты по интересам
|
||
preferredTags: [{
|
||
type: String,
|
||
lowercase: true,
|
||
trim: true
|
||
}],
|
||
// Предложенные пользователем теги (ожидают модерации)
|
||
suggestedTags: [{
|
||
tagName: {
|
||
type: String,
|
||
required: true,
|
||
lowercase: true,
|
||
trim: true
|
||
},
|
||
category: {
|
||
type: String,
|
||
enum: ['theme', 'style', 'mood', 'technical']
|
||
},
|
||
description: String,
|
||
status: {
|
||
type: String,
|
||
enum: ['pending', 'approved', 'rejected'],
|
||
default: 'pending'
|
||
},
|
||
createdAt: {
|
||
type: Date,
|
||
default: Date.now
|
||
}
|
||
}],
|
||
lastActiveAt: {
|
||
type: Date,
|
||
default: Date.now
|
||
},
|
||
banned: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
bannedUntil: Date,
|
||
// Реферальная система
|
||
referralCode: {
|
||
type: String,
|
||
unique: true,
|
||
sparse: true
|
||
},
|
||
referredBy: {
|
||
type: mongoose.Schema.Types.ObjectId,
|
||
ref: 'User'
|
||
},
|
||
referralsCount: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
// Массив дат входа (для реферальной системы)
|
||
loginDates: [{
|
||
type: Date
|
||
}],
|
||
// Флаг, что реферал уже засчитан
|
||
referralCounted: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
// Билеты для Monthly Ladder
|
||
tickets: {
|
||
type: Number,
|
||
default: 0
|
||
},
|
||
// Email и пароль для авторизации через логин/пароль
|
||
email: {
|
||
type: String,
|
||
lowercase: true,
|
||
trim: true,
|
||
sparse: true, // Разрешить null, но если есть - должен быть уникальным
|
||
index: true
|
||
},
|
||
passwordHash: {
|
||
type: String,
|
||
select: false // Не возвращать по умолчанию
|
||
},
|
||
emailVerified: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
createdAt: {
|
||
type: Date,
|
||
default: Date.now
|
||
}
|
||
});
|
||
|
||
// Генерировать реферальный код перед сохранением
|
||
UserSchema.pre('save', async function(next) {
|
||
if (!this.referralCode) {
|
||
// Генерировать уникальный код на основе telegramId
|
||
const code = `ref_${this.telegramId.slice(-8)}${Math.random().toString(36).substring(2, 6)}`.toUpperCase();
|
||
this.referralCode = code;
|
||
}
|
||
next();
|
||
});
|
||
|
||
module.exports = mongoose.model('User', UserSchema);
|
||
|