Database changes: - Add unified_id, contact_id, phone columns to clpr_claims table - Create indexes for fast lookup by these fields - Migrate existing data from payload to new columns - SQL migration: docs/SQL_ALTER_CLPR_CLAIMS_ADD_FIELDS.sql SQL improvements: - Simplify claimsave query: remove complex claim_lookup logic - Use UPSERT (INSERT ON CONFLICT) with known claim_id - Always return claim (fix NULL issue) - Store unified_id, contact_id, phone directly in table columns - SQL: docs/SQL_CLAIMSAVE_UPSERT_SIMPLE.sql Workflow enhancements: - Add branch for form submissions WITHOUT files - Create 6 new nodes: extract, prepare, save, redis, respond - Separate flow for has_files=false in IF node - Instructions: docs/N8N_FORM_GET_NO_FILES_INSTRUCTIONS.md - Node config: docs/N8N_FORM_GET_NO_FILES_BRANCH.json Migration stats: - Total claims: 81 - With unified_id: 77 - Migrated from payload: 2 Next steps: 1. Add 6 nodes to n8n workflow form_get (ID: 8ZVMTsuH7Cmw7snw) 2. Connect TRUE branch of IF node to extract_webhook_data_no_files 3. Test form submission without files 4. Verify PostgreSQL save and Redis event
105 lines
3.1 KiB
Markdown
105 lines
3.1 KiB
Markdown
# Исправление ошибки в Code1: mapDialogHistory
|
||
|
||
## Проблема
|
||
|
||
**Ошибка:**
|
||
```
|
||
Cannot read properties of null (reading 'map') [line 69]
|
||
```
|
||
|
||
**Причина:**
|
||
Функция `mapDialogHistory` получает `null` вместо массива, когда `src.dialog_history` равен `null`.
|
||
|
||
## Исправление
|
||
|
||
### Текущий код (строка 69):
|
||
|
||
```javascript
|
||
function mapDialogHistory(h = []) {
|
||
return h.map(m => ({
|
||
id: toNullish(m.id),
|
||
role: toNullish(m.role),
|
||
message: toNullish(m.message),
|
||
message_type: toNullish(m.message_type),
|
||
tg_message_id: toNullish(m.tg_message_id),
|
||
created_at: toNullish(m.created_at),
|
||
}));
|
||
}
|
||
```
|
||
|
||
### Исправленный код:
|
||
|
||
```javascript
|
||
function mapDialogHistory(h = []) {
|
||
// Проверяем, что h не null и является массивом
|
||
if (!h || !Array.isArray(h)) return [];
|
||
return h.map(m => ({
|
||
id: toNullish(m.id),
|
||
role: toNullish(m.role),
|
||
message: toNullish(m.message),
|
||
message_type: toNullish(m.message_type),
|
||
tg_message_id: toNullish(m.tg_message_id),
|
||
created_at: toNullish(m.created_at),
|
||
}));
|
||
}
|
||
```
|
||
|
||
## Альтернативное решение
|
||
|
||
Можно также исправить в месте вызова:
|
||
|
||
```javascript
|
||
// В функции normalizeOne, строка ~172
|
||
dialog_history: mapDialogHistory(src.dialog_history || []),
|
||
```
|
||
|
||
Но лучше исправить саму функцию, чтобы она была более устойчивой.
|
||
|
||
## Полный исправленный код функции mapDialogHistory
|
||
|
||
```javascript
|
||
function mapDialogHistory(h = []) {
|
||
// Проверяем, что h не null и является массивом
|
||
if (!h || !Array.isArray(h)) return [];
|
||
return h.map(m => ({
|
||
id: toNullish(m.id),
|
||
role: toNullish(m.role),
|
||
message: toNullish(m.message),
|
||
message_type: toNullish(m.message_type),
|
||
tg_message_id: toNullish(m.tg_message_id),
|
||
created_at: toNullish(m.created_at),
|
||
}));
|
||
}
|
||
```
|
||
|
||
## Почему это происходит
|
||
|
||
Когда SQL запрос в ноде `give_data1` возвращает `null` для `dialog_history` (если нет записей в `clpr_dialog_history_tg`), функция `mapDialogHistory` получает `null` вместо массива.
|
||
|
||
PostgreSQL `jsonb_agg` возвращает `null`, если нет строк для агрегации, а не пустой массив `[]`.
|
||
|
||
## Дополнительные проверки
|
||
|
||
Можно также добавить проверки для других функций, которые работают с массивами:
|
||
|
||
```javascript
|
||
function mapDocuments(docs = []) {
|
||
if (!docs || !Array.isArray(docs)) return [];
|
||
return docs.map(d => ({...}));
|
||
}
|
||
|
||
function mapVisionDocs(vds = []) {
|
||
if (!vds || !Array.isArray(vds)) return [];
|
||
return vds.map(v => ({...}));
|
||
}
|
||
|
||
function mapCombinedDocs(cds = []) {
|
||
if (!cds || !Array.isArray(cds)) return [];
|
||
return cds.map(c => ({...}));
|
||
}
|
||
```
|
||
|
||
Но для `mapDialogHistory` это критично, т.к. она вызывается первой и падает.
|
||
|
||
|