diff --git a/data/scud_orion_ai.db b/data/scud_orion_ai.db index 93cbca7..8326b6e 100644 Binary files a/data/scud_orion_ai.db and b/data/scud_orion_ai.db differ diff --git a/Анализ_аномалии_СКУД_и_техзадание.md b/Анализ_аномалии_СКУД_и_техзадание.md new file mode 100644 index 0000000..c051cee --- /dev/null +++ b/Анализ_аномалии_СКУД_и_техзадание.md @@ -0,0 +1,61 @@ +# ТЕХНИЧЕСКИЙ РАЗБОР АНОМАЛИИ СКУД И ТЗ НА ФИКС +> **Проблема скрытого маскирования сбоев турникетов и правила их устранения в проекте `scud_orion_ai`** + +--- + +### 📋 Метаданные инцидента + +| Параметр | Значение | +| :--- | :--- | +| **Дата инцидента:** | 04 августа 2026 г. | +| **Затронуто сотрудников:** | ~119 человек (из 276) | +| **Система:** | СКУД «Орион Pro» (MSSQL) + Python ETL + SQLite | +| **Статус решения:** | Требуется фикс валидации данных (В процессе) | + +--- + +## 1. Суть проблемы («Грабли») + +При утреннем сбое турникетов или контроллеров СКУД (08:00–10:00) события первичного прохода в базу не попадают. В результате у сотрудников в итоговом отчете формируется значение `Начало_дня = «Нет входа»`. + +Однако в течение дня сотрудники перемещаются внутри здания, выходят на обед или прикладывают карты к внутренним считывателям, генерируя сырые транзакции в MSSQL (таблица `pLogData`). + +> 🚨 **Главная баг-логика текущего алгоритма:** +> Скрипт перебирает все события за день и, видя любую дневную/вечернюю активность, **автоматически присваивает сотруднику флаг `is_present = 1` (`Статус = «Присутствовал»`)**. +> +> В итоге система «тихо сглаживает» аномалию: вместо того чтобы поднять тревогу о массовом сбое турникетов (70+ человек без утреннего входа), скрипт отправил 30+ человек в «Итого на работе», искусственно уменьшив список проблемных записей до 7 «неизвестных». + +--- + +## 2. Разбор механики расхождения отчетов (17:00 vs Конец дня) + +Вопреки первоначальной гипотезе, вечерние выходы (17:42 и т.д.) у данных сотрудников не записывались в колонку `time_out` (там оставалось «Нет выхода»). Расхождение выгрузок было вызвано двумя факторами: + +1. **В 17:00** в базе SQL 1С еще отсутствовал полный пакет кадровых документов за день, либо запуск производился без сверки с реестром исключений. +2. **При повторном прогоне** (вечером/ночью) скрипт подтянул полную базу 1С, а для оставшихся «безвходных» отработал скрытый флаг `is_present = 1`, маскируя технический сбой СКУД. + +--- + +## 3. Техническое задание на исправление (Правила фикса) + +* **Строгая валидация флага присутствия (Data Sanitization):** + Если `time_in == 'Нет входа'` и сотрудник отсутствует в `static_reason_workers.csv` (статичные удалёнщики/внештатники), код **ЗАПРЕЩАЕТ** автоматически проставлять `is_present = 1`, даже если выгрузка/агрегатор передает статус «Присутствовал». + +* **Детектор аномалий и «Красный флаг» (Anomaly Detection):** + Если у человека `time_in == 'Нет входа'`, но при этом есть дневные проходы в `pLogData`, система помечает его статусом: + `🚨 АНОМАЛИЯ СКУД: Присутствие без утреннего входа (Зафиксирована активность в течение дня)`. + +* **Группировка массовых сбоев:** + Если процент людей с подобной аномалией превышает **5% от штата**, ИИ/модуль аналитики генерирует системный алерт: + `«Внимание! Зафиксирован массовый сбой регистраторов входа СКУД»`. + +* **Параметризация MSSQL СКУД по времени (`@CutoffDateTime`):** + Добавить возможность делать срезы базы СКУД на конкретный час (например, 17:00), чтобы видеть честное состояние контроллеров и транзакций на выбранный момент времени: + ```sql + DECLARE @CutoffDateTime DATETIME = '2026-08-04 17:00:00'; + SELECT * FROM pLogData WHERE TimeVal <= @CutoffDateTime; + + Хранение истории выгрузок (snapshot_time): +Запретить перезапись (REPLACE) локальной БД SQLite в рамках одного дня. Каждая выгрузка за день должна сохраняться с меткой времени snapshot_time, чтобы сохранять историю срезов (12:00, 17:00, 19:00). + +Документ зафиксирован в рамках проекта scud_orion_ai_v2. \ No newline at end of file