Files
aiform_dev/docs/REDIS_CLAIM_STORAGE_ANALYSIS.md
AI Assistant 0978e485dc feat: Add claim plan confirmation flow via Redis SSE
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
2025-11-24 13:36:14 +03:00

7.0 KiB
Raw Permalink Blame History

Анализ: Нужно ли хранить данные заявки в 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 бот)

Исторически:

  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:

// После 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}).