206 lines
7.4 KiB
JavaScript
206 lines
7.4 KiB
JavaScript
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; |