diff --git a/notifications.js b/notifications.js index d50eac6..b88e3fc 100644 --- a/notifications.js +++ b/notifications.js @@ -1,5 +1,4 @@ // notifications.js -const postgresLogger = require('./postgres'); const { getDb } = require('./database'); const emailNotifications = require('./email-notifications'); @@ -86,24 +85,6 @@ async function sendTaskNotifications(type, taskId, taskTitle, taskDescription, a } } - // Логируем в PostgreSQL (если настроено) - let postgresLogIds = []; - if (postgresLogger.initialized) { - postgresLogIds = await logNotificationToPostgres({ - type, - taskId, - taskTitle, - taskDescription, - authorId, - authorName, - authorLogin, - recipients, - comment, - status, - userName - }); - } - // 5. Отправляем email уведомления выбранным получателям for (const recipient of recipients) { const taskData = { @@ -217,90 +198,6 @@ async function checkUpcomingDeadlines() { }); } -/** - * Логирует уведомление в PostgreSQL - */ -async function logNotificationToPostgres(data) { - try { - const { - type, - taskId, - taskTitle, - taskDescription, - authorId, - authorName, - authorLogin, - recipients = [], - comment = '', - status = '', - userName = '', - error = '' - } = data; - - // Создаем сообщение - let messageContent = ''; - switch (type) { - case 'created': - messageContent = `Создана новая задача: ${taskTitle}`; - break; - case 'updated': - messageContent = `Обновлена задача: ${taskTitle}`; - break; - case 'rework': - messageContent = `Задача возвращена на доработку: ${taskTitle}. Комментарий: ${comment}`; - break; - case 'closed': - messageContent = `Задача закрыта: ${taskTitle}`; - break; - case 'status_changed': - messageContent = `Изменен статус задачи: ${taskTitle}. Новый статус: ${getStatusText(status)}`; - break; - } - - const logIds = []; - - for (const recipient of recipients) { - const logId = await postgresLogger.logNotification({ - taskId, - taskTitle, - taskDescription, - notificationType: type, - authorId, - authorName, - authorLogin, - recipientId: recipient.user_id, - recipientName: recipient.user_name, - recipientLogin: recipient.user_login, - messageContent: `${messageContent}\n\nЗадача: ${taskTitle}\nОписание: ${taskDescription || 'Без описания'}\nАвтор: ${authorName}`, - messageSubject: getNotificationSubject(type, taskTitle), - deliveryMethods: ['email', 'telegram', 'vk'], - comments: error ? `Ошибка: ${error}` : comment - }); - - if (logId) { - logIds.push(logId); - } - } - - return logIds; - - } catch (error) { - console.error('❌ Ошибка логирования в PostgreSQL:', error); - return []; - } -} - -/** - * Обновляет статус доставки уведомления в PostgreSQL - */ -async function updatePostgresLogStatus(logIds, status, errorMessage = null, sentAt = null) { - if (!logIds || logIds.length === 0) return; - - for (const logId of logIds) { - await postgresLogger.updateNotificationStatus(logId, status, errorMessage, sentAt); - } -} - /** * Возвращает тему уведомления в зависимости от типа */ diff --git a/postgres-init.js b/postgres-init.js deleted file mode 100644 index 28d6722..0000000 --- a/postgres-init.js +++ /dev/null @@ -1,100 +0,0 @@ -const { Client } = require('pg'); -require('dotenv').config(); - -async function initializeDatabase() { - console.log('🔄 Инициализация PostgreSQL...'); - - // Сначала подключаемся без конкретной БД - const adminClient = new Client({ - host: process.env.DB_HOST, - port: process.env.DB_PORT || 5432, - user: process.env.DB_USER, - password: process.env.DB_PASSWORD, - database: 'postgres' // Подключаемся к системной БД - }); - - try { - await adminClient.connect(); - console.log('✅ Подключение к PostgreSQL установлено'); - - // Проверяем существование базы данных - const dbCheck = await adminClient.query(` - SELECT 1 FROM pg_database WHERE datname = '${process.env.DB_NAME}' - `); - - if (dbCheck.rows.length === 0) { - console.log(`📦 База данных ${process.env.DB_NAME} не существует, создаем...`); - await adminClient.query(`CREATE DATABASE ${process.env.DB_NAME}`); - console.log(`✅ База данных ${process.env.DB_NAME} создана`); - } else { - console.log(`✅ База данных ${process.env.DB_NAME} уже существует`); - } - - await adminClient.end(); - - // Теперь подключаемся к созданной БД - const dbClient = new Client({ - host: process.env.DB_HOST, - port: process.env.DB_PORT || 5432, - user: process.env.DB_USER, - password: process.env.DB_PASSWORD, - database: process.env.DB_NAME - }); - - await dbClient.connect(); - - // Создаем таблицы - await dbClient.query(` - CREATE TABLE IF NOT EXISTS sms_logs ( - id SERIAL PRIMARY KEY, - task_id INTEGER NOT NULL, - task_title VARCHAR(500) NOT NULL, - task_description TEXT, - notification_type VARCHAR(50) NOT NULL, - creator_id INTEGER, - creator_name VARCHAR(255), - creator_login VARCHAR(100), - assignee_id INTEGER, - assignee_name VARCHAR(255), - assignee_login VARCHAR(100), - message_content TEXT NOT NULL, - message_subject VARCHAR(500), - delivery_methods JSONB DEFAULT '[]', - status VARCHAR(50) DEFAULT 'pending', - error_message TEXT, - retry_count INTEGER DEFAULT 0, - sent_at TIMESTAMP, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - comments TEXT - ) - `); - - // Создаем индексы - const indexes = [ - 'CREATE INDEX IF NOT EXISTS idx_sms_logs_task_id ON sms_logs(task_id)', - 'CREATE INDEX IF NOT EXISTS idx_sms_logs_creator_id ON sms_logs(creator_id)', - 'CREATE INDEX IF NOT EXISTS idx_sms_logs_assignee_id ON sms_logs(assignee_id)', - 'CREATE INDEX IF NOT EXISTS idx_sms_logs_status ON sms_logs(status)', - 'CREATE INDEX IF NOT EXISTS idx_sms_logs_created_at ON sms_logs(created_at)' - ]; - - for (const indexQuery of indexes) { - try { - await dbClient.query(indexQuery); - } catch (err) { - console.warn(`⚠️ Индекс не создан: ${err.message}`); - } - } - - await dbClient.end(); - console.log('✅ PostgreSQL полностью инициализирован'); - return true; - - } catch (error) { - console.error('❌ Ошибка инициализации PostgreSQL:', error.message); - return false; - } -} - -module.exports = { initializeDatabase }; \ No newline at end of file diff --git a/postgres.js b/postgres.js deleted file mode 100644 index 3195886..0000000 --- a/postgres.js +++ /dev/null @@ -1,206 +0,0 @@ -const { Pool } = require('pg'); -require('dotenv').config(); -const { initializeDatabase } = require('./postgres-init'); - -class PostgresLogger { - constructor() { - this.pool = null; - this.initialized = false; - this.init(); - } - - async init() { - try { - console.log('🔌 Инициализация PostgreSQL логгера...'); - - // Проверяем наличие переменных окружения - if (!process.env.DB_HOST || !process.env.DB_USER || !process.env.DB_PASSWORD) { - console.log('⚠️ Переменные окружения для PostgreSQL не заданы'); - console.log(' DB_HOST:', process.env.DB_HOST || 'не задано'); - console.log(' DB_USER:', process.env.DB_USER || 'не задано'); - console.log(' DB_NAME:', process.env.DB_NAME || 'minicrm'); - this.initialized = false; - return; - } - - // Создаем базу данных если нужно - const dbInitialized = await initializeDatabase(); - if (!dbInitialized) { - console.error('❌ Не удалось инициализировать базу данных'); - this.initialized = false; - return; - } - - // Подключаемся к созданной БД - this.pool = new Pool({ - host: process.env.DB_HOST, - port: process.env.DB_PORT || 5432, - database: process.env.DB_NAME || 'minicrm', - user: process.env.DB_USER, - password: process.env.DB_PASSWORD, - max: 5, - idleTimeoutMillis: 30000, - connectionTimeoutMillis: 5000, - }); - - // Тестируем подключение - const client = await this.pool.connect(); - await client.query('SELECT 1'); - client.release(); - - this.initialized = true; - console.log('✅ PostgreSQL логгер готов к работе'); - - } catch (error) { - console.error('❌ Ошибка инициализации PostgreSQL логгера:', error.message); - console.error(' Убедитесь, что:'); - console.error(' 1. PostgreSQL сервер запущен на', process.env.DB_HOST); - console.error(' 2. Пользователь', process.env.DB_USER, 'имеет права на создание БД'); - console.error(' 3. Пароль указан верно в .env файле'); - this.initialized = false; - } - } - - async logNotification(notificationData) { - if (!this.initialized) { - console.log('⚠️ PostgreSQL не инициализирован, логирование пропущено'); - return null; - } - - const { - taskId, - taskTitle, - taskDescription = '', - notificationType, - authorId, - authorName, - authorLogin, - recipientId, - recipientName, - recipientLogin, - messageContent, - messageSubject = '', - deliveryMethods = ['email', 'telegram', 'vk'], - comments = '' - } = notificationData; - - let client; - try { - client = await this.pool.connect(); - - const query = ` - INSERT INTO sms_logs ( - task_id, task_title, task_description, notification_type, - creator_id, creator_name, creator_login, - assignee_id, assignee_name, assignee_login, - message_content, message_subject, delivery_methods, - status, comments, created_at - ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, CURRENT_TIMESTAMP) - RETURNING id; - `; - - const values = [ - taskId, - taskTitle?.substring(0, 500) || 'Без названия', - taskDescription?.substring(0, 5000) || '', - notificationType, - authorId, - authorName || 'Неизвестно', - authorLogin || 'unknown', - recipientId, - recipientName || 'Неизвестно', - recipientLogin || 'unknown', - messageContent?.substring(0, 5000) || '', - messageSubject?.substring(0, 500) || '', - JSON.stringify(deliveryMethods), - 'pending', - comments - ]; - - const result = await client.query(query, values); - const logId = result.rows[0]?.id; - - if (logId) { - console.log(`📝 Уведомление записано в PostgreSQL, ID: ${logId}`); - } - - return logId || null; - - } catch (error) { - console.error('❌ Ошибка записи уведомления в PostgreSQL:', error.message); - return null; - } finally { - if (client) client.release(); - } - } - - async updateNotificationStatus(logId, status, errorMessage = null, sentAt = null) { - if (!this.initialized || !logId) return; - - let client; - try { - client = await this.pool.connect(); - - const query = ` - UPDATE sms_logs - SET status = $1, - error_message = $2, - sent_at = $3, - updated_at = CURRENT_TIMESTAMP - WHERE id = $4; - `; - - await client.query(query, [ - status, - errorMessage, - sentAt ? new Date(sentAt) : (status === 'sent' ? new Date() : null), - logId - ]); - - console.log(`📝 Статус уведомления ${logId} обновлен на: ${status}`); - - } catch (error) { - console.error('❌ Ошибка обновления статуса уведомления:', error.message); - } finally { - if (client) client.release(); - } - } - - async healthCheck() { - if (!this.initialized) { - return { - connected: false, - error: 'PostgreSQL не инициализирован', - timestamp: new Date().toISOString() - }; - } - - let client; - try { - client = await this.pool.connect(); - await client.query('SELECT 1'); - - return { - connected: true, - timestamp: new Date().toISOString(), - database: process.env.DB_NAME || 'minicrm', - host: process.env.DB_HOST - }; - - } catch (error) { - return { - connected: false, - error: error.message, - timestamp: new Date().toISOString() - }; - } finally { - if (client) client.release(); - } - } - - // Другие методы остаются без изменений... -} - -// Экспортируем singleton -const postgresLogger = new PostgresLogger(); -module.exports = postgresLogger; \ No newline at end of file diff --git a/server.js b/server.js index f23c540..c257043 100644 --- a/server.js +++ b/server.js @@ -12,7 +12,6 @@ const userListsAPI = require('./api-user-lists'); // Импортируем модули const { initializeDatabase, getDb, isInitialized } = require('./database'); const authService = require('./auth'); -const postgresLogger = require('./postgres'); const { sendTaskNotifications, checkUpcomingDeadlines, getStatusText } = require('./notifications'); const { setupUploadMiddleware } = require('./upload-middleware'); const { setupTaskEndpoints } = require('./task-endpoints'); @@ -735,20 +734,6 @@ app.get('/api/notification-stats', requireAuth, async (req, res) => { } }); -// API для проверки состояния PostgreSQL -app.get('/api/postgres-health', requireAuth, async (req, res) => { - try { - if (req.session.user.role !== 'admin') { - return res.status(403).json({ error: 'Недостаточно прав' }); - } - - const health = await postgresLogger.healthCheck(); - res.json(health); - } catch (error) { - res.status(500).json({ error: error.message }); - } -}); - // Админ панель app.get('/admin', (req, res) => { if (!req.session.user) {