Files
crm.clientright.ru/analyze_deletions.php
Fedor 840acca51a 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
2025-11-28 18:16:53 +03:00

204 lines
8.1 KiB
PHP
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.

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once '/var/www/fastuser/data/www/crm.clientright.ru/vendor/autoload.php';
require_once '/var/www/fastuser/data/www/crm.clientright.ru/config.inc.php';
$config = require '/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/config.php';
$s3Bucket = $config['s3']['bucket'];
echo "Анализ удалений файлов из S3\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
]);
// Анализируем паттерны удалений
echo "1. Анализ паттернов удалений по датам...\n";
$deletionsByDate = [];
$deletionsByProject = [];
$totalChecked = 0;
$maxToCheck = 5000; // Ограничиваем для скорости
try {
$isTruncated = true;
$continuationToken = null;
$pageCount = 0;
$maxPages = 10;
while ($isTruncated && $pageCount < $maxPages && $totalChecked < $maxToCheck) {
$params = [
'Bucket' => $s3Bucket,
'Prefix' => 'crm2/CRM_Active_Files/Documents/Project/',
'MaxKeys' => 1000
];
if ($continuationToken) {
$params['ContinuationToken'] = $continuationToken;
}
$versions = $s3Client->listObjectVersions($params);
$pageCount++;
if (isset($versions['DeleteMarkers'])) {
foreach ($versions['DeleteMarkers'] as $marker) {
$totalChecked++;
$key = $marker['Key'];
$deleteDate = isset($marker['LastModified']) ? $marker['LastModified'] : null;
if ($deleteDate) {
$dateKey = substr($deleteDate, 0, 10); // YYYY-MM-DD
if (!isset($deletionsByDate[$dateKey])) {
$deletionsByDate[$dateKey] = 0;
}
$deletionsByDate[$dateKey]++;
}
// Извлекаем ID проекта из пути
if (preg_match('/Project\/([^\/]+)_(\d+)\//', $key, $matches)) {
$projectId = $matches[2];
if (!isset($deletionsByProject[$projectId])) {
$deletionsByProject[$projectId] = 0;
}
$deletionsByProject[$projectId]++;
}
}
}
$isTruncated = isset($versions['IsTruncated']) && $versions['IsTruncated'];
$continuationToken = isset($versions['NextContinuationToken']) ? $versions['NextContinuationToken'] : null;
if (!$isTruncated) {
break;
}
}
echo " Проверено delete markers: $totalChecked\n\n";
// Сортируем по датам
krsort($deletionsByDate);
echo " Удаления по датам (топ 20):\n";
$count = 0;
foreach ($deletionsByDate as $date => $count) {
if ($count > 0) {
echo " $date: $count удалений\n";
if (++$count >= 20) break;
}
}
echo "\n";
// Сортируем проекты по количеству удалений
arsort($deletionsByProject);
echo " Проекты с наибольшим количеством удалений (топ 10):\n";
$count = 0;
foreach ($deletionsByProject as $projectId => $deleteCount) {
echo " Проект $projectId: $deleteCount удалений\n";
if (++$count >= 10) break;
}
echo "\n";
} catch (\Aws\Exception\AwsException $e) {
echo " Ошибка: " . $e->getMessage() . "\n";
}
// Проверяем логи системы
echo "2. Проверка логов на наличие записей об удалениях...\n";
$logFiles = [
'/var/log/nginx/error.log',
'/var/log/apache2/error.log',
'/var/www/fastuser/data/www/crm.clientright.ru/logs/debug.log',
'/var/www/fastuser/data/www/crm.clientright.ru/logs/s3_debug.log',
];
foreach ($logFiles as $logFile) {
if (file_exists($logFile)) {
echo " Проверка: $logFile\n";
$lines = file($logFile);
if ($lines) {
$deleteLines = array_filter($lines, function($line) {
return stripos($line, 'delete') !== false &&
(stripos($line, 's3') !== false || stripos($line, 'file') !== false);
});
if (!empty($deleteLines)) {
echo " Найдено строк с упоминанием удалений: " . count($deleteLines) . "\n";
echo " Последние 5 записей:\n";
foreach (array_slice($deleteLines, -5) as $line) {
echo " " . substr(trim($line), 0, 150) . "\n";
}
} else {
echo " Записей об удалениях не найдено\n";
}
}
echo "\n";
}
}
// Проверяем, есть ли скрипты крона, которые могут удалять файлы
echo "3. Поиск скриптов, которые могут удалять файлы...\n";
$cronFiles = [
'/var/spool/cron/crontabs/root',
'/etc/cron.d/',
'/var/www/fastuser/data/www/crm.clientright.ru/cron/',
];
foreach ($cronFiles as $cronPath) {
if (file_exists($cronPath)) {
echo " Проверка: $cronPath\n";
if (is_dir($cronPath)) {
$files = glob($cronPath . '*');
foreach ($files as $file) {
if (is_file($file)) {
$content = file_get_contents($file);
if (stripos($content, 'delete') !== false || stripos($content, 'remove') !== false) {
echo " Найден файл: $file\n";
echo " Содержит упоминания удаления\n";
}
}
}
} else {
$content = file_get_contents($cronPath);
if (stripos($content, 'delete') !== false || stripos($content, 'remove') !== false) {
echo " Файл содержит упоминания удаления\n";
}
}
}
}
echo "\n";
// Проверяем, может быть это связано с синхронизацией Nextcloud
echo "4. Проверка связи с Nextcloud синхронизацией...\n";
$nextcloudFiles = glob('/var/www/fastuser/data/www/crm.clientright.ru/crm_extensions/file_storage/*sync*.php');
if (!empty($nextcloudFiles)) {
echo " Найдено файлов синхронизации: " . count($nextcloudFiles) . "\n";
foreach ($nextcloudFiles as $file) {
$content = file_get_contents($file);
if (stripos($content, 'delete') !== false) {
echo " $file содержит код удаления\n";
}
}
} else {
echo " Файлы синхронизации не найдены\n";
}
echo "\n";
} catch (Exception $e) {
echo "ОШИБКА: " . $e->getMessage() . "\n";
echo "Trace: " . $e->getTraceAsString() . "\n";
}