# 📅 Хронология проекта ERV Platform **Период:** 24 октября - 1 ноября 2025 **Всего сессий:** 8 **Всего строк документации:** 5295+ **Коммитов:** 50+ --- ## 📊 День 1: 24 октября 2025 - Инициализация проекта **Задача:** Развернуть новую платформу обработки страховых обращений ### Что сделано: - ✅ Создана структура проекта: Backend (FastAPI) + Frontend (React TypeScript) - ✅ Подключены внешние сервисы: - PostgreSQL (147.45.189.234:5432) - Redis (crm.clientright.ru:6379) - RabbitMQ (185.197.75.249:5672) - S3 Timeweb Storage - ✅ API endpoints: SMS, Claims, Policy, Upload - ✅ OCR интеграция (147.45.146.17:8001) - ✅ Базовая форма заявки (3 шага) - ✅ Docker контейнеры: frontend, backend, postgres, redis **Логи:** `SESSION_LOG_2025-10-24.md` (708 строк) --- ## 📊 День 2: 26 октября 2025 - N8N интеграция **Задача:** Интеграция с n8n для асинхронной обработки файлов ### Что сделано: - ✅ **N8N Webhooks:** - Проверка полиса в MySQL + запись в PostgreSQL - Загрузка файлов в S3 + OCR + Vision AI - ✅ **React Frontend:** - Автогенерация `claim_id` и `session_id` - Конвертация файлов в PDF на клиенте (jsPDF + browser-image-compression) - Поддержка форматов: JPG, PNG, HEIC, WEBP, PDF - Сжатие изображений до 2MB - ✅ **PostgreSQL:** - Таблицы `claims` и `claim_files` - UPSERT операции - JSONB поля для гибкого хранения - ✅ **Документация:** - `N8N_INTEGRATION.md` - `N8N_SQL_QUERIES.md` - `N8N_PDF_COMPRESS.md` **Проблемы решены:** - Конфликт зависимостей `aioboto3` → удалён - Nullable поля в PostgreSQL - JSON сериализация в n8n **Логи:** `SESSION_LOG_2025-10-26.md` (932 строки) --- ## 📊 День 3: 27 октября 2025 - SSE + Redis Pub/Sub **Задача:** Real-time обработка документов через SSE ### Что сделано: - ✅ **Backend SSE Endpoint** (`/events/{task_id}`): - Server-Sent Events для real-time стриминга - Подписка на Redis Pub/Sub канал `ocr_events:{task_id}` - Обработка вложенного формата от n8n Redis ноды - Автозакрытие соединения после результата - ✅ **Frontend SSE Client:** - Блокирующая модалка с loading spinner - Автоматическое подключение после загрузки файла - Отображение результатов AI анализа - Логирование в Debug Panel - ✅ **Vite Proxy:** - `/events` → `host.docker.internal:8100` - Обход файрвола (порт 8100 закрыт) - ✅ **Docker:** - Frontend в dev режиме (hot reload) - `host.docker.internal` для доступа к хосту **Проблемы решены:** - Неправильный порт SSE → Vite proxy - Backend к локальному Redis → абсолютный путь `.env` - AttributeError decode → убран `.decode()` - Префикс `/api/v1` → убран для events - Frontend не ждёт SSE → модалка + `waitingForOcr` state **Тестирование:** - Время обработки: ~55 секунд - OCR: полис E1000-302545808 - AI: извлечены ФИО, даты, программа - Результат в модалке ✅ **Логи:** `SESSION_LOG_2025-10-27.md` (не найден в списке, но упоминается) --- ## 📊 День 4: 28 октября 2025 - Исправления SSE **Сессия 1 (00:00-01:00):** Исправление SSE error handling ### Проблема: После успешного распознавания показывалась ошибка "Ошибка подключения к серверу" ### Причина: Backend закрывал SSE после отправки события → браузер триггерил `onerror` → фронтенд затирал успешный результат ### Решение: ```typescript eventSource.onerror = (error) => { setOcrModalContent((prev) => { if (prev && prev !== 'loading') { return prev; // НЕ затираем результат } return { success: false, message: 'Ошибка подключения к серверу' }; }); }; ``` **Сессия 2 (13:00-17:00):** Умная форма Step 2 ### Что сделано: - ✅ **Рефакторинг Step 2** с AI-обработкой документов - ✅ **Пошаговая загрузка** с модалками - ✅ **DEV MODE кнопки** во всех 3 шагах - ✅ **PostgreSQL UPSERT** с CTE - ✅ **Конфигурация документов** для каждого типа события **Логи:** `SESSION_LOG_2025-10-28.md` (1063 строки) --- ## 📊 День 5: 29 октября 2025 - Динамический визард **Сессия 1 (12:00-15:00):** Рефакторинг визарда ### Задача: Переделать визард так, чтобы каждый документ был отдельным шагом ### Было: ``` [1. Полис] → [2. Детали + все документы] → [3. Оплата] ``` ### Стало: ``` [1. Полис] → [2. Тип] → [3. Док 1] → [4. Док 2] → ... → [N. Оплата] ``` ### Что сделано: - ✅ `Step2EventType.tsx` - выбор типа страхового случая - ✅ `StepDocumentUpload.tsx` - загрузка каждого документа - ✅ Динамическое количество шагов - ✅ Прогресс-бар с реальными шагами - ✅ SSE для каждого документа с уникальным `event_type` **Проблемы решены:** - Синтаксические ошибки (дублирующийся код) - PostgreSQL INSERT не возвращал данные - `file_size` как строка вместо числа **Логи:** `SESSION_LOG_2025-10-29.md` (645 строк) --- **Сессия 2 (16:30-17:30):** Безопасность N8N Webhooks ### Задача: > "как нам не палить вебхук, а то его видно через код?" ### Проблема: N8N webhook URLs были захардкожены в коде фронтенда → видны в DevTools ### Решение: Backend Proxy - фронтенд больше не знает про n8n! ### Архитектура: ``` Frontend → fetch('/api/n8n/*') → Backend Proxy → N8N (URLs в .env) ``` ### Что сделано: - ✅ `backend/app/api/n8n_proxy.py` - proxy router - ✅ Webhook URLs в `.env` (не коммитятся) - ✅ Frontend использует `/api/n8n/policy/check` и `/api/n8n/upload/file` - ✅ Документация `SECURITY_N8N_PROXY.md` **Проблемы решены:** - "Ошибка соединения" → относительные пути вместо localhost - Пропущенные поля → добавлены `filename` и `upload_timestamp` - event_type не совпадает → гибкая проверка **Логи:** `SESSION_LOG_2025-10-29_part2.md` (627 строк) --- ## 📊 День 6: 30 октября 2025 - Телефон на Step 1 + CRM **Задача:** Перенос телефона на первый шаг и создание контакта в CRM ### Что сделано: - ✅ **Новый Step1Phone** (вместо Step1Policy): - Ввод телефона как первый шаг - SMS верификация - Автосоздание контакта в CRM через n8n webhook - ✅ **CreateWebContact** - операция vTiger webservice: - Создание контакта по телефону - Проверка дубликатов - Возврат `contact_id` - ✅ **N8N Webhook** для создания контакта после SMS - ✅ **Формат телефона без +** (79001234567) - ✅ **DEV MODE** кнопки на всех шагах **Рефакторинг структуры:** ``` Было: Step1Policy → Step2Details → Step3Payment Стало: Step1Phone → Step2Policy → Step3EventType → Step4DocUpload... → StepNPayment ``` **Оптимизация Docker:** - Убраны локальные контейнеры Postgres и Redis - Используются только внешние сервисы - Остались: frontend + backend **Логи:** `SESSION_LOG_2025-10-30.md` (597 строк) --- ## 📊 День 7: 1 ноября 2025 - CreateWebProject + Финальная интеграция **Задача:** Создание проектов в CRM по номеру полиса ### Что сделано: - ✅ **CreateWebProject.php** - операция vTiger: - Поиск проекта по полису (cf_1885) - Создание нового если не найден - Привязка к контакту - Возврат `{"project_id": "123", "is_new": true/false}` - ✅ **Регистрация в БД** vTiger webservice - ✅ **Тестирование:** - Создание нового: `{"project_id":"396865","is_new":true}` ✅ - Повторный вызов: `{"project_id":"396865","is_new":false}` ✅ - ✅ **N8N Webhook URLs** в docker-compose.yml (environment) **Проблемы решены:** - Формат телефона в vTiger (mobile без +) - SMS коды не проходили валидацию - N8N webhook URLs не передавались в backend контейнер **Логи:** `SESSION_LOG_2025-11-01.md` (723 строки) --- ## 🎯 Текущая архитектура (финальная) ``` ┌─────────────────────────────────────────────────────────────────────┐ │ USER BROWSER │ │ http://147.45.146.17:5173 │ │ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ React Frontend (Vite Dev Server) │ │ │ │ - Step1Phone.tsx (SMS верификация) │ │ │ │ - Step2Policy.tsx (проверка полиса) │ │ │ │ - Step3EventType.tsx (тип события) │ │ │ │ - Step4-N DocumentUpload.tsx (документы) │ │ │ │ - StepNPayment.tsx (оплата) │ │ │ │ - SSE Client для real-time обновлений │ │ │ │ - PDF конвертер (HEIC/JPG/PNG → PDF) │ │ │ └────────────┬───────────────────────────────────────────────────┘ │ │ │ Vite Proxy (/api, /events → backend) │ └───────────────┼──────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ BACKEND (FastAPI, port 8100) │ │ PID: 31571 (запущен вне Docker) │ │ │ │ 📁 app/api/ │ │ ├── sms.py - SMS верификация (SigmaSMS) │ │ ├── claims.py - Заявки │ │ ├── policy.py - Проверка полисов │ │ ├── upload.py - Загрузка файлов │ │ ├── events.py - SSE endpoints ⬅️ ВАЖНО │ │ └── n8n_proxy.py - Безопасный proxy к n8n ⬅️ НОВОЕ │ │ │ │ 🔌 Подключения: │ │ ├── PostgreSQL (147.45.189.234:5432) - claims, claim_files │ │ ├── MySQL (localhost:3306) - проверка полисов ERV │ │ ├── Redis (crm.clientright.ru:6379) - Pub/Sub для SSE │ │ ├── RabbitMQ (185.197.75.249:5672) - очереди │ │ └── S3 (Timeweb) - хранилище файлов │ └────────────┬────────────────────────────────────────────────────────┘ │ ├──────────────────────────────────────────────────────┐ │ │ ▼ ▼ ┌──────────────────────────┐ ┌──────────────────────────────┐ │ N8N Workflows │ │ vTiger CRM │ │ n8n.clientright.pro │ │ crm.clientright.ru │ │ │ │ │ │ Webhook 1: Policy Check │ │ Webservice Operations: │ │ - MySQL query │ │ - CreateWebContact │ │ - PostgreSQL insert │ │ - CreateWebProject │ │ - Return insured_persons│ │ - Query │ │ │ │ │ │ Webhook 2: File Upload │ │ Tables: │ │ - S3 upload │────────────────────│ - vtiger_contactdetails │ │ - PostgreSQL insert │ n8n webhook │ - vtiger_project │ │ - OCR Service │ creates contact │ - vtiger_contactscf (mobile) │ │ - AI Vision (Gemini) │ │ - vtiger_projectcf (cf_1885) │ │ - Redis PUBLISH │ │ │ └───────────┬──────────────┘ └───────────────────────────────┘ │ │ Redis PUBLISH: ocr_events:{claim_id} ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ Redis Pub/Sub │ │ crm.clientright.ru:6379 │ │ Channel: ocr_events:{claim_id} │ │ Password: CRM_Redis_Pass_2025_Secure! │ └───────────▲──────────────────────────────────────────────────────────┘ │ │ SUBSCRIBE │ Backend SSE endpoint (/events/{task_id}) ``` --- ## 📝 Ключевые компоненты ### Frontend (React + TypeScript) **Основные файлы:** - `ClaimForm.tsx` - главный визард с прогрессом - `Step1Phone.tsx` - ввод телефона + SMS - `Step2Policy.tsx` - проверка полиса - `Step3EventType.tsx` - выбор типа события - `StepDocumentUpload.tsx` - загрузка документов (динамический) - `StepPayment.tsx` - реквизиты для выплаты - `utils/pdfConverter.ts` - клиентская конвертация в PDF **Технологии:** - Vite (dev server + proxy) - Ant Design (UI компоненты) - EventSource (SSE client) - jsPDF + browser-image-compression ### Backend (FastAPI + Python) **Основные модули:** - `app/main.py` - FastAPI приложение - `app/config.py` - настройки из `.env` - `app/api/*` - роутеры (sms, claims, policy, upload, events, n8n_proxy) - `app/services/*` - сервисы (database, redis, rabbitmq, s3, policy) **Технологии:** - FastAPI (async API) - SQLAlchemy (PostgreSQL) - aiomysql (MySQL) - redis-py (Redis Pub/Sub) - aio-pika (RabbitMQ) - boto3 (S3) - httpx (HTTP client для proxy) ### N8N Workflows **Workflow 1: Policy Check** ``` Webhook → PostgreSQL (INSERT claims) → MySQL (SELECT policy) → Code → Response ``` **Workflow 2: File Upload + OCR** ``` Webhook → S3 Upload → PostgreSQL (INSERT claim_files) → OCR Service → Vision AI → Code (валидация) → PostgreSQL (UPDATE ai_extracted_data) → Redis PUBLISH ``` ### Database Schema **PostgreSQL (147.45.189.234:5432/default_db):** - `claims` - заявки (claim_number, policy_number, status, form_data::jsonb) - `claim_files` - файлы (s3_key, ocr_text, ai_extracted_data::jsonb, ocr_status) **MySQL (localhost:3306/u2768571_crm_db):** - `lexrpiority` - полисы ERV - `lexrpiority_insured_persons` - застрахованные лица **vTiger CRM (crm.clientright.ru):** - `vtiger_contactdetails` - контакты - `vtiger_contactscf` - доп.поля контактов (mobile) - `vtiger_project` - проекты (заявки) - `vtiger_projectcf` - доп.поля проектов (cf_1885 = полис) --- ## 🔒 Безопасность ### N8N Webhooks (спрятаны): ``` ❌ РАНЬШЕ: fetch('https://n8n.../webhook/9eb7bc5b...') // Виден в коде! ✅ ТЕПЕРЬ: fetch('/api/n8n/policy/check') // Proxy через backend ``` **Webhook URLs хранятся в:** - `.env` (не коммитится в git) - `backend/app/config.py` (читает из .env) - `backend/app/api/n8n_proxy.py` (проксирует запросы) ### Redis: ``` Host: crm.clientright.ru:6379 Password: CRM_Redis_Pass_2025_Secure! (в .env) ``` ### PostgreSQL: ``` Host: 147.45.189.234:5432 User: gen_user Password: 2~~9_^kVsU?2\S (в .env) ``` --- ## 📈 Статистика проекта ### Документация: ``` SESSION_LOG_2025-10-24.md: 708 строк SESSION_LOG_2025-10-26.md: 932 строки SESSION_LOG_2025-10-28.md: 1063 строки SESSION_LOG_2025-10-29.md: 645 строк SESSION_LOG_2025-10-29_part2.md: 627 строк SESSION_LOG_2025-10-30.md: 597 строк SESSION_LOG_2025-11-01.md: 723 строки ─────────────────────────────────────────── ИТОГО: 5295 строк Дополнительно: - N8N_INTEGRATION.md - N8N_SQL_QUERIES.md - N8N_PDF_COMPRESS.md - SECURITY_N8N_PROXY.md ``` ### Git коммиты: ``` Всего: 50+ коммитов Период: 24 окт - 1 ноя (8 дней) Среднее: 6-7 коммитов/день ``` ### Файлы проекта: ``` Backend: ~30 файлов Python Frontend: ~20 файлов TypeScript/TSX Configs: ~10 файлов (docker, vite, env) Docs: ~10 файлов Markdown CRM: ~3 файла PHP (vTiger operations) Utils: ~5 скриптов (мониторинг, тесты) ``` --- ## 🚀 Что работает сейчас ### ✅ Полный флоу обработки заявки: 1. **Step 1: Телефон** - Ввод телефона → SMS код → верификация - Создание контакта в CRM (автоматически через n8n) 2. **Step 2: Полис** - Ввод номера полиса - Проверка в MySQL БД - Если найден → показ застрахованных лиц → переход дальше - Если НЕ найден → загрузка скана полиса - OCR + Vision AI → распознавание полиса - Real-time результат через SSE в модалке 3. **Step 3: Тип события** - Выбор типа (задержка, отмена, пропуск стыковки) - Динамическое определение нужных документов 4. **Step 4-N: Документы** - Каждый документ = отдельный шаг - Загрузка → S3 → OCR → AI → результат в модалке - Real-time обработка через SSE 5. **Step N: Оплата** - Реквизиты для СБП - Финальная отправка заявки ### ✅ Интеграции: - **n8n** - асинхронная обработка (webhooks) - **vTiger CRM** - создание контактов и проектов (webservice) - **PostgreSQL** - хранение заявок и файлов - **MySQL** - база полисов ERV - **Redis** - Pub/Sub для SSE событий - **RabbitMQ** - очереди задач - **S3 Timeweb** - хранилище файлов - **OCR Service** - распознавание текста - **Gemini Vision AI** - извлечение данных из документов - **SigmaSMS** - отправка SMS кодов --- ## 📊 Текущий статус (1 ноября 2025) ### Git: ```bash Branch: main Status: clean (nothing to commit) Last commit: c049ed6 - "fix: Добавлены n8n webhook URLs в docker-compose.yml" ``` ### Сервисы: ```bash ✅ Backend: http://147.45.146.17:8100 (PID 31571, uvicorn --reload) ✅ Frontend: http://147.45.146.17:5173 (Docker, Vite dev mode) ✅ PostgreSQL: 147.45.189.234:5432 (внешний) ✅ Redis: crm.clientright.ru:6379 (внешний) ✅ RabbitMQ: 185.197.75.249:5672 (внешний) ✅ MySQL: localhost:3306 (vTiger/ERV полисы) ✅ S3: s3.twcstorage.ru (Timeweb) ✅ OCR: 147.45.146.17:8001 (Python service) ✅ n8n: n8n.clientright.pro (workflows) ✅ vTiger: crm.clientright.ru (CRM) ``` ### Следующие шаги: - [ ] Production mode для frontend (сейчас dev) - [ ] Docker Compose для backend (сейчас venv на хосте) - [ ] Nginx reverse proxy вместо прямого доступа к портам - [ ] SSL сертификаты - [ ] Мониторинг (Grafana/Prometheus) - [ ] Тесты (pytest для backend, Jest для frontend) - [ ] CI/CD pipeline --- **Последнее обновление:** 1 ноября 2025, 13:39 MSK **Автор:** Фёдор + AI Assistant (Claude Sonnet 4.5)