-- ============================================================================ -- Упрощённый SQL запрос для обновления upload_description -- ============================================================================ -- Параметры: -- $1 :: uuid -- claim_document_id (ID документа из таблицы clpr_claim_documents) -- $2 :: text -- upload_description (новое описание документа) -- ============================================================================ -- Этот запрос обновляет описание в payload.body['uploads_descriptions[i]'] -- Это самый приоритетный способ хранения, который проверяется первым при чтении -- ============================================================================ WITH -- Находим документ и извлекаем нужные данные doc_info AS ( SELECT cd.id AS claim_document_id, cd.claim_id::text AS claim_id_text, cd.field_name, -- Извлекаем индекс i из field_name (например, uploads[0][0] -> 0) NULLIF((regexp_match(cd.field_name, 'uploads\[(\d+)\]'))[1], '')::int AS upload_index, c.id AS claim_uuid, c.payload FROM clpr_claim_documents cd JOIN clpr_claims c ON c.id::text = cd.claim_id::text WHERE cd.id = $1 LIMIT 1 ), -- Обновляем payload: обновляем описание в body (самый приоритетный и надёжный способ) updated_claim AS ( UPDATE clpr_claims c SET payload = ( -- Сохраняем весь payload кроме body COALESCE(c.payload, '{}'::jsonb) - 'body' ) || jsonb_build_object( -- Обновляем body: берём существующий body (или пустой объект) и добавляем/обновляем ключ 'body', COALESCE(c.payload->'body', '{}'::jsonb) || jsonb_build_object('uploads_descriptions[' || di.upload_index::text || ']', $2::text) ), updated_at = now() FROM doc_info di WHERE c.id = di.claim_uuid RETURNING c.id, c.payload ) -- Возвращаем обновлённые данные SELECT di.claim_document_id, di.claim_id_text AS claim_id, di.field_name, di.upload_index, -- Проверяем, где сохранилось описание (приоритет: body > корень > массив) COALESCE( uc.payload->'body'->>('uploads_descriptions[' || di.upload_index::text || ']'), uc.payload->>('uploads_descriptions[' || di.upload_index::text || ']'), uc.payload->'edit_fields_parsed'->'uploads_descriptions'->>di.upload_index::text, NULL ) AS upload_description, -- ✅ Диагностика: длина сохранённого значения length( COALESCE( uc.payload->'body'->>('uploads_descriptions[' || di.upload_index::text || ']'), uc.payload->>('uploads_descriptions[' || di.upload_index::text || ']'), uc.payload->'edit_fields_parsed'->'uploads_descriptions'->>di.upload_index::text, '' ) ) AS description_length, -- ✅ Диагностика: длина переданного значения length($2::text) AS input_length, -- ✅ Диагностика: проверяем, что значение сохранилось полностью CASE WHEN length($2::text) = length( COALESCE( uc.payload->'body'->>('uploads_descriptions[' || di.upload_index::text || ']'), uc.payload->>('uploads_descriptions[' || di.upload_index::text || ']'), uc.payload->'edit_fields_parsed'->'uploads_descriptions'->>di.upload_index::text, '' ) ) THEN 'OK' ELSE 'TRUNCATED' END AS status FROM doc_info di JOIN updated_claim uc ON uc.id = di.claim_uuid;