ваше сообщение коммита

This commit is contained in:
2025-06-04 14:39:36 +03:00
parent 2c2115869c
commit 4d5cef853e
17 changed files with 1046 additions and 2038 deletions

View File

@@ -126,4 +126,82 @@
--- ---
## Требования к CRM-интерфейсу для работы с контактами, тегами и настройками RAG-ассистента
### 1. Раздел "Контакты" в CRM
- **Фильтры:**
- Новые пользователи (по дате создания или статусу "новый").
- Новые входящие сообщения (по наличию непрочитанных/неотвеченных сообщений).
- Теги (мультиселект по тегам пользователя).
- **Детали контакта:**
- Просмотр истории сообщений.
- Список тегов пользователя.
- Добавление/удаление тегов через выпадающий список или автокомплит (создание связи в таблице user_tags).
### 2. Настройки ИИ-ассистента
- **Выбор RAG-таблиц:**
- В настройках ассистента отображается список всех доступных RAG-таблиц.
- Администратор выбирает (чекбоксами или мультиселектом), какие таблицы использовать для поиска ответов.
- Для каждой выбранной таблицы отображается список тегов, которые она содержит.
- **Связь с тегами:**
- При генерации ответа ИИ использует только те RAG-таблицы и записи, которые соответствуют тегам пользователя.
### 3. Рекомендации по интерфейсу (Vue)
- Компоненты:
- `ContactList.vue` — фильтры, список пользователей
- `ContactDetails.vue` — история сообщений, теги, добавление тегов
- `AssistantSettings.vue` — выбор RAG-таблиц
- `RagTableSelector.vue` — список таблиц с чекбоксами
- `TagList.vue` — просмотр тегов в выбранной таблице
### 4. Схема действий администратора
1. В разделе "Контакты" находит нового пользователя/сообщение через фильтры.
2. В деталях контакта добавляет нужные теги пользователю.
3. В настройках ассистента выбирает, какие RAG-таблицы использовать для поиска по тегам.
4. ИИ-ассистент при ответе использует только релевантные RAG-таблицы и теги.
### 5. Пример структуры таблиц для RAG и тегов
- `users` — пользователи
- `messages` — сообщения
- `tags` — справочник тегов
- `user_tags` — связь пользователей и тегов (user_id, tag_id)
- `rag_tables` — таблицы знаний (например, FAQ, инструкции)
- `rag_entries` — записи в таблицах знаний (content, rag_table_id, ...)
- `rag_entry_tags` — связь записей знаний и тегов (rag_entry_id, tag_id)
---
## План внедрения RAG-ассистента в CRM
1. **Создать RAG-таблицы для ИИ-ассистента**
- Таблицы для хранения знаний о компании, продуктах, услугах (например, `rag_tables`, `rag_entries`).
- Возможность добавлять, редактировать, удалять записи через UI.
- Каждая запись может быть связана с тегами (например, категория продукта, язык, сегмент клиента).
2. **Создать таблицы с тегами для пользователей**
- Таблица тегов (`tags`).
- Связующая таблица `user_tags` (user_id, tag_id).
- UI для управления тегами и их привязкой к пользователям.
3. **Отредактировать страницу настройки ИИ-ассистента**
- Добавить выбор, какие RAG-таблицы использовать для поиска.
- Отображать список тегов, связанных с выбранными таблицами.
- Возможность быстро подключать/отключать таблицы и теги.
4. **Добавить в раздел "Контакты" фильтры (отдельные компоненты)**
- Фильтр по новым пользователям.
- Фильтр по новым входящим сообщениям.
- Фильтр по тегам (мультиселект).
- Каждый фильтр реализовать отдельным Vue-компонентом для переиспользования.
5. **В "Детали контакта" добавить инлайн-кнопки**
- Кнопки:
- Сгенерировать (ответ с помощью ИИ)
- Редактировать (отредактировать сгенерированный ответ)
- Отправить (отправить ответ пользователю)
- Добавить в RAG-таблицу (сделать сообщение или ответ частью базы знаний)
- Кнопки должны быть доступны для каждого сообщения в истории.
---
**Этот документ будет дополняться по мере реализации каждого этапа.** **Этот документ будет дополняться по мере реализации каждого этапа.**

View File

@@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS ai_assistant_settings (
id SERIAL PRIMARY KEY,
system_prompt TEXT,
selected_rag_tables INTEGER[],
languages TEXT[],
model TEXT,
rules JSONB,
updated_at TIMESTAMP DEFAULT NOW(),
updated_by INTEGER,
);
-- Вставить дефолтную строку (глобальные настройки)
INSERT INTO ai_assistant_settings (system_prompt, selected_rag_tables, languages, model, rules)
VALUES (
'Вы — полезный ассистент. Отвечайте на русском языке.',
ARRAY[]::INTEGER[],
ARRAY['ru'],
'qwen2.5',
'{"checkUserTags": true, "searchRagFirst": true, "generateIfNoRag": true, "requireAdminApproval": true}'
)
ON CONFLICT DO NOTHING;

View File

