Files
aiform_dev/PROJECT_TIMELINE.md

550 lines
24 KiB
Markdown
Raw Normal View History

# 📅 Хронология проекта 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)