# Улучшения системы обработки банковских транзакций ## 1. Упрощение логики бесконечного редактирования ### 1.1 Текущая проблема - Используется таблица `user_sessions` для хранения состояния редактирования - Множественные SELECT/UPDATE запросы при каждом действии пользователя - Сложная логика ветвления в n8n для управления сессиями ### 1.2 Решение: Stateful callback_data с editMessage **Принцип работы:** Храним все состояние редактирования прямо в callback_data кнопок Telegram #### Формат callback_data ```text edit_card_{transactionId}_{counterparty}_{category} set_category_{transactionId}_{counterparty}_{newCategory} edit_field_{transactionId}_{counterparty}_{category}_{field} confirm_{transactionId}_{counterparty}_{category} ``` #### Примеры ```text edit_card_123_Пятёрочка_Продукты set_category_123_Пятёрочка_Авто edit_field_123_Пятёрочка_Продукты_category confirm_123_Пятёрочка_Продукты ``` #### Узлы n8n для удаления 1. ❌ `user_sessions` таблица 2. ❌ `get_session` (SELECT) 3. ❌ `add_session_category` (INSERT) 4. ❌ `add_session_counterparty` (INSERT) 5. ❌ `merge_user_and_session` 6. ❌ `parse_text_input` (частично) 7. ❌ `merge_changes` #### Новые узлы 1. ✅ `create_edit_card` — генерирует карточку редактирования с inline-клавиатурой 2. ✅ `update_card_on_action` — обрабатывает callback и обновляет сообщение через editMessage ### 1.3 Преимущества - **Уменьшение нагрузки на БД на 80%** — убираем 5-7 запросов на одно действие - **Упрощение workflow** — вместо ветвления по сессиям — линейная обработка - **Мгновенная обратная связь** — editMessage вместо новых сообщений - **Stateless архитектура** — нет зависимостей между запросами ## 2. Улучшение UX для выбора категорий ### 2.1 Текущая проблема - Текстовый ввод категорий требует запоминания всех 20 вариантов - Ошибки при ручном вводе (опечатки, синонимы) - Медленный процесс категоризации ### 2.2 Решение: Многоуровневая inline-клавиатура #### Первый уровень — "умные" популярные категории ```javascript // Алгоритм выбора популярных категорий: // 1. Берем топ-3 категории пользователя из истории (если есть) // 2. Добавляем глобально популярные категории // 3. Всего 4 кнопки const getUserTopCategories = async (chatId) => { // Запрос к БД за последние 30 дней const topCats = await db.query(` SELECT category, COUNT(*) as count FROM transactions WHERE chat_id = $1 AND category IS NOT NULL AND received_at > NOW() - INTERVAL '30 days' GROUP BY category ORDER BY count DESC LIMIT 3 `, [chatId]); return topCats.map(row => row.category); }; const getDefaultCategories = () => ["Продукты", "Авто", "Дом"]; ``` #### Второй уровень — все категории компактно ```javascript // Без эмодзи для экономии места const ALL_CATEGORIES = [ ["Продукты", "Авто", "Здоровье", "Арчи"], ["ЖКХ", "Дом", "Проезд", "Одежда"], ["Химия", "Косметика", "Инвестиции", "Развлечения"], ["Общепит", "Штрафы", "Налоги", "Подписки"], ["Перевод", "Наличные", "Подарки", "Спорт"], ["Другое"] ]; // Каждая кнопка: callback_data = "set_category_{id}_{counterparty}_{category}" ``` #### Узлы n8n для изменения 1. 🔄 `category_edit` → `send_category_keyboard` (отправляет 4 кнопки) 2. ✅ `show_all_categories` → новый узел для отправки полного списка 3. ❌ Текстовый ввод категорий удаляется полностью #### Кэширование популярных категорий ```javascript // В Redis или памяти n8n (Global Variables) // Ключ: user_top_cats_{chatId} // TTL: 1 час // Данные: ["Продукты", "Общепит", "Авто"] // При запросе: // 1. Проверяем кэш // 2. Если нет → запрос к БД → сохранение в кэш // 3. Возвращаем данные ``` ### 2.3 Преимущества - **В 3-5 раз быстрее** выбор категории - **Нет ошибок ввода** — только валидные категории - **Персонализация** — показываем часто используемые категории - **Экономия места** — без эмодзи больше категорий на экране ## 3. Техническая реализация ### Изменения в БД ```sql -- Удаляем таблицу user_sessions DROP TABLE IF EXISTS user_sessions; -- Добавляем кэш популярных категорий (опционально) CREATE TABLE IF NOT EXISTS user_category_stats ( chat_id BIGINT, category VARCHAR(100), count INTEGER DEFAULT 1, last_used TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (chat_id, category) ); -- Индекс для быстрого получения топ категорий CREATE INDEX idx_user_cats ON user_category_stats(chat_id, count DESC); ``` ### Изменения в workflow n8n #### Ветка редактирования (новая) ```text edit_field (callback) → IF field = 'category' → get_top_categories (Code + возможно DB) → send_category_keyboard (Telegram Message) IF field = 'counterparty' → request_counterparty_input (Telegram Message) → (текстовый ответ) → update_card_with_new_counterparty (editMessage) ``` #### Ветка выбора категории ```text set_category (callback) → update_category_stats (DB) → -- инкрементируем счетчик update_card (editMessage) → -- обновляем карточку (возврат в режим редактирования) ``` #### Ветка "все категории" ```text show_all_cats (callback) → send_all_categories (Telegram Message) → -- компактная клавиатура 5x4 (пользователь выбирает) → set_category (существующая ветка) ``` ### Лимиты и ограничения 1. **Callback_data length** ≤ 64 байт ```javascript // Решение: кодирование/декодирование длинных строк const encodeData = (str) => encodeURIComponent(str.substring(0, 20)); const decodeData = (str) => decodeURIComponent(str); ``` 2. **Inline keyboard rows** ≤ 8-10 для удобства 3. **Кэш TTL** = 1 час для актуальности ## 4. Ожидаемые результаты ### Метрики улучшений | Показатель | Было | Стало | Улучшение | | ------------ | ------ | ------- | ----------- | | Запросов к БД на действие | 5-7 | 1-2 | ~70% ↓ | | Время категоризации | 10-30 сек | 2-5 сек | 5x ↑ | | Ошибок категоризации | 15-20% | <2% | 10x ↓ | | Пользовательских кликов | 3-5 | 1-2 | 2x ↓ | ### Безопасность 1. Все данные в callback_data URL-encoded 2. Валидация transactionId при каждом запросе 3. Проверка прав доступа к чату ### Резервное решение Если callback_data превышает лимит Telegram: ```javascript // Fallback: короткий хэш + временное хранилище const hash = md5(transactionId + counterparty + category).substring(0, 8); cache.set(`card_${hash}`, {transactionId, counterparty, category}, 300); // 5 мин callback_data = `short_${hash}`; ``` ## 5. План внедрения ### Фаза 1: Подготовка (1-2 дня) 1. Создать новую таблицу `user_category_stats` 2. Написать миграцию данных из истории транзакций 3. Обновить узлы обработки callback_data ### Фаза 2: Внедрение (1 день) 1. Добавить новые узлы n8n параллельно существующим 2. Протестировать на отдельном Telegram-боте 3. Проверить лимиты callback_data ### Фаза 3: Переключение (1 день) 1. Направить 10% трафика на новую систему 2. Сравнить метрики 3. Полное переключение при успехе ### Фаза 4: Оптимизация (непрерывно) 1. Мониторинг нагрузки БД 2. Настройка кэширования 3. A/B тестирование разных наборов популярных категорий ## Заключение Предложенные изменения устраняют основные боли пользователей: - **Упрощают редактирование** через мгновенное обновление карточек - **Ускоряют категоризацию** через умные inline-клавиатуры - **Уменьшают нагрузку** на инфраструктуру через stateless дизайн Общее количество узлов n8n сократится с 36 до ~25 при улучшении UX и производительности.