Files
crm.clientright.ru/DUPLICATE_PREVENTION_GUIDE.md
Fedor 75d3f7942b feat: Обновлены все URL Nextcloud с office.klientprav.tech на office.clientright.ru
Обновленные файлы:
- crm_extensions/nextcloud_api.php (2 места)
- modules/Documents/actions/NcPrepareEdit.php
- crm_extensions/nextcloud_editor/js/nextcloud-editor.js
- crm_extensions/file_storage/api/get_edit_urls.php
- crm_extensions/file_storage/api/simple_edit.php
- crm_extensions/README.md
- NEXTCLOUD_EDIT_BUTTON_IMPLEMENTATION.md
- crm_extensions/docs/NEXTCLOUD_EDITOR.md
- test_syntax_check.html
- crm_extensions/tests/test_edit_button.html

Все ссылки теперь указывают на новый сервер office.clientright.ru
Backup файлы и тестовые директории не изменены
2025-10-20 17:17:34 +03:00

198 lines
7.9 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# 🛡️ Защита от дубликатов в системе парсинга судов
## 📋 Обзор
Система имеет **3 уровня защиты** от создания дубликатов:
### 1⃣ Уровень событий в таблице `subject`
**Файл:** `parsers/BaseCourtParser.php` (метод `saveEvent`)
**Логика:**
- Проверяет наличие события по 3 полям: `event_name`, `event_date`, `publication_date`
- Если событие найдено → **НЕ сохраняет** в БД и возвращает `false`
- Если `skip_duplicate_check=true` → пропускает проверку (только для тестов!)
**SQL запрос:**
```sql
SELECT COUNT(*) FROM subject
WHERE event_name = ?
AND event_date = ?
AND publication_date = ?
```
### 2⃣ Уровень уведомлений в `vtiger_vdnotifierpro`
**Файлы:**
- `parsers/MoscowCourtParser.php` (метод `createCourtEventNotification`)
- `parsers/RegionalCourtParser.php` (метод `createCourtEventNotification`)
**Логика:**
- Проверяет наличие уведомления по: `userid`, `crmid` (project_id), точное совпадение `title`
- Если уведомление **непрочитано** (status=5) → **обновляет время** (modifiedtime)
- Если уведомление **прочитано** (status≠5) → **НЕ создаёт дубликат**
- Если уведомления нет → **создаёт новое**
**SQL запросы:**
```sql
-- Проверка существующего уведомления
SELECT id, status FROM vtiger_vdnotifierpro
WHERE userid = ?
AND crmid = ?
AND title = ?
ORDER BY id DESC LIMIT 1
-- Обновление времени (если непрочитано)
UPDATE vtiger_vdnotifierpro
SET modifiedtime = NOW()
WHERE id = ?
-- Создание нового (если не найдено)
INSERT INTO vtiger_vdnotifierpro
(userid, modulename, crmid, modiuserid, link, title, action, modifiedtime, status)
VALUES (?, 'Project', ?, 0, ?, ?, '', NOW(), 5)
```
### 3⃣ Уровень событий в CRM календаре
**Файл:** `CreateCourtEvent_v2.php`
**Логика:**
- Не проверяет дубликаты напрямую
- Полагается на защиту уровня 1 (таблица `subject`)
---
## ✅ Что нужно сделать для продакшена
### **1. НЕ передавать параметр `skip_duplicate_check=true`**
**ПЛОХО (для тестов):**
```php
$params = [
'project_id' => 364118,
'case_number' => '02-1182/312/2025',
'skip_duplicate_check' => 'true' // ← УБРАТЬ ЭТО!
];
```
**ХОРОШО (для продакшена):**
```php
$params = [
'project_id' => 364118,
'case_number' => '02-1182/312/2025',
'skip_duplicate_check' => 'false' // ← или не передавать вообще (по умолчанию false)
];
```
### **2. Убедиться, что параметр по умолчанию `false`**
В файле `ParseAndCreateEvent.php` (строка 58):
```php
'skip_duplicate_check' => $params['skip_duplicate_check'] ?? 'false'
```
✅ Это уже настроено правильно!
### **3. Убедиться, что в CRM workflow не передаётся `skip_duplicate_check=true`**
Проверьте ваши workflow, которые вызывают `ParseAndCreateEvent.php` или `parscourt.php`.
---
## 🧪 Тестирование защиты от дубликатов
### Тест 1: События в таблице `subject`
```bash
# Запустить парсинг 2 раза подряд
curl "https://crm.clientright.ru/parscourt.php" \
-d "project_id=364118" \
-d "case_number=02-1182/312/2025" \
-d "link1=https://mos-sud.ru/..." \
-d "status=test"
# Проверить, что в таблице subject только 1 запись
mysql -u ci20465_72new -p -D ci20465_72new \
-e "SELECT COUNT(*) FROM subject WHERE case_number = '02-1182/312/2025'"
```
### Тест 2: Уведомления в `vtiger_vdnotifierpro`
```bash
# Запустить парсинг 2 раза подряд
curl "https://crm.clientright.ru/ParseAndCreateEvent.php?project_id=364118&..."
# Проверить, что создано только 1 уведомление
mysql -u ci20465_72new -p -D ci20465_72new \
-e "SELECT id, title, status, modifiedtime FROM vtiger_vdnotifierpro WHERE crmid = 364118 ORDER BY id DESC LIMIT 5"
```
**Ожидаемый результат:**
- При первом запуске: создаётся уведомление (status=5)
- При втором запуске (если не прочитано): обновляется `modifiedtime`, status остаётся 5
- При втором запуске (если прочитано): ничего не происходит, дубликат НЕ создаётся
---
## 📊 Статусы уведомлений в VDNotifierPro
| Status | Значение | Действие при повторном парсинге |
|--------|-----------------|---------------------------------------|
| 5 | Непрочитано | Обновить время (`modifiedtime`) |
| 6 | Прочитано | Не создавать дубликат |
| Другое | Удалено/Архив | Не создавать дубликат |
---
## 🔍 Отладка
### Проверить логи парсера
```bash
tail -50 /var/www/fastuser/data/www/crm.clientright.ru/logs/parser.log
```
**Что искать:**
- `Дубликат найден для события:` - событие не сохранено (защита работает)
- `Обновлено время непрочитанного уведомления ID:` - уведомление обновлено (защита работает)
- `Уведомление ID: X уже существует (статус: Y), дубликат не создан` - дубликат предотвращён (защита работает)
- `⚠️ ТЕСТОВЫЙ РЕЖИМ: Проверка дубликатов отключена` - защита ОТКЛЮЧЕНА (только для тестов!)
### Проверить существующие уведомления
```sql
SELECT
id,
userid,
crmid,
title,
status,
modifiedtime
FROM vtiger_vdnotifierpro
WHERE crmid = 364118 -- ваш project_id
AND title LIKE '%Событие суда%'
ORDER BY id DESC
LIMIT 10;
```
---
## ⚠️ ВАЖНО!
### ❌ **НЕ ДЕЛАТЬ:**
1. Не передавать `skip_duplicate_check=true` в продакшене
2. Не удалять проверки дубликатов из кода
3. Не изменять логику проверки без тестирования
### ✅ **РЕКОМЕНДУЕТСЯ:**
1. Использовать `skip_duplicate_check=false` (по умолчанию)
2. Регулярно проверять логи на наличие `⚠️ ТЕСТОВЫЙ РЕЖИМ`
3. Мониторить количество уведомлений для одного проекта
---
## 🎯 Итог
При правильной настройке (`skip_duplicate_check=false` или не передавать вообще) система:
-**НЕ создаёт** дубликаты событий в таблице `subject`
-**НЕ создаёт** дубликаты уведомлений в `vtiger_vdnotifierpro`
-**Обновляет время** непрочитанных уведомлений
-**Игнорирует** повторные запуски для прочитанных уведомлений
**Защита работает на всех трёх уровнях!** 🛡️