Проблема: Backend proxy не передавал filename и upload_timestamp к n8n
Это ломало обработку файлов в workflow
Изменения:
- Добавлены параметры filename и upload_timestamp в proxy_file_upload()
- Теперь передаём все поля которые отправляет frontend
Было в n8n body: {claim_id, voucher, session_id, file_type}
Стало: {claim_id, voucher, session_id, file_type, filename, upload_timestamp}
- Создан n8n_proxy.py для безопасного проксирования запросов
- Webhook URLs перенесены в .env (скрыты от фронтенда)
- Frontend теперь использует /api/n8n/* endpoints
- Добавлена документация SECURITY_N8N_PROXY.md
Преимущества:
- Webhook URLs не видны в DevTools
- Централизованное логирование
- Возможность добавить rate limiting и auth
- Легко менять URLs без пересборки фронтенда
🎯 Основные изменения:
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
Проблема:
❌ Queue error: 'str' object has no attribute 'get'
❌ ocr_result не инициализировался до try блока
❌ Debug панель не показывала OCR результаты
Решение:
✅ Добавлена инициализация: ocr_result = None
✅ Убрана проверка 'ocr_result' in locals()
✅ Теперь ocr_result всегда определен
Что изменилось:
- Backend не падает при OCR ошибках
- OCR результаты возвращаются в response
- Debug панель получает ocr_result
- Логи показывают процесс OCR
Тестирование:
Загрузи файл полиса → Debug панель покажет:
📤 Upload to S3
🔍 OCR running
📄 OCR completed: XXX chars
🤖 AI analysis: policy/garbage
✅ Extracted data
Step2Details (по скриншоту):
✅ Индикатор '✅ Полис найден' вверху
✅ Select с типами событий из erv_ticket:
- Задержка авиарейса (более 3 часов)
- Отмена авиарейса
- Пропуск стыковочного рейса
- Посадка на запасной аэродром
- Задержка отправки поезда
- Отмена поезда
- Задержка/отмена парома/круизного судна
✅ Дата наступления страхового случая (DatePicker)
✅ Номер рейса/поезда/парома
✅ Загрузка подтверждающих документов:
- Посадочный талон, билет, справка и т.д.
- До 10 файлов по 15MB
- HEIC, PDF, фото
Debug Panel улучшения:
✅ Полные S3 URL (не обрезанные)
✅ Кнопка '🔗 Открыть в новой вкладке'
✅ word-break: break-all для длинных URL
✅ Показывает все файлы из массива
✅ Для каждого файла:
- Filename
- File ID (UUID)
- Size (KB)
- Полный S3 URL (кликабельный)
Теперь в Debug видно КУДА загрузилось:
https://s3.twcstorage.ru/f9825c87-.../policies/20251024_213045_abc123_file.jpg
Можно кликнуть и посмотреть глазами! 👀
Новый сервис ocr_service.py:
✅ OCR распознавание через http://147.45.146.17:8001✅ AI анализ через Gemini Vision (OpenRouter)
✅ Проверка: полис или шляпа
✅ Извлечение данных полиса автоматически
Логика обработки:
1. Файл загружается в S3
2. OCR запускается в фоне (RabbitMQ queue)
3. Gemini Vision анализирует текст:
- document_type: policy/passport/ticket/garbage
- is_valid_policy: true/false
- confidence: 0.0-1.0
- extracted_data: voucher, holder_name, dates
4. Результат сохраняется в Redis (1 час TTL)
Debug логи (в backend):
📤 OCR task queued: file_id - filename
💾 OCR result cached in Redis
📊 Document type: policy/garbage/other
✅ Valid: true/false, Confidence: 0.95
🗑️ GARBAGE uploaded: если не полис (silent)
Новый endpoint:
GET /api/v1/upload/ocr-result/{file_id}
- Получить результат OCR из Redis
- Можно запрашивать когда угодно
Где смотреть логи:
tail -f /var/www/fastuser/data/www/crm.clientright.ru/erv_platform_backend.log
Результаты хранятся в Redis:
key: ocr_result:{file_id}
ttl: 3600 сек (1 час)
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
Проблема: Backend пытался подключиться к удаленной БД turistpr_erv
Решение: Обновлены креды на локальную БД ci20465_erv
Изменения:
- MySQL Host: localhost (было: 141.8.194.131)
- MySQL DB: ci20465_erv (было: turistpr_erv)
- MySQL User: ci20465_erv (было: root)
- MySQL Password: c7vOXbmG (было: пустой)
- MySQL Table: lexrpiority (было: erv_vouchers в коде)
Результат:
✅ MySQL Policy DB подключена успешно
✅ API /api/v1/policy/check работает
✅ Валидация полисов работает (33963 полисов в БД)
Тестирование:
- E1000-302372730 → found: true ✅
- E9999-999999999 → found: false ✅
Изменения в форме (Шаг 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 требует настройки доступа
- Исправлены TypeScript ошибки в Step3Payment.tsx (типизация, неиспользуемые импорты)
- Добавлены недостающие зависимости: aiomysql, pymysql, python-multipart
- Обновлен requirements.txt с актуальными версиями
- Добавлены новые API endpoints: policy check, file upload
- Добавлен policy_service для работы с MySQL
- Все сервисы успешно запущены и работают
- Обновлен SESSION_LOG с документацией процесса