feat(documents): дедупликация documents_meta и исправление field_label

- Исправлен N8N_CODE_PROCESS_UPLOADED_FILES_FIXED.js: использовать uploads_field_labels[0] вместо [grp]
- Создан SQL_CLAIMSAVE_FIXED_NEW_FLOW_DEDUP.sql с дедупликацией documents_meta
- Создан SQL_CLEANUP_DOCUMENTS_META_DUPLICATES.sql для очистки существующих дубликатов
- Создан полный уникальный индекс idx_document_texts_hash_unique на document_texts(file_hash)
- Добавлен SESSION_LOG_2025-11-28_documents_dedup.md с описанием всех изменений

Fixes:
- field_label теперь корректно отображает 'Переписка' вместо 'group-2'
- documents_meta не накапливает дубликаты при повторных сохранениях
- ON CONFLICT (file_hash) теперь работает для document_texts
This commit is contained in:
Fedor
2025-11-28 18:16:53 +03:00
parent 6c770f0a87
commit 840acca51a
118 changed files with 13379 additions and 218 deletions

132
restore_project_391584.php Normal file
View File

@@ -0,0 +1,132 @@
<?php
/**
* Восстановление файлов проекта 391584
*/
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$projectId = 391584;
$s3Bucket = $config['s3']['bucket'];
$projectPrefix = 'crm2/CRM_Active_Files/Documents/Project/ЧужбаОУ_ДПО_ОБРАЗОВАТЕЛЬНЫЕ_ТЕХНОЛОГИИ_СКИЛБОКС_(КОРОБКА_НАВЫКОВ)_391584/';
// Документы проекта
$documents = [
391587 => '8_Договора_оказание_услуг_391587.pdf',
391589 => '9_Подтверждение_оплаты_пооговору_391589.pdf',
391591 => '10_1_Скрин_личногоабинетастца_и_программа_обуч_391591.pdf',
391593 => '7_заявление_потребителя_391593.pdf',
392332 => '11_Доказательство_соблюдения_претензионного_порядк_392332.pdf',
392472 => '11.1_Доказательство_соблюдения_претензионного_поря_392472.pdf',
392475 => '11.2_Доказательство_соблюдения_претензионного_поря_392475.pdf',
395136 => '6_Расчет_искаужба_395136.pdf',
395157 => '0_Исковоеаявление_поелуужбаОУ_ДПО_ОБРАЗОВА_395157.pdf',
395744 => '12.1_Доказательство_оплаты_направления_иска_ответч_395744.pdf',
];
echo "=== ВОССТАНОВЛЕНИЕ ФАЙЛОВ ПРОЕКТА {$projectId} ===\n";
echo str_repeat("=", 80) . "\n\n";
try {
$s3Client = new \Aws\S3\S3Client([
'version' => 'latest',
'region' => $config['s3']['region'],
'endpoint' => $config['s3']['endpoint'],
'use_path_style_endpoint' => true,
'credentials' => [
'key' => $config['s3']['key'],
'secret' => $config['s3']['secret'],
],
'suppress_php_deprecation_warning' => true
]);
$stats = [
'total' => count($documents),
'restored' => 0,
'not_found' => 0,
'already_exists' => 0,
];
foreach ($documents as $docId => $filename) {
$s3Key = $projectPrefix . $filename;
echo "Документ ID: {$docId}\n";
echo " Файл: {$filename}\n";
// Проверяем, существует ли файл
if ($s3Client->doesObjectExist($s3Bucket, $s3Key)) {
echo " ✅ Файл уже существует\n\n";
$stats['already_exists']++;
continue;
}
// Проверяем наличие версий и delete markers
try {
$versions = $s3Client->listObjectVersions([
'Bucket' => $s3Bucket,
'Prefix' => $s3Key,
'MaxKeys' => 10,
]);
$deleteMarkers = $versions['DeleteMarkers'] ?? [];
$fileVersions = $versions['Versions'] ?? [];
if (empty($deleteMarkers) && empty($fileVersions)) {
echo " ❌ Файл не найден и нет версий\n\n";
$stats['not_found']++;
continue;
}
// Удаляем delete markers
foreach ($deleteMarkers as $marker) {
$s3Client->deleteObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key,
'VersionId' => $marker['VersionId'],
]);
echo " ✅ Delete marker удален\n";
}
// Если файл все еще не существует, восстанавливаем из версии
if (!$s3Client->doesObjectExist($s3Bucket, $s3Key) && !empty($fileVersions)) {
$latestVersion = $fileVersions[0];
$s3Client->copyObject([
'Bucket' => $s3Bucket,
'Key' => $s3Key,
'CopySource' => "{$s3Bucket}/{$s3Key}?versionId={$latestVersion['VersionId']}",
]);
echo " ✅ Файл восстановлен из версии\n";
} else {
echo " ✅ Файл восстановлен\n";
}
$stats['restored']++;
sleep(1);
} catch (Exception $e) {
echo " ❌ Ошибка: " . $e->getMessage() . "\n";
$stats['not_found']++;
}
echo "\n";
}
// Итоги
echo str_repeat("=", 80) . "\n";
echo "ИТОГИ:\n";
echo "Всего документов: {$stats['total']}\n";
echo "✅ Восстановлено: {$stats['restored']}\n";
echo "✅ Уже существовало: {$stats['already_exists']}\n";
echo "Не найдено: {$stats['not_found']}\n\n";
echo "=== ГОТОВО ===\n";
} catch (Exception $e) {
echo "❌ Критическая ошибка: " . $e->getMessage() . "\n";
exit(1);
}