Изменения в /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-обработки
339 lines
9.9 KiB
Markdown
339 lines
9.9 KiB
Markdown
# 📎 API для привязки документов к проекту/заявке
|
||
|
||
## ✅ Готово к использованию!
|
||
|
||
---
|
||
|
||
## 🎯 Эндпоинт
|
||
|
||
```
|
||
POST https://crm.clientright.ru/api/n8n/documents/attach
|
||
```
|
||
|
||
---
|
||
|
||
## 📋 Формат входных данных
|
||
|
||
**Тип:** JSON массив документов
|
||
|
||
```json
|
||
[
|
||
{
|
||
"claim_id": "CLM-2025-11-02-WNRZZZ",
|
||
"event_type": "delay_flight",
|
||
"contact_id": "320096",
|
||
"project_id": "396868",
|
||
"ticket_id": "396936",
|
||
"filename": "boarding_pass.pdf",
|
||
"file_type": "flight_delay_boarding_or_ticket",
|
||
"file": "/bucket/path/to/file.pdf"
|
||
}
|
||
]
|
||
```
|
||
|
||
### Поля документа:
|
||
|
||
| Параметр | Тип | Обязательно | Описание | Пример |
|
||
|----------|-----|-------------|----------|--------|
|
||
| `contact_id` | string | ✅ Да | ID контакта в vTiger | `"320096"` |
|
||
| `project_id` | string | ✅ Да | ID проекта (полиса) в vTiger | `"396874"` |
|
||
| `file` или `file_url` | string | ✅ Да | Путь к файлу в S3 (с/без хоста) | `"/bucket/path/file.pdf"` |
|
||
| `filename` или `file_name` | string | ✅ Да | Имя файла | `"boarding_pass.pdf"` |
|
||
| `ticket_id` | string | ⚠️ Опц. | ID заявки<br/>**Если указан → HelpDesk**<br/>**Если НЕ указан → Project** | `"396935"` |
|
||
| `file_type` | string | ⚠️ Опц. | Тип документа | `"flight_delay_boarding_or_ticket"` |
|
||
| `claim_id` | string | ⚠️ Опц. | ID заявки (для логирования) | `"CLM-2025-11-02-..."` |
|
||
| `event_type` | string | ⚠️ Опц. | Тип события (для логирования) | `"delay_flight"` |
|
||
|
||
### 🔧 Умная обработка путей:
|
||
|
||
Эндпоинт автоматически определяет формат пути и добавляет хост S3 если нужно:
|
||
|
||
| Входной формат | Обработка | Результат |
|
||
|----------------|-----------|-----------|
|
||
| `/bucket/path/file.pdf` | ➕ Добавляем хост | `https://s3.twcstorage.ru/bucket/path/file.pdf` |
|
||
| `bucket/path/file.pdf` | ➕ Добавляем `/` и хост | `https://s3.twcstorage.ru/bucket/path/file.pdf` |
|
||
| `https://s3.twcstorage.ru/...` | ✅ Уже полный URL | `https://s3.twcstorage.ru/...` |
|
||
|
||
---
|
||
|
||
## 🔧 Логика работы
|
||
|
||
```
|
||
┌─────────────────────────────────────────────┐
|
||
│ POST /api/n8n/documents/attach │
|
||
└─────────────────┬───────────────────────────┘
|
||
│
|
||
▼
|
||
┌────────────────┐
|
||
│ ticket_id есть?│
|
||
└────────┬───────┘
|
||
│
|
||
┌─────────┴─────────┐
|
||
│ │
|
||
ДА НЕТ
|
||
│ │
|
||
▼ ▼
|
||
┌───────────────┐ ┌──────────────┐
|
||
│ Привязка к │ │ Привязка к │
|
||
│ HelpDesk │ │ Project │
|
||
│ (заявке) │ │ (проекту) │
|
||
└───────────────┘ └──────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 📤 Примеры запросов
|
||
|
||
### 1️⃣ Один документ к заявке (реальный пример)
|
||
|
||
```bash
|
||
curl -X POST "https://crm.clientright.ru/api/n8n/documents/attach" \
|
||
-H "Content-Type: application/json" \
|
||
-d '[
|
||
{
|
||
"claim_id": "CLM-2025-11-02-WNRZZZ",
|
||
"event_type": "delay_flight",
|
||
"contact_id": "320096",
|
||
"project_id": "396868",
|
||
"ticket_id": "396936",
|
||
"filename": "flight_delay_boarding_or_ticket.pdf",
|
||
"file_type": "flight_delay_boarding_or_ticket",
|
||
"file": "/f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c/crm2/CRM_Active_Files/Documents/HelpDesk/ЗАЯВКА_827_396936/flight_delay_boarding_or_ticket.pdf"
|
||
}
|
||
]'
|
||
```
|
||
|
||
**Ответ:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"total_processed": 1,
|
||
"successful": 1,
|
||
"failed": 0,
|
||
"results": [
|
||
{
|
||
"document_id": "15x396941",
|
||
"document_numeric_id": "396941",
|
||
"attached_to": "ticket",
|
||
"attached_to_id": "396936",
|
||
"file_name": "flight_delay_boarding_or_ticket.pdf",
|
||
"file_type": "flight_delay_boarding_or_ticket",
|
||
"s3_bucket": "f9825c87-4e3558f6-f9b6-405c-ad3d-d1535c49b61c",
|
||
"s3_key": "crm2/CRM_Active_Files/Documents/HelpDesk/ЗАЯВКА_827_396936/flight_delay_boarding_or_ticket.pdf",
|
||
"file_size": 85320,
|
||
"message": "Документ создан с правильными S3 метаданными и привязан к проекту"
|
||
}
|
||
],
|
||
"errors": null
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2️⃣ Несколько документов за раз (batch)
|
||
|
||
```bash
|
||
curl -X POST "https://crm.clientright.ru/api/n8n/documents/attach" \
|
||
-H "Content-Type: application/json" \
|
||
-d '[
|
||
{
|
||
"contact_id": "320096",
|
||
"project_id": "396868",
|
||
"ticket_id": "396936",
|
||
"filename": "boarding_pass.pdf",
|
||
"file_type": "flight_delay_boarding_or_ticket",
|
||
"file": "/bucket/path/boarding_pass.pdf"
|
||
},
|
||
{
|
||
"contact_id": "320096",
|
||
"project_id": "396868",
|
||
"ticket_id": "396936",
|
||
"filename": "delay_confirmation.pdf",
|
||
"file_type": "flight_delay_confirmation",
|
||
"file": "/bucket/path/delay_confirmation.pdf"
|
||
}
|
||
]'
|
||
```
|
||
|
||
**Ответ:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"total_processed": 2,
|
||
"successful": 2,
|
||
"failed": 0,
|
||
"results": [
|
||
{
|
||
"document_id": "15x396941",
|
||
"attached_to": "ticket",
|
||
"file_name": "boarding_pass.pdf",
|
||
"...": "..."
|
||
},
|
||
{
|
||
"document_id": "15x396942",
|
||
"attached_to": "ticket",
|
||
"file_name": "delay_confirmation.pdf",
|
||
"...": "..."
|
||
}
|
||
],
|
||
"errors": null
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3️⃣ Привязка к проекту (без ticket_id)
|
||
|
||
```bash
|
||
curl -X POST "https://crm.clientright.ru/api/n8n/documents/attach" \
|
||
-H "Content-Type: application/json" \
|
||
-d '[
|
||
{
|
||
"contact_id": "320096",
|
||
"project_id": "396874",
|
||
"filename": "policy_scan.pdf",
|
||
"file_type": "Скан полиса ERV",
|
||
"file": "https://s3.twcstorage.ru/bucket/path/policy.pdf"
|
||
}
|
||
]'
|
||
```
|
||
|
||
**Ответ:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"total_processed": 1,
|
||
"successful": 1,
|
||
"failed": 0,
|
||
"results": [
|
||
{
|
||
"document_id": "15x396940",
|
||
"attached_to": "project",
|
||
"attached_to_id": "396874",
|
||
"file_name": "policy_scan.pdf",
|
||
"...": "..."
|
||
}
|
||
],
|
||
"errors": null
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🗂️ Типы файлов (file_type)
|
||
|
||
Примеры значений для `file_type`:
|
||
|
||
| Тип | Описание |
|
||
|-----|----------|
|
||
| `flight_delay_boarding_or_ticket` | Посадочный талон / билет при задержке рейса |
|
||
| `flight_delay_confirmation` | Подтверждение задержки рейса |
|
||
| `flight_cancel_confirmation` | Подтверждение отмены рейса |
|
||
| `medical_receipt` | Медицинский чек |
|
||
| `medical_report` | Медицинское заключение |
|
||
| `luggage_delay_report` | Акт о задержке багажа |
|
||
| `passport_scan` | Скан паспорта |
|
||
| `policy_scan` | Скан страхового полиса |
|
||
| `other` | Прочие документы |
|
||
|
||
---
|
||
|
||
## 📊 Интеграция с n8n
|
||
|
||
### В workflow после загрузки файла в S3:
|
||
|
||
```javascript
|
||
// HTTP Request Node: POST /api/n8n/documents/attach
|
||
{
|
||
"contact_id": "{{ $json.contact_id }}",
|
||
"project_id": "{{ $json.project_id }}",
|
||
"ticket_id": "{{ $json.ticket_id }}", // Опционально
|
||
"file_url": "{{ $json.s3_url }}",
|
||
"file_name": "{{ $json.original_filename }}",
|
||
"file_type": "{{ $json.document_type }}"
|
||
}
|
||
```
|
||
|
||
### Ответ сохранить в Redis:
|
||
|
||
```javascript
|
||
// Добавить в session:
|
||
{
|
||
...session_data,
|
||
documents: [
|
||
...session_data.documents,
|
||
{
|
||
document_id: $json.result.document_id,
|
||
file_name: $json.result.file_name,
|
||
file_type: $json.result.file_type,
|
||
attached_to: $json.result.attached_to,
|
||
uploaded_at: new Date().toISOString()
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🔍 Логи
|
||
|
||
### Backend (FastAPI):
|
||
```bash
|
||
cd /var/www/fastuser/data/www/crm.clientright.ru/erv_platform
|
||
docker-compose logs -f backend | grep "Attaching document"
|
||
```
|
||
|
||
**Пример вывода:**
|
||
```
|
||
📎 Attaching document: boarding_pass.pdf (type: flight_delay_boarding_or_ticket)
|
||
Contact: 320096, Project: 396874, Ticket: 396935
|
||
📤 Sending to CRM: {...}
|
||
✅ Document attached successfully. Response: {...}
|
||
```
|
||
|
||
### CRM (PHP):
|
||
```bash
|
||
tail -f /var/www/fastuser/data/www/crm.clientright.ru/logs/upload_documents.log
|
||
```
|
||
|
||
**Пример вывода:**
|
||
```
|
||
[2025-11-02 16:30:15] 🚀 Начинаем создание документов...
|
||
[2025-11-02 16:30:15] 📄 Обрабатываем файл #0: boarding_pass.pdf
|
||
[2025-11-02 16:30:16] ✅ Документ создан: 15x396941 (numeric: 396941)
|
||
[2025-11-02 16:30:16] 📎 Привязываем к HelpDesk ticket_id: 396935
|
||
[2025-11-02 16:30:17] ✅ Документ привязан к HelpDesk #396935
|
||
```
|
||
|
||
---
|
||
|
||
## ⚠️ Обработка ошибок
|
||
|
||
### 400 Bad Request - Отсутствуют обязательные поля
|
||
```json
|
||
{
|
||
"detail": "Обязательные поля: contact_id, project_id, file_url, file_name"
|
||
}
|
||
```
|
||
|
||
### 500 Internal Server Error - Ошибка CRM
|
||
```json
|
||
{
|
||
"detail": "CRM error: Не найден Project ID 999999"
|
||
}
|
||
```
|
||
|
||
### 504 Gateway Timeout - Таймаут CRM
|
||
```json
|
||
{
|
||
"detail": "Таймаут загрузки в CRM"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## ✅ Готово к использованию!
|
||
|
||
Эндпоинт протестирован и готов к интеграции в n8n workflow! 🚀
|
||
|