Files
aiform_prod/fix_claim_documents_field_names.py

155 lines
5.7 KiB
Python
Raw Normal View History

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
#!/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())