ваше сообщение коммита
This commit is contained in:
@@ -114,13 +114,13 @@ app.use((req, res, next) => sessionConfig.sessionMiddleware(req, res, next));
|
||||
|
||||
// Добавим middleware для проверки сессии
|
||||
app.use(async (req, res, next) => {
|
||||
console.log('Request cookies:', req.headers.cookie);
|
||||
console.log('Session ID:', req.sessionID);
|
||||
// console.log('Request cookies:', req.headers.cookie);
|
||||
// console.log('Session ID:', req.sessionID);
|
||||
|
||||
// Проверяем сессию в базе данных
|
||||
if (req.sessionID) {
|
||||
const result = await db.getQuery()('SELECT sess FROM session WHERE sid = $1', [req.sessionID]);
|
||||
console.log('Session from DB:', result.rows[0]?.sess);
|
||||
// console.log('Session from DB:', result.rows[0]?.sess);
|
||||
}
|
||||
|
||||
// Если сессия уже есть, используем её
|
||||
@@ -156,7 +156,7 @@ app.use(async (req, res, next) => {
|
||||
await new Promise((resolve) => req.session.save(resolve));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking auth header:', error);
|
||||
// console.error('Error checking auth header:', error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ app.use(
|
||||
|
||||
// Логирование запросов
|
||||
app.use((req, res, next) => {
|
||||
console.log('[APP] Глобальный лог:', req.method, req.originalUrl);
|
||||
// console.log('[APP] Глобальный лог:', req.method, req.originalUrl);
|
||||
logger.info(`${req.method} ${req.url}`);
|
||||
next();
|
||||
});
|
||||
@@ -224,21 +224,21 @@ const nonceStore = new Map(); // или любая другая реализац
|
||||
const redactedValue = '***********';
|
||||
|
||||
// Логируем переменные окружения для отладки
|
||||
console.log('NODE_ENV:', process.env.NODE_ENV);
|
||||
console.log('PORT:', process.env.PORT);
|
||||
console.log('POSTGRES_HOST:', process.env.POSTGRES_HOST);
|
||||
console.log('POSTGRES_PORT:', process.env.POSTGRES_PORT);
|
||||
console.log('POSTGRES_DB:', process.env.POSTGRES_DB);
|
||||
console.log('POSTGRES_USER:', redactedValue);
|
||||
console.log('POSTGRES_PASSWORD:', redactedValue);
|
||||
console.log('TELEGRAM_BOT_TOKEN:', redactedValue);
|
||||
console.log('TELEGRAM_BOT_USERNAME:', process.env.TELEGRAM_BOT_USERNAME);
|
||||
console.log('OPENAI_API_KEY:', redactedValue);
|
||||
// console.log('NODE_ENV:', process.env.NODE_ENV);
|
||||
// console.log('PORT:', process.env.PORT);
|
||||
// console.log('POSTGRES_HOST:', process.env.POSTGRES_HOST);
|
||||
// console.log('POSTGRES_PORT:', process.env.POSTGRES_PORT);
|
||||
// console.log('POSTGRES_DB:', process.env.POSTGRES_DB);
|
||||
// console.log('POSTGRES_USER:', redactedValue);
|
||||
// console.log('POSTGRES_PASSWORD:', redactedValue);
|
||||
// console.log('TELEGRAM_BOT_TOKEN:', redactedValue);
|
||||
// console.log('TELEGRAM_BOT_USERNAME:', process.env.TELEGRAM_BOT_USERNAME);
|
||||
// console.log('OPENAI_API_KEY:', redactedValue);
|
||||
// console.log('SESSION_SECRET:', process.env.SESSION_SECRET); // Убираем вывод секретного ключа
|
||||
console.log('EMAIL_USER:', process.env.EMAIL_USER);
|
||||
console.log('EMAIL_PASSWORD:', redactedValue);
|
||||
// console.log('EMAIL_USER:', process.env.EMAIL_USER);
|
||||
// console.log('EMAIL_PASSWORD:', redactedValue);
|
||||
|
||||
console.log('typeof errorHandler:', typeof errorHandler, errorHandler.name);
|
||||
// console.log('typeof errorHandler:', typeof errorHandler, errorHandler.name);
|
||||
|
||||
// Добавляем обработчик ошибок последним
|
||||
app.use(errorHandler);
|
||||
@@ -303,7 +303,7 @@ setInterval(
|
||||
try {
|
||||
await db.getQuery('DELETE FROM session WHERE expire < NOW()');
|
||||
} catch (error) {
|
||||
console.error('Error cleaning old sessions:', error);
|
||||
// console.error('Error cleaning old sessions:', error);
|
||||
}
|
||||
},
|
||||
15 * 60 * 1000
|
||||
|
||||
@@ -44,7 +44,7 @@ async function initRoles() {
|
||||
(4, 'admin', 'Администратор с полным доступом');
|
||||
`);
|
||||
|
||||
console.log('Таблица roles создана и заполнена');
|
||||
// console.log('Таблица roles создана и заполнена');
|
||||
} else {
|
||||
// Проверяем наличие ролей
|
||||
const rolesExist = await pool.query(`
|
||||
@@ -74,11 +74,11 @@ async function initRoles() {
|
||||
`);
|
||||
}
|
||||
|
||||
console.log('Таблица roles обновлена');
|
||||
// console.log('Таблица roles обновлена');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка при инициализации таблицы roles:', error);
|
||||
// console.error('Ошибка при инициализации таблицы roles:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||
*/
|
||||
|
||||
console.log('[DIAG][auth.js] Файл загружен:', __filename);
|
||||
// console.log('[DIAG][auth.js] Файл загружен:', __filename);
|
||||
|
||||
const { createError } = require('../utils/error');
|
||||
const authService = require('../services/auth-service');
|
||||
@@ -30,14 +30,14 @@ try {
|
||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||
}
|
||||
} catch (keyError) {
|
||||
console.error('Error reading encryption key:', keyError);
|
||||
// console.error('Error reading encryption key:', keyError);
|
||||
}
|
||||
|
||||
/**
|
||||
* Middleware для проверки аутентификации
|
||||
*/
|
||||
const requireAuth = async (req, res, next) => {
|
||||
console.log('[DIAG][requireAuth] session:', req.session);
|
||||
// console.log('[DIAG][requireAuth] session:', req.session);
|
||||
if (!req.session || !req.session.authenticated) {
|
||||
return res.status(401).json({ error: 'Требуется аутентификация' });
|
||||
}
|
||||
@@ -148,7 +148,7 @@ async function checkRole(req, res, next) {
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
console.error('Error in checkRole middleware:', error);
|
||||
// console.error('Error in checkRole middleware:', error);
|
||||
res.status(500).json({ error: 'Internal server error' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,11 +18,11 @@ const { ERROR_CODES } = require('../utils/constants');
|
||||
* Middleware для обработки ошибок
|
||||
*/
|
||||
const errorHandler = (err, req, res, next) => {
|
||||
console.log('errorHandler called, arguments:', arguments);
|
||||
console.log('typeof res:', typeof res, 'isFunction:', typeof res === 'function');
|
||||
console.error('errorHandler: err =', err);
|
||||
console.error('errorHandler: typeof err =', typeof err);
|
||||
console.error('errorHandler: stack =', err && err.stack);
|
||||
// console.log('errorHandler called, arguments:', arguments);
|
||||
// console.log('typeof res:', typeof res, 'isFunction:', typeof res === 'function');
|
||||
// console.error('errorHandler: err =', err);
|
||||
// console.error('errorHandler: typeof err =', typeof err);
|
||||
// console.error('errorHandler: stack =', err && err.stack);
|
||||
// Логируем ошибку
|
||||
logger.error(`Error: ${err.message}`, {
|
||||
stack: err.stack,
|
||||
|
||||
@@ -146,28 +146,28 @@ router.post('/', async (req, res) => {
|
||||
// 4. Если это исходящее сообщение для Telegram — отправляем через бота
|
||||
if (channel === 'telegram' && direction === 'out') {
|
||||
try {
|
||||
console.log(`[messages.js] Попытка отправки сообщения в Telegram для user_id=${user_id}`);
|
||||
// console.log(`[messages.js] Попытка отправки сообщения в Telegram для user_id=${user_id}`);
|
||||
// Получаем Telegram ID пользователя
|
||||
const tgIdentity = await db.getQuery()(
|
||||
'SELECT decrypt_text(provider_id_encrypted, $3) as provider_id FROM user_identities WHERE user_id = $1 AND provider_encrypted = encrypt_text($2, $3) LIMIT 1',
|
||||
[user_id, 'telegram', encryptionKey]
|
||||
);
|
||||
console.log(`[messages.js] Результат поиска Telegram ID:`, tgIdentity.rows);
|
||||
// console.log(`[messages.js] Результат поиска Telegram ID:`, tgIdentity.rows);
|
||||
if (tgIdentity.rows.length > 0) {
|
||||
const telegramId = tgIdentity.rows[0].provider_id;
|
||||
console.log(`[messages.js] Отправка сообщения в Telegram ID: ${telegramId}, текст: ${content}`);
|
||||
// console.log(`[messages.js] Отправка сообщения в Telegram ID: ${telegramId}, текст: ${content}`);
|
||||
const bot = await telegramBot.getBot();
|
||||
try {
|
||||
const sendResult = await bot.telegram.sendMessage(telegramId, content);
|
||||
console.log(`[messages.js] Результат отправки в Telegram:`, sendResult);
|
||||
// console.log(`[messages.js] Результат отправки в Telegram:`, sendResult);
|
||||
} catch (sendErr) {
|
||||
console.error(`[messages.js] Ошибка при отправке в Telegram:`, sendErr);
|
||||
// console.error(`[messages.js] Ошибка при отправке в Telegram:`, sendErr);
|
||||
}
|
||||
} else {
|
||||
console.warn(`[messages.js] Не найден Telegram ID для user_id=${user_id}`);
|
||||
// console.warn(`[messages.js] Не найден Telegram ID для user_id=${user_id}`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[messages.js] Ошибка отправки сообщения в Telegram:', err);
|
||||
// console.error('[messages.js] Ошибка отправки сообщения в Telegram:', err);
|
||||
}
|
||||
}
|
||||
// 5. Если это исходящее сообщение для Email — отправляем email
|
||||
@@ -183,7 +183,7 @@ router.post('/', async (req, res) => {
|
||||
await emailBot.sendEmail(email, 'Новое сообщение', content);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[messages.js] Ошибка отправки email:', err);
|
||||
// console.error('[messages.js] Ошибка отправки email:', err);
|
||||
}
|
||||
}
|
||||
broadcastMessagesUpdate();
|
||||
@@ -196,16 +196,16 @@ router.post('/', async (req, res) => {
|
||||
// POST /api/messages/mark-read
|
||||
router.post('/mark-read', async (req, res) => {
|
||||
try {
|
||||
console.log('[DEBUG] /mark-read req.user:', req.user);
|
||||
console.log('[DEBUG] /mark-read req.body:', req.body);
|
||||
// console.log('[DEBUG] /mark-read req.user:', req.user);
|
||||
// console.log('[DEBUG] /mark-read req.body:', req.body);
|
||||
const adminId = req.user && req.user.id;
|
||||
const { userId, lastReadAt } = req.body;
|
||||
if (!adminId) {
|
||||
console.error('[ERROR] /mark-read: adminId (req.user.id) is missing');
|
||||
// console.error('[ERROR] /mark-read: adminId (req.user.id) is missing');
|
||||
return res.status(401).json({ error: 'Unauthorized: adminId missing' });
|
||||
}
|
||||
if (!userId || !lastReadAt) {
|
||||
console.error('[ERROR] /mark-read: userId or lastReadAt missing');
|
||||
// console.error('[ERROR] /mark-read: userId or lastReadAt missing');
|
||||
return res.status(400).json({ error: 'userId and lastReadAt required' });
|
||||
}
|
||||
await db.query(`
|
||||
@@ -215,7 +215,7 @@ router.post('/mark-read', async (req, res) => {
|
||||
`, [adminId, userId, lastReadAt]);
|
||||
res.json({ success: true });
|
||||
} catch (e) {
|
||||
console.error('[ERROR] /mark-read:', e);
|
||||
// console.error('[ERROR] /mark-read:', e);
|
||||
res.status(500).json({ error: e.message });
|
||||
}
|
||||
});
|
||||
@@ -223,23 +223,23 @@ router.post('/mark-read', async (req, res) => {
|
||||
// GET /api/messages/read-status
|
||||
router.get('/read-status', async (req, res) => {
|
||||
try {
|
||||
console.log('[DEBUG] /read-status req.user:', req.user);
|
||||
console.log('[DEBUG] /read-status req.session:', req.session);
|
||||
console.log('[DEBUG] /read-status req.session.userId:', req.session && req.session.userId);
|
||||
// console.log('[DEBUG] /read-status req.user:', req.user);
|
||||
// console.log('[DEBUG] /read-status req.session:', req.session);
|
||||
// console.log('[DEBUG] /read-status req.session.userId:', req.session && req.session.userId);
|
||||
const adminId = req.user && req.user.id;
|
||||
if (!adminId) {
|
||||
console.error('[ERROR] /read-status: adminId (req.user.id) is missing');
|
||||
// console.error('[ERROR] /read-status: adminId (req.user.id) is missing');
|
||||
return res.status(401).json({ error: 'Unauthorized: adminId missing' });
|
||||
}
|
||||
const result = await db.query('SELECT user_id, last_read_at FROM admin_read_messages WHERE admin_id = $1', [adminId]);
|
||||
console.log('[DEBUG] /read-status SQL result:', result.rows);
|
||||
// console.log('[DEBUG] /read-status SQL result:', result.rows);
|
||||
const map = {};
|
||||
for (const row of result.rows) {
|
||||
map[row.user_id] = row.last_read_at;
|
||||
}
|
||||
res.json(map);
|
||||
} catch (e) {
|
||||
console.error('[ERROR] /read-status:', e);
|
||||
// console.error('[ERROR] /read-status:', e);
|
||||
res.status(500).json({ error: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||
*/
|
||||
|
||||
console.log('[DIAG][tables.js] Файл загружен:', __filename);
|
||||
// console.log('[DIAG][tables.js] Файл загружен:', __filename);
|
||||
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
@@ -32,7 +32,7 @@ function getEncryptionKey() {
|
||||
}
|
||||
|
||||
router.use((req, res, next) => {
|
||||
console.log('Tables router received:', req.method, req.originalUrl);
|
||||
// console.log('Tables router received:', req.method, req.originalUrl);
|
||||
next();
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ router.get('/', async (req, res, next) => {
|
||||
try {
|
||||
encryptionKey = getEncryptionKey();
|
||||
} catch (keyError) {
|
||||
console.error('Error reading encryption key:', keyError);
|
||||
// console.error('Error reading encryption key:', keyError);
|
||||
return res.status(500).json({ error: 'Database encryption error' });
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ router.post('/', async (req, res, next) => {
|
||||
try {
|
||||
encryptionKey = getEncryptionKey();
|
||||
} catch (keyError) {
|
||||
console.error('Error reading encryption key:', keyError);
|
||||
// console.error('Error reading encryption key:', keyError);
|
||||
return res.status(500).json({ error: 'Database encryption error' });
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ router.get('/rag-sources', async (req, res, next) => {
|
||||
|
||||
res.json(result.rows);
|
||||
} catch (err) {
|
||||
console.error('[RAG Sources] Error:', err);
|
||||
// console.error('[RAG Sources] Error:', err);
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
@@ -236,7 +236,7 @@ router.post('/:id/rows', async (req, res, next) => {
|
||||
'INSERT INTO user_rows (table_id) VALUES ($1) RETURNING *',
|
||||
[tableId]
|
||||
);
|
||||
console.log('[DEBUG][addRow] result.rows[0]:', result.rows[0]);
|
||||
// console.log('[DEBUG][addRow] result.rows[0]:', result.rows[0]);
|
||||
// Получаем ключ шифрования
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
@@ -260,11 +260,11 @@ router.post('/:id/rows', async (req, res, next) => {
|
||||
// Получаем все строки и значения для upsert
|
||||
const rows = (await db.getQuery()('SELECT r.id as row_id, decrypt_text(c.value_encrypted, $2) as text, decrypt_text(c2.value_encrypted, $2) as answer FROM user_rows r LEFT JOIN user_cell_values c ON c.row_id = r.id AND c.column_id = 1 LEFT JOIN user_cell_values c2 ON c2.row_id = r.id AND c2.column_id = 2 WHERE r.table_id = $1', [tableId, encryptionKey])).rows;
|
||||
const upsertRows = rows.filter(r => r.row_id && r.text).map(r => ({ row_id: r.row_id, text: r.text, metadata: { answer: r.answer } }));
|
||||
console.log('[DEBUG][upsertRows]', upsertRows);
|
||||
// console.log('[DEBUG][upsertRows]', upsertRows);
|
||||
if (upsertRows.length > 0) {
|
||||
await vectorSearchClient.upsert(tableId, upsertRows);
|
||||
}
|
||||
console.log('[DEBUG][addRow] res.json:', result.rows[0]);
|
||||
// console.log('[DEBUG][addRow] res.json:', result.rows[0]);
|
||||
res.json(result.rows[0]);
|
||||
broadcastTableUpdate(tableId);
|
||||
} catch (err) {
|
||||
|
||||
@@ -16,10 +16,10 @@ const db = require('../db');
|
||||
const { requireAuth } = require('../middleware/auth');
|
||||
const { broadcastTagsUpdate } = require('../wsHub');
|
||||
|
||||
console.log('[tags.js] ROUTER LOADED');
|
||||
// console.log('[tags.js] ROUTER LOADED');
|
||||
|
||||
router.use((req, res, next) => {
|
||||
console.log('[tags.js] ROUTER REQUEST:', req.method, req.originalUrl);
|
||||
// console.log('[tags.js] ROUTER REQUEST:', req.method, req.originalUrl);
|
||||
next();
|
||||
});
|
||||
|
||||
@@ -100,15 +100,15 @@ router.post('/user/:rowId/multirelations', async (req, res) => {
|
||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||
}
|
||||
} catch (keyError) {
|
||||
console.error('Error reading encryption key:', keyError);
|
||||
// console.error('Error reading encryption key:', keyError);
|
||||
}
|
||||
|
||||
// Проверяем, является ли это обновлением тегов (проверяем связанную таблицу)
|
||||
const relatedTableName = (await db.getQuery()('SELECT decrypt_text(name_encrypted, $2) as name FROM user_tables WHERE id = $1', [to_table_id, encryptionKey])).rows[0];
|
||||
console.log('🔄 [Tags] Multirelations: проверяем связанную таблицу:', { to_table_id, tableName: relatedTableName?.name });
|
||||
// console.log('🔄 [Tags] Multirelations: проверяем связанную таблицу:', { to_table_id, tableName: relatedTableName?.name });
|
||||
|
||||
if (relatedTableName && relatedTableName.name === 'Теги клиентов') {
|
||||
console.log('🔄 [Tags] Multirelations: обновление тегов для строки:', rowId);
|
||||
// console.log('🔄 [Tags] Multirelations: обновление тегов для строки:', rowId);
|
||||
|
||||
// Удаляем старые связи для этой строки/столбца
|
||||
await db.getQuery()('DELETE FROM user_table_relations WHERE from_row_id = $1 AND column_id = $2', [rowId, column_id]);
|
||||
|
||||
@@ -19,10 +19,10 @@ const { deleteUserById } = require('../services/userDeleteService');
|
||||
const { broadcastContactsUpdate } = require('../wsHub');
|
||||
// const userService = require('../services/userService');
|
||||
|
||||
console.log('[users.js] ROUTER LOADED');
|
||||
// console.log('[users.js] ROUTER LOADED');
|
||||
|
||||
router.use((req, res, next) => {
|
||||
console.log('[users.js] ROUTER REQUEST:', req.method, req.originalUrl);
|
||||
// console.log('[users.js] ROUTER REQUEST:', req.method, req.originalUrl);
|
||||
next();
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@ router.get('/profile', requireAuth, async (req, res) => {
|
||||
}
|
||||
res.json({ success: true, user });
|
||||
} catch (error) {
|
||||
console.error('Error getting user profile:', error);
|
||||
// console.error('Error getting user profile:', error);
|
||||
res.status(500).json({ success: false, message: 'Internal server error' });
|
||||
}
|
||||
});
|
||||
@@ -57,7 +57,7 @@ router.put('/profile', requireAuth, async (req, res) => {
|
||||
const updatedUser = await userService.updateUserProfile(userId, profileData);
|
||||
res.json({ success: true, user: updatedUser, message: 'Profile updated successfully' });
|
||||
} catch (error) {
|
||||
console.error('Error updating user profile:', error);
|
||||
// console.error('Error updating user profile:', error);
|
||||
// Можно добавить более специфичную обработку ошибок, например, если данные невалидны
|
||||
res.status(500).json({ success: false, message: 'Internal server error' });
|
||||
}
|
||||
@@ -382,19 +382,19 @@ router.patch('/:id', requireAuth, async (req, res) => {
|
||||
|
||||
// DELETE /api/users/:id — удалить контакт и все связанные данные
|
||||
router.delete('/:id', requireAuth, async (req, res) => {
|
||||
console.log('[users.js] DELETE HANDLER', req.params.id);
|
||||
// console.log('[users.js] DELETE HANDLER', req.params.id);
|
||||
const userId = Number(req.params.id);
|
||||
console.log('[ROUTER] Перед вызовом deleteUserById для userId:', userId);
|
||||
// console.log('[ROUTER] Перед вызовом deleteUserById для userId:', userId);
|
||||
try {
|
||||
const deletedCount = await deleteUserById(userId);
|
||||
console.log('[ROUTER] deleteUserById вернул:', deletedCount);
|
||||
// console.log('[ROUTER] deleteUserById вернул:', deletedCount);
|
||||
if (deletedCount === 0) {
|
||||
return res.status(404).json({ success: false, deleted: 0, error: 'User not found' });
|
||||
}
|
||||
broadcastContactsUpdate();
|
||||
res.json({ success: true, deleted: deletedCount });
|
||||
} catch (e) {
|
||||
console.error('[DELETE] Ошибка при удалении пользователя:', e);
|
||||
// console.error('[DELETE] Ошибка при удалении пользователя:', e);
|
||||
res.status(500).json({ error: 'DB error', details: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -21,9 +21,9 @@ const requiredDependencies = ['express-rate-limit', 'winston', 'helmet', 'csurf'
|
||||
const missingDependencies = requiredDependencies.filter((dep) => !dependencies[dep]);
|
||||
|
||||
if (missingDependencies.length > 0) {
|
||||
console.error('Missing dependencies:', missingDependencies);
|
||||
console.error('Please install them with: yarn add ' + missingDependencies.join(' '));
|
||||
// console.error('Missing dependencies:', missingDependencies);
|
||||
// console.error('Please install them with: yarn add ' + missingDependencies.join(' '));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('All required dependencies are installed.');
|
||||
// console.log('All required dependencies are installed.');
|
||||
|
||||
@@ -15,19 +15,19 @@ const db = require('../db');
|
||||
|
||||
async function cleanupSessions() {
|
||||
try {
|
||||
console.log('Starting session cleanup...');
|
||||
// console.log('Starting session cleanup...');
|
||||
|
||||
const result = await sessionService.cleanupProcessedGuestIds();
|
||||
|
||||
if (result) {
|
||||
console.log('Session cleanup completed successfully');
|
||||
// console.log('Session cleanup completed successfully');
|
||||
} else {
|
||||
console.log('Session cleanup failed');
|
||||
// console.log('Session cleanup failed');
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
console.error('Error during cleanup:', error);
|
||||
// console.error('Error during cleanup:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,14 +17,14 @@ process.env.OLLAMA_MODEL = 'qwen2.5:7b';
|
||||
const aiQueueService = require('../services/ai-queue');
|
||||
|
||||
async function testQueueInDocker() {
|
||||
console.log('🐳 Тестирование AI очереди в Docker...\n');
|
||||
// console.log('🐳 Тестирование AI очереди в Docker...\n');
|
||||
|
||||
try {
|
||||
// Проверяем инициализацию
|
||||
console.log('1. Проверка инициализации очереди...');
|
||||
// console.log('1. Проверка инициализации очереди...');
|
||||
const stats = aiQueueService.getStats();
|
||||
console.log('✅ Очередь инициализирована:', stats.isInitialized);
|
||||
console.log('📊 Статистика:', {
|
||||
// console.log('✅ Очередь инициализирована:', stats.isInitialized);
|
||||
// console.log('📊 Статистика:', {
|
||||
totalProcessed: stats.totalProcessed,
|
||||
totalFailed: stats.totalFailed,
|
||||
currentQueueSize: stats.currentQueueSize,
|
||||
|
||||
@@ -11,7 +11,7 @@ const OLLAMA_URL = process.env.OLLAMA_URL || 'http://ollama:11434';
|
||||
const MODEL_NAME = process.env.OLLAMA_MODEL || 'qwen2.5:7b';
|
||||
|
||||
async function warmupModel() {
|
||||
console.log('🔥 Разогрев модели Ollama...');
|
||||
// console.log('🔥 Разогрев модели Ollama...');
|
||||
|
||||
try {
|
||||
// Проверяем доступность Ollama
|
||||
@@ -20,7 +20,7 @@ async function warmupModel() {
|
||||
throw new Error(`Ollama недоступен: ${healthResponse.status}`);
|
||||
}
|
||||
|
||||
console.log('✅ Ollama доступен');
|
||||
// console.log('✅ Ollama доступен');
|
||||
|
||||
// Отправляем простой запрос для разогрева
|
||||
const warmupResponse = await fetch(`${OLLAMA_URL}/v1/chat/completions`, {
|
||||
@@ -54,11 +54,11 @@ async function warmupModel() {
|
||||
}
|
||||
|
||||
const data = await warmupResponse.json();
|
||||
console.log('✅ Модель разогрета успешно');
|
||||
console.log(`📝 Ответ модели: ${data.choices?.[0]?.message?.content?.substring(0, 100)}...`);
|
||||
// console.log('✅ Модель разогрета успешно');
|
||||
// console.log(`📝 Ответ модели: ${data.choices?.[0]?.message?.content?.substring(0, 100)}...`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Ошибка разогрева модели:', error.message);
|
||||
// console.error('❌ Ошибка разогрева модели:', error.message);
|
||||
// Не прерываем запуск приложения
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,41 +22,41 @@ const { warmupModel } = require('./scripts/warmup-model'); // Добавляем
|
||||
|
||||
const PORT = process.env.PORT || 8000;
|
||||
|
||||
console.log('Начало выполнения server.js');
|
||||
console.log('Переменная окружения PORT:', process.env.PORT);
|
||||
console.log('Используемый порт:', process.env.PORT || 8000);
|
||||
// console.log('Начало выполнения server.js');
|
||||
// console.log('Переменная окружения PORT:', process.env.PORT);
|
||||
// console.log('Используемый порт:', process.env.PORT || 8000);
|
||||
|
||||
// Инициализация сервисов
|
||||
async function initServices() {
|
||||
try {
|
||||
console.log('Инициализация сервисов...');
|
||||
console.log('[initServices] Запуск Email-бота...');
|
||||
console.log('[initServices] Создаю экземпляр EmailBotService...');
|
||||
// console.log('Инициализация сервисов...');
|
||||
// console.log('[initServices] Запуск Email-бота...');
|
||||
// console.log('[initServices] Создаю экземпляр EmailBotService...');
|
||||
let emailBot;
|
||||
try {
|
||||
emailBot = new EmailBotService();
|
||||
console.log('[initServices] Экземпляр EmailBotService создан');
|
||||
// console.log('[initServices] Экземпляр EmailBotService создан');
|
||||
} catch (err) {
|
||||
console.error('[initServices] Ошибка при создании экземпляра EmailBotService:', err);
|
||||
// console.error('[initServices] Ошибка при создании экземпляра EmailBotService:', err);
|
||||
throw err;
|
||||
}
|
||||
console.log('[initServices] Перед вызовом emailBot.start()');
|
||||
// console.log('[initServices] Перед вызовом emailBot.start()');
|
||||
try {
|
||||
await emailBot.start();
|
||||
console.log('[initServices] Email-бот успешно запущен');
|
||||
// console.log('[initServices] Email-бот успешно запущен');
|
||||
} catch (err) {
|
||||
console.error('[initServices] Ошибка при запуске emailBot:', err);
|
||||
// console.error('[initServices] Ошибка при запуске emailBot:', err);
|
||||
}
|
||||
console.log('[initServices] Запуск Telegram-бота...');
|
||||
// console.log('[initServices] Запуск Telegram-бота...');
|
||||
try {
|
||||
await getBot();
|
||||
console.log('[initServices] Telegram-бот успешно запущен');
|
||||
// console.log('[initServices] Telegram-бот успешно запущен');
|
||||
} catch (err) {
|
||||
console.error('[initServices] Ошибка при запуске Telegram-бота:', err);
|
||||
// console.error('[initServices] Ошибка при запуске Telegram-бота:', err);
|
||||
}
|
||||
} catch (error) {
|
||||
// console.error('Ошибка при инициализации сервисов:', error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка при инициализации сервисов:', error);
|
||||
}
|
||||
}
|
||||
|
||||
const server = http.createServer(app);
|
||||
@@ -67,22 +67,22 @@ async function startServer() {
|
||||
await seedAIAssistantSettings(); // Инициализация ассистента после загрузки модели Ollama
|
||||
|
||||
// Разогрев модели Ollama
|
||||
console.log('🔥 Запуск разогрева модели...');
|
||||
// console.log('🔥 Запуск разогрева модели...');
|
||||
setTimeout(() => {
|
||||
warmupModel().catch(err => {
|
||||
console.error('❌ Ошибка разогрева модели:', err.message);
|
||||
// console.error('❌ Ошибка разогрева модели:', err.message);
|
||||
});
|
||||
}, 10000); // Задержка 10 секунд для полной инициализации
|
||||
|
||||
await initServices(); // Только теперь запускать сервисы
|
||||
console.log(`Server is running on port ${PORT}`);
|
||||
// console.log(`Server is running on port ${PORT}`);
|
||||
}
|
||||
|
||||
server.listen(PORT, async () => {
|
||||
try {
|
||||
await startServer();
|
||||
} catch (error) {
|
||||
console.error('Error starting server:', error);
|
||||
// console.error('Error starting server:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -44,9 +44,9 @@ async function checkAdminRole(address) {
|
||||
if (fs.existsSync(keyPath)) {
|
||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||
}
|
||||
} catch (keyError) {
|
||||
console.error('Error reading encryption key:', keyError);
|
||||
}
|
||||
} catch (keyError) {
|
||||
// console.error('Error reading encryption key:', keyError);
|
||||
}
|
||||
|
||||
// Получаем токены и RPC из базы с расшифровкой
|
||||
const tokensResult = await db.getQuery()(
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||
*/
|
||||
|
||||
console.log('[ai-assistant] loaded');
|
||||
// console.log('[ai-assistant] loaded');
|
||||
|
||||
const { ChatOllama } = require('@langchain/ollama');
|
||||
const { HNSWLib } = require('@langchain/community/vectorstores/hnswlib');
|
||||
@@ -51,7 +51,7 @@ class AIAssistant {
|
||||
this.isModelLoaded = false;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Model health check failed:', error);
|
||||
// console.error('Model health check failed:', error);
|
||||
this.isModelLoaded = false;
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ class AIAssistant {
|
||||
// Основной метод для получения ответа
|
||||
async getResponse(message, language = 'auto', history = null, systemPrompt = '', rules = null) {
|
||||
try {
|
||||
console.log('getResponse called with:', { message, language, history, systemPrompt, rules });
|
||||
// console.log('getResponse called with:', { message, language, history, systemPrompt, rules });
|
||||
|
||||
// Очищаем старый кэш
|
||||
this.cleanupCache();
|
||||
@@ -150,7 +150,7 @@ class AIAssistant {
|
||||
// Проверяем здоровье модели
|
||||
const isHealthy = await this.checkModelHealth();
|
||||
if (!isHealthy) {
|
||||
console.warn('Model is not healthy, returning fallback response');
|
||||
// console.warn('Model is not healthy, returning fallback response');
|
||||
return 'Извините, модель временно недоступна. Пожалуйста, попробуйте позже.';
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ class AIAssistant {
|
||||
});
|
||||
const cachedResponse = aiCache.get(cacheKey);
|
||||
if (cachedResponse) {
|
||||
console.log('Returning cached response');
|
||||
// console.log('Returning cached response');
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
@@ -207,7 +207,7 @@ class AIAssistant {
|
||||
|
||||
// Определяем язык, если не указан явно
|
||||
const detectedLanguage = language === 'auto' ? this.detectLanguage(message) : language;
|
||||
console.log('Detected language:', detectedLanguage);
|
||||
// console.log('Detected language:', detectedLanguage);
|
||||
|
||||
// Формируем system prompt с учётом правил
|
||||
let fullSystemPrompt = systemPrompt || '';
|
||||
@@ -234,22 +234,22 @@ class AIAssistant {
|
||||
|
||||
// Пробуем прямой API запрос (OpenAI-совместимый endpoint)
|
||||
try {
|
||||
console.log('Trying direct API request...');
|
||||
// console.log('Trying direct API request...');
|
||||
response = await this.fallbackRequestOpenAI(messages, detectedLanguage, fullSystemPrompt);
|
||||
console.log('Direct API response received:', response);
|
||||
// console.log('Direct API response received:', response);
|
||||
} catch (error) {
|
||||
console.error('Error in direct API request:', error);
|
||||
// console.error('Error in direct API request:', error);
|
||||
|
||||
// Если прямой запрос не удался, пробуем через ChatOllama (склеиваем сообщения в текст)
|
||||
const chat = this.createChat(detectedLanguage, fullSystemPrompt);
|
||||
try {
|
||||
const prompt = messages.map(m => `${m.role === 'user' ? 'Пользователь' : m.role === 'assistant' ? 'Ассистент' : 'Система'}: ${m.content}`).join('\n');
|
||||
console.log('Sending request to ChatOllama...');
|
||||
// console.log('Sending request to ChatOllama...');
|
||||
const chatResponse = await chat.invoke(prompt);
|
||||
console.log('ChatOllama response:', chatResponse);
|
||||
// console.log('ChatOllama response:', chatResponse);
|
||||
response = chatResponse.content;
|
||||
} catch (chatError) {
|
||||
console.error('Error using ChatOllama:', chatError);
|
||||
// console.error('Error using ChatOllama:', chatError);
|
||||
throw chatError;
|
||||
}
|
||||
}
|
||||
@@ -261,7 +261,7 @@ class AIAssistant {
|
||||
|
||||
return response;
|
||||
} catch (error) {
|
||||
console.error('Error in getResponse:', error);
|
||||
// console.error('Error in getResponse:', error);
|
||||
return 'Извините, я не смог обработать ваш запрос. Пожалуйста, попробуйте позже.';
|
||||
}
|
||||
}
|
||||
@@ -269,7 +269,7 @@ class AIAssistant {
|
||||
// Новый метод для OpenAI/Qwen2.5 совместимого endpoint
|
||||
async fallbackRequestOpenAI(messages, language, systemPrompt = '') {
|
||||
try {
|
||||
console.log('Using fallbackRequestOpenAI with:', { messages, language, systemPrompt });
|
||||
// console.log('Using fallbackRequestOpenAI with:', { messages, language, systemPrompt });
|
||||
const model = this.defaultModel;
|
||||
|
||||
// Создаем AbortController для таймаута
|
||||
@@ -315,7 +315,7 @@ class AIAssistant {
|
||||
}
|
||||
return data.response || '';
|
||||
} catch (error) {
|
||||
console.error('Error in fallbackRequestOpenAI:', error);
|
||||
// console.error('Error in fallbackRequestOpenAI:', error);
|
||||
if (error.name === 'AbortError') {
|
||||
throw new Error('Request timeout - модель не ответила в течение 120 секунд');
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ async function getSettings() {
|
||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||
}
|
||||
} catch (keyError) {
|
||||
console.error('Error reading encryption key:', keyError);
|
||||
// console.error('Error reading encryption key:', keyError);
|
||||
}
|
||||
|
||||
// Получаем связанные данные из telegram_settings и email_settings
|
||||
|
||||
@@ -148,7 +148,7 @@ async function getAllLLMModels() {
|
||||
}
|
||||
}
|
||||
} catch (ollamaError) {
|
||||
console.error('Error checking Ollama models:', ollamaError);
|
||||
// console.error('Error checking Ollama models:', ollamaError);
|
||||
// Если не удалось проверить Ollama, добавляем базовые модели
|
||||
allModels.push({ id: 'qwen2.5:7b', provider: 'ollama' });
|
||||
}
|
||||
@@ -167,7 +167,7 @@ async function getAllLLMModels() {
|
||||
|
||||
return uniqueModels;
|
||||
} catch (error) {
|
||||
console.error('Error getting LLM models:', error);
|
||||
// console.error('Error getting LLM models:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -213,7 +213,7 @@ async function getAllEmbeddingModels() {
|
||||
}
|
||||
}
|
||||
} catch (ollamaError) {
|
||||
console.error('Error checking Ollama embedding models:', ollamaError);
|
||||
// console.error('Error checking Ollama embedding models:', ollamaError);
|
||||
// Если не удалось проверить Ollama, добавляем базовые embedding модели
|
||||
allModels.push({ id: 'mxbai-embed-large:latest', provider: 'ollama' });
|
||||
}
|
||||
@@ -232,7 +232,7 @@ async function getAllEmbeddingModels() {
|
||||
|
||||
return uniqueModels;
|
||||
} catch (error) {
|
||||
console.error('Error getting embedding models:', error);
|
||||
// console.error('Error getting embedding models:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||
*/
|
||||
|
||||
console.log('[EmailBot] emailBot.js loaded');
|
||||
// console.log('[EmailBot] emailBot.js loaded');
|
||||
const encryptedDb = require('./encryptedDatabaseService');
|
||||
const db = require('../db');
|
||||
const nodemailer = require('nodemailer');
|
||||
@@ -28,7 +28,7 @@ const { isUserBlocked } = require('../utils/userUtils');
|
||||
|
||||
class EmailBotService {
|
||||
constructor() {
|
||||
console.log('[EmailBot] constructor called');
|
||||
// console.log('[EmailBot] constructor called');
|
||||
}
|
||||
|
||||
async getSettingsFromDb() {
|
||||
@@ -43,7 +43,7 @@ class EmailBotService {
|
||||
encryptionKey = fs.readFileSync(keyPath, 'utf8').trim();
|
||||
}
|
||||
} catch (keyError) {
|
||||
console.error('Error reading encryption key:', keyError);
|
||||
// console.error('Error reading encryption key:', keyError);
|
||||
}
|
||||
|
||||
const { rows } = await db.getQuery()(
|
||||
@@ -530,7 +530,7 @@ class EmailBotService {
|
||||
|
||||
async start() {
|
||||
try {
|
||||
console.log('[EmailBot] start() called');
|
||||
// console.log('[EmailBot] start() called');
|
||||
logger.info('[EmailBot] start() called');
|
||||
const imapConfig = await this.getImapConfig();
|
||||
// Логируем IMAP-конфиг (без пароля)
|
||||
@@ -580,7 +580,7 @@ class EmailBotService {
|
||||
};
|
||||
tryConnect();
|
||||
} catch (err) {
|
||||
console.error('[EmailBot] Ошибка при старте:', err);
|
||||
// console.error('[EmailBot] Ошибка при старте:', err);
|
||||
logger.error('[EmailBot] Ошибка при старте:', err);
|
||||
throw err;
|
||||
}
|
||||
@@ -592,5 +592,5 @@ class EmailBotService {
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[EmailBot] module.exports = EmailBotService');
|
||||
// console.log('[EmailBot] module.exports = EmailBotService');
|
||||
module.exports = EmailBotService;
|
||||
|
||||
@@ -20,34 +20,34 @@ class EncryptedDataService {
|
||||
this.isEncryptionEnabled = !!this.encryptionKey;
|
||||
|
||||
if (this.isEncryptionEnabled) {
|
||||
console.log('🔐 Шифрование базы данных активировано');
|
||||
console.log('📋 Автоматическое определение зашифрованных колонок');
|
||||
// console.log('🔐 Шифрование базы данных активировано');
|
||||
// console.log('📋 Автоматическое определение зашифрованных колонок');
|
||||
} else {
|
||||
console.log('⚠️ Шифрование базы данных отключено - ключ не найден');
|
||||
// console.log('⚠️ Шифрование базы данных отключено - ключ не найден');
|
||||
}
|
||||
}
|
||||
|
||||
loadEncryptionKey() {
|
||||
try {
|
||||
const keyPath = path.join(__dirname, '../../ssl/keys/full_db_encryption.key');
|
||||
console.log(`[EncryptedDB] Trying key path: ${keyPath}`);
|
||||
// console.log(`[EncryptedDB] Trying key path: ${keyPath}`);
|
||||
if (fs.existsSync(keyPath)) {
|
||||
const key = fs.readFileSync(keyPath, 'utf8').trim();
|
||||
console.log(`[EncryptedDB] Key loaded from: ${keyPath}, length: ${key.length}`);
|
||||
// console.log(`[EncryptedDB] Key loaded from: ${keyPath}, length: ${key.length}`);
|
||||
return key;
|
||||
}
|
||||
// Попробуем альтернативный путь относительно корня приложения
|
||||
const altKeyPath = '/app/ssl/keys/full_db_encryption.key';
|
||||
console.log(`[EncryptedDB] Trying alternative key path: ${altKeyPath}`);
|
||||
// console.log(`[EncryptedDB] Trying alternative key path: ${altKeyPath}`);
|
||||
if (fs.existsSync(altKeyPath)) {
|
||||
const key = fs.readFileSync(altKeyPath, 'utf8').trim();
|
||||
console.log(`[EncryptedDB] Key loaded from: ${altKeyPath}, length: ${key.length}`);
|
||||
// console.log(`[EncryptedDB] Key loaded from: ${altKeyPath}, length: ${key.length}`);
|
||||
return key;
|
||||
}
|
||||
console.log(`[EncryptedDB] No key file found, using default key`);
|
||||
// console.log(`[EncryptedDB] No key file found, using default key`);
|
||||
return 'default-key';
|
||||
} catch (error) {
|
||||
console.error('❌ Ошибка загрузки ключа шифрования:', error);
|
||||
// console.error('❌ Ошибка загрузки ключа шифрования:', error);
|
||||
return 'default-key';
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ class EncryptedDataService {
|
||||
const selectFields = columns.map(col => {
|
||||
if (col.column_name.endsWith('_encrypted')) {
|
||||
const originalName = col.column_name.replace('_encrypted', '');
|
||||
console.log(`🔓 Расшифровываем поле ${col.column_name} -> ${originalName}`);
|
||||
// console.log(`🔓 Расшифровываем поле ${col.column_name} -> ${originalName}`);
|
||||
if (col.data_type === 'jsonb') {
|
||||
return `decrypt_json(${col.column_name}, $1) as "${originalName}"`;
|
||||
} else {
|
||||
@@ -89,7 +89,7 @@ class EncryptedDataService {
|
||||
|
||||
// Если есть зашифрованная версия, пропускаем незашифрованную
|
||||
if (hasEncryptedVersion) {
|
||||
console.log(`⚠️ Пропускаем незашифрованное поле ${col.column_name} (есть зашифрованная версия)`);
|
||||
// console.log(`⚠️ Пропускаем незашифрованное поле ${col.column_name} (есть зашифрованная версия)`);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -171,16 +171,16 @@ class EncryptedDataService {
|
||||
query += ` LIMIT ${limit}`;
|
||||
}
|
||||
|
||||
console.log(`🔍 [getData] Выполняем запрос:`, query);
|
||||
console.log(`🔍 [getData] Параметры:`, params);
|
||||
// console.log(`🔍 [getData] Выполняем запрос:`, query);
|
||||
// console.log(`🔍 [getData] Параметры:`, params);
|
||||
|
||||
const { rows } = await db.getQuery()(query, params);
|
||||
|
||||
console.log(`📊 Результат запроса из ${tableName}:`, rows);
|
||||
// console.log(`📊 Результат запроса из ${tableName}:`, rows);
|
||||
|
||||
return rows;
|
||||
} catch (error) {
|
||||
console.error(`❌ Ошибка получения данных из ${tableName}:`, error);
|
||||
// console.error(`❌ Ошибка получения данных из ${tableName}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -223,19 +223,19 @@ class EncryptedDataService {
|
||||
const encryptedColumn = columns.find(col => col.column_name === `${key}_encrypted`);
|
||||
const unencryptedColumn = columns.find(col => col.column_name === key);
|
||||
|
||||
console.log(`🔍 Обрабатываем поле ${key} = "${value}" (тип: ${typeof value})`);
|
||||
// console.log(`🔍 Обрабатываем поле ${key} = "${value}" (тип: ${typeof value})`);
|
||||
|
||||
if (encryptedColumn) {
|
||||
// Если есть зашифрованная колонка, шифруем данные
|
||||
// Проверяем, что значение не пустое перед шифрованием
|
||||
if (value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) {
|
||||
// Пропускаем пустые значения
|
||||
console.log(`⚠️ Пропускаем пустое зашифрованное поле ${key}`);
|
||||
// console.log(`⚠️ Пропускаем пустое зашифрованное поле ${key}`);
|
||||
continue;
|
||||
}
|
||||
const currentParamIndex = paramIndex++;
|
||||
filteredData[key] = value; // Добавляем в отфильтрованные данные
|
||||
console.log(`✅ Добавили зашифрованное поле ${key} в filteredData`);
|
||||
// console.log(`✅ Добавили зашифрованное поле ${key} в filteredData`);
|
||||
if (encryptedColumn.data_type === 'jsonb') {
|
||||
encryptedData[`${key}_encrypted`] = `encrypt_json($${currentParamIndex}, ${hasEncryptedFields ? '$1::text' : 'NULL'})`;
|
||||
} else {
|
||||
@@ -247,15 +247,15 @@ class EncryptedDataService {
|
||||
if ((value === null || value === undefined || (typeof value === 'string' && value.trim() === '')) &&
|
||||
key !== 'role' && key !== 'sender_type') {
|
||||
// Пропускаем пустые значения, кроме role и sender_type
|
||||
console.log(`⚠️ Пропускаем пустое незашифрованное поле ${key}`);
|
||||
// console.log(`⚠️ Пропускаем пустое незашифрованное поле ${key}`);
|
||||
continue;
|
||||
}
|
||||
filteredData[key] = value; // Добавляем в отфильтрованные данные
|
||||
unencryptedData[key] = `$${paramIndex++}`;
|
||||
console.log(`✅ Добавили незашифрованное поле ${key} в filteredData и unencryptedData`);
|
||||
// console.log(`✅ Добавили незашифрованное поле ${key} в filteredData и unencryptedData`);
|
||||
} else {
|
||||
// Если колонка не найдена, пропускаем
|
||||
console.warn(`⚠️ Колонка ${key} не найдена в таблице ${tableName}`);
|
||||
// console.warn(`⚠️ Колонка ${key} не найдена в таблице ${tableName}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,9 +263,9 @@ class EncryptedDataService {
|
||||
|
||||
// Проверяем, есть ли данные для сохранения
|
||||
if (Object.keys(allData).length === 0) {
|
||||
console.warn(`⚠️ Нет данных для сохранения в таблице ${tableName} - все значения пустые`);
|
||||
console.warn(`⚠️ Исходные данные:`, data);
|
||||
console.warn(`⚠️ Отфильтрованные данные:`, filteredData);
|
||||
// console.warn(`⚠️ Нет данных для сохранения в таблице ${tableName} - все значения пустые`);
|
||||
// console.warn(`⚠️ Исходные данные:`, data);
|
||||
// console.warn(`⚠️ Отфильтрованные данные:`, filteredData);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -301,7 +301,7 @@ class EncryptedDataService {
|
||||
return rows[0];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`❌ Ошибка сохранения данных в ${tableName}:`, error);
|
||||
// console.error(`❌ Ошибка сохранения данных в ${tableName}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -352,7 +352,7 @@ class EncryptedDataService {
|
||||
const result = await db.getQuery()(query, params);
|
||||
return result.rows;
|
||||
} catch (error) {
|
||||
console.error(`❌ Ошибка удаления данных из ${tableName}:`, error);
|
||||
// console.error(`❌ Ошибка удаления данных из ${tableName}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* GitHub: https://github.com/HB3-ACCELERATOR
|
||||
*/
|
||||
|
||||
console.log('[identity-service] loaded');
|
||||
// console.log('[identity-service] loaded');
|
||||
|
||||
const encryptedDb = require('./encryptedDatabaseService');
|
||||
const db = require('../db');
|
||||
|
||||
@@ -14,23 +14,23 @@ const encryptedDb = require('./encryptedDatabaseService');
|
||||
const vectorSearch = require('./vectorSearchClient');
|
||||
const { getProviderSettings } = require('./aiProviderSettingsService');
|
||||
|
||||
console.log('[RAG] ragService.js loaded');
|
||||
// console.log('[RAG] ragService.js loaded');
|
||||
|
||||
// Простой кэш для RAG результатов
|
||||
const ragCache = new Map();
|
||||
const RAG_CACHE_TTL = 5 * 60 * 1000; // 5 минут
|
||||
|
||||
async function getTableData(tableId) {
|
||||
console.log(`[RAG] getTableData called for tableId: ${tableId}`);
|
||||
// console.log(`[RAG] getTableData called for tableId: ${tableId}`);
|
||||
|
||||
const columns = await encryptedDb.getData('user_columns', { table_id: tableId });
|
||||
console.log(`[RAG] Found ${columns.length} columns:`, columns.map(col => ({ id: col.id, name: col.name, purpose: col.options?.purpose })));
|
||||
// console.log(`[RAG] Found ${columns.length} columns:`, columns.map(col => ({ id: col.id, name: col.name, purpose: col.options?.purpose })));
|
||||
|
||||
const rows = await encryptedDb.getData('user_rows', { table_id: tableId });
|
||||
console.log(`[RAG] Found ${rows.length} rows:`, rows.map(row => ({ id: row.id, name: row.name })));
|
||||
// console.log(`[RAG] Found ${rows.length} rows:`, rows.map(row => ({ id: row.id, name: row.name })));
|
||||
|
||||
const cellValues = await encryptedDb.getData('user_cell_values', { row_id: { $in: rows.map(row => row.id) } });
|
||||
console.log(`[RAG] Found ${cellValues.length} cell values`);
|
||||
// console.log(`[RAG] Found ${cellValues.length} cell values`);
|
||||
|
||||
const getColId = purpose => columns.find(col => col.options?.purpose === purpose)?.id;
|
||||
const questionColId = getColId('question');
|
||||
@@ -40,14 +40,14 @@ async function getTableData(tableId) {
|
||||
const priorityColId = getColId('priority');
|
||||
const dateColId = getColId('date');
|
||||
|
||||
console.log(`[RAG] Column IDs:`, {
|
||||
question: questionColId,
|
||||
answer: answerColId,
|
||||
context: contextColId,
|
||||
product: productColId,
|
||||
priority: priorityColId,
|
||||
date: dateColId
|
||||
});
|
||||
// console.log(`[RAG] Column IDs:`, {
|
||||
// question: questionColId,
|
||||
// answer: answerColId,
|
||||
// context: contextColId,
|
||||
// product: productColId,
|
||||
// priority: priorityColId,
|
||||
// date: dateColId
|
||||
// });
|
||||
|
||||
const data = rows.map(row => {
|
||||
const cells = cellValues.filter(cell => cell.row_id === row.id);
|
||||
@@ -61,34 +61,34 @@ async function getTableData(tableId) {
|
||||
priority: cells.find(c => c.column_id === priorityColId)?.value,
|
||||
date: cells.find(c => c.column_id === dateColId)?.value,
|
||||
};
|
||||
console.log(`[RAG] Processed row ${row.id}:`, result);
|
||||
// console.log(`[RAG] Processed row ${row.id}:`, result);
|
||||
return result;
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10 }) {
|
||||
console.log(`[RAG] ragAnswer called: tableId=${tableId}, userQuestion="${userQuestion}"`);
|
||||
// console.log(`[RAG] ragAnswer called: tableId=${tableId}, userQuestion="${userQuestion}"`);
|
||||
|
||||
// Проверяем кэш
|
||||
const cacheKey = `${tableId}:${userQuestion}:${product}`;
|
||||
const cached = ragCache.get(cacheKey);
|
||||
if (cached && (Date.now() - cached.timestamp) < RAG_CACHE_TTL) {
|
||||
console.log(`[RAG] Returning cached result for: ${cacheKey}`);
|
||||
// console.log(`[RAG] Returning cached result for: ${cacheKey}`);
|
||||
return cached.result;
|
||||
}
|
||||
|
||||
const data = await getTableData(tableId);
|
||||
console.log(`[RAG] Got ${data.length} rows from database`);
|
||||
// console.log(`[RAG] Got ${data.length} rows from database`);
|
||||
|
||||
// Подробное логирование данных
|
||||
data.forEach((row, index) => {
|
||||
console.log(`[RAG] Row ${index}:`, {
|
||||
id: row.id,
|
||||
question: row.question,
|
||||
answer: row.answer,
|
||||
product: row.product
|
||||
});
|
||||
// console.log(`[RAG] Row ${index}:`, {
|
||||
// id: row.id,
|
||||
// question: row.question,
|
||||
// answer: row.answer,
|
||||
// product: row.product
|
||||
// });
|
||||
});
|
||||
|
||||
const questions = data.map(row => row.question && typeof row.question === 'string' ? row.question.trim() : row.question);
|
||||
@@ -108,61 +108,61 @@ async function ragAnswer({ tableId, userQuestion, product = null, threshold = 10
|
||||
}
|
||||
}));
|
||||
|
||||
console.log(`[RAG] Prepared ${rowsForUpsert.length} rows for upsert`);
|
||||
console.log(`[RAG] First row:`, rowsForUpsert[0]);
|
||||
// console.log(`[RAG] Prepared ${rowsForUpsert.length} rows for upsert`);
|
||||
// console.log(`[RAG] First row:`, rowsForUpsert[0]);
|
||||
|
||||
// Upsert все вопросы в индекс (можно оптимизировать по изменению)
|
||||
if (rowsForUpsert.length > 0) {
|
||||
await vectorSearch.upsert(tableId, rowsForUpsert);
|
||||
console.log(`[RAG] Upsert completed`);
|
||||
// console.log(`[RAG] Upsert completed`);
|
||||
} else {
|
||||
console.log(`[RAG] No rows to upsert, skipping`);
|
||||
// console.log(`[RAG] No rows to upsert, skipping`);
|
||||
}
|
||||
|
||||
// Поиск
|
||||
let results = [];
|
||||
if (rowsForUpsert.length > 0) {
|
||||
results = await vectorSearch.search(tableId, userQuestion, 2); // Уменьшаем до 2 результатов
|
||||
console.log(`[RAG] Search completed, got ${results.length} results`);
|
||||
// console.log(`[RAG] Search completed, got ${results.length} results`);
|
||||
|
||||
// Подробное логирование результатов поиска
|
||||
results.forEach((result, index) => {
|
||||
console.log(`[RAG] Search result ${index}:`, {
|
||||
row_id: result.row_id,
|
||||
score: result.score,
|
||||
metadata: result.metadata
|
||||
});
|
||||
// console.log(`[RAG] Search result ${index}:`, {
|
||||
// row_id: result.row_id,
|
||||
// score: result.score,
|
||||
// metadata: result.metadata
|
||||
// });
|
||||
});
|
||||
} else {
|
||||
console.log(`[RAG] No data in table, skipping search`);
|
||||
// console.log(`[RAG] No data in table, skipping search`);
|
||||
}
|
||||
|
||||
// Фильтрация по тегам/продукту
|
||||
let filtered = results;
|
||||
console.log(`[RAG] Before filtering: ${filtered.length} results`);
|
||||
// console.log(`[RAG] Before filtering: ${filtered.length} results`);
|
||||
|
||||
if (product) {
|
||||
console.log(`[RAG] Filtering by product:`, product);
|
||||
// console.log(`[RAG] Filtering by product:`, product);
|
||||
filtered = filtered.filter(row => Array.isArray(row.metadata.product) ? row.metadata.product.includes(product) : row.metadata.product === product);
|
||||
console.log(`[RAG] After product filtering: ${filtered.length} results`);
|
||||
// console.log(`[RAG] After product filtering: ${filtered.length} results`);
|
||||
}
|
||||
|
||||
// Берём ближайший результат с учётом порога (по модулю)
|
||||
console.log(`[RAG] Looking for best result with abs(threshold): ${threshold}`);
|
||||
// console.log(`[RAG] Looking for best result with abs(threshold): ${threshold}`);
|
||||
const best = filtered.reduce((acc, row) => {
|
||||
if (Math.abs(row.score) <= threshold && (acc === null || Math.abs(row.score) < Math.abs(acc.score))) {
|
||||
return row;
|
||||
}
|
||||
return acc;
|
||||
}, null);
|
||||
console.log(`[RAG] Best result:`, best);
|
||||
// console.log(`[RAG] Best result:`, best);
|
||||
|
||||
// Логируем все результаты с их score для диагностики
|
||||
if (filtered.length > 0) {
|
||||
console.log(`[RAG] All filtered results with scores:`);
|
||||
filtered.forEach((result, index) => {
|
||||
console.log(`[RAG] ${index}: score=${result.score}, meets_threshold=${Math.abs(result.score) <= threshold}`);
|
||||
});
|
||||
// console.log(`[RAG] All filtered results with scores:`);
|
||||
// filtered.forEach((result, index) => {
|
||||
// console.log(`[RAG] ${index}: score=${result.score}, meets_threshold=${Math.abs(result.score) <= threshold}`);
|
||||
// });
|
||||
}
|
||||
|
||||
const result = {
|
||||
@@ -238,18 +238,18 @@ async function generateLLMResponse({
|
||||
model,
|
||||
language
|
||||
}) {
|
||||
console.log(`[RAG] generateLLMResponse called with:`, {
|
||||
userQuestion,
|
||||
context,
|
||||
answer,
|
||||
systemPrompt,
|
||||
userTags,
|
||||
product,
|
||||
priority,
|
||||
date,
|
||||
model,
|
||||
language
|
||||
});
|
||||
// console.log(`[RAG] generateLLMResponse called with:`, {
|
||||
// userQuestion,
|
||||
// context,
|
||||
// answer,
|
||||
// systemPrompt,
|
||||
// userTags,
|
||||
// product,
|
||||
// priority,
|
||||
// date,
|
||||
// model,
|
||||
// language
|
||||
// });
|
||||
|
||||
try {
|
||||
const aiAssistant = require('./ai-assistant');
|
||||
@@ -286,10 +286,10 @@ async function generateLLMResponse({
|
||||
rules
|
||||
);
|
||||
|
||||
console.log(`[RAG] LLM response generated:`, llmResponse);
|
||||
// console.log(`[RAG] LLM response generated:`, llmResponse);
|
||||
return llmResponse;
|
||||
} catch (error) {
|
||||
console.error(`[RAG] Error generating LLM response:`, error);
|
||||
// console.error(`[RAG] Error generating LLM response:`, error);
|
||||
return 'Извините, произошла ошибка при генерации ответа.';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,13 +40,13 @@ async function getTelegramSettings() {
|
||||
|
||||
// Создание и настройка бота
|
||||
async function getBot() {
|
||||
console.log('[TelegramBot] getBot() called');
|
||||
// console.log('[TelegramBot] getBot() called');
|
||||
if (!botInstance) {
|
||||
console.log('[TelegramBot] Creating new bot instance...');
|
||||
// console.log('[TelegramBot] Creating new bot instance...');
|
||||
const settings = await getTelegramSettings();
|
||||
console.log('[TelegramBot] Got settings, creating Telegraf instance...');
|
||||
// console.log('[TelegramBot] Got settings, creating Telegraf instance...');
|
||||
botInstance = new Telegraf(settings.bot_token);
|
||||
console.log('[TelegramBot] Telegraf instance created');
|
||||
// console.log('[TelegramBot] Telegraf instance created');
|
||||
|
||||
// Обработка команды /start
|
||||
botInstance.command('start', (ctx) => {
|
||||
@@ -489,7 +489,7 @@ async function getBot() {
|
||||
});
|
||||
|
||||
// Запуск бота с таймаутом
|
||||
console.log('[TelegramBot] Before botInstance.launch()');
|
||||
// console.log('[TelegramBot] Before botInstance.launch()');
|
||||
try {
|
||||
// Запускаем бота с таймаутом
|
||||
const launchPromise = botInstance.launch();
|
||||
@@ -498,12 +498,12 @@ async function getBot() {
|
||||
});
|
||||
|
||||
await Promise.race([launchPromise, timeoutPromise]);
|
||||
console.log('[TelegramBot] After botInstance.launch()');
|
||||
// console.log('[TelegramBot] After botInstance.launch()');
|
||||
logger.info('[TelegramBot] Бот запущен');
|
||||
} catch (error) {
|
||||
console.error('[TelegramBot] Error launching bot:', error);
|
||||
// console.error('[TelegramBot] Error launching bot:', error);
|
||||
// Не выбрасываем ошибку, чтобы не блокировать запуск сервера
|
||||
console.log('[TelegramBot] Bot launch failed, but continuing...');
|
||||
// console.log('[TelegramBot] Bot launch failed, but continuing...');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,23 +13,23 @@
|
||||
const encryptedDb = require('./encryptedDatabaseService');
|
||||
|
||||
async function deleteUserById(userId) {
|
||||
console.log('[DELETE] Вызван deleteUserById для userId:', userId);
|
||||
// console.log('[DELETE] Вызван deleteUserById для userId:', userId);
|
||||
try {
|
||||
console.log('[DELETE] Начинаем удаление user_identities для userId:', userId);
|
||||
// console.log('[DELETE] Начинаем удаление user_identities для userId:', userId);
|
||||
const resIdentities = await encryptedDb.deleteData('user_identities', { user_id: userId });
|
||||
console.log('[DELETE] Удалено user_identities:', resIdentities.length);
|
||||
// console.log('[DELETE] Удалено user_identities:', resIdentities.length);
|
||||
|
||||
console.log('[DELETE] Начинаем удаление messages для userId:', userId);
|
||||
// console.log('[DELETE] Начинаем удаление messages для userId:', userId);
|
||||
const resMessages = await encryptedDb.deleteData('messages', { user_id: userId });
|
||||
console.log('[DELETE] Удалено messages:', resMessages.length);
|
||||
// console.log('[DELETE] Удалено messages:', resMessages.length);
|
||||
|
||||
console.log('[DELETE] Начинаем удаление пользователя из users:', userId);
|
||||
// console.log('[DELETE] Начинаем удаление пользователя из users:', userId);
|
||||
const result = await encryptedDb.deleteData('users', { id: userId });
|
||||
console.log('[DELETE] Результат удаления пользователя:', result.length, result);
|
||||
// console.log('[DELETE] Результат удаления пользователя:', result.length, result);
|
||||
|
||||
return result.length;
|
||||
} catch (e) {
|
||||
console.error('[DELETE] Ошибка при удалении пользователя:', e);
|
||||
// console.error('[DELETE] Ошибка при удалении пользователя:', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,10 @@ function initWSS(server) {
|
||||
wss = new WebSocket.Server({ server, path: '/ws' });
|
||||
|
||||
wss.on('connection', (ws, req) => {
|
||||
console.log('🔌 [WebSocket] Новое подключение');
|
||||
console.log('🔌 [WebSocket] IP клиента:', req.socket.remoteAddress);
|
||||
console.log('🔌 [WebSocket] User-Agent:', req.headers['user-agent']);
|
||||
console.log('🔌 [WebSocket] Origin:', req.headers.origin);
|
||||
// console.log('🔌 [WebSocket] Новое подключение');
|
||||
// console.log('🔌 [WebSocket] IP клиента:', req.socket.remoteAddress);
|
||||
// console.log('🔌 [WebSocket] User-Agent:', req.headers['user-agent']);
|
||||
// console.log('🔌 [WebSocket] Origin:', req.headers.origin);
|
||||
|
||||
// Добавляем клиента в общий список
|
||||
if (!wsClients.has('anonymous')) {
|
||||
@@ -43,7 +43,7 @@ function initWSS(server) {
|
||||
ws.on('message', (message) => {
|
||||
try {
|
||||
const data = JSON.parse(message);
|
||||
console.log('📨 [WebSocket] Получено сообщение:', data);
|
||||
// console.log('📨 [WebSocket] Получено сообщение:', data);
|
||||
|
||||
if (data.type === 'auth' && data.userId) {
|
||||
// Аутентификация пользователя
|
||||
@@ -58,12 +58,12 @@ function initWSS(server) {
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ [WebSocket] Ошибка парсинга сообщения:', error);
|
||||
// console.error('❌ [WebSocket] Ошибка парсинга сообщения:', error);
|
||||
}
|
||||
});
|
||||
|
||||
ws.on('close', (code, reason) => {
|
||||
console.log('🔌 [WebSocket] Соединение закрыто', { code, reason: reason.toString() });
|
||||
// console.log('🔌 [WebSocket] Соединение закрыто', { code, reason: reason.toString() });
|
||||
// Удаляем клиента из всех списков
|
||||
for (const [userId, clients] of wsClients.entries()) {
|
||||
clients.delete(ws);
|
||||
@@ -74,15 +74,15 @@ function initWSS(server) {
|
||||
});
|
||||
|
||||
ws.on('error', (error) => {
|
||||
console.error('❌ [WebSocket] Ошибка соединения:', error.message);
|
||||
// console.error('❌ [WebSocket] Ошибка соединения:', error.message);
|
||||
});
|
||||
});
|
||||
|
||||
console.log('🚀 [WebSocket] Сервер запущен на /ws');
|
||||
// console.log('🚀 [WebSocket] Сервер запущен на /ws');
|
||||
}
|
||||
|
||||
function authenticateUser(ws, userId) {
|
||||
console.log(`🔐 [WebSocket] Аутентификация пользователя ${userId}`);
|
||||
// console.log(`🔐 [WebSocket] Аутентификация пользователя ${userId}`);
|
||||
|
||||
// Удаляем из анонимных
|
||||
if (wsClients.has('anonymous')) {
|
||||
@@ -103,7 +103,7 @@ function authenticateUser(ws, userId) {
|
||||
}
|
||||
|
||||
function broadcastContactsUpdate() {
|
||||
console.log('📢 [WebSocket] Отправка обновления контактов всем клиентам');
|
||||
// console.log('📢 [WebSocket] Отправка обновления контактов всем клиентам');
|
||||
for (const [userId, clients] of wsClients.entries()) {
|
||||
for (const ws of clients) {
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
@@ -114,7 +114,7 @@ function broadcastContactsUpdate() {
|
||||
}
|
||||
|
||||
function broadcastMessagesUpdate() {
|
||||
console.log('📢 [WebSocket] Отправка обновления сообщений всем клиентам');
|
||||
// console.log('📢 [WebSocket] Отправка обновления сообщений всем клиентам');
|
||||
for (const [userId, clients] of wsClients.entries()) {
|
||||
for (const ws of clients) {
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
@@ -125,10 +125,10 @@ function broadcastMessagesUpdate() {
|
||||
}
|
||||
|
||||
function broadcastChatMessage(message, targetUserId = null) {
|
||||
console.log(`📢 [WebSocket] Отправка сообщения чата`, {
|
||||
messageId: message.id,
|
||||
targetUserId
|
||||
});
|
||||
// console.log(`📢 [WebSocket] Отправка сообщения чата`, {
|
||||
// messageId: message.id,
|
||||
// targetUserId
|
||||
// });
|
||||
|
||||
if (targetUserId) {
|
||||
// Отправляем конкретному пользователю
|
||||
@@ -159,10 +159,10 @@ function broadcastChatMessage(message, targetUserId = null) {
|
||||
}
|
||||
|
||||
function broadcastConversationUpdate(conversationId, targetUserId = null) {
|
||||
console.log(`📢 [WebSocket] Отправка обновления диалога`, {
|
||||
conversationId,
|
||||
targetUserId
|
||||
});
|
||||
// console.log(`📢 [WebSocket] Отправка обновления диалога`, {
|
||||
// conversationId,
|
||||
// targetUserId
|
||||
// });
|
||||
|
||||
const payload = {
|
||||
type: 'conversation-updated',
|
||||
@@ -192,7 +192,7 @@ function broadcastConversationUpdate(conversationId, targetUserId = null) {
|
||||
}
|
||||
|
||||
function broadcastTableUpdate(tableId) {
|
||||
console.log('📢 [WebSocket] Отправка обновления таблицы', tableId);
|
||||
// console.log('📢 [WebSocket] Отправка обновления таблицы', tableId);
|
||||
const payload = { type: 'table-updated', tableId };
|
||||
for (const [userId, clients] of wsClients.entries()) {
|
||||
for (const ws of clients) {
|
||||
@@ -204,11 +204,11 @@ function broadcastTableUpdate(tableId) {
|
||||
}
|
||||
|
||||
function broadcastTableRelationsUpdate(tableId, rowId, targetUserId = null) {
|
||||
console.log(`📢 [WebSocket] Отправка обновления связей таблицы`, {
|
||||
tableId,
|
||||
rowId,
|
||||
targetUserId
|
||||
});
|
||||
// console.log(`📢 [WebSocket] Отправка обновления связей таблицы`, {
|
||||
// tableId,
|
||||
// rowId,
|
||||
// targetUserId
|
||||
// });
|
||||
|
||||
const payload = {
|
||||
type: 'table-relations-updated',
|
||||
@@ -246,7 +246,7 @@ function broadcastTagsUpdate(targetUserId = null, rowId = null) {
|
||||
|
||||
// Устанавливаем новый таймаут
|
||||
tagsUpdateTimeout = setTimeout(() => {
|
||||
console.log('🔔 [WebSocket] Отправляем уведомление об обновлении тегов', rowId ? `для строки ${rowId}` : '');
|
||||
// console.log('🔔 [WebSocket] Отправляем уведомление об обновлении тегов', rowId ? `для строки ${rowId}` : '');
|
||||
const message = JSON.stringify({
|
||||
type: 'tags-updated',
|
||||
timestamp: Date.now(),
|
||||
@@ -262,7 +262,7 @@ function broadcastTagsUpdate(targetUserId = null, rowId = null) {
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`🔔 [WebSocket] Отправлено tags-updated ${sentCount} клиентам`);
|
||||
// console.log(`🔔 [WebSocket] Отправлено tags-updated ${sentCount} клиентам`);
|
||||
}, TAGS_UPDATE_DEBOUNCE);
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ function getStats() {
|
||||
|
||||
// Функция для отправки уведомлений о статусе AI
|
||||
function broadcastAIStatus(status) {
|
||||
console.log('📢 [WebSocket] Отправка статуса AI всем клиентам');
|
||||
// console.log('📢 [WebSocket] Отправка статуса AI всем клиентам');
|
||||
for (const [userId, clients] of wsClients.entries()) {
|
||||
for (const ws of clients) {
|
||||
if (ws.readyState === WebSocket.OPEN) {
|
||||
|
||||
Reference in New Issue
Block a user