fix: Prevent duplicate claims by searching both by ID and payload claim_id
Problem: - Multiple records created with same claim_id but different IDs - Example: ID=0eb051ec... (correct) vs ID=b532b1b3... (duplicate) - Different SQL queries used different approaches: * Some used claim_id as UUID for ID (partial.claim_id_str::uuid) * Others searched by payload->>'claim_id' and created new UUID if not found Root Cause: - SQL_CLAIMSAVE_UPSERT_SIMPLE.sql only searched by ID: WHERE id = claim_id_str::uuid - If record existed with different ID but same claim_id in payload, it wasn't found and new record was created Solution: 1. existing_claim now searches both by ID and payload->>'claim_id': WHERE id = claim_id_str::uuid OR payload->>'claim_id' = claim_id_str ORDER BY priority (ID match first), then updated_at DESC 2. INSERT uses ID from existing_claim if found: COALESCE((SELECT id FROM existing_claim), partial.claim_id_str::uuid) 3. This ensures same record is always used, preventing duplicates Files: - docs/SQL_CLAIMSAVE_UPSERT_SIMPLE.sql: Fixed search logic and INSERT ID
This commit is contained in:
@@ -15,12 +15,17 @@ WITH partial AS (
|
||||
),
|
||||
|
||||
-- Получаем существующий payload из БД (если запись есть)
|
||||
-- ✅ ИСПРАВЛЕНО: Ищем и по ID, и по payload->>'claim_id', чтобы избежать дубликатов
|
||||
existing_claim AS (
|
||||
SELECT
|
||||
id,
|
||||
payload
|
||||
FROM clpr_claims
|
||||
WHERE id = (SELECT claim_id_str::uuid FROM partial)
|
||||
OR payload->>'claim_id' = (SELECT claim_id_str FROM partial)
|
||||
ORDER BY
|
||||
CASE WHEN id = (SELECT claim_id_str::uuid FROM partial) THEN 1 ELSE 2 END,
|
||||
updated_at DESC
|
||||
LIMIT 1
|
||||
),
|
||||
|
||||
@@ -143,6 +148,7 @@ problem_description_parsed AS (
|
||||
),
|
||||
|
||||
-- UPSERT claim
|
||||
-- ✅ ИСПРАВЛЕНО: Используем ID из existing_claim, если он найден, чтобы избежать дубликатов
|
||||
claim_upsert AS (
|
||||
INSERT INTO clpr_claims (
|
||||
id,
|
||||
@@ -159,7 +165,10 @@ claim_upsert AS (
|
||||
expires_at
|
||||
)
|
||||
SELECT
|
||||
partial.claim_id_str::uuid,
|
||||
COALESCE(
|
||||
(SELECT id FROM existing_claim),
|
||||
partial.claim_id_str::uuid
|
||||
),
|
||||
COALESCE(
|
||||
partial.p->>'session_id',
|
||||
partial.p->'edit_fields_parsed'->'body'->>'session_id',
|
||||
@@ -202,7 +211,7 @@ claim_upsert AS (
|
||||
'email', COALESCE(partial.p->>'email', (SELECT payload->>'email' FROM existing_claim))
|
||||
),
|
||||
COALESCE(
|
||||
(SELECT created_at FROM clpr_claims WHERE id = partial.claim_id_str::uuid),
|
||||
(SELECT created_at FROM existing_claim),
|
||||
now()
|
||||
),
|
||||
now(),
|
||||
@@ -289,6 +298,22 @@ SELECT
|
||||
3. Это критично для workflow form_get, где wizard_plan создаётся на Step 2,
|
||||
а файлы загружаются на Step 3 (без повторной отправки wizard_plan)
|
||||
|
||||
============================================================================
|
||||
ИСПРАВЛЕНИЕ ДУБЛИКАТОВ (2025-11-24):
|
||||
============================================================================
|
||||
|
||||
ПРОБЛЕМА: Создавались дубликаты записей с одинаковым claim_id, но разными ID
|
||||
Причина: Разные SQL запросы использовали разные подходы:
|
||||
- Одни использовали claim_id как UUID для ID (partial.claim_id_str::uuid)
|
||||
- Другие искали по payload->>'claim_id' и создавали новый UUID, если не находили
|
||||
|
||||
РЕШЕНИЕ:
|
||||
1. existing_claim теперь ищет и по ID, и по payload->>'claim_id':
|
||||
WHERE id = claim_id_str::uuid OR payload->>'claim_id' = claim_id_str
|
||||
2. INSERT использует ID из existing_claim, если он найден:
|
||||
COALESCE((SELECT id FROM existing_claim), partial.claim_id_str::uuid)
|
||||
3. Это гарантирует, что всегда используется одна и та же запись
|
||||
|
||||
============================================================================
|
||||
ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:
|
||||
============================================================================
|
||||
|
||||
Reference in New Issue
Block a user