Files
sst_site/models/Service.js
Andrey K. Choi 9477ff6de0 feat: Реализован полный CRUD для админ-панели и улучшена функциональность
- Portfolio CRUD: добавление, редактирование, удаление, переключение публикации
- Services CRUD: полное управление услугами с возможностью активации/деактивации
- Banner system: новая модель Banner с CRUD операциями и аналитикой кликов
- Telegram integration: расширенные настройки бота, обнаружение чатов, отправка сообщений
- Media management: улучшенная загрузка файлов с оптимизацией изображений и превью
- UI improvements: обновлённые админ-панели с rich-text редактором и drag&drop загрузкой
- Database: добавлена таблица banners с полями для баннеров и аналитики
2025-10-22 20:32:16 +09:00

96 lines
1.9 KiB
JavaScript

const { DataTypes } = require('sequelize');
const { sequelize } = require('../config/database');
const Service = sequelize.define('Service', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false,
validate: {
len: [1, 255]
},
set(value) {
this.setDataValue('name', value.trim());
}
},
description: {
type: DataTypes.TEXT,
allowNull: false
},
shortDescription: {
type: DataTypes.STRING(150),
allowNull: false
},
icon: {
type: DataTypes.STRING,
allowNull: false
},
category: {
type: DataTypes.ENUM('development', 'design', 'consulting', 'marketing', 'maintenance'),
allowNull: false
},
features: {
type: DataTypes.JSONB,
defaultValue: []
},
pricing: {
type: DataTypes.JSONB,
allowNull: false,
validate: {
isValidPricing(value) {
if (!value.basePrice || value.basePrice < 0) {
throw new Error('Base price must be a positive number');
}
}
}
},
estimatedTime: {
type: DataTypes.JSONB,
allowNull: false,
validate: {
isValidTime(value) {
if (!value.min || !value.max || value.min > value.max) {
throw new Error('Invalid estimated time range');
}
}
}
},
isActive: {
type: DataTypes.BOOLEAN,
defaultValue: true
},
featured: {
type: DataTypes.BOOLEAN,
defaultValue: false
},
order: {
type: DataTypes.INTEGER,
defaultValue: 0
},
tags: {
type: DataTypes.ARRAY(DataTypes.STRING),
defaultValue: []
},
seo: {
type: DataTypes.JSONB,
defaultValue: {}
}
}, {
tableName: 'services',
timestamps: true,
indexes: [
{
fields: ['category', 'featured', 'order']
},
{
type: 'gin',
fields: ['tags']
}
]
});
module.exports = Service;