From 40ad46c0263450177f87a9d66de3d2424e8df580 Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Fri, 21 Nov 2025 16:10:57 +0300 Subject: [PATCH] fix: Parse wizard_plan from edit_fields_parsed structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: - wizard_plan comes in nested structure: edit_fields_parsed.wizard_plan_parsed - Old SQL looked for wizard_plan at root level (partial.p->'wizard_plan') - Result: wizard_plan was always NULL even though it existed in payload Solution: - Updated wizard_plan_parsed CTE to check multiple locations: 1. edit_fields_parsed.wizard_plan_parsed (already parsed object) ✅ 2. edit_fields_raw.body.wizard_plan (escaped JSON string) 3. Root level wizard_plan (backward compatibility) 4. Database fallback (if not in payload) - Updated wizard_answers_parsed CTE: 1. edit_fields_raw.body.wizard_answers (string) ✅ 2. edit_fields_parsed.body.wizard_answers (string) 3. Root level (backward compatibility) - Updated session_id, unified_id, contact_id, phone extraction: COALESCE() checks edit_fields_parsed.body and edit_fields_raw.body Input structure from n8n workflow form_get: { "payload_partial_json": { "edit_fields_parsed": { "wizard_plan_parsed": {...}, ← TARGET "body": { "session_id": "sess_xxx", ← ALSO HERE "unified_id": "usr_xxx", "wizard_answers": "{...}" } } } } Now: wizard_plan preserves correctly when uploading files ✅ --- docs/SQL_CLAIMSAVE_UPSERT_SIMPLE.sql | 43 ++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/docs/SQL_CLAIMSAVE_UPSERT_SIMPLE.sql b/docs/SQL_CLAIMSAVE_UPSERT_SIMPLE.sql index 74022ca..6292b7e 100644 --- a/docs/SQL_CLAIMSAVE_UPSERT_SIMPLE.sql +++ b/docs/SQL_CLAIMSAVE_UPSERT_SIMPLE.sql @@ -28,8 +28,16 @@ existing_claim AS ( wizard_answers_parsed AS ( SELECT CASE + -- Из edit_fields_raw.body.wizard_answers (строка) + WHEN partial.p->'edit_fields_raw'->'body'->>'wizard_answers' IS NOT NULL + THEN (partial.p->'edit_fields_raw'->'body'->>'wizard_answers')::jsonb + -- Из edit_fields_parsed.body.wizard_answers (строка) + WHEN partial.p->'edit_fields_parsed'->'body'->>'wizard_answers' IS NOT NULL + THEN (partial.p->'edit_fields_parsed'->'body'->>'wizard_answers')::jsonb + -- Из корня как строка WHEN partial.p->>'wizard_answers' IS NOT NULL THEN (partial.p->>'wizard_answers')::jsonb + -- Из корня как объект WHEN partial.p->'wizard_answers' IS NOT NULL AND jsonb_typeof(partial.p->'wizard_answers') = 'object' THEN partial.p->'wizard_answers' @@ -42,12 +50,20 @@ wizard_answers_parsed AS ( wizard_plan_parsed AS ( SELECT CASE - -- Сначала пытаемся взять из входящих данных + -- Сначала пытаемся взять из edit_fields_parsed.wizard_plan_parsed (уже объект) + WHEN partial.p->'edit_fields_parsed'->'wizard_plan_parsed' IS NOT NULL + AND jsonb_typeof(partial.p->'edit_fields_parsed'->'wizard_plan_parsed') = 'object' + THEN partial.p->'edit_fields_parsed'->'wizard_plan_parsed' + -- Или из корня как строка WHEN partial.p->>'wizard_plan' IS NOT NULL THEN (partial.p->>'wizard_plan')::jsonb + -- Или из корня как объект WHEN partial.p->'wizard_plan' IS NOT NULL AND jsonb_typeof(partial.p->'wizard_plan') = 'object' THEN partial.p->'wizard_plan' + -- Или из edit_fields_raw.body.wizard_plan (строка) + WHEN partial.p->'edit_fields_raw'->'body'->>'wizard_plan' IS NOT NULL + THEN (partial.p->'edit_fields_raw'->'body'->>'wizard_plan')::jsonb -- Если нет в payload - берём из существующей записи в БД WHEN EXISTS (SELECT 1 FROM existing_claim WHERE payload->'wizard_plan' IS NOT NULL) THEN (SELECT payload->'wizard_plan' FROM existing_claim) @@ -144,10 +160,27 @@ claim_upsert AS ( ) SELECT partial.claim_id_str::uuid, - COALESCE(partial.p->>'session_id', 'sess-unknown'), - partial.p->>'unified_id', - partial.p->>'contact_id', - partial.p->>'phone', + COALESCE( + partial.p->>'session_id', + partial.p->'edit_fields_parsed'->'body'->>'session_id', + partial.p->'edit_fields_raw'->'body'->>'session_id', + 'sess-unknown' + ), + COALESCE( + partial.p->>'unified_id', + partial.p->'edit_fields_parsed'->'body'->>'unified_id', + partial.p->'edit_fields_raw'->'body'->>'unified_id' + ), + COALESCE( + partial.p->>'contact_id', + partial.p->'edit_fields_parsed'->'body'->>'contact_id', + partial.p->'edit_fields_raw'->'body'->>'contact_id' + ), + COALESCE( + partial.p->>'phone', + partial.p->'edit_fields_parsed'->'body'->>'phone', + partial.p->'edit_fields_raw'->'body'->>'phone' + ), 'web_form', COALESCE(partial.p->>'type_code', 'consumer'), CASE