# Инструкция: Добавление узла `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 на наличие ошибок - Проверьте, что все узлы-источники данных выполнены успешно