fix: Add claim_lookup CTE to send_to_form_approve SQL query

Problem:
- Query only searched by ID: WHERE id = claim_id::uuid
- If record exists with different ID but same claim_id in payload,
  it wasn't found and send_to_form_approve wasn't saved

Solution:
- Added claim_lookup CTE that searches both by ID and payload->>'claim_id':
  WHERE c.id = claim_id::uuid OR c.payload->>'claim_id' = claim_id::text
- base now uses claim_lookup instead of direct query
- UPDATE uses claim_lookup.id instead of direct claim_id::uuid
- This ensures correct record is always used

Changes:
- Added claim_lookup CTE for record lookup
- base reads from claim_lookup instead of direct query
- UPDATE uses claim_lookup.id instead of claim_id::uuid

Files:
- docs/SQL_SEND_TO_FORM_APPROVE_FIXED.sql: Fixed version with claim_lookup
This commit is contained in:
AI Assistant
2025-11-24 17:07:52 +03:00
parent d08e0da1ad
commit f26e0ba48e

View File

@@ -0,0 +1,101 @@
-- Исправленный SQL для сохранения send_to_form_approve
-- ✅ ИСПРАВЛЕНО: Ищем запись и по ID, и по payload->>'claim_id', чтобы избежать дубликатов
-- Используется в n8n workflow для сохранения данных формы подтверждения
-- Параметры:
-- $json.meta.claim_id - UUID заявки (может быть как ID записи, так и claim_id из payload)
-- $json - полные данные для сохранения в send_to_form_approve.draft
WITH
-- ✅ ИСПРАВЛЕНО: Ищем запись и по ID, и по payload->>'claim_id'
claim_lookup AS (
SELECT
c.id,
c.payload
FROM {{ $('set').first()?.json?.prefix ?? '' }}claims c
WHERE c.id = '{{ $json.meta.claim_id }}'::uuid
OR c.payload->>'claim_id' = '{{ $json.meta.claim_id }}'::text
ORDER BY
CASE WHEN c.id = '{{ $json.meta.claim_id }}'::uuid THEN 1 ELSE 2 END,
c.updated_at DESC
LIMIT 1
),
base AS (
SELECT coalesce(c.payload, '{}'::jsonb) AS p
FROM claim_lookup c
),
entry AS (
SELECT jsonb_build_object(
'id', gen_random_uuid(),
'draft', '{{ JSON.stringify($json) }}'::jsonb,
'status', 'pending',
'created_at', to_jsonb(now()),
'created_by', 'miniapp'
) AS e
),
upd AS (
SELECT
jsonb_set(
jsonb_set(
p,
'{send_to_form_approve_history}',
coalesce((p->'send_to_form_approve_history')::jsonb, '[]'::jsonb) || e,
true
),
'{send_to_form_approve}',
e,
true
) AS new_payload
FROM base b CROSS JOIN entry
)
UPDATE {{ $('set').first()?.json?.prefix ?? '' }}claims c
SET payload = u.new_payload,
updated_at = now()
FROM upd u, claim_lookup cl
WHERE c.id = cl.id
RETURNING
c.id,
c.payload->'send_to_form_approve' AS send_to_form_approve,
jsonb_array_length(c.payload->'send_to_form_approve_history') AS history_length;
/*
============================================================================
ИСПРАВЛЕНИЯ (2025-11-24):
============================================================================
ПРОБЛЕМА: Запрос искал запись только по ID:
WHERE id = '{{ $json.meta.claim_id }}'::uuid
Если запись была создана с другим ID, но с тем же claim_id в payload,
она не находилась и send_to_form_approve не сохранялся.
РЕШЕНИЕ:
1. Добавлен CTE claim_lookup - ищет запись и по ID, и по payload->>'claim_id':
WHERE c.id = claim_id::uuid OR c.payload->>'claim_id' = claim_id::text
2. base теперь использует claim_lookup вместо прямого запроса
3. UPDATE использует claim_lookup.id вместо прямого claim_id::uuid
4. Это гарантирует, что всегда используется правильная запись
ИЗМЕНЕНИЯ:
- Добавлен claim_lookup CTE для поиска записи
- base теперь читает из claim_lookup вместо прямого запроса
- UPDATE использует claim_lookup.id вместо claim_id::uuid
============================================================================
ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:
============================================================================
1. С claim_id как UUID (ID записи):
$json.meta.claim_id = '0eb051ec-23a6-4e06-8b98-f02d20d35f68'
→ Найдет запись по ID
2. С claim_id как UUID из payload:
$json.meta.claim_id = '0eb051ec-23a6-4e06-8b98-f02d20d35f68'
→ Если ID не совпадает, найдет по payload->>'claim_id'
============================================================================
*/