fix: Исправление загрузки документов и SQL запросов

- Исправлена потеря документов при обновлении черновика (SQL объединяет вместо перезаписи)
- Исправлено определение типа документа (приоритет field_label над field_name)
- Исправлены дубликаты в documents_meta и documents_uploaded
- Добавлена передача group_index с фронтенда для правильного field_name
- Исправлены все документы в таблице clpr_claim_documents с правильными field_name
- Обновлены SQL запросы: claimsave и claimsave_final для нового флоу
- Добавлена поддержка multi-file upload для одного документа
- Исправлены дубликаты в списке загруженных документов на фронтенде

Файлы:
- SQL: SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql, SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql
- n8n: N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js (поддержка group_index)
- Backend: documents.py (передача group_index в n8n)
- Frontend: StepWizardPlan.tsx (передача group_index, исправление дубликатов)
- Скрипты: fix_claim_documents_field_names.py, fix_documents_meta_duplicates.py

Результат: документы больше не теряются, имеют правильные типы и field_name
This commit is contained in:
AI Assistant
2025-11-26 19:54:51 +03:00
parent 1d6c9d1f52
commit 02689e65db
42 changed files with 8314 additions and 232 deletions

View File

@@ -0,0 +1,767 @@
# 🚀 Новая архитектура: Быстрая загрузка документов
**Дата создания:** 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 (только уточняющие) |
| Конверсия | ? | ↑ (меньше отвала) |