From f82df1ebd79975ff03b07ae25cc060cf38a0ad8a Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Mon, 24 Nov 2025 17:44:30 +0300 Subject: [PATCH] fix: Add propertyName to caseJson for iframe form data Problem: - Form was empty because propertyName was not passed to iframe - JavaScript code checked for injected.propertyName but it was undefined - Only case (normalized) was passed, not the original propertyName Solution: - Added propertyName to caseJson object that gets embedded in HTML - Now JavaScript code can access both case and propertyName - This allows the form to properly display data from send_to_form_approve.draft Files: - frontend/src/components/form/generateConfirmationFormHTML.ts: Added propertyName to caseJson --- docs/CHECK_DUPLICATES.sql | 62 +++++++++++++ docs/DELETE_DUPLICATES_KEEP_SPECIFIC.sql | 86 +++++++++++++++++++ docs/SQL_SEND_TO_FORM_APPROVE_FIXED.sql | 1 + .../form/generateConfirmationFormHTML.ts | 2 + 4 files changed, 151 insertions(+) create mode 100644 docs/CHECK_DUPLICATES.sql create mode 100644 docs/DELETE_DUPLICATES_KEEP_SPECIFIC.sql diff --git a/docs/CHECK_DUPLICATES.sql b/docs/CHECK_DUPLICATES.sql new file mode 100644 index 0000000..f6931b3 --- /dev/null +++ b/docs/CHECK_DUPLICATES.sql @@ -0,0 +1,62 @@ +-- SQL запрос для проверки дубликатов claim_id в таблице clpr_claims +-- Показывает записи с одинаковым claim_id в payload, но разными ID + +-- 1. Найти все claim_id, которые встречаются более одного раза +WITH claim_id_counts AS ( + SELECT + payload->>'claim_id' AS claim_id, + COUNT(*) AS count, + array_agg(id ORDER BY updated_at DESC) AS ids, + array_agg(updated_at ORDER BY updated_at DESC) AS updated_dates + FROM clpr_claims + WHERE payload->>'claim_id' IS NOT NULL + GROUP BY payload->>'claim_id' + HAVING COUNT(*) > 1 +) +SELECT + claim_id, + count AS duplicate_count, + ids AS record_ids, + updated_dates, + -- Показываем разницу во времени между записями + updated_dates[1] - updated_dates[array_length(updated_dates, 1)] AS time_diff +FROM claim_id_counts +ORDER BY count DESC, claim_id +LIMIT 20; + +-- 2. Детальная информация о дубликатах (для конкретного claim_id) +-- Замените 'YOUR_CLAIM_ID' на реальный claim_id +/* +SELECT + id, + payload->>'claim_id' AS claim_id, + status_code, + channel, + created_at, + updated_at, + -- Показываем, есть ли send_to_form_approve в разных записях + CASE + WHEN payload->'send_to_form_approve' IS NOT NULL THEN 'YES' + ELSE 'NO' + END AS has_send_to_form_approve, + -- Показываем размер payload для сравнения + pg_column_size(payload) AS payload_size_bytes +FROM clpr_claims +WHERE payload->>'claim_id' = 'YOUR_CLAIM_ID' +ORDER BY updated_at DESC; +*/ + +-- 3. Статистика: сколько всего дубликатов +SELECT + COUNT(*) AS total_duplicate_claim_ids, + SUM(count) AS total_duplicate_records +FROM ( + SELECT + payload->>'claim_id' AS claim_id, + COUNT(*) AS count + FROM clpr_claims + WHERE payload->>'claim_id' IS NOT NULL + GROUP BY payload->>'claim_id' + HAVING COUNT(*) > 1 +) AS duplicates; + diff --git a/docs/DELETE_DUPLICATES_KEEP_SPECIFIC.sql b/docs/DELETE_DUPLICATES_KEEP_SPECIFIC.sql new file mode 100644 index 0000000..2e8148f --- /dev/null +++ b/docs/DELETE_DUPLICATES_KEEP_SPECIFIC.sql @@ -0,0 +1,86 @@ +-- SQL скрипт для удаления дубликатов claim_id +-- Оставляет только запись с id = '0eb051ec-23a6-4e06-8b98-f02d20d35f68' +-- Удаляет все остальные записи с таким же claim_id в payload + +-- ⚠️ ВНИМАНИЕ: Перед выполнением DELETE обязательно выполните SELECT ниже, +-- чтобы увидеть, что будет удалено! + +-- ============================================================================ +-- ШАГ 1: ПРОВЕРКА - Какие записи будут удалены? +-- ============================================================================ +-- Выполните этот запрос ПЕРВЫМ, чтобы увидеть, что будет удалено: + +SELECT + id, + payload->>'claim_id' AS claim_id, + status_code, + channel, + created_at, + updated_at, + CASE + WHEN id = '0eb051ec-23a6-4e06-8b98-f02d20d35f68'::uuid THEN '✅ ОСТАВИТЬ' + ELSE '❌ УДАЛИТЬ' + END AS action, + -- Показываем, есть ли send_to_form_approve + CASE + WHEN payload->'send_to_form_approve' IS NOT NULL THEN 'YES' + ELSE 'NO' + END AS has_send_to_form_approve, + -- Размер payload + pg_column_size(payload) AS payload_size_bytes +FROM clpr_claims +WHERE payload->>'claim_id' = '0eb051ec-23a6-4e06-8b98-f02d20d35f68' +ORDER BY updated_at DESC; + +-- ============================================================================ +-- ШАГ 2: УДАЛЕНИЕ - Удаляем все записи, кроме нужной +-- ============================================================================ +-- ⚠️ ВНИМАНИЕ: Этот запрос УДАЛИТ данные! Выполняйте только после проверки! + +-- Вариант 1: Удалить все записи с таким claim_id, кроме нужной +DELETE FROM clpr_claims +WHERE payload->>'claim_id' = '0eb051ec-23a6-4e06-8b98-f02d20d35f68' + AND id != '0eb051ec-23a6-4e06-8b98-f02d20d35f68'::uuid +RETURNING + id, + payload->>'claim_id' AS claim_id, + status_code, + created_at, + updated_at; + +-- ============================================================================ +-- ШАГ 3: ПРОВЕРКА - Убедиться, что осталась только одна запись +-- ============================================================================ +-- После удаления выполните этот запрос, чтобы проверить результат: + +SELECT + id, + payload->>'claim_id' AS claim_id, + status_code, + channel, + created_at, + updated_at, + CASE + WHEN payload->'send_to_form_approve' IS NOT NULL THEN 'YES' + ELSE 'NO' + END AS has_send_to_form_approve +FROM clpr_claims +WHERE payload->>'claim_id' = '0eb051ec-23a6-4e06-8b98-f02d20d35f68' +ORDER BY updated_at DESC; + +-- Должна остаться только одна запись с id = '0eb051ec-23a6-4e06-8b98-f02d20d35f68' + +-- ============================================================================ +-- АЛЬТЕРНАТИВНЫЙ ВАРИАНТ: Удалить по ID (если знаете конкретные ID дубликатов) +-- ============================================================================ +/* +-- Если вы знаете конкретные ID дубликатов, можно удалить их напрямую: +DELETE FROM clpr_claims +WHERE id IN ( + 'uuid-дубликата-1', + 'uuid-дубликата-2', + 'uuid-дубликата-3' +) +RETURNING id, payload->>'claim_id' AS claim_id; +*/ + diff --git a/docs/SQL_SEND_TO_FORM_APPROVE_FIXED.sql b/docs/SQL_SEND_TO_FORM_APPROVE_FIXED.sql index f4bc163..a27dca3 100644 --- a/docs/SQL_SEND_TO_FORM_APPROVE_FIXED.sql +++ b/docs/SQL_SEND_TO_FORM_APPROVE_FIXED.sql @@ -99,3 +99,4 @@ RETURNING ============================================================================ */ + diff --git a/frontend/src/components/form/generateConfirmationFormHTML.ts b/frontend/src/components/form/generateConfirmationFormHTML.ts index be1acf9..63a87a2 100644 --- a/frontend/src/components/form/generateConfirmationFormHTML.ts +++ b/frontend/src/components/form/generateConfirmationFormHTML.ts @@ -280,8 +280,10 @@ export function generateConfirmationFormHTML(data: any): string { }; // Безопасно встраиваем данные в HTML + // ✅ ВАЖНО: Передаем и case (нормализованный), и propertyName (оригинальный), чтобы JavaScript мог использовать оба формата let caseJson = JSON.stringify({ case: caseObj, + propertyName: data.propertyName || null, // ✅ Добавляем propertyName для JavaScript кода session_token: sessionToken, telegram_id: telegramId, token: data.token || '',