🎯 Изменения:
- Документы загружаются по очереди (один за другим)
- После загрузки каждого документа открывается модалка с крутилкой
- SSE слушает конкретный event_type: {file_type}_processed
- Модалка показывает результат распознавания с извлечёнными данными
- Кнопка 'Продолжить' → переход к следующему документу
- Опциональные документы можно пропустить
- После обработки всех обязательных → 'Далее на Step 3'
📊 UX флоу:
1. Выбор типа события → показываются нужные документы
2. Документ 1: Выбрать файл → Загрузить → Модалка → Результат → Продолжить
3. Документ 2: Выбрать файл → Загрузить → Модалка → Результат → Продолжить
4. Документ 3 (опц): Загрузить ИЛИ Пропустить
5. Все обязательные обработаны → Далее на Step 3
🔑 Каждый документ получает свой уникальный event_type:
- frontend отправляет file_type
- n8n возвращает event_type = {file_type}_processed
- frontend слушает этот конкретный event_type через SSE
✅ При успешном распознавании полиса - кнопка 'Продолжить →' → переход на Step 2
❌ При ошибке распознавания - кнопка 'Загрузить другой файл' → возврат к форме загрузки
Проблема: Backend закрывает SSE после отправки события, браузер триггерит onerror,
фронтенд перезаписывал успешный результат сообщением 'Ошибка подключения к серверу'.
Решение: Проверяем в onerror что если уже получили результат (prev !== 'loading'),
не затираем его ошибкой.
🎯 Основные изменения:
Backend:
- Реализован SSE endpoint /events/{task_id} для real-time стриминга событий
- Интеграция Redis Pub/Sub для получения событий от n8n
- Исправлен путь к .env файлу (абсолютный путь)
- Убран префикс /api/v1 для events router
- Добавлено подробное логирование событий
Frontend:
- Переключён на Vite dev mode для работы proxy
- Настроен proxy /events -> backend:8100
- Реализована модалка с крутилкой при загрузке файла
- SSE клиент для получения OCR результатов в real-time
- Отображение результатов AI анализа в модалке
Docker:
- Frontend: изменён на npm run dev (Vite dev server)
- Добавлен host.docker.internal для доступа к backend
- Настроен proxy в docker-compose
Утилиты:
- monitor_redis_direct.py - мониторинг Redis Pub/Sub
- test_redis_publish_direct.py - тестирование публикации в Redis
🚀 Полная цепочка работает:
Frontend → Backend SSE → Redis Pub/Sub ← n8n → OCR/AI → Result
1. ✅ OCR Progress Bar:
- Добавлен polling OCR результатов каждые 3 сек
- Визуальный индикатор: 🔍 Обработка OCR... (1/10)
- Progress bar с анимацией
- Статусы: 🔄 Запуск → 🔍 Обработка → ✅ Завершен
- Gemini Vision результаты в Debug панели
2. ✅ Убран некорректный 'Полис найден':
- Было: показывался сразу после загрузки файла
- Проблема: OCR еще не закончился, может быть шляпа
- Решение: убрана зеленая плашка с Step2
- Статус полиса только после реальной проверки
3. ✅ Условные поля для стыковочного рейса:
- Если выбран 'miss_connection' → показываются 4 доп поля:
• Номер рейса прибытия
• Дата рейса прибытия
• Номер рейса отправления
• Дата рейса отправления
- Если выбран 'cancel_flight' → доп поле:
• Подтверждение отмены от АК
- Для обычных рейсов: только номер рейса
Frontend изменения:
- Step1Policy: OCR polling, progress bar
- Step2Details: условная логика полей (как в erv_ticket)
- useState для eventType
- handleEventTypeChange для динамики
Теперь:
✅ Видно прогресс OCR
✅ Видно результаты Gemini Vision
✅ Условные поля работают
✅ Нет ложных статусов
Новый UI:
✅ Split-screen layout:
- Слева (60%): форма заявки
- Справа (40%): Debug Console в реальном времени
Компонент DebugPanel.tsx:
✅ Темная тема (VS Code style)
✅ Timeline с событиями
✅ Real-time обновления
✅ Показывает:
- Form Data (JSON в реальном времени)
- Events Log с иконками и цветами
- Детали каждого события
События которые отображаются:
1. policy_check:
- ✅ Полис найден в MySQL БД
- ⚠️ Полис не найден
- Показывает: voucher, found status
2. upload:
- 📤 Загружаю X файлов в S3
- ✅ Загружено в S3: X/Y
- Показывает: file_id, size, S3 URL
3. ocr:
- 🔍 Запущен OCR
- 📄 OCR завершен: XXX символов
- Показывает: текст preview
4. ai_analysis:
- 🤖 AI: policy/garbage, confidence: 95%
- 🗑️ ШЛЯПА DETECTED! (пользователю не говорим)
- Показывает: document_type, is_valid, confidence, extracted_data
5. sms:
- 📱 Отправляю SMS
- ✅ SMS отправлен (DEBUG mode)
- 🔐 Проверяю код
- ✅ Телефон подтвержден
- Показывает: phone, debug_code
UX:
- Sticky panel (прилипает при скролле)
- Monospace шрифт для данных
- Цветовая кодировка статусов
- JSON форматирование
Layout:
- Row + Col от Ant Design
- Responsive: mobile = 1 column, desktop = split
Теперь видно ВСЁ что происходит в реальном времени! 🔍
1. ✅ Placeholder с тире E1000-302538524
- Теперь в placeholder тоже тире
2. ✅ Email перенесен на Step3
- Убран с Step1 (проверка полиса)
- Добавлен на Step3 (вместе с телефоном)
- Теперь телефон + email + выплата на одном шаге
3. ✅ HEIC формат + мультилоад
- Добавлена поддержка .heic, .heif (iPhone формат)
- Убран maxCount - неограниченная загрузка
- Параметр multiple для множественной загрузки
4. ✅ S3 Upload
- Создан s3_service.py для работы с Timeweb S3
- Новый endpoint: POST /api/v1/upload/files
- Поддержка мультизагрузки файлов
- Автоматическая генерация уникальных имен
- Файлы грузятся в S3, не локально
5. ✅ Draft автосохранение
- Создана таблица claims_draft в PostgreSQL
- Новый API: POST /api/v1/draft/save
- GET /api/v1/draft/stats - статистика по шагам
- GET /api/v1/draft/list - список последних драфтов
- Для аналитики: где люди бросают заполнение
6. ✅ Миграция БД
- 002_create_claims_draft.sql применена
- Индексы для быстрого поиска
- JSONB поле для гибкости данных
Backend:
- s3_service.py - сервис для S3
- draft.py - API автосохранения
- upload.py - обновлен endpoint для S3
- main.py - добавлены роуты и подключения
Frontend:
- Step1Policy: убран email, добавлен HEIC
- Step3Payment: добавлен email после телефона
Статус: ✅ Backend подключен к S3, таблица создана, всё работает
Изменения в UX (Step1Policy):
✅ Автоматическая маска ввода E1000-302538524
- Тире вставляется автоматически
- Не нужно вводить вручную
✅ Расширенная автозамена кириллицы:
- А→A, а→A, С→C, с→C, Е→E, е→E и т.д.
- Поддержка строчных и заглавных
✅ Автоматический uppercase
- Все буквы автоматически заглавные
✅ Логика при ненайденном полисе:
- НЕ переходит на следующий шаг
- Показывает поле загрузки скана прямо на месте
- Кнопка "Продолжить со сканом"
- Поддержка изображений и PDF
✅ Обработка paste:
- Корректная обработка вставки текста
- Применяются все правила форматирования
Backend (policy.py):
✅ Убран вывод holder_name (для продакшна)
- API не возвращает персональные данные
- Только found: true/false
Формат полиса:
Ввод: k78486489849494 или К7848-6489849494
Результат: K7848-648984949
Изменения в форме (Шаг 1):
- Полис в одну строку: E1000-302538524 (было: отдельно серия и номер)
- Email теперь обязателен (было: опционально)
- Убран ИНН (было: опционально)
- Автозамена кириллицы на латиницу (Е→E, О→O и т.д.)
- Валидация формата: буква + 4 цифры + тире + 9 цифр
Изменения в Backend API:
- PolicyCheckRequest: voucher + email (убран inn)
- policy_service: упрощен запрос к MySQL
- Добавлено подключение MySQL в lifespan
Изменения в ClaimForm:
- FormData обновлен: voucher вместо policyNumber/policySeries
- Убрано поле inn из всей логики
Статус: Frontend работает, MySQL требует настройки доступа
Изменения в UX:
- Шаг 1: Проверка полиса (было: телефон + SMS)
- Шаг 2: Детали происшествия (без изменений)
- Шаг 3: Телефон + SMS + Выплата (было: только выплата)
Обновленные компоненты:
- Удален: Step1Phone.tsx
- Создан: Step1Policy.tsx - проверка полиса через API
- Обновлен: Step3Payment.tsx - добавлена SMS верификация
- Обновлен: ClaimForm.tsx - новая структура шагов
Логика: сначала проверяем полис, потом детали, в конце верификация телефона и выплата