Files
aiform_dev/docs/REDIS_VS_POSTGRESQL_SPEED.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

201 lines
7.1 KiB
Markdown
Raw Permalink 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 vs PostgreSQL: Когда что использовать?
## Скорость доступа
### Redis:
-**0.1-1 мс** (данные в памяти)
- Мгновенный доступ
- Идеально для частых чтений
### PostgreSQL:
- 🐢 **1-10 мс** (с индексами)
- Зависит от нагрузки и индексов
- Но всё равно очень быстро
---
## Когда Redis имеет смысл
### ✅ Используй Redis, если:
1. **Очень частые чтения** (каждый запрос, каждый клик)
- Например: счетчики, rate limiting, сессии
2. **Временные данные** (TTL, автоочистка)
- Например: SMS коды, временные токены
3. **Кеширование результатов запросов**
- Например: результаты AI классификации, шаблоны визардов
4. **Pub/Sub события** (реал-тайм)
- Например: `ocr_events:{claim_id}` для SSE
---
## Когда PostgreSQL достаточно
### ✅ Используй только PostgreSQL, если:
1. **Данные читаются не так часто**
- Загрузка страницы, переход между шагами
- Пользователь не заметит разницу 1-10 мс
2. **Важна консистентность**
- Нужна гарантия актуальности данных
- Нет риска рассинхронизации
3. **Данные уже в PostgreSQL**
- Не нужно дублировать
- Проще архитектура
---
## Для веб-формы: Анализ использования
### Когда читаются данные заявки:
1. **При загрузке страницы** (1 раз)
- Пользователь открывает форму
- Можно загрузить из PostgreSQL (10 мс) - не критично
2. **При переходах между шагами** (редко)
- Пользователь нажимает "Далее"
- Можно загрузить из PostgreSQL (10 мс) - не критично
3. **При обновлении данных** (редко)
- Пользователь заполняет форму
- Сохраняется в PostgreSQL
### Вывод:
-**НЕ критично по скорости** - пользователь не заметит разницу
-**Важнее консистентность** - данные всегда актуальные
-**Проще архитектура** - один источник истины
---
## Компромиссное решение
### Вариант: Кеширование в Redis с инвалидацией
```python
# При чтении данных заявки
async def get_claim(claim_id: str):
# 1. Пробуем Redis (быстро)
cached = await redis.get(f"claim:{claim_id}")
if cached:
return json.loads(cached)
# 2. Если нет в кеше - из PostgreSQL
claim = await db.get_claim(claim_id)
# 3. Сохраняем в кеш на 1 час
await redis.set(f"claim:{claim_id}", json.dumps(claim), ttl=3600)
return claim
# При обновлении данных
async def update_claim(claim_id: str, data: dict):
# 1. Обновляем PostgreSQL
await db.update_claim(claim_id, data)
# 2. Инвалидируем кеш (удаляем из Redis)
await redis.delete(f"claim:{claim_id}")
# Или обновляем кеш сразу
await redis.set(f"claim:{claim_id}", json.dumps(data), ttl=3600)
```
### Плюсы:
- ✅ Быстрый доступ (если есть в кеше)
- ✅ Актуальные данные (инвалидация при обновлении)
- ✅ Fallback на PostgreSQL (если кеш пуст)
### Минусы:
- ❌ Дополнительная сложность
- ❌ Нужно инвалидировать кеш при каждом обновлении
- ❌ Риск устаревших данных (если забыли инвалидировать)
---
## Рекомендация для веб-формы
### Вариант 1: Только PostgreSQL (рекомендую)
**Когда использовать:**
- Данные читаются не так часто (загрузка страницы, переходы)
- Важна консистентность
- Простота архитектуры важнее скорости
**Плюсы:**
- ✅ Просто (один источник данных)
- ✅ Всегда актуальные данные
- ✅ Нет рассинхронизации
- ✅ PostgreSQL с индексами всё равно быстро (1-10 мс)
**Минусы:**
- ❌ Чуть медленнее, чем Redis (но не критично)
---
### Вариант 2: PostgreSQL + Redis кеш (если нужна скорость)
**Когда использовать:**
- Очень частые чтения (каждый запрос)
- Критична скорость (но для веб-формы это не так)
**Плюсы:**
- ✅ Быстрый доступ (0.1-1 мс)
- ✅ Меньше нагрузки на PostgreSQL
**Минусы:**
- ❌ Сложнее (нужна инвалидация кеша)
- ❌ Риск устаревших данных
- ❌ Больше кода для поддержки
---
## Итог
### Для веб-формы:
**Рекомендую: Только PostgreSQL**
**Почему:**
1. ⚡ PostgreSQL с индексами быстро (1-10 мс) - пользователь не заметит
2. ✅ Всегда актуальные данные (нет рассинхронизации)
3. ✅ Проще архитектура (один источник истины)
4. ✅ Данные читаются не так часто (не каждый запрос)
**Redis используй только для:**
- ✅ Pub/Sub (`ocr_events:{claim_id}`) - события в реальном времени
- ✅ Кеширование AI ответов (классификация, визарды) - если нужно
- ✅ SMS коды, временные токены - с TTL
**НЕ используй Redis для:**
- ❌ Основных данных заявки (есть в PostgreSQL)
- ❌ Документов (есть в PostgreSQL)
- ❌ Ответов визарда (есть в PostgreSQL)
---
## Если всё-таки нужен Redis кеш
Можно добавить опциональное кеширование:
```python
# В n8n workflow после claimsave
if (channel === 'web_form' && enable_cache === true) {
// Опционально: кешируем в Redis на 1 час
await redis.set(
`claim:${claim_id}`,
JSON.stringify(claim_data),
ttl=3600
);
}
```
Но это опционально и не обязательно для веб-формы.