- Добавлен сервис CrmMySQLService для прямого подключения к MySQL CRM - Обновлён метод get_draft() для получения cf_2624 напрямую из БД - Реализована блокировка полей (readonly) при contact_data_confirmed = true - Добавлен выбор банка для СБП выплат с динамической загрузкой из API - Обновлена документация по работе с cf_2624 и MySQL - Добавлен network_mode: host в docker-compose для доступа к MySQL - Обновлены компоненты формы для поддержки блокировки полей
282 lines
10 KiB
Markdown
282 lines
10 KiB
Markdown
# Session Log 2025-12-01
|
||
|
||
## Сессия: UI/UX улучшения + CRM интеграция + Исправление дубликатов
|
||
|
||
### Участники
|
||
- Пользователь: Фёдор
|
||
- AI: Claude (Cursor)
|
||
|
||
---
|
||
|
||
## 1. UI/UX Улучшения формы заявки
|
||
|
||
### 1.1 Изменение заголовков
|
||
- **Главный заголовок формы**: "Подать заявку на выплату" → "Подать обращение о защите прав потребителя"
|
||
- **Заголовок вкладки браузера**: "ERV Insurance Platform" → "Clientright — защита прав потребителей"
|
||
|
||
**Файлы:**
|
||
- `ticket_form/frontend/src/pages/ClaimForm.tsx`
|
||
- `ticket_form/frontend/index.html`
|
||
- `ticket_form/frontend/public/index.html`
|
||
|
||
### 1.2 Улучшение отображения черновиков
|
||
**Файлы:**
|
||
- `ticket_form/frontend/src/components/form/StepDraftSelection.tsx`
|
||
- `ticket_form/backend/app/api/claims.py`
|
||
|
||
**Изменения:**
|
||
- Описание проблемы: увеличено до 250 символов, многострочное отображение
|
||
- Добавлен заголовок проблемы (`problem_title` из `ai_analysis.problem`)
|
||
- Добавлена категория (`category`) как фиолетовый тег
|
||
- Прогресс-бар документов: `X / Y` с иконками статуса (✓ зелёный / ○ красный/серый)
|
||
- Удалены избыточные теги "✓ Описание", "✓ План", "✓ Документы"
|
||
- Убран дублирующий "++" из кнопки "Создать новую заявку"
|
||
|
||
### 1.3 Исправление навигации
|
||
- Кнопка "Назад" теперь всегда возвращает к списку черновиков (Step 0)
|
||
- Пропуск шагов "Проверка полиса" и "Тип события" для нового флоу (`documents_required` present)
|
||
|
||
**Файлы:**
|
||
- `ticket_form/frontend/src/pages/ClaimForm.tsx`
|
||
- `ticket_form/frontend/src/components/form/StepWizardPlan.tsx`
|
||
|
||
### 1.4 Переименование шагов
|
||
```
|
||
'Телефон' → 'Вход'
|
||
'Описание' → 'Обращение'
|
||
'Рекомендации' → 'Документы'
|
||
'Оплата' → 'Заявление'
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Backend улучшения
|
||
|
||
### 2.1 Исправление IP клиента
|
||
**Проблема:** Отображался Docker IP `192.168.0.1`
|
||
|
||
**Решение:** Добавлена функция `_get_client_ip()` с проверкой заголовков:
|
||
```python
|
||
def _get_client_ip(request: Request) -> str:
|
||
# 1. X-Forwarded-For
|
||
# 2. X-Real-IP
|
||
# 3. request.client.host (fallback)
|
||
```
|
||
|
||
**Файл:** `ticket_form/backend/app/api/documents.py`
|
||
|
||
### 2.2 Расширение API списка черновиков
|
||
**Добавлены поля:**
|
||
- `problem_title` - заголовок проблемы
|
||
- `category` - категория
|
||
- `documents_total` - всего документов
|
||
- `documents_uploaded` - загружено (уникальных типов)
|
||
- `documents_skipped` - пропущено
|
||
- `documents_required_list` - детальный список с статусами
|
||
|
||
**Файл:** `ticket_form/backend/app/api/claims.py`
|
||
|
||
### 2.3 SSE для OCR статуса
|
||
Добавлено подключение SSE для получения статуса OCR обработки после загрузки документов.
|
||
|
||
**Файл:** `ticket_form/frontend/src/components/form/StepWizardPlan.tsx`
|
||
|
||
---
|
||
|
||
## 3. CRM Webservices (PHP)
|
||
|
||
### 3.1 UpsertContact.php
|
||
**Назначение:** Создание/обновление контакта с поддержкой `tgid`
|
||
|
||
**Приоритет поиска:**
|
||
1. `contact_id` - если передан
|
||
2. `mobile` - поиск по телефону
|
||
3. `tgid` - поиск по Telegram ID
|
||
|
||
**Параметры:** `contact_json` (JSON строка)
|
||
|
||
**Регистрация в БД:**
|
||
```sql
|
||
INSERT INTO vtiger_ws_operation (operationid, name, handler_path, handler_method, type, prelogin)
|
||
VALUES (57, 'UpsertContact', 'include/Webservices/UpsertContact.php', 'vtws_upsertcontact', 'POST', 0);
|
||
|
||
INSERT INTO vtiger_ws_operation_parameters (operationid, name, type, sequence)
|
||
VALUES (57, 'contact_json', 'string', 1);
|
||
```
|
||
|
||
### 3.2 UpsertAccounts.php
|
||
**Назначение:** Пакетное создание/поиск контрагентов (offenders) по ИНН
|
||
|
||
**Логика:**
|
||
- Поиск по ИНН
|
||
- Если найден - возвращает ID без обновления
|
||
- Если не найден - создаёт новый
|
||
|
||
**Параметры:** `offenders_json` (JSON массив)
|
||
|
||
**Регистрация в БД:**
|
||
```sql
|
||
INSERT INTO vtiger_ws_operation (operationid, name, handler_path, handler_method, type, prelogin)
|
||
VALUES (58, 'UpsertAccounts', 'include/Webservices/UpsertAccounts.php', 'vtws_upsertaccounts', 'POST', 0);
|
||
|
||
INSERT INTO vtiger_ws_operation_parameters (operationid, name, type, sequence)
|
||
VALUES (58, 'offenders_json', 'string', 1);
|
||
```
|
||
|
||
### 3.3 UpsertProject.php
|
||
**Назначение:** Создание/обновление проекта с маппингом ответчиков
|
||
|
||
**Параметры:** `project_json` (JSON объект содержит):
|
||
- `project_id` - ID проекта для обновления
|
||
- `claim_id` - ID заявки
|
||
- `contact_id` - ID контакта
|
||
- `result` - JSON строка с `offender_ids`
|
||
- `projectdata` - данные проекта
|
||
|
||
**Маппинг ответчиков:**
|
||
- Первый ответчик → `cf_2274` (основной)
|
||
- Второй ответчик → `cf_2276` (агент)
|
||
|
||
**Регистрация в БД:**
|
||
```sql
|
||
INSERT INTO vtiger_ws_operation (operationid, name, handler_path, handler_method, type, prelogin)
|
||
VALUES (59, 'UpsertProject', 'include/Webservices/UpsertProject.php', 'vtws_upsertproject', 'POST', 0);
|
||
|
||
INSERT INTO vtiger_ws_operation_parameters (operationid, name, type, sequence)
|
||
VALUES (59, 'project_json', 'string', 1);
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Исправление дубликатов documents_meta
|
||
|
||
### 4.1 Проблема
|
||
В `documents_meta` накапливались дубликаты при каждой загрузке документа.
|
||
|
||
**Причина:** SQL-запрос использовал простую конкатенацию `||` без дедупликации:
|
||
```sql
|
||
'{documents_meta}',
|
||
COALESCE(...новые...) || COALESCE(...старые...)
|
||
```
|
||
|
||
### 4.2 Найденные дубликаты
|
||
| claim_id | Было записей | Уникальных |
|
||
|----------|--------------|------------|
|
||
| `bddb6815-8e17-4d54-a721-5e94382942c7` | 11 | 5 |
|
||
| `226564ce-d7cf-48ee-a820-690e8f5ec8e5` | 3 | 2 |
|
||
| `509872e2-9666-4c5e-8ab7-2304dd6a5d18` | 4 | 3 |
|
||
| `ef853bac-f54b-46aa-adf8-f0c9c0cd76bc` | 4 | 3 |
|
||
|
||
### 4.3 SQL для исправления
|
||
```sql
|
||
-- Дедупликация по field_name (оставляем последний файл)
|
||
UPDATE clpr_claims
|
||
SET payload = jsonb_set(
|
||
payload,
|
||
'{documents_meta}',
|
||
(
|
||
SELECT COALESCE(
|
||
jsonb_agg(doc ORDER BY (doc->>'uploaded_at') DESC NULLS LAST),
|
||
'[]'::jsonb
|
||
)
|
||
FROM (
|
||
SELECT DISTINCT ON (doc->>'field_name') doc
|
||
FROM jsonb_array_elements(payload->'documents_meta') doc
|
||
ORDER BY doc->>'field_name', (doc->>'uploaded_at') DESC NULLS LAST
|
||
) unique_docs
|
||
),
|
||
true
|
||
),
|
||
updated_at = now()
|
||
WHERE id IN (...);
|
||
```
|
||
|
||
### 4.4 Исправленный SQL для загрузки документов
|
||
Добавлен CTE `documents_meta_dedup`:
|
||
```sql
|
||
documents_meta_dedup AS (
|
||
SELECT COALESCE(
|
||
(
|
||
SELECT jsonb_agg(doc ORDER BY (doc->>'uploaded_at') DESC NULLS LAST)
|
||
FROM (
|
||
SELECT DISTINCT ON (doc->>'field_name', doc->>'file_id') doc
|
||
FROM (
|
||
-- Новые записи (приоритет 1)
|
||
SELECT jsonb_array_elements(...) AS doc, 1 AS priority
|
||
UNION ALL
|
||
-- Существующие записи (приоритет 2)
|
||
SELECT jsonb_array_elements(...) AS doc, 2 AS priority
|
||
) all_docs
|
||
ORDER BY doc->>'field_name', doc->>'file_id', priority
|
||
) unique_docs
|
||
),
|
||
'[]'::jsonb
|
||
) AS documents_meta
|
||
)
|
||
```
|
||
|
||
---
|
||
|
||
## 5. n8n Workflows
|
||
|
||
### 5.1 Проблема с Redis каналами
|
||
**Бэкенд публикует:** `clpr:check:ocr_status`
|
||
|
||
**n8n слушает:**
|
||
- `fnSo3FTTbQcMjwt3` → `clpr:ocr:clime_file`
|
||
- `1IKe2PccqXLkD2KR` → `clpr:ocr:jobs`
|
||
|
||
**Нужно:** Либо создать новый workflow для `clpr:check:ocr_status`, либо изменить канал в бэкенде.
|
||
|
||
---
|
||
|
||
## 6. Файлы изменены
|
||
|
||
### Frontend
|
||
- `ticket_form/frontend/index.html`
|
||
- `ticket_form/frontend/public/index.html`
|
||
- `ticket_form/frontend/src/pages/ClaimForm.tsx`
|
||
- `ticket_form/frontend/src/components/form/StepDraftSelection.tsx`
|
||
- `ticket_form/frontend/src/components/form/StepWizardPlan.tsx`
|
||
- `ticket_form/frontend/src/components/form/generateConfirmationFormHTML.ts`
|
||
|
||
### Backend
|
||
- `ticket_form/backend/app/api/claims.py`
|
||
- `ticket_form/backend/app/api/documents.py`
|
||
- `ticket_form/backend/app/api/events.py`
|
||
|
||
### CRM
|
||
- `include/Webservices/UpsertContact.php` (NEW)
|
||
- `include/Webservices/UpsertAccounts.php` (NEW)
|
||
- `include/Webservices/UpsertProject.php` (NEW)
|
||
|
||
---
|
||
|
||
## 7. Коммит
|
||
|
||
```
|
||
git commit -m "feat: UI/UX improvements + CRM integration methods + documents_meta deduplication"
|
||
Commit: da82100b
|
||
12 files changed, 1531 insertions(+), 145 deletions(-)
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Нерешённые задачи
|
||
|
||
1. **n8n workflow для `clpr:check:ocr_status`** - нужно либо создать новый, либо изменить канал
|
||
2. **Обновить SQL в бэкенде** - заменить SQL загрузки документов на версию с дедупликацией
|
||
3. **Обновить n8n ноды** для использования новых CRM методов:
|
||
- `Create Contact` → `UpsertContact`
|
||
- `Create Account` → `UpsertAccounts`
|
||
- `Create Project` → `UpsertProject`
|
||
|
||
---
|
||
|
||
## Метаданные сессии
|
||
|
||
- **Дата:** 2025-12-01
|
||
- **Продолжительность:** ~2 часа
|
||
- **Основной фокус:** UI/UX, CRM интеграция, исправление дубликатов
|
||
|