-- ============================================================================ -- SQL запрос для n8n: Сохранение первичного черновика заявки (ЧИСТАЯ ВЕРСИЯ) -- ============================================================================ -- Назначение: Сохранить первичный черновик сразу после генерации wizard_plan -- Использует session_token для связи (claim_id генерируется позже) -- -- Параметры: -- $1 = payload_json (jsonb) - полный payload с wizard_plan, problem_description, -- AI Agent1, AI Agent13 и т.д. -- $2 = session_token (text) - сессия пользователя -- $3 = unified_id (text, опционально) - unified_id пользователя -- -- Возвращает: -- claim - объект с claim_id (UUID), session_token, status_code, payload -- ============================================================================ WITH partial AS ( SELECT $1::jsonb AS p, $2::text AS session_token_str, NULLIF($3::text, '') AS unified_id_str ), claim_lookup AS ( SELECT COALESCE( (SELECT id FROM clpr_claims WHERE session_token = partial.session_token_str LIMIT 1), gen_random_uuid() ) AS claim_uuid FROM partial ), claim_created AS ( INSERT INTO clpr_claims ( id, session_token, unified_id, channel, type_code, status_code, payload, created_at, updated_at, expires_at ) SELECT claim_lookup.claim_uuid, partial.session_token_str, partial.unified_id_str, 'web_form', COALESCE(partial.p->>'type_code', 'consumer'), 'draft', jsonb_build_object( 'claim_id', NULL, 'problem_description', partial.p->>'problem_description', 'wizard_plan', CASE 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' ELSE NULL END, 'answers_prefill', CASE WHEN partial.p->>'answers_prefill' IS NOT NULL THEN (partial.p->>'answers_prefill')::jsonb WHEN partial.p->'answers_prefill' IS NOT NULL AND jsonb_typeof(partial.p->'answers_prefill') = 'array' THEN partial.p->'answers_prefill' ELSE '[]'::jsonb END, 'coverage_report', CASE WHEN partial.p->>'coverage_report' IS NOT NULL THEN (partial.p->>'coverage_report')::jsonb WHEN partial.p->'coverage_report' IS NOT NULL AND jsonb_typeof(partial.p->'coverage_report') = 'object' THEN partial.p->'coverage_report' ELSE NULL END, 'ai_agent1_facts', CASE WHEN partial.p->'ai_agent1_facts' IS NOT NULL AND jsonb_typeof(partial.p->'ai_agent1_facts') = 'object' THEN partial.p->'ai_agent1_facts' ELSE NULL END, 'ai_agent13_rag', CASE WHEN partial.p->'ai_agent13_rag' IS NOT NULL AND jsonb_typeof(partial.p->'ai_agent13_rag') = 'object' THEN partial.p->'ai_agent13_rag' WHEN partial.p->>'ai_agent13_rag' IS NOT NULL THEN to_jsonb(partial.p->>'ai_agent13_rag') ELSE NULL END, 'phone', partial.p->>'phone', 'email', partial.p->>'email' ), now(), now(), now() + interval '14 days' FROM partial, claim_lookup WHERE NOT EXISTS ( SELECT 1 FROM clpr_claims WHERE id = claim_lookup.claim_uuid ) ON CONFLICT (id) DO NOTHING RETURNING id, status_code, payload ), claim_final AS ( SELECT CASE WHEN EXISTS (SELECT 1 FROM claim_created) THEN (SELECT id FROM claim_created LIMIT 1) ELSE claim_lookup.claim_uuid END AS claim_uuid FROM claim_lookup ), upd AS ( UPDATE clpr_claims c SET unified_id = COALESCE(partial.unified_id_str, c.unified_id), payload = jsonb_set( jsonb_set( jsonb_set( jsonb_set( jsonb_set( COALESCE(c.payload, '{}'::jsonb), '{wizard_plan}', COALESCE( CASE 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' ELSE NULL END, c.payload->'wizard_plan' ), true ), '{ai_agent1_facts}', COALESCE( CASE WHEN partial.p->'ai_agent1_facts' IS NOT NULL AND jsonb_typeof(partial.p->'ai_agent1_facts') = 'object' THEN partial.p->'ai_agent1_facts' ELSE NULL END, c.payload->'ai_agent1_facts' ), true ), '{ai_agent13_rag}', COALESCE( CASE WHEN partial.p->'ai_agent13_rag' IS NOT NULL AND jsonb_typeof(partial.p->'ai_agent13_rag') = 'object' THEN partial.p->'ai_agent13_rag' WHEN partial.p->>'ai_agent13_rag' IS NOT NULL THEN to_jsonb(partial.p->>'ai_agent13_rag') ELSE NULL END, c.payload->'ai_agent13_rag' ), true ), '{problem_description}', to_jsonb(COALESCE(partial.p->>'problem_description', c.payload->>'problem_description')), true ), '{answers_prefill}', COALESCE( CASE WHEN partial.p->>'answers_prefill' IS NOT NULL THEN (partial.p->>'answers_prefill')::jsonb WHEN partial.p->'answers_prefill' IS NOT NULL AND jsonb_typeof(partial.p->'answers_prefill') = 'array' THEN partial.p->'answers_prefill' ELSE '[]'::jsonb END, c.payload->'answers_prefill', '[]'::jsonb ), true ), updated_at = now(), expires_at = now() + interval '14 days' FROM partial, claim_final WHERE c.id = claim_final.claim_uuid AND EXISTS (SELECT 1 FROM claim_lookup WHERE claim_uuid = c.id) RETURNING c.id, c.status_code, c.payload ) SELECT jsonb_build_object( 'claim_id', COALESCE( (SELECT id::text FROM upd LIMIT 1), (SELECT claim_uuid::text FROM claim_final LIMIT 1), (SELECT id::text FROM claim_created LIMIT 1) ), 'session_token', (SELECT session_token_str FROM partial LIMIT 1), 'status_code', COALESCE( (SELECT status_code FROM upd LIMIT 1), (SELECT status_code FROM claim_created LIMIT 1), 'draft' ), 'payload', COALESCE( (SELECT payload FROM upd LIMIT 1), (SELECT payload FROM claim_created LIMIT 1), jsonb_build_object() ) ) AS claim;