@@ -0,0 +1,11 @@
CREATE TABLE IF NOT EXISTS ai_assistant_rules (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
rules JSONB NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
ALTER TABLE ai_assistant_settings
ADD COLUMN IF NOT EXISTS rules_id INTEGER REFERENCES ai_assistant_rules(id);

View File

@@ -0,0 +1,5 @@
-- Добавление недостающих полей для интеграции с Telegram и Email, а также для системного сообщения
ALTER TABLE ai_assistant_settings
ADD COLUMN IF NOT EXISTS telegram_settings_id INTEGER REFERENCES telegram_settings(id),
ADD COLUMN IF NOT EXISTS email_settings_id INTEGER REFERENCES email_settings(id),
ADD COLUMN IF NOT EXISTS system_message TEXT;

File diff suppressed because it is too large Load Diff

View File

@@ -1,515 +1,12 @@
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:09:35.925Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.268Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:09:35.927Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.269Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:09:35.927Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.269Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:09:51.210Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.269Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.958Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.270Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.958Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.270Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.959Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.270Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.959Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.270Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.959Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.270Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.960Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.271Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.960Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.271Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.960Z"} {"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-04T11:33:45.271Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.961Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.961Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.961Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.961Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.962Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.962Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.962Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.963Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.963Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:17:27.964Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.321Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.322Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.322Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.322Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.323Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.323Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.323Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.323Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.324Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.324Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.324Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:23:00.324Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:24:20.893Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:34:53.717Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:34:53.719Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:34:53.719Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:34:53.719Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:34:53.719Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:34:53.720Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:39:16.697Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:39:16.698Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:39:24.562Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:42:24.304Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:42:24.305Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:42:24.305Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:42:24.305Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:42:24.305Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:46:56.098Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:51:47.393Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:51:47.394Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:51:47.394Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:51:47.394Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:51:47.394Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:51:47.394Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:51:47.394Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:52:05.373Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:52:05.374Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T11:53:38.082Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:53:38.082Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:53:38.082Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:53:38.082Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:53:38.082Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:53:38.082Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:54:14.127Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:54:14.128Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:54:51.568Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:54:51.569Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:55:46.954Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:55:46.955Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:55:46.955Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:56:24.274Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T11:56:24.275Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:05:47.191Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:05:47.192Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:05:47.192Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:05:47.192Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:05:47.192Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:05:47.192Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:05:47.192Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:05:47.192Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:05:47.192Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:07:37.812Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:07:37.812Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:07:37.813Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:07:37.813Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:07:37.813Z"}
{"level":"error","message":"Uncaught Exception: Cannot set properties of undefined (setting 'name')","stack":"TypeError: Cannot set properties of undefined (setting 'name')\n at Connection.<anonymous> (/app/node_modules/imap/lib/Connection.js:431:22)\n at Connection._resTagged (/app/node_modules/imap/lib/Connection.js:1535:22)\n at Parser.<anonymous> (/app/node_modules/imap/lib/Connection.js:194:10)\n at Parser.emit (node:events:524:28)\n at Parser._resTagged (/app/node_modules/imap/lib/Parser.js:175:10)\n at Parser._parse (/app/node_modules/imap/lib/Parser.js:139:16)\n at Parser._tryread (/app/node_modules/imap/lib/Parser.js:82:15)\n at Parser._cbReadable (/app/node_modules/imap/lib/Parser.js:53:12)\n at TLSSocket.emit (node:events:524:28)\n at emitReadable_ (node:internal/streams/readable:834:12)","timestamp":"2025-06-01T12:07:51.222Z"}
{"level":"error","message":"Uncaught Exception: Cannot read properties of undefined (reading 'type')","stack":"TypeError: Cannot read properties of undefined (reading 'type')\n at Connection._resUntagged (/app/node_modules/imap/lib/Connection.js:1265:52)\n at Parser.<anonymous> (/app/node_modules/imap/lib/Connection.js:191:10)\n at Parser.emit (node:events:524:28)\n at Parser._resUntagged (/app/node_modules/imap/lib/Parser.js:271:10)\n at Parser._parse (/app/node_modules/imap/lib/Parser.js:137:16)\n at Parser._tryread (/app/node_modules/imap/lib/Parser.js:82:15)\n at Parser._cbReadable (/app/node_modules/imap/lib/Parser.js:53:12)\n at TLSSocket.emit (node:events:524:28)\n at emitReadable_ (node:internal/streams/readable:834:12)\n at process.processTicksAndRejections (node:internal/process/task_queues:81:21)","timestamp":"2025-06-01T12:07:51.310Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:07:51.509Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:07:51.510Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:07:51.510Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:09:28.645Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:09:28.646Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:09:28.646Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:09:28.646Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:09:46.751Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:09:46.752Z"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: Требуется аутентификация","method":"GET","stack":"Error: Требуется аутентификация\n at createError (/app/utils/error.js:8:17)\n at requireAdmin (/app/middleware/auth.js:97:19)\n at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)\n at next (/app/node_modules/express/lib/router/route.js:149:13)\n at Route.dispatch (/app/node_modules/express/lib/router/route.js:119:3)\n at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)\n at /app/node_modules/express/lib/router/index.js:284:15\n at Function.process_params (/app/node_modules/express/lib/router/index.js:346:12)\n at next (/app/node_modules/express/lib/router/index.js:280:10)\n at Function.handle (/app/node_modules/express/lib/router/index.js:175:3)","timestamp":"2025-06-01T12:09:57.262Z","url":"/api/settings/rpc"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: Требуется аутентификация","method":"GET","stack":"Error: Требуется аутентификация\n at createError (/app/utils/error.js:8:17)\n at requireAdmin (/app/middleware/auth.js:97:19)\n at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)\n at next (/app/node_modules/express/lib/router/route.js:149:13)\n at Route.dispatch (/app/node_modules/express/lib/router/route.js:119:3)\n at Layer.handle [as handle_request] (/app/node_modules/express/lib/router/layer.js:95:5)\n at /app/node_modules/express/lib/router/index.js:284:15\n at param (/app/node_modules/express/lib/router/index.js:365:14)\n at param (/app/node_modules/express/lib/router/index.js:376:14)\n at Function.process_params (/app/node_modules/express/lib/router/index.js:421:3)","timestamp":"2025-06-01T12:10:24.332Z","url":"/api/settings/ai-settings/google"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:10:37.655Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:10:37.655Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:10:37.655Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:11:33.089Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:11:33.089Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:11:33.090Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:13:04.750Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:13:04.751Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:13:04.751Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:30:13.610Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:30:13.611Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:30:13.611Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:30:13.611Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:32:59.820Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:32:59.821Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:32:59.821Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:32:59.821Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:32:59.821Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:32:59.822Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:32:59.822Z"}
{"level":"error","message":"Uncaught Exception: Not authenticated","stack":"Error: Not authenticated\n at Connection.openBox (/app/node_modules/imap/lib/Connection.js:409:11)\n at Connection.<anonymous> (/app/services/emailBot.js:98:19)\n at Object.onceWrapper (node:events:638:28)\n at Connection.emit (node:events:536:35)\n at Connection.<anonymous> (/app/node_modules/imap/lib/Connection.js:1623:12)\n at Connection._resTagged (/app/node_modules/imap/lib/Connection.js:1535:22)\n at Parser.<anonymous> (/app/node_modules/imap/lib/Connection.js:194:10)\n at Parser.emit (node:events:524:28)\n at Parser._resTagged (/app/node_modules/imap/lib/Parser.js:175:10)\n at Parser._parse (/app/node_modules/imap/lib/Parser.js:139:16)","timestamp":"2025-06-01T12:33:08.570Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:33:55.215Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:33:55.216Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:33:55.216Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:33:55.217Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:34:08.611Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:34:08.612Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:35:59.510Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:35:59.510Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:35:59.510Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:35:59.510Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:35:59.511Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:35:59.512Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:36:54.929Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:36:54.930Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:36:54.930Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:37:50.416Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:37:50.416Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:37:50.416Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:38:45.807Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:38:45.808Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:38:45.808Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:39:41.119Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:39:41.119Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:39:41.119Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:40:35.667Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:40:35.667Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:40:35.667Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:41:17.106Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:41:30.247Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:41:30.247Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:42:24.659Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:42:24.660Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:42:24.660Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:45:19.446Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:47:59.820Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:55:18.678Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:55:18.679Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:55:18.680Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:55:31.780Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:55:31.781Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:57:16.610Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T12:57:16.611Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T12:57:27.541Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T13:00:04.844Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:00:04.845Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:00:04.846Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:00:04.846Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T13:01:15.296Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:01:15.297Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:01:15.297Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:01:15.297Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T13:02:23.121Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:02:23.122Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:02:23.122Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:02:23.123Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:02:23.123Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:03:17.628Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:03:17.629Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:03:17.629Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T13:06:51.568Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:06:51.569Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T13:08:02.186Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:08:02.186Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:08:02.187Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:08:02.187Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T13:08:14.872Z"}
{"level":"error","message":"Uncaught Exception: Not authenticated","stack":"Error: Not authenticated\n at Connection.openBox (/app/node_modules/imap/lib/Connection.js:409:11)\n at Connection.<anonymous> (/app/services/emailBot.js:98:19)\n at Object.onceWrapper (node:events:638:28)\n at Connection.emit (node:events:536:35)\n at Connection.<anonymous> (/app/node_modules/imap/lib/Connection.js:1623:12)\n at Connection._resTagged (/app/node_modules/imap/lib/Connection.js:1535:22)\n at Parser.<anonymous> (/app/node_modules/imap/lib/Connection.js:194:10)\n at Parser.emit (node:events:524:28)\n at Parser._resTagged (/app/node_modules/imap/lib/Parser.js:175:10)\n at Parser._parse (/app/node_modules/imap/lib/Parser.js:139:16)","timestamp":"2025-06-01T13:08:35.973Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:08:56.585Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:08:56.586Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:08:56.586Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T13:15:33.243Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:15:33.244Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:15:33.245Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:15:33.245Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:15:33.245Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:15:33.245Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:15:33.246Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T13:15:53.531Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:15:53.532Z"}
{"level":"error","message":"[EmailBot] IMAP connection error: Timed out while authenticating with server","timestamp":"2025-06-01T13:16:06.271Z"}
{"level":"error","message":"Uncaught Exception: Not authenticated","stack":"Error: Not authenticated\n at Connection.openBox (/app/node_modules/imap/lib/Connection.js:409:11)\n at Connection.<anonymous> (/app/services/emailBot.js:98:19)\n at Object.onceWrapper (node:events:638:28)\n at Connection.emit (node:events:536:35)\n at Connection.<anonymous> (/app/node_modules/imap/lib/Connection.js:1623:12)\n at Connection._resTagged (/app/node_modules/imap/lib/Connection.js:1535:22)\n at Parser.<anonymous> (/app/node_modules/imap/lib/Connection.js:194:10)\n at Parser.emit (node:events:524:28)\n at Parser._resTagged (/app/node_modules/imap/lib/Parser.js:175:10)\n at Parser._parse (/app/node_modules/imap/lib/Parser.js:139:16)","timestamp":"2025-06-01T13:16:23.502Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:17:22.573Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:17:22.574Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:17:22.574Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:17:22.574Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:17:22.574Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:17:42.841Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:18:17.144Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:18:17.145Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:19:11.722Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:19:11.723Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:19:11.723Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:20:06.223Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:20:06.224Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:20:06.224Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:21:00.825Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:21:00.825Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:21:00.825Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:21:21.116Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:22:15.614Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:22:15.615Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:22:15.615Z"}
{"level":"error","message":"Uncaught Exception: Cannot read properties of undefined (reading 'type')","stack":"TypeError: Cannot read properties of undefined (reading 'type')\n at Connection._resUntagged (/app/node_modules/imap/lib/Connection.js:1265:52)\n at Parser.<anonymous> (/app/node_modules/imap/lib/Connection.js:191:10)\n at Parser.emit (node:events:524:28)\n at Parser._resUntagged (/app/node_modules/imap/lib/Parser.js:271:10)\n at Parser._parse (/app/node_modules/imap/lib/Parser.js:137:16)\n at Parser._tryread (/app/node_modules/imap/lib/Parser.js:82:15)\n at Parser._cbReadable (/app/node_modules/imap/lib/Parser.js:53:12)\n at TLSSocket.emit (node:events:524:28)\n at emitReadable_ (node:internal/streams/readable:834:12)\n at process.processTicksAndRejections (node:internal/process/task_queues:81:21)","timestamp":"2025-06-01T13:22:45.249Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:23:44.328Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:23:44.328Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:23:44.328Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:23:44.328Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:23:44.328Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:24:04.569Z"}
{"level":"error","message":"Uncaught Exception: Cannot read properties of undefined (reading 'type')","stack":"TypeError: Cannot read properties of undefined (reading 'type')\n at Connection._resUntagged (/app/node_modules/imap/lib/Connection.js:1265:52)\n at Parser.<anonymous> (/app/node_modules/imap/lib/Connection.js:191:10)\n at Parser.emit (node:events:524:28)\n at Parser._resUntagged (/app/node_modules/imap/lib/Parser.js:271:10)\n at Parser._parse (/app/node_modules/imap/lib/Parser.js:137:16)\n at Parser._tryread (/app/node_modules/imap/lib/Parser.js:82:15)\n at Parser._cbReadable (/app/node_modules/imap/lib/Parser.js:53:12)\n at TLSSocket.emit (node:events:524:28)\n at emitReadable_ (node:internal/streams/readable:834:12)\n at process.processTicksAndRejections (node:internal/process/task_queues:81:21)","timestamp":"2025-06-01T13:24:34.225Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:25:33.534Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:25:33.534Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:25:33.535Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:25:33.535Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:25:33.535Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:26:28.054Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:26:28.055Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:26:28.055Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:27:23.322Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:27:23.323Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:27:23.323Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:27:43.035Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:28:37.605Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:28:37.605Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:28:37.605Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:30:06.234Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:30:06.235Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:30:06.235Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:30:06.235Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:30:06.236Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:31:00.791Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:31:00.792Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:31:00.792Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:31:55.225Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:31:55.225Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:31:55.226Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:33:44.284Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:33:44.285Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:33:44.285Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:33:44.285Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:33:44.285Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:33:44.286Z"}
{"level":"error","message":"Uncaught Exception: Cannot read properties of undefined (reading 'cbargs')","stack":"TypeError: Cannot read properties of undefined (reading 'cbargs')\n at Connection._resUntagged (/app/node_modules/imap/lib/Connection.js:1253:20)\n at Parser.<anonymous> (/app/node_modules/imap/lib/Connection.js:191:10)\n at Parser.emit (node:events:524:28)\n at Parser._resUntagged (/app/node_modules/imap/lib/Parser.js:271:10)\n at Parser._parse (/app/node_modules/imap/lib/Parser.js:137:16)\n at Parser._tryread (/app/node_modules/imap/lib/Parser.js:82:15)\n at Parser._cbReadable (/app/node_modules/imap/lib/Parser.js:53:12)\n at TLSSocket.emit (node:events:524:28)\n at emitReadable_ (node:internal/streams/readable:834:12)\n at process.processTicksAndRejections (node:internal/process/task_queues:81:21)","timestamp":"2025-06-01T13:34:34.438Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:35:33.575Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:35:33.575Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:35:33.575Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:35:33.575Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:35:33.576Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:35:33.576Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:37:22.712Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:37:22.713Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:37:22.713Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:37:22.713Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:37:22.713Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:37:22.713Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:38:17.269Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:38:17.269Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:38:17.270Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:38:37.670Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:39:11.851Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:39:11.852Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:40:06.385Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:40:06.386Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:40:06.386Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:41:00.818Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:41:00.819Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:41:00.819Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:41:55.333Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:41:55.334Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:41:55.335Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:42:50.061Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:42:50.062Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:42:50.062Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:43:44.501Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:43:44.501Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:43:44.502Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:44:39.448Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:44:39.449Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:44:39.449Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:44:43.990Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:44:57.552Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:45:34.003Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:45:34.004Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T13:45:35.365Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:45:38.523Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:45:57.304Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:46:23.401Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:46:23.402Z"}
{"level":"error","message":"Uncaught Exception: Timed out while authenticating with server","source":"timeout-auth","stack":"Error: Timed out while authenticating with server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:139:17)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:46:29.033Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T13:46:29.876Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:46:48.814Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:47:22.968Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:47:22.969Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T13:47:24.629Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:47:27.484Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:47:43.555Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:48:17.540Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:48:17.541Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T13:48:18.776Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:49:12.034Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:49:12.035Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:49:12.036Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:50:06.545Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:50:06.546Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:50:06.546Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:50:11.115Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:51:01.000Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:51:01.001Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:51:01.001Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T13:51:02.524Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:51:21.495Z"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: null value in column \"row_id\" of relation \"user_cell_values\" violates not-null constraint","method":"POST","stack":"error: null value in column \"row_id\" of relation \"user_cell_values\" violates not-null constraint\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:98:20","timestamp":"2025-06-01T13:51:50.270Z","url":"/api/tables/cell","userId":1}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:52:45.247Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:52:45.248Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:52:45.249Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:52:45.249Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:52:45.250Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:52:54.606Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:53:44.904Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:53:44.905Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:53:44.905Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T13:53:45.796Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:54:05.329Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:54:34.464Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:54:34.465Z"}
{"level":"error","message":"Uncaught Exception: Timed out while authenticating with server","source":"timeout-auth","stack":"Error: Timed out while authenticating with server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:139:17)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:54:39.847Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:55:33.932Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:55:33.933Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:55:33.933Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T13:55:35.269Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:56:28.573Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:56:28.574Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:56:28.574Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:56:33.108Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:56:49.071Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:57:18.235Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:57:18.235Z"}
{"level":"error","message":"Uncaught Exception: Timed out while authenticating with server","source":"timeout-auth","stack":"Error: Timed out while authenticating with server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:139:17)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:57:22.920Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T13:57:24.248Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:57:43.441Z"}
{"level":"error","message":"IMAP connection error during check: This socket has been ended by the other party","timestamp":"2025-06-01T13:58:18.318Z"}
{"level":"error","message":"IMAP connection error during check: This socket has been ended by the other party","timestamp":"2025-06-01T13:58:18.318Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:59:07.369Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:59:07.370Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T13:59:07.370Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T13:59:16.600Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T13:59:32.648Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:00:06.570Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:00:06.570Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:00:07.403Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:00:11.062Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:01:01.053Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:01:01.054Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:01:01.054Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:01:02.304Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:01:55.533Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:01:55.534Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:01:55.534Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:02:16.043Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T14:02:45.737Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T14:02:45.738Z"}
{"level":"error","message":"Uncaught Exception: Timed out while authenticating with server","source":"timeout-auth","stack":"Error: Timed out while authenticating with server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:139:17)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:02:54.330Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:02:54.962Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:03:44.962Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:03:44.963Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:03:44.963Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:03:49.493Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:03:49.772Z"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: column \"updated_at\" of relation \"user_columns\" does not exist","method":"PATCH","stack":"error: column \"updated_at\" of relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:168:20","timestamp":"2025-06-01T14:04:32.473Z","url":"/api/tables/column/4","userId":1}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: column \"updated_at\" of relation \"user_columns\" does not exist","method":"PATCH","stack":"error: column \"updated_at\" of relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:168:20","timestamp":"2025-06-01T14:04:32.566Z","url":"/api/tables/column/4","userId":1}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T14:04:34.517Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T14:04:34.518Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T14:04:34.519Z"}
{"level":"error","message":"Uncaught Exception: Timed out while authenticating with server","source":"timeout-auth","stack":"Error: Timed out while authenticating with server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:139:17)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:04:40.137Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:04:40.873Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:05:34.012Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:05:34.013Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:05:34.013Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:05:35.550Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:05:54.263Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T14:06:23.536Z"}
{"level":"error","message":"IMAP connection error during check: write after end","timestamp":"2025-06-01T14:06:23.537Z"}
{"level":"error","message":"Uncaught Exception: Timed out while authenticating with server","source":"timeout-auth","stack":"Error: Timed out while authenticating with server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:139:17)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:06:29.153Z"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: column \"updated_at\" of relation \"user_columns\" does not exist","method":"PATCH","stack":"error: column \"updated_at\" of relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:168:20","timestamp":"2025-06-01T14:06:34.510Z","url":"/api/tables/column/4","userId":1}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: column \"updated_at\" of relation \"user_columns\" does not exist","method":"PATCH","stack":"error: column \"updated_at\" of relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:168:20","timestamp":"2025-06-01T14:06:34.533Z","url":"/api/tables/column/4","userId":1}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:07:22.950Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:07:22.950Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:07:22.951Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:07:24.722Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:08:17.572Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:08:17.572Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:08:17.572Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:08:22.108Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:08:38.006Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:09:12.007Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:09:12.007Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:09:13.141Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:09:16.601Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:10:06.492Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:10:06.493Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:10:06.493Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:10:07.723Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:10:11.079Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:10:26.925Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:11:00.881Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:11:00.882Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:11:02.214Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:11:56.561Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:11:56.563Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:11:56.564Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:12:00.478Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:12:50.560Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:12:50.560Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:12:50.561Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:12:55.023Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:12:55.680Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:13:10.680Z"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: column \"updated_at\" of relation \"user_columns\" does not exist","method":"PATCH","stack":"error: column \"updated_at\" of relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:168:20","timestamp":"2025-06-01T14:13:38.721Z","url":"/api/tables/column/4","userId":1}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: column \"updated_at\" of relation \"user_columns\" does not exist","method":"PATCH","stack":"error: column \"updated_at\" of relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:168:20","timestamp":"2025-06-01T14:13:38.765Z","url":"/api/tables/column/4","userId":1}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:13:45.094Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:13:45.095Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:13:46.280Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:13:49.544Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:14:39.614Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:14:39.615Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:14:39.615Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:14:44.117Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:15:34.134Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:15:34.135Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:15:34.135Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:15:38.607Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:16:29.150Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:16:29.150Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:16:29.151Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:16:30.684Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:16:49.883Z"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: relation \"user_columns\" does not exist","method":"GET","stack":"error: relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:41:22","timestamp":"2025-06-01T14:16:51.620Z","url":"/api/tables/5","userId":1}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: relation \"user_columns\" does not exist","method":"GET","stack":"error: relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:41:22","timestamp":"2025-06-01T14:16:58.294Z","url":"/api/tables/6","userId":1}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:17:23.182Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:17:23.183Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:17:27.611Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:18:17.543Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:18:17.544Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:18:17.544Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:18:18.767Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:18:22.099Z"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: relation \"user_columns\" does not exist","method":"GET","stack":"error: relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:41:22","timestamp":"2025-06-01T14:18:32.090Z","url":"/api/tables/5","userId":1}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:19:12.901Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:19:12.902Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:19:12.902Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:19:16.584Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:19:32.492Z"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: relation \"user_columns\" does not exist","method":"GET","stack":"error: relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:41:22","timestamp":"2025-06-01T14:20:00.513Z","url":"/api/tables/6","userId":1}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: relation \"user_columns\" does not exist","method":"GET","stack":"error: relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:41:22","timestamp":"2025-06-01T14:20:04.400Z","url":"/api/tables/5","userId":1}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:20:06.485Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:20:06.486Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:20:11.102Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:20:11.804Z"}
{"ip":"::ffff:172.18.0.1","level":"error","message":"Error: relation \"user_columns\" does not exist","method":"GET","stack":"error: relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async /app/routes/tables.js:41:22","timestamp":"2025-06-01T14:20:15.672Z","url":"/api/tables/5","userId":1}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:20:27.055Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:21:01.439Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:21:01.440Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:21:02.675Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:21:05.997Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:21:55.972Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:21:55.973Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:21:55.973Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:22:00.452Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:22:50.614Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:22:50.615Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:22:50.615Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:22:51.727Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:22:55.083Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:23:45.075Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:23:45.076Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:23:45.076Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:23:46.369Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:23:49.616Z"}
{"code":"42P01","file":"namespace.c","length":110,"level":"error","line":"434","message":"Error executing migration 028_create_dynamic_tables.sql: relation \"user_columns\" does not exist","name":"error","routine":"RangeVarGetRelidExtended","severity":"ERROR","stack":"error: relation \"user_columns\" does not exist\n at /app/node_modules/pg-pool/index.js:45:11\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async runMigrations (/app/scripts/run-migrations.js:77:11)","timestamp":"2025-06-01T14:24:37.212Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:24:39.543Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:24:39.544Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:24:39.545Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:24:40.703Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:24:44.101Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:25:34.214Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:25:34.214Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:25:34.214Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:25:38.580Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:26:28.660Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:26:28.660Z"}
{"level":"error","message":"IMAP connection error during check: Timed out while authenticating with server","timestamp":"2025-06-01T14:26:28.661Z"}
{"code":"EPIPE","level":"error","message":"Uncaught Exception: This socket has been ended by the other party","source":"socket","stack":"Error: This socket has been ended by the other party\n at genericNodeError (node:internal/errors:984:15)\n at wrappedFn (node:internal/errors:538:14)\n at Socket.writeAfterFIN [as write] (node:net:566:14)\n at JSStreamSocket.doWrite (node:internal/js_stream_socket:199:19)\n at JSStream.onwrite (node:internal/js_stream_socket:35:57)\n at Socket._final (node:net:537:28)\n at prefinish (node:internal/streams/writable:916:14)\n at finishMaybe (node:internal/streams/writable:930:5)\n at Writable.end (node:internal/streams/writable:845:5)\n at Socket.end (node:net:728:31)","timestamp":"2025-06-01T14:26:29.827Z"}
{"level":"error","message":"Uncaught Exception: Timed out while connecting to server","source":"timeout","stack":"Error: Timed out while connecting to server\n at Timeout._onTimeout (/app/node_modules/imap/lib/Connection.js:280:15)\n at listOnTimeout (node:internal/timers:581:17)\n at process.processTimers (node:internal/timers:519:7)","timestamp":"2025-06-01T14:26:33.094Z"}

