768 lines
24 KiB
Markdown
768 lines
24 KiB
Markdown
|
|
# 🚀 Новая архитектура: Быстрая загрузка документов
|
|||
|
|
|
|||
|
|
**Дата создания:** 2025-11-26
|
|||
|
|
**Статус:** В разработке
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📋 Проблема
|
|||
|
|
|
|||
|
|
Текущий флоу слишком медленный:
|
|||
|
|
1. **2 минуты** — генерация визарда (RAG + AI анализ)
|
|||
|
|
2. **Длинная анкета** — слишком много вопросов для пользователя
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ Новое решение
|
|||
|
|
|
|||
|
|
### Концепция
|
|||
|
|
1. После описания проблемы → сразу запрашиваем документы (без ожидания визарда)
|
|||
|
|
2. Пока пользователь загружает документы → в бэке генерируется визард + OCR
|
|||
|
|
3. После всех документов → показываем готовое заявление на апрув
|
|||
|
|
|
|||
|
|
### Преимущества
|
|||
|
|
- **Быстрый старт** — пользователь не ждёт 2 минуты
|
|||
|
|
- **Параллельная работа** — OCR и визард генерируются пока пользователь ищет документы
|
|||
|
|
- **Меньше вопросов** — большая часть данных извлекается из документов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔄 Новый флоу (шаги)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 1. Телефон │ (уже есть)
|
|||
|
|
│ SMS верификация
|
|||
|
|
└────────┬────────┘
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 2. Черновики │ (уже есть, обновить UI)
|
|||
|
|
│ - Новые статусы│
|
|||
|
|
│ - Legacy→"Начать заново"
|
|||
|
|
└────────┬────────┘
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 3. Описание │ (уже есть)
|
|||
|
|
│ Свободный текст│
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼ → n8n: быстрая генерация списка документов (5-10 сек)
|
|||
|
|
│ → n8n: параллельно запускает генерацию визарда (в фоне)
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 4. Документы │ 🆕 НОВЫЙ КОМПОНЕНТ
|
|||
|
|
│ - Поэкранная загрузка
|
|||
|
|
│ - Критичные помечены
|
|||
|
|
│ - Можно пропустить
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼ → n8n: OCR каждого документа → заполнение визарда (в фоне)
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 5. Ожидание │ 🆕 НОВЫЙ КОМПОНЕНТ
|
|||
|
|
│ "Формируем заявление..."
|
|||
|
|
│ Loader + прогресс
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼ ← n8n: claim_ready event (SSE)
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 6. Заявление │ (уже есть StepClaimConfirmation)
|
|||
|
|
│ Просмотр + редактирование
|
|||
|
|
└────────┬────────┘
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 7. SMS апрув │ (уже есть)
|
|||
|
|
└─────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 Статусы черновика (status_code)
|
|||
|
|
|
|||
|
|
| Статус | Описание | UI при открытии |
|
|||
|
|
|--------|----------|-----------------|
|
|||
|
|
| `draft_new` | Только описание | → Шаг документов |
|
|||
|
|
| `draft_docs_progress` | Часть документов загружена | → Продолжить с текущего документа |
|
|||
|
|
| `draft_docs_complete` | Все документы загружены | → Показать loader |
|
|||
|
|
| `draft_claim_ready` | Заявление готово | → Показать заявление |
|
|||
|
|
| `awaiting_sms` | Ждёт SMS | → Форма SMS |
|
|||
|
|
| `approved` | Отправлено | Не показываем |
|
|||
|
|
|
|||
|
|
### Legacy черновики (старый формат)
|
|||
|
|
- Нет `documents_required` → показываем с пометкой "устаревший"
|
|||
|
|
- Кнопка "Начать заново" → копирует description, создаёт новый черновик
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📦 Структура payload черновика
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
// === Идентификаторы ===
|
|||
|
|
"claim_id": "CLM-2025-11-26-X7Y8Z9",
|
|||
|
|
"session_token": "sess_abc123...",
|
|||
|
|
"unified_id": "user_456...",
|
|||
|
|
"phone": "+79991234567",
|
|||
|
|
"email": "user@example.com",
|
|||
|
|
|
|||
|
|
// === Описание проблемы ===
|
|||
|
|
"problem_description": "Купил курсы за 50000р, компания не отвечает...",
|
|||
|
|
|
|||
|
|
// === Документы (новое!) ===
|
|||
|
|
"documents_required": [
|
|||
|
|
{
|
|||
|
|
"type": "contract",
|
|||
|
|
"name": "Договор или оферта",
|
|||
|
|
"critical": true,
|
|||
|
|
"hints": "Скриншот или PDF договора/оферты"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"type": "payment",
|
|||
|
|
"name": "Подтверждение оплаты",
|
|||
|
|
"critical": true,
|
|||
|
|
"hints": "Чек, выписка из банка, скриншот платежа"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"type": "correspondence",
|
|||
|
|
"name": "Переписка с продавцом",
|
|||
|
|
"critical": false,
|
|||
|
|
"hints": "Скриншоты переписки, email, чаты"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"documents_uploaded": [
|
|||
|
|
{
|
|||
|
|
"type": "contract",
|
|||
|
|
"file_id": "s3://...",
|
|||
|
|
"ocr_status": "completed",
|
|||
|
|
"ocr_data": {...}
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"documents_skipped": ["correspondence"],
|
|||
|
|
"current_doc_index": 1,
|
|||
|
|
|
|||
|
|
// === Визард (генерируется в фоне) ===
|
|||
|
|
"wizard_plan": {...}, // AI-generated questions
|
|||
|
|
"wizard_answers": {...}, // Auto-filled from OCR
|
|||
|
|
"wizard_ready": true, // Флаг готовности
|
|||
|
|
|
|||
|
|
// === Заявление ===
|
|||
|
|
"claim_ready": false, // Флаг готовности заявления
|
|||
|
|
"claim_data": { // Готовое заявление для апрува
|
|||
|
|
"applicant": {...},
|
|||
|
|
"case": {...},
|
|||
|
|
"contract_or_service": {...},
|
|||
|
|
"offenders": [...],
|
|||
|
|
"claim": {...},
|
|||
|
|
"attachments": [...]
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// === Метаданные ===
|
|||
|
|
"created_at": "2025-11-26T10:00:00Z",
|
|||
|
|
"updated_at": "2025-11-26T10:05:00Z"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔌 API Endpoints
|
|||
|
|
|
|||
|
|
### Существующие (без изменений)
|
|||
|
|
- `POST /api/v1/claims/description` — публикация описания в Redis
|
|||
|
|
- `GET /api/v1/claims/drafts/list` — список черновиков
|
|||
|
|
- `GET /api/v1/claims/drafts/{claim_id}` — полные данные черновика
|
|||
|
|
- `POST /api/v1/claims/approve` — финальный апрув (SMS)
|
|||
|
|
|
|||
|
|
### Новые/Изменённые
|
|||
|
|
|
|||
|
|
#### 1. SSE: Получение списка документов
|
|||
|
|
```
|
|||
|
|
GET /api/v1/events/{session_id}
|
|||
|
|
|
|||
|
|
Event: documents_list_ready
|
|||
|
|
Data: {
|
|||
|
|
"event_type": "documents_list_ready",
|
|||
|
|
"documents_required": [...]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. Загрузка документа
|
|||
|
|
```
|
|||
|
|
POST /api/v1/documents/upload
|
|||
|
|
Content-Type: multipart/form-data
|
|||
|
|
|
|||
|
|
Body:
|
|||
|
|
- claim_id: string
|
|||
|
|
- document_type: string (contract, payment, etc.)
|
|||
|
|
- file: binary
|
|||
|
|
|
|||
|
|
Response:
|
|||
|
|
{
|
|||
|
|
"success": true,
|
|||
|
|
"file_id": "s3://...",
|
|||
|
|
"ocr_status": "processing"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. SSE: Статус OCR и формирования заявления
|
|||
|
|
```
|
|||
|
|
GET /api/v1/events/{session_id}
|
|||
|
|
|
|||
|
|
Event: document_ocr_completed
|
|||
|
|
Data: {
|
|||
|
|
"event_type": "document_ocr_completed",
|
|||
|
|
"document_type": "contract",
|
|||
|
|
"ocr_data": {...}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Event: claim_ready
|
|||
|
|
Data: {
|
|||
|
|
"event_type": "claim_ready",
|
|||
|
|
"claim_data": {...}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. Получение статуса черновика
|
|||
|
|
```
|
|||
|
|
GET /api/v1/claims/drafts/{claim_id}/status
|
|||
|
|
|
|||
|
|
Response:
|
|||
|
|
{
|
|||
|
|
"status_code": "draft_docs_progress",
|
|||
|
|
"documents_total": 3,
|
|||
|
|
"documents_uploaded": 1,
|
|||
|
|
"documents_skipped": 0,
|
|||
|
|
"wizard_ready": false,
|
|||
|
|
"claim_ready": false
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🖥️ Frontend компоненты
|
|||
|
|
|
|||
|
|
### 1. StepDocumentsNew.tsx (НОВЫЙ)
|
|||
|
|
```tsx
|
|||
|
|
// Поэкранная загрузка документов
|
|||
|
|
// Один документ на экран
|
|||
|
|
// Критичные помечены алертом
|
|||
|
|
// Кнопки: "Загрузить", "Пропустить", "Назад"
|
|||
|
|
|
|||
|
|
interface Props {
|
|||
|
|
documents: DocumentConfig[];
|
|||
|
|
currentIndex: number;
|
|||
|
|
onUpload: (file: File) => void;
|
|||
|
|
onSkip: () => void;
|
|||
|
|
onNext: () => void;
|
|||
|
|
onPrev: () => void;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. StepWaitingClaim.tsx (НОВЫЙ)
|
|||
|
|
```tsx
|
|||
|
|
// Loader пока формируется заявление
|
|||
|
|
// Прогресс: "OCR документов...", "Анализ данных...", "Формирование заявления..."
|
|||
|
|
// SSE подписка на claim_ready
|
|||
|
|
|
|||
|
|
interface Props {
|
|||
|
|
sessionId: string;
|
|||
|
|
onClaimReady: (claimData: any) => void;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. StepDraftSelection.tsx (ОБНОВИТЬ)
|
|||
|
|
```tsx
|
|||
|
|
// Новые статусы черновиков
|
|||
|
|
// Разные действия для разных статусов
|
|||
|
|
// Legacy черновики → "Начать заново"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. ClaimForm.tsx (ОБНОВИТЬ)
|
|||
|
|
```tsx
|
|||
|
|
// Новая логика шагов
|
|||
|
|
// Убрать StepWizardPlan из основного флоу
|
|||
|
|
// Добавить StepDocumentsNew и StepWaitingClaim
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ⚙️ n8n Воркфлоу
|
|||
|
|
|
|||
|
|
### 1. Генерация списка документов (быстрая)
|
|||
|
|
```
|
|||
|
|
Redis Trigger (ticket_form:description)
|
|||
|
|
↓
|
|||
|
|
AI: Быстрый анализ → список документов (5-10 сек)
|
|||
|
|
↓
|
|||
|
|
Redis Publish (ocr_events:{session_id})
|
|||
|
|
+ event_type: documents_list_ready
|
|||
|
|
↓
|
|||
|
|
PostgreSQL: Сохранить documents_required в черновик
|
|||
|
|
↓
|
|||
|
|
Параллельно: Запустить генерацию визарда (отдельный воркфлоу)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Генерация визарда (фоновая)
|
|||
|
|
```
|
|||
|
|
(Запускается из воркфлоу 1)
|
|||
|
|
↓
|
|||
|
|
AI Agent: RAG + генерация вопросов (2 мин)
|
|||
|
|
↓
|
|||
|
|
PostgreSQL: Сохранить wizard_plan в черновик
|
|||
|
|
+ wizard_ready = true
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. OCR документа
|
|||
|
|
```
|
|||
|
|
Webhook (upload документа)
|
|||
|
|
↓
|
|||
|
|
S3 Upload
|
|||
|
|
↓
|
|||
|
|
AI Vision: OCR + извлечение данных
|
|||
|
|
↓
|
|||
|
|
PostgreSQL: Сохранить в documents_uploaded
|
|||
|
|
↓
|
|||
|
|
Redis Publish: document_ocr_completed
|
|||
|
|
↓
|
|||
|
|
Если все документы загружены:
|
|||
|
|
↓ (Запустить формирование заявления)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. Формирование заявления
|
|||
|
|
```
|
|||
|
|
(После всех документов)
|
|||
|
|
↓
|
|||
|
|
Собрать данные из:
|
|||
|
|
- wizard_plan
|
|||
|
|
- documents_uploaded (OCR данные)
|
|||
|
|
- CRM контакт
|
|||
|
|
↓
|
|||
|
|
AI: Сформировать заявление
|
|||
|
|
↓
|
|||
|
|
PostgreSQL: Сохранить claim_data
|
|||
|
|
+ claim_ready = true
|
|||
|
|
↓
|
|||
|
|
Redis Publish: claim_ready
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 План реализации
|
|||
|
|
|
|||
|
|
### Фаза 1: Frontend (без n8n)
|
|||
|
|
1. ✅ Создать `StepDocumentsNew.tsx` — заглушка с mock данными
|
|||
|
|
2. ✅ Создать `StepWaitingClaim.tsx` — loader
|
|||
|
|
3. ✅ Обновить `ClaimForm.tsx` — новый флоу шагов
|
|||
|
|
4. ✅ Обновить `StepDraftSelection.tsx` — новые статусы
|
|||
|
|
|
|||
|
|
### Фаза 2: Backend
|
|||
|
|
1. ✅ Эндпоинт `POST /api/v1/documents/upload`
|
|||
|
|
2. ✅ SSE events: `documents_list_ready`, `document_ocr_completed`, `claim_ready`
|
|||
|
|
3. ✅ Эндпоинт `GET /api/v1/claims/drafts/{claim_id}/status`
|
|||
|
|
|
|||
|
|
### Фаза 3: n8n
|
|||
|
|
1. ✅ Воркфлоу: Генерация списка документов
|
|||
|
|
2. ✅ Воркфлоу: OCR документа
|
|||
|
|
3. ✅ Воркфлоу: Формирование заявления
|
|||
|
|
|
|||
|
|
### Фаза 4: Интеграция и тестирование
|
|||
|
|
1. ✅ Полный цикл с реальными данными
|
|||
|
|
2. ✅ Обработка ошибок
|
|||
|
|
3. ✅ Legacy черновики
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 Ожидаемый результат
|
|||
|
|
|
|||
|
|
| Метрика | Было | Стало |
|
|||
|
|
|---------|------|-------|
|
|||
|
|
| Время до первого действия | ~2 мин | ~10 сек |
|
|||
|
|
| Количество вопросов | 10-15 | 0-3 (только уточняющие) |
|
|||
|
|
| Конверсия | ? | ↑ (меньше отвала) |
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
**Дата создания:** 2025-11-26
|
|||
|
|
**Статус:** В разработке
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📋 Проблема
|
|||
|
|
|
|||
|
|
Текущий флоу слишком медленный:
|
|||
|
|
1. **2 минуты** — генерация визарда (RAG + AI анализ)
|
|||
|
|
2. **Длинная анкета** — слишком много вопросов для пользователя
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ✅ Новое решение
|
|||
|
|
|
|||
|
|
### Концепция
|
|||
|
|
1. После описания проблемы → сразу запрашиваем документы (без ожидания визарда)
|
|||
|
|
2. Пока пользователь загружает документы → в бэке генерируется визард + OCR
|
|||
|
|
3. После всех документов → показываем готовое заявление на апрув
|
|||
|
|
|
|||
|
|
### Преимущества
|
|||
|
|
- **Быстрый старт** — пользователь не ждёт 2 минуты
|
|||
|
|
- **Параллельная работа** — OCR и визард генерируются пока пользователь ищет документы
|
|||
|
|
- **Меньше вопросов** — большая часть данных извлекается из документов
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔄 Новый флоу (шаги)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 1. Телефон │ (уже есть)
|
|||
|
|
│ SMS верификация
|
|||
|
|
└────────┬────────┘
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 2. Черновики │ (уже есть, обновить UI)
|
|||
|
|
│ - Новые статусы│
|
|||
|
|
│ - Legacy→"Начать заново"
|
|||
|
|
└────────┬────────┘
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 3. Описание │ (уже есть)
|
|||
|
|
│ Свободный текст│
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼ → n8n: быстрая генерация списка документов (5-10 сек)
|
|||
|
|
│ → n8n: параллельно запускает генерацию визарда (в фоне)
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 4. Документы │ 🆕 НОВЫЙ КОМПОНЕНТ
|
|||
|
|
│ - Поэкранная загрузка
|
|||
|
|
│ - Критичные помечены
|
|||
|
|
│ - Можно пропустить
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼ → n8n: OCR каждого документа → заполнение визарда (в фоне)
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 5. Ожидание │ 🆕 НОВЫЙ КОМПОНЕНТ
|
|||
|
|
│ "Формируем заявление..."
|
|||
|
|
│ Loader + прогресс
|
|||
|
|
└────────┬────────┘
|
|||
|
|
│
|
|||
|
|
▼ ← n8n: claim_ready event (SSE)
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 6. Заявление │ (уже есть StepClaimConfirmation)
|
|||
|
|
│ Просмотр + редактирование
|
|||
|
|
└────────┬────────┘
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ 7. SMS апрув │ (уже есть)
|
|||
|
|
└─────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 Статусы черновика (status_code)
|
|||
|
|
|
|||
|
|
| Статус | Описание | UI при открытии |
|
|||
|
|
|--------|----------|-----------------|
|
|||
|
|
| `draft_new` | Только описание | → Шаг документов |
|
|||
|
|
| `draft_docs_progress` | Часть документов загружена | → Продолжить с текущего документа |
|
|||
|
|
| `draft_docs_complete` | Все документы загружены | → Показать loader |
|
|||
|
|
| `draft_claim_ready` | Заявление готово | → Показать заявление |
|
|||
|
|
| `awaiting_sms` | Ждёт SMS | → Форма SMS |
|
|||
|
|
| `approved` | Отправлено | Не показываем |
|
|||
|
|
|
|||
|
|
### Legacy черновики (старый формат)
|
|||
|
|
- Нет `documents_required` → показываем с пометкой "устаревший"
|
|||
|
|
- Кнопка "Начать заново" → копирует description, создаёт новый черновик
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📦 Структура payload черновика
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
// === Идентификаторы ===
|
|||
|
|
"claim_id": "CLM-2025-11-26-X7Y8Z9",
|
|||
|
|
"session_token": "sess_abc123...",
|
|||
|
|
"unified_id": "user_456...",
|
|||
|
|
"phone": "+79991234567",
|
|||
|
|
"email": "user@example.com",
|
|||
|
|
|
|||
|
|
// === Описание проблемы ===
|
|||
|
|
"problem_description": "Купил курсы за 50000р, компания не отвечает...",
|
|||
|
|
|
|||
|
|
// === Документы (новое!) ===
|
|||
|
|
"documents_required": [
|
|||
|
|
{
|
|||
|
|
"type": "contract",
|
|||
|
|
"name": "Договор или оферта",
|
|||
|
|
"critical": true,
|
|||
|
|
"hints": "Скриншот или PDF договора/оферты"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"type": "payment",
|
|||
|
|
"name": "Подтверждение оплаты",
|
|||
|
|
"critical": true,
|
|||
|
|
"hints": "Чек, выписка из банка, скриншот платежа"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"type": "correspondence",
|
|||
|
|
"name": "Переписка с продавцом",
|
|||
|
|
"critical": false,
|
|||
|
|
"hints": "Скриншоты переписки, email, чаты"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"documents_uploaded": [
|
|||
|
|
{
|
|||
|
|
"type": "contract",
|
|||
|
|
"file_id": "s3://...",
|
|||
|
|
"ocr_status": "completed",
|
|||
|
|
"ocr_data": {...}
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"documents_skipped": ["correspondence"],
|
|||
|
|
"current_doc_index": 1,
|
|||
|
|
|
|||
|
|
// === Визард (генерируется в фоне) ===
|
|||
|
|
"wizard_plan": {...}, // AI-generated questions
|
|||
|
|
"wizard_answers": {...}, // Auto-filled from OCR
|
|||
|
|
"wizard_ready": true, // Флаг готовности
|
|||
|
|
|
|||
|
|
// === Заявление ===
|
|||
|
|
"claim_ready": false, // Флаг готовности заявления
|
|||
|
|
"claim_data": { // Готовое заявление для апрува
|
|||
|
|
"applicant": {...},
|
|||
|
|
"case": {...},
|
|||
|
|
"contract_or_service": {...},
|
|||
|
|
"offenders": [...],
|
|||
|
|
"claim": {...},
|
|||
|
|
"attachments": [...]
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
// === Метаданные ===
|
|||
|
|
"created_at": "2025-11-26T10:00:00Z",
|
|||
|
|
"updated_at": "2025-11-26T10:05:00Z"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔌 API Endpoints
|
|||
|
|
|
|||
|
|
### Существующие (без изменений)
|
|||
|
|
- `POST /api/v1/claims/description` — публикация описания в Redis
|
|||
|
|
- `GET /api/v1/claims/drafts/list` — список черновиков
|
|||
|
|
- `GET /api/v1/claims/drafts/{claim_id}` — полные данные черновика
|
|||
|
|
- `POST /api/v1/claims/approve` — финальный апрув (SMS)
|
|||
|
|
|
|||
|
|
### Новые/Изменённые
|
|||
|
|
|
|||
|
|
#### 1. SSE: Получение списка документов
|
|||
|
|
```
|
|||
|
|
GET /api/v1/events/{session_id}
|
|||
|
|
|
|||
|
|
Event: documents_list_ready
|
|||
|
|
Data: {
|
|||
|
|
"event_type": "documents_list_ready",
|
|||
|
|
"documents_required": [...]
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. Загрузка документа
|
|||
|
|
```
|
|||
|
|
POST /api/v1/documents/upload
|
|||
|
|
Content-Type: multipart/form-data
|
|||
|
|
|
|||
|
|
Body:
|
|||
|
|
- claim_id: string
|
|||
|
|
- document_type: string (contract, payment, etc.)
|
|||
|
|
- file: binary
|
|||
|
|
|
|||
|
|
Response:
|
|||
|
|
{
|
|||
|
|
"success": true,
|
|||
|
|
"file_id": "s3://...",
|
|||
|
|
"ocr_status": "processing"
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. SSE: Статус OCR и формирования заявления
|
|||
|
|
```
|
|||
|
|
GET /api/v1/events/{session_id}
|
|||
|
|
|
|||
|
|
Event: document_ocr_completed
|
|||
|
|
Data: {
|
|||
|
|
"event_type": "document_ocr_completed",
|
|||
|
|
"document_type": "contract",
|
|||
|
|
"ocr_data": {...}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Event: claim_ready
|
|||
|
|
Data: {
|
|||
|
|
"event_type": "claim_ready",
|
|||
|
|
"claim_data": {...}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 4. Получение статуса черновика
|
|||
|
|
```
|
|||
|
|
GET /api/v1/claims/drafts/{claim_id}/status
|
|||
|
|
|
|||
|
|
Response:
|
|||
|
|
{
|
|||
|
|
"status_code": "draft_docs_progress",
|
|||
|
|
"documents_total": 3,
|
|||
|
|
"documents_uploaded": 1,
|
|||
|
|
"documents_skipped": 0,
|
|||
|
|
"wizard_ready": false,
|
|||
|
|
"claim_ready": false
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🖥️ Frontend компоненты
|
|||
|
|
|
|||
|
|
### 1. StepDocumentsNew.tsx (НОВЫЙ)
|
|||
|
|
```tsx
|
|||
|
|
// Поэкранная загрузка документов
|
|||
|
|
// Один документ на экран
|
|||
|
|
// Критичные помечены алертом
|
|||
|
|
// Кнопки: "Загрузить", "Пропустить", "Назад"
|
|||
|
|
|
|||
|
|
interface Props {
|
|||
|
|
documents: DocumentConfig[];
|
|||
|
|
currentIndex: number;
|
|||
|
|
onUpload: (file: File) => void;
|
|||
|
|
onSkip: () => void;
|
|||
|
|
onNext: () => void;
|
|||
|
|
onPrev: () => void;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. StepWaitingClaim.tsx (НОВЫЙ)
|
|||
|
|
```tsx
|
|||
|
|
// Loader пока формируется заявление
|
|||
|
|
// Прогресс: "OCR документов...", "Анализ данных...", "Формирование заявления..."
|
|||
|
|
// SSE подписка на claim_ready
|
|||
|
|
|
|||
|
|
interface Props {
|
|||
|
|
sessionId: string;
|
|||
|
|
onClaimReady: (claimData: any) => void;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. StepDraftSelection.tsx (ОБНОВИТЬ)
|
|||
|
|
```tsx
|
|||
|
|
// Новые статусы черновиков
|
|||
|
|
// Разные действия для разных статусов
|
|||
|
|
// Legacy черновики → "Начать заново"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. ClaimForm.tsx (ОБНОВИТЬ)
|
|||
|
|
```tsx
|
|||
|
|
// Новая логика шагов
|
|||
|
|
// Убрать StepWizardPlan из основного флоу
|
|||
|
|
// Добавить StepDocumentsNew и StepWaitingClaim
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## ⚙️ n8n Воркфлоу
|
|||
|
|
|
|||
|
|
### 1. Генерация списка документов (быстрая)
|
|||
|
|
```
|
|||
|
|
Redis Trigger (ticket_form:description)
|
|||
|
|
↓
|
|||
|
|
AI: Быстрый анализ → список документов (5-10 сек)
|
|||
|
|
↓
|
|||
|
|
Redis Publish (ocr_events:{session_id})
|
|||
|
|
+ event_type: documents_list_ready
|
|||
|
|
↓
|
|||
|
|
PostgreSQL: Сохранить documents_required в черновик
|
|||
|
|
↓
|
|||
|
|
Параллельно: Запустить генерацию визарда (отдельный воркфлоу)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. Генерация визарда (фоновая)
|
|||
|
|
```
|
|||
|
|
(Запускается из воркфлоу 1)
|
|||
|
|
↓
|
|||
|
|
AI Agent: RAG + генерация вопросов (2 мин)
|
|||
|
|
↓
|
|||
|
|
PostgreSQL: Сохранить wizard_plan в черновик
|
|||
|
|
+ wizard_ready = true
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. OCR документа
|
|||
|
|
```
|
|||
|
|
Webhook (upload документа)
|
|||
|
|
↓
|
|||
|
|
S3 Upload
|
|||
|
|
↓
|
|||
|
|
AI Vision: OCR + извлечение данных
|
|||
|
|
↓
|
|||
|
|
PostgreSQL: Сохранить в documents_uploaded
|
|||
|
|
↓
|
|||
|
|
Redis Publish: document_ocr_completed
|
|||
|
|
↓
|
|||
|
|
Если все документы загружены:
|
|||
|
|
↓ (Запустить формирование заявления)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. Формирование заявления
|
|||
|
|
```
|
|||
|
|
(После всех документов)
|
|||
|
|
↓
|
|||
|
|
Собрать данные из:
|
|||
|
|
- wizard_plan
|
|||
|
|
- documents_uploaded (OCR данные)
|
|||
|
|
- CRM контакт
|
|||
|
|
↓
|
|||
|
|
AI: Сформировать заявление
|
|||
|
|
↓
|
|||
|
|
PostgreSQL: Сохранить claim_data
|
|||
|
|
+ claim_ready = true
|
|||
|
|
↓
|
|||
|
|
Redis Publish: claim_ready
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 План реализации
|
|||
|
|
|
|||
|
|
### Фаза 1: Frontend (без n8n)
|
|||
|
|
1. ✅ Создать `StepDocumentsNew.tsx` — заглушка с mock данными
|
|||
|
|
2. ✅ Создать `StepWaitingClaim.tsx` — loader
|
|||
|
|
3. ✅ Обновить `ClaimForm.tsx` — новый флоу шагов
|
|||
|
|
4. ✅ Обновить `StepDraftSelection.tsx` — новые статусы
|
|||
|
|
|
|||
|
|
### Фаза 2: Backend
|
|||
|
|
1. ✅ Эндпоинт `POST /api/v1/documents/upload`
|
|||
|
|
2. ✅ SSE events: `documents_list_ready`, `document_ocr_completed`, `claim_ready`
|
|||
|
|
3. ✅ Эндпоинт `GET /api/v1/claims/drafts/{claim_id}/status`
|
|||
|
|
|
|||
|
|
### Фаза 3: n8n
|
|||
|
|
1. ✅ Воркфлоу: Генерация списка документов
|
|||
|
|
2. ✅ Воркфлоу: OCR документа
|
|||
|
|
3. ✅ Воркфлоу: Формирование заявления
|
|||
|
|
|
|||
|
|
### Фаза 4: Интеграция и тестирование
|
|||
|
|
1. ✅ Полный цикл с реальными данными
|
|||
|
|
2. ✅ Обработка ошибок
|
|||
|
|
3. ✅ Legacy черновики
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 Ожидаемый результат
|
|||
|
|
|
|||
|
|
| Метрика | Было | Стало |
|
|||
|
|
|---------|------|-------|
|
|||
|
|
| Время до первого действия | ~2 мин | ~10 сек |
|
|||
|
|
| Количество вопросов | 10-15 | 0-3 (только уточняющие) |
|
|||
|
|
| Конверсия | ? | ↑ (меньше отвала) |
|
|||
|
|
|
|||
|
|
|