Files
aiform_dev/docs/REDIS_CLAIM_STORAGE_ANALYSIS.md
AI Assistant d6b17baa7d feat: Add PostgreSQL fields and workflow for form without files
Database changes:
- Add unified_id, contact_id, phone columns to clpr_claims table
- Create indexes for fast lookup by these fields
- Migrate existing data from payload to new columns
- SQL migration: docs/SQL_ALTER_CLPR_CLAIMS_ADD_FIELDS.sql

SQL improvements:
- Simplify claimsave query: remove complex claim_lookup logic
- Use UPSERT (INSERT ON CONFLICT) with known claim_id
- Always return claim (fix NULL issue)
- Store unified_id, contact_id, phone directly in table columns
- SQL: docs/SQL_CLAIMSAVE_UPSERT_SIMPLE.sql

Workflow enhancements:
- Add branch for form submissions WITHOUT files
- Create 6 new nodes: extract, prepare, save, redis, respond
- Separate flow for has_files=false in IF node
- Instructions: docs/N8N_FORM_GET_NO_FILES_INSTRUCTIONS.md
- Node config: docs/N8N_FORM_GET_NO_FILES_BRANCH.json

Migration stats:
- Total claims: 81
- With unified_id: 77
- Migrated from payload: 2

Next steps:
1. Add 6 nodes to n8n workflow form_get (ID: 8ZVMTsuH7Cmw7snw)
2. Connect TRUE branch of IF node to extract_webhook_data_no_files
3. Test form submission without files
4. Verify PostgreSQL save and Redis event
2025-11-21 15:57:18 +03:00

193 lines
7.0 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.

# Анализ: Нужно ли хранить данные заявки в Redis?
## Текущая ситуация
### Что сейчас в Redis:
**Ключ:** `claim:CLM-2025-11-18-GEQ3KL`
**Значение:**
```json
{
"claim_id": "CLM-2025-11-18-GEQ3KL",
"contact_id": "398523",
"phone": "72352352352",
"is_new_contact": true,
"status": "draft",
"current_step": 2,
"created_at": "2025-11-18T20:43:47.033Z",
"updated_at": "2025-11-18T20:44:59.217Z",
"voucher": null,
"event_type": null,
"documents": {},
"email": null,
"bank_name": null,
"project_id": "398524",
"is_new_project": true
}
```
**TTL:** ~6.5 дней (563566 секунд)
---
## Для чего использовался Redis (Telegram бот)
### Исторически:
1. **Быстрый доступ к сессии** - Telegram бот не имеет постоянного состояния
2. **Хранение промежуточных данных** - пока пользователь заполняет форму
3. **TTL 7 дней** - автоматическая очистка старых сессий
4. **Легковесное хранилище** - не нужна полная БД для временных данных
### Проблемы:
- ❌ Дублирование данных (есть в PostgreSQL)
- ❌ Нужно синхронизировать Redis и PostgreSQL
- ❌ Риск рассинхронизации данных
- ❌ Дополнительная сложность
---
## Текущая архитектура (веб-форма)
### PostgreSQL (основное хранилище):
-`clpr_claims` - полные данные заявки в `payload` (JSONB)
-`clpr_claim_documents` - документы
- ✅ Постоянное хранилище
- ✅ Транзакции и целостность данных
- ✅ История изменений (updated_at)
### Redis (только Pub/Sub):
-`ocr_events:{claim_id}` - события обработки файлов (SSE)
- ✅ Временные события, не хранятся постоянно
---
## Нужно ли хранить в Redis для веб-формы?
### ❌ НЕТ, не нужно!
**Причины:**
1. **Данные уже в PostgreSQL**
- Все данные заявки хранятся в `clpr_claims.payload`
- Полная информация доступна из БД
- Нет необходимости дублировать
2. **Веб-форма != Telegram бот**
- Telegram бот: нет постоянного состояния, нужен быстрый доступ к сессии
- Веб-форма: состояние хранится в React (useState), данные в PostgreSQL
- Не нужен промежуточный кеш
3. **Риск рассинхронизации**
- Если данные в Redis и PostgreSQL расходятся - проблемы
- Сложнее поддерживать консистентность
- Дополнительная точка отказа
4. **Усложнение архитектуры**
- Нужно обновлять и Redis, и PostgreSQL
- Больше кода для поддержки
- Больше мест, где может что-то сломаться
---
## Что делать с существующими данными в Redis?
### Вариант 1: Оставить как есть (для совместимости)
-Не ломает существующий Telegram бот
- ✅ Можно использовать для быстрого доступа к базовым данным
- ❌ Дублирование данных
- ❌ Нужно синхронизировать
### Вариант 2: Убрать для веб-формы, оставить для Telegram
- ✅ Чистая архитектура для веб-формы
- ✅ Telegram бот продолжает работать
- ✅ Нет дублирования для веб-формы
- ⚠️ Нужно различать источник (channel: 'web_form' vs 'telegram')
### Вариант 3: Полностью убрать (миграция на PostgreSQL)
- ✅ Единый источник истины (PostgreSQL)
- ✅ Проще архитектура
- ❌ Нужно мигрировать Telegram бот
- ❌ Может сломать существующую логику
---
## Рекомендация
### Для веб-формы (`channel: 'web_form'`):
**НЕ сохранять в Redis**, потому что:
1. ✅ Данные уже в PostgreSQL (`clpr_claims`)
2. ✅ Состояние формы в React (`useState`)
3. ✅ Нет необходимости в промежуточном кеше
4. ✅ Меньше сложности, меньше багов
### Для Telegram бота (`channel: 'telegram'`):
**Оставить Redis** (если используется), потому что:
1. ✅ Telegram бот может нуждаться в быстром доступе к сессии
2. ✅ Нет постоянного состояния в боте
3. ✅ TTL автоматически очищает старые сессии
---
## Итог
**Для веб-формы (`ticket_form`):**
-**НЕ нужно** сохранять в Redis `claim:CLM-...`
-Все данные в PostgreSQL (`clpr_claims`)
- ✅ Redis используется только для Pub/Sub (`ocr_events:{claim_id}`)
**Для Telegram бота:**
- ✅ Можно оставить Redis для совместимости
- ⚠️ Но лучше тоже мигрировать на PostgreSQL для единообразия
---
## Что делать в n8n workflow?
### В ноде `claimsave` и `claimsave_final`:
**НЕ добавлять сохранение в Redis**, если:
- `channel = 'web_form'` (веб-форма)
- Данные уже сохранены в PostgreSQL
**Можно добавить сохранение в Redis**, если:
- `channel = 'telegram'` (Telegram бот)
- Нужна обратная совместимость
### Пример проверки в n8n:
```javascript
// После SQL запроса (claimsave)
const channel = $json.channel || 'web_form';
if (channel === 'telegram') {
// Сохраняем в Redis для Telegram бота
return {
redis_key: `claim:${$json.claim_id}`,
redis_value: JSON.stringify({
claim_id: $json.claim_id,
contact_id: $json.contact_id,
// ... остальные поля
}),
ttl: 604800 // 7 дней
};
} else {
// Для веб-формы - не сохраняем в Redis
return $json;
}
```
---
## Вывод
**Для веб-формы НЕ нужно сохранять в Redis `claim:CLM-...`**
Все данные уже в PostgreSQL, и этого достаточно. Redis используется только для Pub/Sub событий (`ocr_events:{claim_id}`).