Files
test/improvement.md
2026-01-16 18:37:32 +03:00

266 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Улучшения системы обработки банковских транзакций
## 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 и производительности.