Изменения в /api/n8n/documents/attach:
✅ Принимает массив документов (не одиночный объект)
✅ Умная обработка S3 путей:
- /bucket/path → https://s3.twcstorage.ru/bucket/path
- bucket/path → https://s3.twcstorage.ru/bucket/path
- https://... → без изменений
✅ Поддержка обоих форматов полей:
- file / file_url
- filename / file_name
✅ Batch-обработка с детальной статистикой
✅ Возвращает результаты для каждого документа отдельно
✅ Логирование успешных и неуспешных операций
Формат ответа:
{
total_processed: N,
successful: M,
failed: K,
results: [...],
errors: [...]
}
Тесты:
- TEST_REAL_DATA.sh - тест с реальными данными из n8n
- TEST_QUICK.sh - быстрые тесты
Документация обновлена с примерами batch-обработки
Изменения:
✅ Новый endpoint: POST /api/n8n/documents/attach
✅ Поддерживает привязку к Project или HelpDesk
✅ Логика: если указан ticket_id → HelpDesk, иначе → Project
✅ Полное логирование всех операций
✅ Интеграция с upload_documents_to_crm.php
Входные данные:
- contact_id (обязательно)
- project_id (обязательно)
- file_url (обязательно)
- file_name (обязательно)
- ticket_id (опционально, для привязки к заявке)
- file_type (опционально, описание документа)
Готово к интеграции в n8n workflow!
Изменения:
✅ Добавлены переменные n8n_create_contact_webhook и n8n_create_claim_webhook в Settings
✅ Все webhook URLs теперь централизованно в .env
✅ Удалён хардкод из n8n_proxy.py
Теперь все N8N webhooks:
- N8N_POLICY_CHECK_WEBHOOK
- N8N_FILE_UPLOAD_WEBHOOK
- N8N_CREATE_CONTACT_WEBHOOK
- N8N_CREATE_CLAIM_WEBHOOK
Проблема:
- Backend не логировал что именно n8n возвращает для /api/n8n/policy/check
- Не видно откуда брать project_id в response
Исправление:
✅ Добавлено логирование response.text[:500] для policy/check
✅ Добавлена обработка ошибок парсинга JSON
Теперь в логах видно полный ответ от n8n!
Проблема:
- Step1Phone делал запрос НАПРЯМУЮ к n8n (палил webhook URL)
- В backend логах не было видно что n8n возвращает для контакта
- Нельзя было отследить contact_id, claim_id, is_new_contact
Решение:
✅ Добавлен endpoint /api/n8n/contact/create в n8n_proxy.py
✅ Step1Phone.tsx теперь использует proxy вместо прямого URL
✅ Backend логирует полный response от n8n (contact_id, claim_id и тд)
Теперь весь трафик к n8n идёт через backend proxy!
- ✅ Новый endpoint: POST /api/n8n/claim/create
- ✅ Проксирует запросы к n8n webhook создания заявки
- ✅ Frontend теперь использует /api/n8n/claim/create вместо прямого URL
- ✅ Решает проблему CORS и скрывает webhook URL
- ✅ Логирование запросов и ошибок
- Step1Phone теперь вызывает n8n webhook после SMS верификации
- Webhook создаёт/находит контакт в CRM через CreateWebContact
- Возвращает: contact_id, claim_id, is_new_contact
- Данные сохраняются в formData для дальнейшей работы
- Исправлена нормализация телефона в sms_service (убираем +)
- Отключен rate limiting SMS для тестирования
- Backend подключён к внешнему Redis (crm.clientright.ru:6379)
- Добавлены поля contact_id, is_new_contact в FormData
- Frontend пересобран с новым кодом
Проблема: 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 с документацией процесса