View File

@@ -6,6 +6,8 @@ const db = require('../db');
const logger = require('../utils/logger'); const logger = require('../utils/logger');
const { requireAuth } = require('../middleware/auth'); const { requireAuth } = require('../middleware/auth');
const crypto = require('crypto'); const crypto = require('crypto');
const aiAssistantSettingsService = require('../services/aiAssistantSettingsService');
const aiAssistantRulesService = require('../services/aiAssistantRulesService');
// Настройка multer для обработки файлов в памяти // Настройка multer для обработки файлов в памяти
const storage = multer.memoryStorage(); const storage = multer.memoryStorage();
@@ -61,19 +63,28 @@ async function processGuestMessages(userId, guestId) {
const guestMessages = guestMessagesResult.rows; const guestMessages = guestMessagesResult.rows;
logger.info(`Found ${guestMessages.length} guest messages for guest ID ${guestId}`); logger.info(`Found ${guestMessages.length} guest messages for guest ID ${guestId}`);
// Создаем новый диалог для этих сообщений // --- Новый порядок: ищем последний диалог пользователя ---
const firstMessage = guestMessages[0]; let conversation = null;
const title = firstMessage.content const lastConvResult = await db.getQuery()(
? (firstMessage.content.length > 30 ? `${firstMessage.content.substring(0, 30)}...` : firstMessage.content) 'SELECT * FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1',
: (firstMessage.attachment_filename ? `Файл: ${firstMessage.attachment_filename}` : 'Новый диалог'); [userId]
const newConversationResult = await db.getQuery()(
'INSERT INTO conversations (user_id, title) VALUES ($1, $2) RETURNING *',
[userId, title]
); );
if (lastConvResult.rows.length > 0) {
const conversation = newConversationResult.rows[0]; conversation = lastConvResult.rows[0];
logger.info(`Created new conversation ${conversation.id} for guest messages`); } else {
// Если нет ни одного диалога, создаём новый
const firstMessage = guestMessages[0];
const title = firstMessage.content
? (firstMessage.content.length > 30 ? `${firstMessage.content.substring(0, 30)}...` : firstMessage.content)
: (firstMessage.attachment_filename ? `Файл: ${firstMessage.attachment_filename}` : 'Новый диалог');
const newConversationResult = await db.getQuery()(
'INSERT INTO conversations (user_id, title) VALUES ($1, $2) RETURNING *',
[userId, title]
);
conversation = newConversationResult.rows[0];
logger.info(`Created new conversation ${conversation.id} for guest messages`);
}
// --- КОНЕЦ блока поиска/создания диалога ---
// Отслеживаем успешные сохранения сообщений // Отслеживаем успешные сохранения сообщений
const savedMessageIds = []; const savedMessageIds = [];
@@ -81,7 +92,6 @@ async function processGuestMessages(userId, guestId) {
// Обрабатываем каждое гостевое сообщение // Обрабатываем каждое гостевое сообщение
for (const guestMessage of guestMessages) { for (const guestMessage of guestMessages) {
logger.info(`Processing guest message ID ${guestMessage.id}: ${guestMessage.content || guestMessage.attachment_filename || '(empty)'}`); logger.info(`Processing guest message ID ${guestMessage.id}: ${guestMessage.content || guestMessage.attachment_filename || '(empty)'}`);
try { try {
// Сохраняем сообщение пользователя в таблицу messages, включая данные файла // Сохраняем сообщение пользователя в таблицу messages, включая данные файла
const userMessageResult = await db.getQuery()( const userMessageResult = await db.getQuery()(
@@ -103,39 +113,59 @@ async function processGuestMessages(userId, guestId) {
guestMessage.attachment_data // BYTEA guestMessage.attachment_data // BYTEA
] ]
); );
const savedUserMessage = userMessageResult.rows[0]; const savedUserMessage = userMessageResult.rows[0];
logger.info(`Saved user message with ID ${savedUserMessage.id}`); logger.info(`Saved user message with ID ${savedUserMessage.id}`);
savedMessageIds.push(guestMessage.id); savedMessageIds.push(guestMessage.id);
// --- Генерируем ответ ИИ на гостевое сообщение, если это текст ---
// Получаем ответ от ИИ только для текстовых сообщений if (guestMessage.content) {
if (!guestMessage.is_ai && guestMessage.content) { // Проверяем, что на это сообщение ещё нет ответа ассистента
logger.info('Getting AI response for:', guestMessage.content); const aiReplyExists = await db.getQuery()(
const language = guestMessage.language || 'auto'; `SELECT 1 FROM messages WHERE conversation_id = $1 AND sender_type = 'assistant' AND created_at > $2 LIMIT 1`,
// Предполагаем, что aiAssistant.getResponse принимает только текст [conversation.id, guestMessage.created_at]
const aiResponseContent = await aiAssistant.getResponse(guestMessage.content, language); );
logger.info('AI response received' + (aiResponseContent ? '' : ' (empty)'), 'for conversation', conversation.id); if (!aiReplyExists.rows.length) {
try {
if (aiResponseContent) { // Получаем настройки ассистента
// Сохраняем ответ от ИИ (у него нет вложений) const aiSettings = await aiAssistantSettingsService.getSettings();
const aiMessageResult = await db.getQuery()( let rules = null;
`INSERT INTO messages if (aiSettings && aiSettings.rules_id) {
(conversation_id, content, sender_type, role, channel, created_at, user_id) rules = await aiAssistantRulesService.getRuleById(aiSettings.rules_id);
VALUES }
($1, $2, 'assistant', 'assistant', 'web', $3, $4) // Получаем историю сообщений до этого guestMessage (до created_at)
RETURNING *`, const historyResult = await db.getQuery()(
[ 'SELECT sender_type, content FROM messages WHERE conversation_id = $1 AND created_at < $2 ORDER BY created_at DESC LIMIT 10',
conversation.id, [conversation.id, guestMessage.created_at]
aiResponseContent,
new Date(),
userId
]
); );
logger.info(`Saved AI response with ID ${aiMessageResult.rows[0].id}`); const history = historyResult.rows.reverse().map(msg => ({
role: msg.sender_type === 'user' ? 'user' : 'assistant',
content: msg.content
}));
// Язык guestMessage.language или auto
const detectedLanguage = guestMessage.language === 'auto' ? aiAssistant.detectLanguage(guestMessage.content) : guestMessage.language;
logger.info('Getting AI response for guest message:', guestMessage.content);
const aiResponseContent = await aiAssistant.getResponse(
guestMessage.content,
detectedLanguage,
history,
aiSettings ? aiSettings.system_prompt : '',
rules ? rules.rules : null
);
logger.info('AI response for guest message received' + (aiResponseContent ? '' : ' (empty)'), { conversationId: conversation.id });
if (aiResponseContent) {
await db.getQuery()(
`INSERT INTO messages
(conversation_id, user_id, content, sender_type, role, channel)
VALUES ($1, $2, $3, 'assistant', 'assistant', 'web')`,
[conversation.id, userId, aiResponseContent]
);
logger.info('AI response for guest message saved', { conversationId: conversation.id });
}
} catch (aiError) {
logger.error('Error getting or saving AI response for guest message:', aiError);
}
} }
} else {
logger.info(`Skipping AI response for guest message ID ${guestMessage.id} (is_ai: ${guestMessage.is_ai}, hasContent: ${!!guestMessage.content})`);
} }
// --- конец блока генерации ответа ИИ ---
} catch (error) { } catch (error) {
logger.error(`Error processing guest message ${guestMessage.id}: ${error.message}`, { stack: error.stack }); logger.error(`Error processing guest message ${guestMessage.id}: ${error.message}`, { stack: error.stack });
// Продолжаем с другими сообщениями в случае ошибки // Продолжаем с другими сообщениями в случае ошибки
@@ -254,10 +284,28 @@ router.post('/guest-message', upload.array('attachments'), async (req, res) => {
// Не прерываем ответ пользователю из-за ошибки сессии // Не прерываем ответ пользователю из-за ошибки сессии
} }
// Получаем настройки ассистента для systemMessage
let telegramBotUrl = null;
let supportEmailAddr = null;
try {
const aiSettings = await aiAssistantSettingsService.getSettings();
if (aiSettings && aiSettings.telegramBot && aiSettings.telegramBot.bot_username) {
telegramBotUrl = `https://t.me/${aiSettings.telegramBot.bot_username}`;
}
if (aiSettings && aiSettings.supportEmail && aiSettings.supportEmail.from_email) {
supportEmailAddr = aiSettings.supportEmail.from_email;
}
} catch (e) {
logger.error('Ошибка получения настроек ассистента для systemMessage:', e);
}
res.json({ res.json({
success: true, success: true,
messageId: savedMessageId, // Возвращаем ID сохраненного сообщения messageId: savedMessageId, // Возвращаем ID сохраненного сообщения
guestId: guestId // Возвращаем использованный guestId guestId: guestId, // Возвращаем использованный guestId
systemMessage: 'Для продолжения диалога авторизуйтесь: подключите кошелек, перейдите в чат-бот Telegram или отправьте письмо на email.',
telegramBotUrl,
supportEmail: supportEmailAddr
}); });
} catch (error) { } catch (error) {
logger.error('Error saving guest message:', error); logger.error('Error saving guest message:', error);
@@ -303,18 +351,27 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re
} }
conversation = convResult.rows[0]; conversation = convResult.rows[0];
} else { } else {
// Создаем новый диалог, если ID не предоставлен // Ищем последний диалог пользователя
const title = message const lastConvResult = await db.getQuery()(
? (message.length > 50 ? `${message.substring(0, 50)}...` : message) 'SELECT * FROM conversations WHERE user_id = $1 ORDER BY updated_at DESC, created_at DESC LIMIT 1',
: (file ? `Файл: ${file.originalname}` : 'Новый диалог'); [userId]
const newConvResult = await db.getQuery()(
'INSERT INTO conversations (user_id, title) VALUES ($1, $2) RETURNING *',
[userId, title]
); );
conversation = newConvResult.rows[0]; if (lastConvResult.rows.length > 0) {
conversationId = conversation.id; conversation = lastConvResult.rows[0];
logger.info('Created new conversation', { conversationId, userId }); conversationId = conversation.id;
} else {
// Создаем новый диалог, если нет ни одного
const title = message
? (message.length > 50 ? `${message.substring(0, 50)}...` : message)
: (file ? `Файл: ${file.originalname}` : 'Новый диалог');
const newConvResult = await db.getQuery()(
'INSERT INTO conversations (user_id, title) VALUES ($1, $2) RETURNING *',
[userId, title]
);
conversation = newConvResult.rows[0];
conversationId = conversation.id;
logger.info('Created new conversation', { conversationId, userId });
}
} }
// Подготавливаем данные для вставки сообщения пользователя // Подготавливаем данные для вставки сообщения пользователя
@@ -348,9 +405,32 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re
let aiMessage = null; let aiMessage = null;
if (messageContent) { // Только для текстовых сообщений if (messageContent) { // Только для текстовых сообщений
try { try {
// Получаем настройки ассистента
const aiSettings = await aiAssistantSettingsService.getSettings();
let rules = null;
if (aiSettings && aiSettings.rules_id) {
rules = await aiAssistantRulesService.getRuleById(aiSettings.rules_id);
}
logger.info('AI System Prompt:', aiSettings ? aiSettings.system_prompt : 'not set');
logger.info('AI Rules:', rules ? JSON.stringify(rules.rules) : 'not set');
// Получаем последние 10 сообщений из диалога для истории (до текущего сообщения)
const historyResult = await db.getQuery()(
'SELECT sender_type, content FROM messages WHERE conversation_id = $1 AND id < $2 ORDER BY created_at DESC LIMIT 10',
[conversationId, userMessage.id]
);
const history = historyResult.rows.reverse().map(msg => ({
role: msg.sender_type === 'user' ? 'user' : 'assistant',
content: msg.content
}));
const detectedLanguage = language === 'auto' ? aiAssistant.detectLanguage(messageContent) : language; const detectedLanguage = language === 'auto' ? aiAssistant.detectLanguage(messageContent) : language;
logger.info('Getting AI response for:', messageContent); logger.info('Getting AI response for:', messageContent);
const aiResponseContent = await aiAssistant.getResponse(messageContent, detectedLanguage); const aiResponseContent = await aiAssistant.getResponse(
messageContent,
detectedLanguage,
history,
aiSettings ? aiSettings.system_prompt : '',
rules ? rules.rules : null
);
logger.info('AI response received' + (aiResponseContent ? '' : ' (empty)'), { conversationId }); logger.info('AI response received' + (aiResponseContent ? '' : ' (empty)'), { conversationId });
if (aiResponseContent) { if (aiResponseContent) {
@@ -396,6 +476,12 @@ router.post('/message', requireAuth, upload.array('attachments'), async (req, re
return formatted; return formatted;
}; };
// Обновляем updated_at у диалога
await db.getQuery()(
'UPDATE conversations SET updated_at = NOW() WHERE id = $1',
[conversationId]
);
res.json({ res.json({
success: true, success: true,
conversationId: conversationId, conversationId: conversationId,
@@ -541,6 +627,26 @@ router.get('/history', requireAuth, async (req, res) => {
} }
}); });
// --- Новый роут для связывания гостя после аутентификации ---
router.post('/process-guest', requireAuth, async (req, res) => {
const userId = req.session.userId;
const { guestId } = req.body;
if (!guestId) {
return res.status(400).json({ success: false, error: 'guestId is required' });
}
try {
const result = await module.exports.processGuestMessages(userId, guestId);
if (result && result.conversationId) {
return res.json({ success: true, conversationId: result.conversationId });
} else {
return res.json({ success: false, error: result.error || 'No conversation created' });
}
} catch (error) {
logger.error('Error in /process-guest:', error);
return res.status(500).json({ success: false, error: 'Internal error' });
}
});
// Экспортируем маршрутизатор и функцию processGuestMessages отдельно // Экспортируем маршрутизатор и функцию processGuestMessages отдельно
module.exports = router; module.exports = router;
module.exports.processGuestMessages = processGuestMessages; module.exports.processGuestMessages = processGuestMessages;

View File

@@ -8,6 +8,8 @@ const authTokenService = require('../services/authTokenService');
const aiProviderSettingsService = require('../services/aiProviderSettingsService'); const aiProviderSettingsService = require('../services/aiProviderSettingsService');
const aiAssistant = require('../services/ai-assistant'); const aiAssistant = require('../services/ai-assistant');
const dns = require('node:dns').promises; const dns = require('node:dns').promises;
const aiAssistantSettingsService = require('../services/aiAssistantSettingsService');
const aiAssistantRulesService = require('../services/aiAssistantRulesService');
// Логируем версию ethers для отладки // Логируем версию ethers для отладки
logger.info(`Ethers version: ${ethers.version || 'unknown'}`); logger.info(`Ethers version: ${ethers.version || 'unknown'}`);
@@ -239,4 +241,92 @@ router.post('/ai-settings/:provider/verify', requireAdmin, async (req, res, next
} }
}); });
router.get('/ai-assistant', requireAdmin, async (req, res, next) => {
try {
const settings = await aiAssistantSettingsService.getSettings();
res.json({ success: true, settings });
} catch (error) {
next(error);
}
});
router.put('/ai-assistant', requireAdmin, async (req, res, next) => {
try {
const updated = await aiAssistantSettingsService.upsertSettings({ ...req.body, updated_by: req.session.userId || null });
res.json({ success: true, settings: updated });
} catch (error) {
next(error);
}
});
// Получить все наборы правил
router.get('/ai-assistant-rules', requireAdmin, async (req, res, next) => {
try {
const rules = await aiAssistantRulesService.getAllRules();
res.json({ success: true, rules });
} catch (error) {
next(error);
}
});
// Получить набор правил по id
router.get('/ai-assistant-rules/:id', requireAdmin, async (req, res, next) => {
try {
const rule = await aiAssistantRulesService.getRuleById(req.params.id);
res.json({ success: true, rule });
} catch (error) {
next(error);
}
});
// Создать набор правил
router.post('/ai-assistant-rules', requireAdmin, async (req, res, next) => {
try {
const created = await aiAssistantRulesService.createRule(req.body);
res.json({ success: true, rule: created });
} catch (error) {
next(error);
}
});
// Обновить набор правил
router.put('/ai-assistant-rules/:id', requireAdmin, async (req, res, next) => {
try {
const updated = await aiAssistantRulesService.updateRule(req.params.id, req.body);
res.json({ success: true, rule: updated });
} catch (error) {
next(error);
}
});
// Удалить набор правил
router.delete('/ai-assistant-rules/:id', requireAdmin, async (req, res, next) => {
try {
await aiAssistantRulesService.deleteRule(req.params.id);
res.json({ success: true });
} catch (error) {
next(error);
}
});
// Получить все email_settings для выпадающего списка
router.get('/email-settings', requireAdmin, async (req, res, next) => {
try {
const { rows } = await require('../db').getQuery()('SELECT id, from_email FROM email_settings ORDER BY id');
res.json({ success: true, items: rows });
} catch (error) {
next(error);
}
});
// Получить все telegram_settings для выпадающего списка
router.get('/telegram-settings', requireAdmin, async (req, res, next) => {
try {
const { rows } = await require('../db').getQuery()('SELECT id, bot_username FROM telegram_settings ORDER BY id');
res.json({ success: true, items: rows });
} catch (error) {
next(error);
}
});
module.exports = router; module.exports = router;

View File

@@ -34,30 +34,51 @@ class AIAssistant {
} }
// Основной метод для получения ответа // Основной метод для получения ответа
async getResponse(message, language = 'auto') { async getResponse(message, language = 'auto', history = null, systemPrompt = '', rules = null) {
try { try {
console.log('getResponse called with:', { message, language }); console.log('getResponse called with:', { message, language, history, systemPrompt, rules });
// Определяем язык, если не указан явно // Определяем язык, если не указан явно
const detectedLanguage = language === 'auto' ? this.detectLanguage(message) : language; const detectedLanguage = language === 'auto' ? this.detectLanguage(message) : language;
console.log('Detected language:', detectedLanguage); console.log('Detected language:', detectedLanguage);
// Сначала пробуем прямой API запрос // Формируем system prompt с учётом правил
let fullSystemPrompt = systemPrompt || '';
if (rules && typeof rules === 'object') {
fullSystemPrompt += '\n' + JSON.stringify(rules, null, 2);
}
// Формируем массив сообщений для Qwen2.5/OpenAI API
const messages = [];
if (fullSystemPrompt) {
messages.push({ role: 'system', content: fullSystemPrompt });
}
if (Array.isArray(history) && history.length > 0) {
for (const msg of history) {
if (msg.role && msg.content) {
messages.push({ role: msg.role, content: msg.content });
}
}
}
// Добавляем текущее сообщение пользователя
messages.push({ role: 'user', content: message });
// Пробуем прямой API запрос (OpenAI-совместимый endpoint)
try { try {
console.log('Trying direct API request...'); console.log('Trying direct API request...');
const response = await this.fallbackRequest(message, detectedLanguage); const response = await this.fallbackRequestOpenAI(messages, detectedLanguage);
console.log('Direct API response received:', response); console.log('Direct API response received:', response);
return response; return response;
} catch (error) { } catch (error) {
console.error('Error in direct API request:', error); console.error('Error in direct API request:', error);
} }
// Если прямой запрос не удался, пробуем через ChatOllama // Если прямой запрос не удался, пробуем через ChatOllama (склеиваем сообщения в текст)
const chat = this.createChat(detectedLanguage); const chat = this.createChat(detectedLanguage);
try { 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 response = await chat.invoke(message); const response = await chat.invoke(prompt);
console.log('ChatOllama response:', response); console.log('ChatOllama response:', response);
return response.content; return response.content;
} catch (error) { } catch (error) {
@@ -70,24 +91,17 @@ class AIAssistant {
} }
} }
// Альтернативный метод запроса через прямой API // Новый метод для OpenAI/Qwen2.5 совместимого endpoint
async fallbackRequest(message, language) { async fallbackRequestOpenAI(messages, language) {
try { try {
console.log('Using fallback request method with:', { message, language }); console.log('Using fallbackRequestOpenAI with:', { messages, language });
const model = this.defaultModel;
const systemPrompt = const response = await fetch(`${this.baseUrl}/v1/chat/completions`, {
language === 'ru'
? 'Вы - полезный ассистент. Отвечайте на русском языке.'
: 'You are a helpful assistant. Respond in English.';
console.log('Sending request to Ollama API...');
const response = await fetch(`${this.baseUrl}/api/generate`, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ body: JSON.stringify({
model: this.defaultModel, model,
prompt: message, messages,
system: systemPrompt,
stream: false, stream: false,
options: { options: {
temperature: 0.7, temperature: 0.7,
@@ -95,16 +109,17 @@ class AIAssistant {
}, },
}), }),
}); });
if (!response.ok) { if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`); throw new Error(`HTTP error! status: ${response.status}`);
} }
const data = await response.json(); const data = await response.json();
console.log('Ollama API response:', data); // Qwen2.5/OpenAI API возвращает ответ в data.choices[0].message.content
return data.response; if (data.choices && data.choices[0] && data.choices[0].message && data.choices[0].message.content) {
return data.choices[0].message.content;
}
return data.response || '';
} catch (error) { } catch (error) {
console.error('Error in fallback request:', error); console.error('Error in fallbackRequestOpenAI:', error);
throw error; throw error;
} }
} }

View File

@@ -0,0 +1,35 @@
const db = require('../db');
const TABLE = 'ai_assistant_rules';
async function getAllRules() {
const { rows } = await db.getQuery()(`SELECT * FROM ${TABLE} ORDER BY id`);
return rows;
}
async function getRuleById(id) {
const { rows } = await db.getQuery()(`SELECT * FROM ${TABLE} WHERE id = $1`, [id]);
return rows[0] || null;
}
async function createRule({ name, description, rules }) {
const { rows } = await db.getQuery()(
`INSERT INTO ${TABLE} (name, description, rules, created_at, updated_at)
VALUES ($1, $2, $3, NOW(), NOW()) RETURNING *`,
[name, description, rules]
);
return rows[0];
}
async function updateRule(id, { name, description, rules }) {
const { rows } = await db.getQuery()(
`UPDATE ${TABLE} SET name = $1, description = $2, rules = $3, updated_at = NOW() WHERE id = $4 RETURNING *`,
[name, description, rules, id]
);
return rows[0];
}
async function deleteRule(id) {
await db.getQuery()(`DELETE FROM ${TABLE} WHERE id = $1`, [id]);
}
module.exports = { getAllRules, getRuleById, createRule, updateRule, deleteRule };

View File

@@ -0,0 +1,48 @@
const db = require('../db');
const TABLE = 'ai_assistant_settings';
async function getSettings() {
const { rows } = await db.getQuery()(`SELECT * FROM ${TABLE} ORDER BY id LIMIT 1`);
const settings = rows[0] || null;
if (!settings) return null;
// Получаем связанные данные из telegram_settings и email_settings
let telegramBot = null;
let supportEmail = null;
if (settings.telegram_settings_id) {
const tg = await db.getQuery()('SELECT * FROM telegram_settings WHERE id = $1', [settings.telegram_settings_id]);
telegramBot = tg.rows[0] || null;
}
if (settings.email_settings_id) {
const em = await db.getQuery()('SELECT * FROM email_settings WHERE id = $1', [settings.email_settings_id]);
supportEmail = em.rows[0] || null;
}
return {
...settings,
telegramBot,
supportEmail
};
}
async function upsertSettings({ system_prompt, selected_rag_tables, languages, model, rules, updated_by, telegram_settings_id, email_settings_id, system_message }) {
const { rows } = await db.getQuery()(
`INSERT INTO ${TABLE} (id, system_prompt, selected_rag_tables, languages, model, rules, updated_at, updated_by, telegram_settings_id, email_settings_id, system_message)
VALUES (1, $1, $2, $3, $4, $5, NOW(), $6, $7, $8, $9)
ON CONFLICT (id) DO UPDATE SET
system_prompt = EXCLUDED.system_prompt,
selected_rag_tables = EXCLUDED.selected_rag_tables,
languages = EXCLUDED.languages,
model = EXCLUDED.model,
rules = EXCLUDED.rules,
updated_at = NOW(),
updated_by = EXCLUDED.updated_by,
telegram_settings_id = EXCLUDED.telegram_settings_id,
email_settings_id = EXCLUDED.email_settings_id,
system_message = EXCLUDED.system_message
RETURNING *`,
[system_prompt, selected_rag_tables, languages, model, rules, updated_by, telegram_settings_id, email_settings_id, system_message]
);
return rows[0];
}
module.exports = { getSettings, upsertSettings };

View File

@@ -15,6 +15,12 @@
<!-- eslint-disable-next-line vue/no-v-html --> <!-- eslint-disable-next-line vue/no-v-html -->
<div v-if="message.content" class="message-content" v-html="formattedContent" /> <div v-if="message.content" class="message-content" v-html="formattedContent" />
<!-- Кнопки для системного сообщения -->
<div v-if="message.sender_type === 'system' && (message.telegramBotUrl || message.supportEmail)" class="system-actions">
<button v-if="message.telegramBotUrl" @click="openTelegram(message.telegramBotUrl)" class="system-btn">Перейти в Telegram-бот</button>
<button v-if="message.supportEmail" @click="copyEmail(message.supportEmail)" class="system-btn">Скопировать email</button>
</div>
<!-- Блок для отображения прикрепленного файла (теперь с плеерами/изображением/ссылкой) --> <!-- Блок для отображения прикрепленного файла (теперь с плеерами/изображением/ссылкой) -->
<div v-if="attachment" class="message-attachments"> <div v-if="attachment" class="message-attachments">
<div class="attachment-item"> <div class="attachment-item">
@@ -168,6 +174,14 @@ const formatFileSize = (bytes) => {
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}; };
function openTelegram(url) {
window.open(url, '_blank');
}
function copyEmail(email) {
navigator.clipboard.writeText(email);
// Можно добавить уведомление "Email скопирован"
}
</script> </script>
<style scoped> <style scoped>
@@ -360,4 +374,23 @@ const formatFileSize = (bytes) => {
max-height: 200px; max-height: 200px;
} }
} }
.system-actions {
margin-top: 10px;
display: flex;
gap: 10px;
}
.system-btn {
background: var(--color-primary, #3b82f6);
color: #fff;
border: none;
border-radius: 6px;
padding: 6px 14px;
cursor: pointer;
font-size: 1em;
transition: background 0.2s;
}
.system-btn:hover {
background: var(--color-primary-dark, #2563eb);
}
</style> </style>

View File

@@ -0,0 +1,122 @@
<template>
<div class='modal-bg'>
<div class='modal'>
<h3>{{ rule ? 'Редактировать' : 'Создать' }} набор правил</h3>
<label>Название</label>
<input v-model="name" />
<label>Описание</label>
<textarea v-model="description" rows="3" placeholder="Опишите правило в свободной форме" />
<button type="button" @click="convertToJson" style="margin: 0.5rem 0;">Преобразовать в JSON</button>
<label>Правила (JSON)</label>
<textarea v-model="rulesJson" rows="6"></textarea>
<div v-if="error" class="error">{{ error }}</div>
<div class="actions">
<button @click="save">Сохранить</button>
<button @click="close">Отмена</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
import axios from 'axios';
const emit = defineEmits(['close']);
const props = defineProps({ rule: Object });
const name = ref(props.rule ? props.rule.name : '');
const description = ref(props.rule ? props.rule.description : '');
const rulesJson = ref(props.rule ? JSON.stringify(props.rule.rules, null, 2) : '{\n "checkUserTags": true\n}');
const error = ref('');
watch(() => props.rule, (newRule) => {
name.value = newRule ? newRule.name : '';
description.value = newRule ? newRule.description : '';
rulesJson.value = newRule ? JSON.stringify(newRule.rules, null, 2) : '{\n "checkUserTags": true\n}';
});
function convertToJson() {
// Простейший пример: если в описании есть "теги", выставляем checkUserTags
// В реальном проекте здесь можно интегрировать LLM или шаблоны
try {
if (/тег[а-я]* пользов/.test(description.value.toLowerCase())) {
rulesJson.value = JSON.stringify({ checkUserTags: true }, null, 2);
error.value = '';
} else {
rulesJson.value = JSON.stringify({ customRule: description.value }, null, 2);
error.value = '';
}
} catch (e) {
error.value = 'Не удалось преобразовать описание в JSON';
}
}
async function save() {
let rules;
try {
rules = JSON.parse(rulesJson.value);
} catch (e) {
error.value = 'Ошибка в формате JSON!';
return;
}
if (props.rule && props.rule.id) {
await axios.put(`/api/settings/ai-assistant-rules/${props.rule.id}`, { name: name.value, description: description.value, rules });
} else {
await axios.post('/api/settings/ai-assistant-rules', { name: name.value, description: description.value, rules });
}
emit('close', true);
}
function close() { emit('close', false); }
</script>
<style scoped>
.modal-bg {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.25);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal {
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 16px rgba(0,0,0,0.12);
padding: 2rem;
min-width: 320px;
max-width: 420px;
}
label {
display: block;
margin-top: 1rem;
font-weight: 500;
}
input, textarea {
width: 100%;
margin-top: 0.5rem;
padding: 0.5rem;
border-radius: 6px;
border: 1px solid #ddd;
font-size: 1rem;
}
.actions {
display: flex;
gap: 1rem;
margin-top: 2rem;
}
button {
background: var(--color-primary);
color: #fff;
border: none;
border-radius: 6px;
padding: 0.5rem 1.5rem;
cursor: pointer;
font-size: 1rem;
}
button:last-child {
background: #eee;
color: #333;
}
.error {
color: #c00;
margin-top: 0.5rem;
}
</style>

View File

@@ -3,6 +3,15 @@ import api from '../api/axios';
import { getFromStorage, setToStorage, removeFromStorage } from '../utils/storage'; import { getFromStorage, setToStorage, removeFromStorage } from '../utils/storage';
import { generateUniqueId } from '../utils/helpers'; import { generateUniqueId } from '../utils/helpers';
function initGuestId() {
let id = getFromStorage('guestId', '');
if (!id) {
id = generateUniqueId();
setToStorage('guestId', id);
}
return id;
}
export function useChat(auth) { export function useChat(auth) {
const messages = ref([]); const messages = ref([]);
const newMessage = ref(''); const newMessage = ref('');
@@ -20,7 +29,7 @@ export function useChat(auth) {
isLinkingGuest: false, // Флаг для процесса связывания гостевых сообщений (пока не используется активно) isLinkingGuest: false, // Флаг для процесса связывания гостевых сообщений (пока не используется активно)
}); });
const guestId = ref(getFromStorage('guestId', '')); const guestId = ref(initGuestId());
const shouldLoadHistory = computed(() => { const shouldLoadHistory = computed(() => {
return auth.isAuthenticated.value || !!guestId.value; return auth.isAuthenticated.value || !!guestId.value;
@@ -133,7 +142,7 @@ export function useChat(auth) {
// Очищаем гостевые данные после успешной аутентификации и загрузки // Очищаем гостевые данные после успешной аутентификации и загрузки
if (authType) { if (authType) {
removeFromStorage('guestMessages'); removeFromStorage('guestMessages');
removeFromStorage('guestId'); // removeFromStorage('guestId'); // Удаление guestId теперь только после успешного связывания
guestId.value = ''; guestId.value = '';
} }
@@ -219,7 +228,7 @@ export function useChat(auth) {
let apiUrl = '/api/chat/message'; let apiUrl = '/api/chat/message';
if (isGuestMessage) { if (isGuestMessage) {
if (!guestId.value) { if (!guestId.value) {
guestId.value = generateUniqueId(); guestId.value = initGuestId();
setToStorage('guestId', guestId.value); setToStorage('guestId', guestId.value);
} }
formData.append('guestId', guestId.value); formData.append('guestId', guestId.value);
@@ -254,6 +263,20 @@ export function useChat(auth) {
}); });
} }
// Добавляем системное сообщение для гостя (только на клиенте, не сохраняется в истории)
if (isGuestMessage && response.data.systemMessage) {
messages.value.push({
id: `system-${Date.now()}`,
content: response.data.systemMessage,
sender_type: 'system',
role: 'system',
timestamp: new Date().toISOString(),
isSystem: true,
telegramBotUrl: response.data.telegramBotUrl,
supportEmail: response.data.supportEmail
});
}
// Сохраняем гостевое сообщение (если нужно) // Сохраняем гостевое сообщение (если нужно)
// В текущей реализации HomeView гостевые сообщения из localstorage загружаются только при старте // В текущей реализации HomeView гостевые сообщения из localstorage загружаются только при старте
// Если нужна синхронизация после отправки, логику нужно добавить/изменить // Если нужна синхронизация после отправки, логику нужно добавить/изменить
@@ -325,6 +348,23 @@ export function useChat(auth) {
} }
}; };
// --- Связывание гостевых сообщений после аутентификации ---
const linkGuestMessagesAfterAuth = async () => {
if (!guestId.value) return;
try {
const response = await api.post('/api/chat/process-guest', { guestId: guestId.value });
if (response.data.success && response.data.conversationId) {
// Можно сразу загрузить историю по этому диалогу, если нужно
await loadMessages({ initial: true });
// Удаляем guestId только после успешного связывания
removeFromStorage('guestId');
guestId.value = '';
}
} catch (error) {
console.error('[useChat] Ошибка связывания гостевых сообщений:', error);
}
};
// --- Watchers --- // --- Watchers ---
// Сортировка сообщений при изменении // Сортировка сообщений при изменении
watch(messages, (newMessages) => { watch(messages, (newMessages) => {
@@ -379,5 +419,6 @@ export function useChat(auth) {
loadMessages, loadMessages,
handleSendMessage, handleSendMessage,
loadGuestMessagesFromStorage, // Экспортируем на всякий случай loadGuestMessagesFromStorage, // Экспортируем на всякий случай
linkGuestMessagesAfterAuth, // Экспортируем для вызова после авторизации
}; };
} }

View File

@@ -64,6 +64,7 @@
messageLoading, messageLoading,
loadMessages, loadMessages,
handleSendMessage, handleSendMessage,
linkGuestMessagesAfterAuth,
} = useChat(auth); } = useChat(auth);
// ===================================================================== // =====================================================================
@@ -91,10 +92,12 @@
// ===================================================================== // =====================================================================
// Функция обновления сообщений после авторизации // Функция обновления сообщений после авторизации
const handleAuthEvent = (eventData) => { const handleAuthEvent = async (eventData) => {
console.log('[HomeView] Получено событие изменения авторизации:', eventData); console.log('[HomeView] Получено событие изменения авторизации:', eventData);
if (eventData.isAuthenticated) { if (eventData.isAuthenticated) {
// Пользователь только что авторизовался - загрузим сообщения // Сначала связываем гостевые сообщения, если есть
await linkGuestMessagesAfterAuth();
// Затем загружаем сообщения (если не было гостя, просто загрузка)
loadMessages({ initial: true, authType: eventData.authType || 'wallet' }); loadMessages({ initial: true, authType: eventData.authType || 'wallet' });
} else { } else {
// Пользователь вышел из системы - можно очистить или обновить данные // Пользователь вышел из системы - можно очистить или обновить данные

View File

@@ -0,0 +1,211 @@
<template>
<div class="ai-assistant-settings-modal">
<h2>Настройки ИИ-ассистента</h2>
<form @submit.prevent="saveSettings">
<label>Системный промт</label>
<textarea v-model="settings.system_prompt" rows="3" />
<label>Языки</label>
<input v-model="languagesInput" placeholder="ru, en, es" />
<label>Модель</label>
<input v-model="settings.model" placeholder="qwen2.5" />
<label>Выбранные RAG-таблицы</label>
<select v-model="settings.selected_rag_tables" multiple>
<option v-for="table in userTables" :key="table.id" :value="table.id">
{{ table.name }}
</option>
</select>
<label>Набор правил</label>
<div class="rules-row">
<select v-model="settings.rules_id">
<option v-for="rule in rulesList" :key="rule.id" :value="rule.id">
{{ rule.name }}
</option>
</select>
<button type="button" @click="openRuleEditor()">Создать</button>
<button type="button" :disabled="!settings.rules_id" @click="openRuleEditor(settings.rules_id)">Редактировать</button>
<button type="button" :disabled="!settings.rules_id" @click="deleteRule(settings.rules_id)">Удалить</button>
</div>
<div v-if="selectedRule">
<p><b>Описание:</b> {{ selectedRule.description }}</p>
<pre class="rules-json">{{ JSON.stringify(selectedRule.rules, null, 2) }}</pre>
</div>
<label>Telegram-бот</label>
<select v-model="settings.telegram_settings_id">
<option v-for="tg in telegramBots" :key="tg.id" :value="tg.id">
{{ tg.bot_username }}
</option>
</select>
<label>Email для связи</label>
<select v-model="settings.email_settings_id">
<option v-for="em in emailList" :key="em.id" :value="em.id">
{{ em.from_email }}
</option>
</select>
<div class="actions">
<button type="submit">Сохранить</button>
<button type="button" @click="emit('cancel')">Отмена</button>
</div>
</form>
<RuleEditor v-if="showRuleEditor" :rule="editingRule" @close="onRuleEditorClose" />
</div>
</template>
<script setup>
import { ref, onMounted, computed } from 'vue';
import axios from 'axios';
import RuleEditor from '../../components/ai-assistant/RuleEditor.vue';
const emit = defineEmits(['cancel']);
const settings = ref({ system_prompt: '', model: '', selected_rag_tables: [], languages: [], rules_id: null });
const languagesInput = ref('');
const userTables = ref([]);
const rulesList = ref([]);
const showRuleEditor = ref(false);
const editingRule = ref(null);
const telegramBots = ref([]);
const emailList = ref([]);
const selectedRule = computed(() => rulesList.value.find(r => r.id === settings.value.rules_id) || null);
async function loadUserTables() {
const { data } = await axios.get('/api/tables');
userTables.value = Array.isArray(data) ? data : [];
}
async function loadRules() {
const { data } = await axios.get('/api/settings/ai-assistant-rules');
rulesList.value = data.rules || [];
}
async function loadSettings() {
const { data } = await axios.get('/api/settings/ai-assistant');
if (data.success && data.settings) {
settings.value = data.settings;
languagesInput.value = (data.settings.languages || []).join(', ');
}
}
async function loadTelegramBots() {
const { data } = await axios.get('/api/settings/telegram-settings');
telegramBots.value = data.items || [];
}
async function loadEmailList() {
const { data } = await axios.get('/api/settings/email-settings');
emailList.value = data.items || [];
}
onMounted(() => {
loadSettings();
loadUserTables();
loadRules();
loadTelegramBots();
loadEmailList();
});
async function saveSettings() {
settings.value.languages = languagesInput.value.split(',').map(s => s.trim()).filter(Boolean);
await axios.put('/api/settings/ai-assistant', settings.value);
emit('cancel');
}
function openRuleEditor(ruleId = null) {
if (ruleId) {
editingRule.value = rulesList.value.find(r => r.id === ruleId) || null;
} else {
editingRule.value = null;
}
showRuleEditor.value = true;
}
async function deleteRule(ruleId) {
if (!confirm('Удалить этот набор правил?')) return;
await axios.delete(`/api/settings/ai-assistant-rules/${ruleId}`);
await loadRules();
if (settings.value.rules_id === ruleId) settings.value.rules_id = null;
}
async function onRuleEditorClose(updated) {
showRuleEditor.value = false;
editingRule.value = null;
if (updated) await loadRules();
}
</script>
<style scoped>
.ai-assistant-settings-modal {
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
padding: 2rem;
max-width: 540px;
margin: 2rem auto;
}
label {
display: block;
margin-top: 1rem;
font-weight: 500;
}
textarea, input, select {
width: 100%;
margin-top: 0.5rem;
padding: 0.5rem;
border-radius: 6px;
border: 1px solid #ddd;
font-size: 1rem;
}
select[multiple] {
min-height: 80px;
}
.rules-row {
display: flex;
gap: 0.5rem;
align-items: center;
margin-bottom: 0.5rem;
}
.rules-json {
background: #f7f7f7;
border-radius: 6px;
padding: 0.5rem;
font-size: 0.95em;
margin-top: 0.5rem;
white-space: pre-wrap;
}
.actions {
display: flex;
gap: 1rem;
margin-top: 2rem;
}
button[type="submit"], .actions button {
background: var(--color-primary);
color: #fff;
border: none;
border-radius: 6px;
padding: 0.5rem 1.5rem;
cursor: pointer;
font-size: 1rem;
}
button[type="button"] {
background: #eee;
color: #333;
border: none;
border-radius: 6px;
padding: 0.5rem 1.5rem;
cursor: pointer;
font-size: 1rem;
}
.modal-bg {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,0.25);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal {
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 16px rgba(0,0,0,0.12);
padding: 2rem;
min-width: 320px;
max-width: 420px;
}
.error {
color: #c00;
margin-top: 0.5rem;
}
</style>

View File

@@ -37,6 +37,11 @@
<p>Интеграция с PostgreSQL для хранения данных приложения и управления настройками.</p> <p>Интеграция с PostgreSQL для хранения данных приложения и управления настройками.</p>
<button class="details-btn" @click="showDbSettings = true">Подробнее</button> <button class="details-btn" @click="showDbSettings = true">Подробнее</button>
</div> </div>
<div class="integration-block">
<h3>ИИ-ассистент</h3>
<p>Настройки поведения, языков, моделей и правил работы ассистента.</p>
<button class="details-btn" @click="showAiAssistantSettings = true">Подробнее</button>
</div>
</div> </div>
<AIProviderSettings <AIProviderSettings
v-if="showProvider" v-if="showProvider"
@@ -52,6 +57,7 @@
<TelegramSettingsView v-if="showTelegramSettings" @cancel="showTelegramSettings = false" /> <TelegramSettingsView v-if="showTelegramSettings" @cancel="showTelegramSettings = false" />
<EmailSettingsView v-if="showEmailSettings" @cancel="showEmailSettings = false" /> <EmailSettingsView v-if="showEmailSettings" @cancel="showEmailSettings = false" />
<DatabaseSettingsView v-if="showDbSettings" @cancel="showDbSettings = false" /> <DatabaseSettingsView v-if="showDbSettings" @cancel="showDbSettings = false" />
<AiAssistantSettings v-if="showAiAssistantSettings" @cancel="showAiAssistantSettings = false" />
</div> </div>
</template> </template>
@@ -61,10 +67,13 @@ import AIProviderSettings from './AIProviderSettings.vue';
import TelegramSettingsView from './TelegramSettingsView.vue'; import TelegramSettingsView from './TelegramSettingsView.vue';
import EmailSettingsView from './EmailSettingsView.vue'; import EmailSettingsView from './EmailSettingsView.vue';
import DatabaseSettingsView from './DatabaseSettingsView.vue'; import DatabaseSettingsView from './DatabaseSettingsView.vue';
import AiAssistantSettings from './AiAssistantSettings.vue';
const showProvider = ref(null); const showProvider = ref(null);
const showTelegramSettings = ref(false); const showTelegramSettings = ref(false);
const showEmailSettings = ref(false); const showEmailSettings = ref(false);
const showDbSettings = ref(false); const showDbSettings = ref(false);
const showAiAssistantSettings = ref(false);
const providerLabels = { const providerLabels = {
openai: { openai: {