Problem:
- After wizard form submission, need to wait for claim data from n8n
- Claim data comes via Redis channel claim:plan:{session_token}
- Need to display confirmation form with claim data
Solution:
1. Backend: Added SSE endpoint /api/v1/claim-plan/{session_token}
- Subscribes to Redis channel claim:plan:{session_token}
- Streams claim data from n8n to frontend
- Handles timeouts and errors gracefully
2. Frontend: Added subscription to claim:plan channel
- StepWizardPlan: After form submission, subscribes to SSE
- Waits for claim_plan_ready event
- Shows loading message while waiting
- On success: saves claimPlanData and shows confirmation step
3. New component: StepClaimConfirmation
- Displays claim confirmation form in iframe
- Receives claimPlanData from parent
- Generates HTML form (placeholder - should call n8n for real HTML)
- Handles confirmation/cancellation via postMessage
4. ClaimForm: Added conditional step for confirmation
- Shows StepClaimConfirmation when showClaimConfirmation=true
- Step appears after StepWizardPlan
- Only visible when claimPlanData is available
Flow:
1. User fills wizard form → submits
2. Form data sent to n8n via /api/v1/claims/wizard
3. Frontend subscribes to SSE /api/v1/claim-plan/{session_token}
4. n8n processes data → publishes to Redis claim:plan:{session_token}
5. Backend receives → streams to frontend via SSE
6. Frontend receives → shows StepClaimConfirmation
7. User confirms → proceeds to next step
Files:
- backend/app/api/events.py: Added stream_claim_plan endpoint
- frontend/src/components/form/StepWizardPlan.tsx: Added subscribeToClaimPlan
- frontend/src/components/form/StepClaimConfirmation.tsx: New component
- frontend/src/pages/ClaimForm.tsx: Added confirmation step to steps array
7.0 KiB
7.0 KiB
Анализ: Нужно ли хранить данные заявки в Redis?
Текущая ситуация
Что сейчас в Redis:
Ключ: claim:CLM-2025-11-18-GEQ3KL
Значение:
{
"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 бот)
Исторически:
- Быстрый доступ к сессии - Telegram бот не имеет постоянного состояния
- Хранение промежуточных данных - пока пользователь заполняет форму
- TTL 7 дней - автоматическая очистка старых сессий
- Легковесное хранилище - не нужна полная БД для временных данных
Проблемы:
- ❌ Дублирование данных (есть в PostgreSQL)
- ❌ Нужно синхронизировать Redis и PostgreSQL
- ❌ Риск рассинхронизации данных
- ❌ Дополнительная сложность
Текущая архитектура (веб-форма)
PostgreSQL (основное хранилище):
- ✅
clpr_claims- полные данные заявки вpayload(JSONB) - ✅
clpr_claim_documents- документы - ✅ Постоянное хранилище
- ✅ Транзакции и целостность данных
- ✅ История изменений (updated_at)
Redis (только Pub/Sub):
- ✅
ocr_events:{claim_id}- события обработки файлов (SSE) - ✅ Временные события, не хранятся постоянно
Нужно ли хранить в Redis для веб-формы?
❌ НЕТ, не нужно!
Причины:
-
Данные уже в PostgreSQL
- Все данные заявки хранятся в
clpr_claims.payload - Полная информация доступна из БД
- Нет необходимости дублировать
- Все данные заявки хранятся в
-
Веб-форма != Telegram бот
- Telegram бот: нет постоянного состояния, нужен быстрый доступ к сессии
- Веб-форма: состояние хранится в React (useState), данные в PostgreSQL
- Не нужен промежуточный кеш
-
Риск рассинхронизации
- Если данные в Redis и PostgreSQL расходятся - проблемы
- Сложнее поддерживать консистентность
- Дополнительная точка отказа
-
Усложнение архитектуры
- Нужно обновлять и Redis, и PostgreSQL
- Больше кода для поддержки
- Больше мест, где может что-то сломаться
Что делать с существующими данными в Redis?
Вариант 1: Оставить как есть (для совместимости)
- ✅ Не ломает существующий Telegram бот
- ✅ Можно использовать для быстрого доступа к базовым данным
- ❌ Дублирование данных
- ❌ Нужно синхронизировать
Вариант 2: Убрать для веб-формы, оставить для Telegram
- ✅ Чистая архитектура для веб-формы
- ✅ Telegram бот продолжает работать
- ✅ Нет дублирования для веб-формы
- ⚠️ Нужно различать источник (channel: 'web_form' vs 'telegram')
Вариант 3: Полностью убрать (миграция на PostgreSQL)
- ✅ Единый источник истины (PostgreSQL)
- ✅ Проще архитектура
- ❌ Нужно мигрировать Telegram бот
- ❌ Может сломать существующую логику
Рекомендация
Для веб-формы (channel: 'web_form'):
НЕ сохранять в Redis, потому что:
- ✅ Данные уже в PostgreSQL (
clpr_claims) - ✅ Состояние формы в React (
useState) - ✅ Нет необходимости в промежуточном кеше
- ✅ Меньше сложности, меньше багов
Для Telegram бота (channel: 'telegram'):
Оставить Redis (если используется), потому что:
- ✅ Telegram бот может нуждаться в быстром доступе к сессии
- ✅ Нет постоянного состояния в боте
- ✅ 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:
// После 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}).