226 lines
9.5 KiB
Markdown
226 lines
9.5 KiB
Markdown
|
|
# Инструкция: Добавление узла `claimsave_primary` в workflow b4K4u851b4JFivyD
|
|||
|
|
|
|||
|
|
## Позиция узла
|
|||
|
|
|
|||
|
|
**Между узлами:**
|
|||
|
|
- **После:** `Code4` (форматирует данные для Redis)
|
|||
|
|
- **Перед:** `push_wizard1` (пушит wizard_plan в Redis для SSE)
|
|||
|
|
|
|||
|
|
## Порядок узлов в workflow
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
1. Redis Trigger
|
|||
|
|
2. get_claime_data1
|
|||
|
|
3. Edit Fields8
|
|||
|
|
4. Merge2
|
|||
|
|
5. Get row(s) in sheet2
|
|||
|
|
6. Edit Fields16
|
|||
|
|
7. AI Agent1
|
|||
|
|
8. пробрасываем факт фул и факт шорт1
|
|||
|
|
9. AI Agent13
|
|||
|
|
10. output_set1
|
|||
|
|
11. Edit Fields11
|
|||
|
|
12. AI Agent12
|
|||
|
|
13. Code
|
|||
|
|
14. Code4
|
|||
|
|
15. ⭐ Code: Prepare Claimsave Data ← ВСТАВИТЬ ЗДЕСЬ (Code Node)
|
|||
|
|
16. ⭐ claimsave_primary ← ВСТАВИТЬ ЗДЕСЬ (PostgreSQL)
|
|||
|
|
17. push_wizard1
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Шаги настройки
|
|||
|
|
|
|||
|
|
### 1. Добавить Code Node для подготовки данных
|
|||
|
|
|
|||
|
|
**Рекомендуется:** Добавить Code Node перед PostgreSQL для удобства отладки и валидации данных.
|
|||
|
|
|
|||
|
|
1. Откройте workflow `b4K4u851b4JFivyD` в n8n
|
|||
|
|
2. Найдите узел `Code4`
|
|||
|
|
3. Добавьте новый узел **Code** после `Code4`
|
|||
|
|
4. Назовите узел: `Code: Prepare Claimsave Data`
|
|||
|
|
5. Подключите:
|
|||
|
|
- **Вход:** от узла `Code4`
|
|||
|
|
- **Выход:** к узлу `claimsave_primary` (PostgreSQL)
|
|||
|
|
|
|||
|
|
**Код для Code Node:** См. файл `docs/CODE_CLAIMSAVE_PRIMARY_PREPARE.js`
|
|||
|
|
|
|||
|
|
**Режим выполнения:** `Run Once for All Items`
|
|||
|
|
|
|||
|
|
### 2. Добавить новый узел PostgreSQL
|
|||
|
|
|
|||
|
|
1. Откройте workflow `b4K4u851b4JFivyD` в n8n
|
|||
|
|
2. Найдите узел `Code4`
|
|||
|
|
3. Добавьте новый узел **PostgreSQL** после `Code4`
|
|||
|
|
4. Назовите узел: `claimsave_primary`
|
|||
|
|
5. Подключите:
|
|||
|
|
- **Вход:** от узла `Code4`
|
|||
|
|
- **Выход:** к узлу `push_wizard1`
|
|||
|
|
|
|||
|
|
### 2. Настройка PostgreSQL узла
|
|||
|
|
|
|||
|
|
**Connection:** Выберите подключение к PostgreSQL (то же, что используется в других узлах)
|
|||
|
|
|
|||
|
|
**Operation:** `Execute Query`
|
|||
|
|
|
|||
|
|
**Query:** Вставьте SQL из файла `docs/SQL_CLAIMSAVE_PRIMARY_DRAFT_CLEAN.sql` (чистая версия без плейсхолдеров)
|
|||
|
|
|
|||
|
|
**⚠️ ВАЖНО:** Используйте файл `SQL_CLAIMSAVE_PRIMARY_DRAFT_CLEAN.sql`, а не `SQL_CLAIMSAVE_PRIMARY_DRAFT.sql`!
|
|||
|
|
|
|||
|
|
### 3. Параметры запроса
|
|||
|
|
|
|||
|
|
**Query Replacement:** Оставьте пустым (не используем)
|
|||
|
|
|
|||
|
|
**Parameters:** Добавьте 3 параметра (если используете Code Node для подготовки):
|
|||
|
|
|
|||
|
|
#### Параметр $1 (payload_json):
|
|||
|
|
```javascript
|
|||
|
|
{{ JSON.stringify($('Code: Prepare Claimsave Data').first().json.payload_json) }}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Параметр $2 (session_token):
|
|||
|
|
```javascript
|
|||
|
|
{{ $('Code: Prepare Claimsave Data').first().json.session_token }}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Параметр $3 (unified_id):
|
|||
|
|
```javascript
|
|||
|
|
{{ $('Code: Prepare Claimsave Data').first().json.unified_id }}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Примечание:** Code Node берёт `unified_id` из ноды `propertyName` (приоритет: `propertyName` > `Edit Fields10` > `Redis Trigger`)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**Альтернатива (без Code Node):** Если не используете Code Node, можно собрать данные напрямую:
|
|||
|
|
|
|||
|
|
#### Параметр $1 (payload_json):
|
|||
|
|
```javascript
|
|||
|
|
{{ JSON.stringify({
|
|||
|
|
problem_description: $('Edit Fields16').first().json.chatInput,
|
|||
|
|
wizard_plan: $('Code4').first().json.redis_value.wizard_plan,
|
|||
|
|
answers_prefill: $('Code4').first().json.redis_value.answers_prefill || [],
|
|||
|
|
coverage_report: $('Code4').first().json.redis_value.coverage_report || {},
|
|||
|
|
ai_agent1_facts: {
|
|||
|
|
facts_short: $('пробрасываем факт фул и факт шорт1').first().json.facts_short,
|
|||
|
|
facts_full: $('пробрасываем факт фул и факт шорт1').first().json.facts_full,
|
|||
|
|
problem: $('пробрасываем факт фул и факт шорт1').first().json.problem
|
|||
|
|
},
|
|||
|
|
ai_agent13_rag: $('AI Agent13').first().json.output,
|
|||
|
|
phone: $('Redis Trigger').first().json.message.phone,
|
|||
|
|
email: $('Redis Trigger').first().json.message.email || null,
|
|||
|
|
type_code: $('Code4').first().json.redis_value.wizard_plan?.case_type || 'consumer'
|
|||
|
|
}) }}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Параметр $2 (session_token):
|
|||
|
|
```javascript
|
|||
|
|
{{ $('Edit Fields11').first().json.session_token || $('Redis Trigger').first().json.message.session_id }}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Параметр $3 (unified_id):
|
|||
|
|
```javascript
|
|||
|
|
{{ $('propertyName').first().json.unified_id || $('Edit Fields10').first().json.unified_id || $('Redis Trigger').first().json.message.unified_id || null }}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Примечание:** Приоритет источников `unified_id`: `propertyName` > `Edit Fields10` > `Redis Trigger`
|
|||
|
|
|
|||
|
|
### 4. Проверка подключений
|
|||
|
|
|
|||
|
|
Убедитесь, что:
|
|||
|
|
- ✅ Узел `Code: Prepare Claimsave Data` получает данные от `Code4`
|
|||
|
|
- ✅ Узел `claimsave_primary` получает данные от `Code: Prepare Claimsave Data`
|
|||
|
|
- ✅ Узел `push_wizard1` получает данные от `claimsave_primary` (или от `Code4`, если нужно)
|
|||
|
|
- ✅ Все пути данных корректны
|
|||
|
|
|
|||
|
|
## Преимущества использования Code Node
|
|||
|
|
|
|||
|
|
✅ **Упрощение параметров PostgreSQL:** Вместо сложных выражений в параметрах SQL, используем простые ссылки на Code Node
|
|||
|
|
|
|||
|
|
✅ **Валидация данных:** Code Node проверяет наличие обязательных полей и выводит предупреждения
|
|||
|
|
|
|||
|
|
✅ **Отладка:** Легче отслеживать, какие данные собраны, через логи Code Node
|
|||
|
|
|
|||
|
|
✅ **Обработка edge cases:** Можно добавить fallback значения и обработку ошибок
|
|||
|
|
|
|||
|
|
✅ **Читаемость:** Код подготовки данных отделён от SQL запроса
|
|||
|
|
|
|||
|
|
## Что сохраняется
|
|||
|
|
|
|||
|
|
После выполнения узла `claimsave_primary` в БД будет создана/обновлена запись в `clpr_claims`:
|
|||
|
|
|
|||
|
|
- ✅ `session_token` - для связи
|
|||
|
|
- ✅ `unified_id` - если передан
|
|||
|
|
- ✅ `status_code = 'draft'` - статус черновика
|
|||
|
|
- ✅ `payload.wizard_plan` - план вопросов
|
|||
|
|
- ✅ `payload.problem_description` - описание проблемы
|
|||
|
|
- ✅ `payload.answers_prefill` - предзаполненные ответы
|
|||
|
|
- ✅ `payload.coverage_report` - отчёт о покрытии
|
|||
|
|
- ✅ `payload.ai_agent1_facts` - факты из AI Agent1
|
|||
|
|
- ✅ `payload.ai_agent13_rag` - RAG ответ
|
|||
|
|
- ✅ `payload.phone`, `payload.email` - контакты
|
|||
|
|
- ⚠️ `payload.claim_id = NULL` - будет сгенерирован позже
|
|||
|
|
|
|||
|
|
## Возвращаемое значение
|
|||
|
|
|
|||
|
|
Узел возвращает объект:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"claim": {
|
|||
|
|
"claim_id": "uuid-записи",
|
|||
|
|
"session_token": "sess-...",
|
|||
|
|
"status_code": "draft",
|
|||
|
|
"payload": { ... }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Важные замечания
|
|||
|
|
|
|||
|
|
1. **Узел работает в режиме UPSERT:**
|
|||
|
|
- Если запись с таким `session_token` существует → обновляет её
|
|||
|
|
- Если записи нет → создаёт новую
|
|||
|
|
|
|||
|
|
2. **`claim_id` генерируется позже:**
|
|||
|
|
- На этом этапе `claim_id` в `payload` = `NULL`
|
|||
|
|
- UUID записи (`clpr_claims.id`) используется как временный идентификатор
|
|||
|
|
- Позже `claim_id` будет сгенерирован в формате `CLM-YYYY-MM-DD-XXXXXX`
|
|||
|
|
|
|||
|
|
3. **Данные из предыдущих узлов:**
|
|||
|
|
- `wizard_plan` берётся из `Code4.redis_value.wizard_plan`
|
|||
|
|
- `problem_description` берётся из `Edit Fields16.chatInput`
|
|||
|
|
- `ai_agent1_facts` берётся из узла `пробрасываем факт фул и факт шорт1`
|
|||
|
|
- `ai_agent13_rag` берётся из `AI Agent13.output`
|
|||
|
|
|
|||
|
|
## Тестирование
|
|||
|
|
|
|||
|
|
После добавления узла:
|
|||
|
|
|
|||
|
|
1. Запустите workflow с тестовыми данными
|
|||
|
|
2. Проверьте, что узел выполняется без ошибок
|
|||
|
|
3. Проверьте в БД, что запись создана/обновлена:
|
|||
|
|
```sql
|
|||
|
|
SELECT id, session_token, unified_id, status_code, payload->>'wizard_plan'
|
|||
|
|
FROM clpr_claims
|
|||
|
|
WHERE session_token = 'sess-...'
|
|||
|
|
ORDER BY updated_at DESC
|
|||
|
|
LIMIT 1;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Если что-то не работает
|
|||
|
|
|
|||
|
|
1. **Ошибка "column does not exist":**
|
|||
|
|
- Проверьте, что все поля в SQL запросе существуют в таблице `clpr_claims`
|
|||
|
|
|
|||
|
|
2. **Ошибка "invalid input syntax for type jsonb":**
|
|||
|
|
- Проверьте, что параметр `$1` правильно сериализован через `JSON.stringify()`
|
|||
|
|
- Убедитесь, что все вложенные объекты корректны
|
|||
|
|
|
|||
|
|
3. **Ошибка "session_token is null":**
|
|||
|
|
- Проверьте, что `Edit Fields11` содержит `session_token`
|
|||
|
|
- Проверьте fallback на `Redis Trigger.message.session_id`
|
|||
|
|
|
|||
|
|
4. **Данные не сохраняются:**
|
|||
|
|
- Проверьте логи n8n на наличие ошибок
|
|||
|
|
- Проверьте, что все узлы-источники данных выполнены успешно
|
|||
|
|
|