Files
aiform_dev/fix_claim_documents_field_names.py
AI Assistant 02689e65db fix: Исправление загрузки документов и SQL запросов
- Исправлена потеря документов при обновлении черновика (SQL объединяет вместо перезаписи)
- Исправлено определение типа документа (приоритет field_label над field_name)
- Исправлены дубликаты в documents_meta и documents_uploaded
- Добавлена передача group_index с фронтенда для правильного field_name
- Исправлены все документы в таблице clpr_claim_documents с правильными field_name
- Обновлены SQL запросы: claimsave и claimsave_final для нового флоу
- Добавлена поддержка multi-file upload для одного документа
- Исправлены дубликаты в списке загруженных документов на фронтенде

Файлы:
- SQL: SQL_CLAIMSAVE_FIXED_NEW_FLOW.sql, SQL_CLAIMSAVE_FINAL_FIXED_NEW_FLOW_WITH_UPLOADED.sql
- n8n: N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js (поддержка group_index)
- Backend: documents.py (передача group_index в n8n)
- Frontend: StepWizardPlan.tsx (передача group_index, исправление дубликатов)
- Скрипты: fix_claim_documents_field_names.py, fix_documents_meta_duplicates.py

Результат: документы больше не теряются, имеют правильные типы и field_name
2025-11-26 19:54:51 +03:00

155 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Исправление field_name в таблице clpr_claim_documents
Пересоздаёт записи с правильными field_name на основе documents_uploaded и documents_required
"""
import asyncio
import asyncpg
import json
from datetime import datetime
POSTGRES_HOST = "147.45.189.234"
POSTGRES_PORT = 5432
POSTGRES_DB = "default_db"
POSTGRES_USER = "gen_user"
POSTGRES_PASSWORD = "2~~9_^kVsU?2\\S"
CLAIM_ID = "bddb6815-8e17-4d54-a721-5e94382942c7"
async def fix_field_names():
conn = await asyncpg.connect(
host=POSTGRES_HOST,
port=POSTGRES_PORT,
database=POSTGRES_DB,
user=POSTGRES_USER,
password=POSTGRES_PASSWORD
)
try:
# Получаем данные черновика
row = await conn.fetchrow("""
SELECT id, payload
FROM clpr_claims
WHERE id::text = $1 OR payload->>'claim_id' = $1
ORDER BY updated_at DESC
LIMIT 1
""", CLAIM_ID)
if not row:
print(f"❌ Черновик {CLAIM_ID} не найден!")
return
claim_uuid = row['id']
payload = row['payload'] if isinstance(row['payload'], dict) else json.loads(row['payload'])
documents_required = payload.get('documents_required', [])
documents_uploaded = payload.get('documents_uploaded', [])
print(f"📋 documents_required: {len(documents_required)} документов")
print(f"📋 documents_uploaded: {len(documents_uploaded)} документов")
# Создаём мапу: doc_id -> group_index
doc_id_to_index = {}
for idx, doc_req in enumerate(documents_required):
doc_id = doc_req.get('id')
if doc_id:
doc_id_to_index[doc_id] = idx
print(f"\n📋 Маппинг документов:")
for doc_id, idx in doc_id_to_index.items():
print(f" {doc_id} -> group_index {idx}")
# Удаляем старые записи
deleted_count = await conn.execute("""
DELETE FROM clpr_claim_documents
WHERE claim_id = $1
""", str(claim_uuid))
print(f"\n🗑️ Удалено старых записей: {deleted_count.split()[-1]}")
# Вставляем новые записи с правильными field_name
inserted_count = 0
for doc_up in documents_uploaded:
doc_type = doc_up.get('type') or doc_up.get('id')
file_id = doc_up.get('file_id')
if not doc_type or not file_id:
print(f" ⚠️ Пропущен документ без type/id или file_id: {doc_up}")
continue
group_index = doc_id_to_index.get(doc_type)
if group_index is None:
print(f" ⚠️ Не найден group_index для типа {doc_type}")
continue
field_name = f"uploads[{group_index}][0]"
# Парсим uploaded_at
uploaded_at_str = doc_up.get('uploaded_at')
uploaded_at = None
if uploaded_at_str:
try:
# Пробуем разные форматы даты
if isinstance(uploaded_at_str, str):
if 'T' in uploaded_at_str:
uploaded_at = datetime.fromisoformat(uploaded_at_str.replace('Z', '+00:00'))
else:
uploaded_at = datetime.fromisoformat(uploaded_at_str)
elif isinstance(uploaded_at_str, datetime):
uploaded_at = uploaded_at_str
except Exception as e:
print(f" ⚠️ Ошибка парсинга даты {uploaded_at_str}: {e}")
uploaded_at = None
await conn.execute("""
INSERT INTO clpr_claim_documents (
claim_id,
field_name,
file_id,
file_name,
original_file_name,
uploaded_at
)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (claim_id, field_name) DO UPDATE SET
file_id = EXCLUDED.file_id,
file_name = EXCLUDED.file_name,
original_file_name = EXCLUDED.original_file_name,
uploaded_at = EXCLUDED.uploaded_at
""",
str(claim_uuid),
field_name,
file_id,
doc_up.get('file_name', ''),
doc_up.get('original_file_name', ''),
uploaded_at
)
inserted_count += 1
print(f" ✅ Вставлен: {field_name} -> {doc_type} ({file_id[:50]}...)")
print(f"\n✅ Вставлено новых записей: {inserted_count}")
# Проверяем результат
result_rows = await conn.fetch("""
SELECT
field_name,
file_id,
file_name,
original_file_name
FROM clpr_claim_documents
WHERE claim_id = $1
ORDER BY field_name
""", str(claim_uuid))
print(f"\n📊 Результат в таблице ({len(result_rows)} записей):")
for row in result_rows:
print(f" {row['field_name']}: {row['file_name']} ({row['file_id'][:50]}...)")
finally:
await conn.close()
if __name__ == "__main__":
asyncio.run(fix_field_names())