fix: Parse wizard_plan from edit_fields_parsed structure

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 
This commit is contained in:
AI Assistant
2025-11-21 16:10:57 +03:00
parent 60a67c7e37
commit 40ad46c026

View File

@@ -28,8 +28,16 @@ existing_claim AS (
wizard_answers_parsed AS ( wizard_answers_parsed AS (
SELECT SELECT
CASE 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 WHEN partial.p->>'wizard_answers' IS NOT NULL
THEN (partial.p->>'wizard_answers')::jsonb THEN (partial.p->>'wizard_answers')::jsonb
-- Из корня как объект
WHEN partial.p->'wizard_answers' IS NOT NULL WHEN partial.p->'wizard_answers' IS NOT NULL
AND jsonb_typeof(partial.p->'wizard_answers') = 'object' AND jsonb_typeof(partial.p->'wizard_answers') = 'object'
THEN partial.p->'wizard_answers' THEN partial.p->'wizard_answers'
@@ -42,12 +50,20 @@ wizard_answers_parsed AS (
wizard_plan_parsed AS ( wizard_plan_parsed AS (
SELECT SELECT
CASE 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 WHEN partial.p->>'wizard_plan' IS NOT NULL
THEN (partial.p->>'wizard_plan')::jsonb THEN (partial.p->>'wizard_plan')::jsonb
-- Или из корня как объект
WHEN partial.p->'wizard_plan' IS NOT NULL WHEN partial.p->'wizard_plan' IS NOT NULL
AND jsonb_typeof(partial.p->'wizard_plan') = 'object' AND jsonb_typeof(partial.p->'wizard_plan') = 'object'
THEN partial.p->'wizard_plan' 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 - берём из существующей записи в БД -- Если нет в payload - берём из существующей записи в БД
WHEN EXISTS (SELECT 1 FROM existing_claim WHERE payload->'wizard_plan' IS NOT NULL) WHEN EXISTS (SELECT 1 FROM existing_claim WHERE payload->'wizard_plan' IS NOT NULL)
THEN (SELECT payload->'wizard_plan' FROM existing_claim) THEN (SELECT payload->'wizard_plan' FROM existing_claim)
@@ -144,10 +160,27 @@ claim_upsert AS (
) )
SELECT SELECT
partial.claim_id_str::uuid, partial.claim_id_str::uuid,
COALESCE(partial.p->>'session_id', 'sess-unknown'), COALESCE(
partial.p->>'unified_id', partial.p->>'session_id',
partial.p->>'contact_id', partial.p->'edit_fields_parsed'->'body'->>'session_id',
partial.p->>'phone', 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', 'web_form',
COALESCE(partial.p->>'type_code', 'consumer'), COALESCE(partial.p->>'type_code', 'consumer'),
CASE CASE