# Changelog Все важные изменения проекта документируются в этом файле. ## [2.5.8] - 2026-09-10 ### Добавлено (Added) - **Двухконтурная физическая модель СКУД (Правый PERCo):** - Поддержка проходов через оба турникета (`DoorIndex IN (1, 2)`) для сотрудников дворовых служб (отделы `ЭТО`, `ЛЦ` и др.). - Реестр доступа к правому турникету в `exceptions_registry` с категориями `turnstile_fio` и `turnstile_departments`. - Корректная склейка ФИО (`Name + FirstName + MidName`) в динамическом SQL-фильтре MS SQL. - **Интерактивное модальное окно исключений:** - Замена браузерного `prompt()` на модальную форму в едином Tailwind-стиле с автоподбором сотрудников из 1С:ЗУП (`staff-autocomplete`). - Поле примечания/комментария для фиксации оснований допуска. - **Точное локальное время создания срезов:** - Явная фиксация времени хоста при записи срезов в `scud_logs.created_at`, устраняющая 3-часовое смещение UTC внутри контейнеров. - **Декларативное подтверждение удаления срезов:** - Добавление параметра `confirmed: boolean` в схему `TOOLS_SCHEMA` инструмента `db_delete_snapshots`, исключающее зацикливание подтверждений в LLM. ### Изменено (Changed) - **Упразднение искусственного автозакрытия смен:** - Полное отключение механизма `calculate_autoclose_time` по согласованию с отделом кадров. При отсутствии физической отметки на турникете статус «Нет выхода» сохраняется без искажения аналитики. - **Математический расчет временных границ срезов:** - Перевод формирования `@EndDate` в `services/scud_export.py` на цепочку функций `DATEADD` от `@StartDate`, устраняющий зависимость от регионального формата даты (`DMY` vs `MDY`). ## [Unreleased] - 2026-09-07 ### Добавлено - Механизм Gemini-скроллинга диалогового окна: функция `scrollToUserMessageTop` в `core.js` автоматически поднимает отправленный вопрос к верхнему срезу экрана, скрывая громоздкие предыдущие ответы. - CSS-отступ `padding-bottom: 80vh` у `#chat-messages-container`, гарантирующий свободное вертикальное пространство для прокрутки без сдвига строки ввода. - Пункт 2.9 системного промпта, жестко обязывающий модель вызывать нативный инструмент `db_get_rules` при запросах Базы Знаний и регламентов вместо текстовой имитации. ### Запланировано - Рефакторинг интерпретации аппаратных кодов турникетов PERCO в `services/scud_export.py`: разделение логики разрешения прохода (`Event 28`) и факта проворота створки (`Event 32`), приоритет направления по `log.Mode` (1 — вход, 2 — выход) для устранения фантомных выходов. - Создание DDL-схемы и таблицы `scud_events_raw` в SQLite для гранулярного хранения всех внутридневных перемещений сотрудников (база для учета перекуров и инструмента «Кто в здании»). ## [0.9.5] - 2026-08-28 ### Добавлено - Механизм отказоустойчивого сохранения отчетов `safe_close_workbook` в `services/excel_exporter.py`: при блокировке файла открытым процессом Excel создается резервный файл с таймстемпом вида `..._timestamp.xlsx`. ### Изменено - Экспорт всех Excel-документов (`services/scud_export.py`, `services/excel_exporter.py`) полностью переведен с `openpyxl` на `xlsxwriter`. - Скорректирована верстка детального отчета: столбец «Подразделение» выровнен строго по центру, колонка «ФИО» расширена на 10% (ширина 33), а избыточная ширина столбцов «Первая активность» и «Отклонение от нормы» уменьшена до 11 пунктов для корректного размещения на экране без горизонтальной прокрутки. - В модуле сетевой синхронизации `services/share_copier.py` вызов `shutil.copy2` заменен на `shutil.copyfile`, что устранило ошибки метаданных `[Errno 1] Operation not permitted` при монтировании SMB-шары. ### Исправлено - Устранена системная ошибка структуры OpenXML (`errorXXXXXX_01.xml`, «Обнаружена ошибка в части содержимого книги...»), возникавшая при открытии сгенерированных отчетов в MS Excel. - Восстановлены сворачиваемые интерактивные категории с кнопками `[+]` / `[-]` в файле ежедневной сводки (`outline_settings(symbols_below=False)`). ## [Unreleased] - 2026-08-28 ### Fixed - **Генерация Excel-книг (`services/excel_exporter.py`, `services/scud_export.py`):** полный перевод экспорта с `openpyxl` на `xlsxwriter`, что устранило хроническую ошибку структуры OpenXML («В книге обнаружено нечитаемое содержимое...»). - **Группировки в Сводке:** восстановлено корректное отображение интерактивных кнопок `[+]`/`[-]` и сворачивание категорий по умолчанию (`outline_settings`, `level=1`, `collapsed=True`). - **Верстка и пропорции Детального отчета:** центрирование столбца «Подразделение», калибровка ширины колонок «ФИО» (+10%), «Первая активность» и «Отклонение от нормы» для плотного размещения таблицы на одном экране без горизонтальной прокрутки. - **Безопасное сохранение при блокировках:** внедрена функция `safe_close_workbook` для фонового сохранения резервных копий с timestamp, если файл открыт пользователем в Excel. - **Сетевое копирование 1С (`services/share_copier.py`):** замена `shutil.copy2` на `shutil.copyfile` для устранения сбоя `[Errno 1] Operation not permitted` при работе с SMB/CIFS-шарой. ## [Unreleased] - 2026-08-28 ### Fixed - **Инкремент Snapshot ID (`core/repositories/scud_repo.py`):** заменена строковая сортировка `ORDER BY snapshot_id DESC` на целочисленный парсинг суффиксов, что устранило залипание номеров снапшотов (`-002`). ### Added - **Режим тихих почасовых срезов (`--export-only`):** быстрый экспорт данных СКУД напрямую в SQLite без построения отчетов для интеграции в cron. - **Интерактивный справочник CLI (`main_etl.py`):** полный баннер справки по всем аргументам (`-h`, `--help`, `help`). - **Автоматическая ротация промежуточных срезов (`services/snapshots/retention.py`):** ночная очистка устаревших почасовых срезов старше 2 дней с сохранением полуденного (`13:00`) и итогового `Y` (`23:59:59`). ## [Unreleased] - 2026-08-28 ### Added - **Smart Snap-to-Grid Finder (`services/snapshots/finder.py`):** интеллектуальный поиск ближайшего среза СКУД в SQLite с допуском ±20 минут и поддержкой On-Demand экспорта из MS SQL при отсутствии готового среза. - **Параметр `--time` в `main_etl.py`:** возможность формирования оперативной сводки на произвольное время суток. - **Раздельные генераторы отчетов:** - `services/scud_etl/svodka_generator.py` — оперативная сводка за сегодня с группировками. - `services/scud_etl/otchet_generator.py` — суточный детальный отчет за вчера по финишному срезу `Y` (23:59:59) с учетом рабочего норматива 8.5 ч. ### Changed - **Фиксация финишного среза `Y` на `23:59:59`:** обновлено время снапшота в `services/scud_export.py`, `core/repositories/scud_repo.py` и `services/scud_etl/pipeline.py` с сохранением обратной совместимости со срезами на `22:00:00`. - **Путь виртуального окружения в `run_cron_etl.sh`:** скорректирован на актуальный `/home/puh/projects/scud_ai/venv/bin/python`. - **Игнорирование временных файлов SQLite:** добавлены `*.db-shm` и `*.db-wal` в `.gitignore`. ## [3.2.0] — 2026-08-27 ### 🧠 Интеллектуальный арбитраж личностей, агрегация мульти-пропусков и автозакрытие смен #### ✨ Добавлено: - **Кэш сопоставлений личностей (`person_identity_mapping`)**: - Создана таблица в SQLite (`core/schema.py`) для постоянного хранения подтвержденных связок между сырыми ФИО СКУД и эталонными ФИО 1С:ЗУП. - Поддержка мгновенного извлечения проверенных сопоставлений в `merger.py` (время выборки < 1 мс). - **Агрегация дубликатов пропусков и мульти-учеток СКУД (`merger.py`)**: - Функция `aggregate_scud_by_person` объединяет все карты/записи одного физлица: фиксирует самый ранний вход `min(valid_ins)`, самый поздний выход `max(valid_outs)` и итоговый статус присутствия. - Исключено ложное попадание сотрудников с несколькими пропусками (например, Кондрашова Е.В.) в категорию «неизвестно». - **Интеллектуальный выбор ставки совместителей 1С (`merger.py`)**: - Функция `select_best_zup_position` сопоставляет множественные должности одного сотрудника в 1С со СКУД и подтягивает ставку того подразделения, где человек находится физически. - **Автозакрытие незакрытых смен по Правилу 8.5ч (`excel_exporter.py`)**: - При наличии утреннего входа и отсутствии вечернего выхода у офисных сотрудников в детальном отчете за вчера расчетный выход ставится как `Вход + 8ч 30мин`, норма 8 часов и нулевое отклонение `0:00` (вместо ложного штрафа `-8:00`). - **Теневой ИИ-арбитраж нераспознанных ФИО (`text_reporter.py`)**: - Модуль `find_ai_identity_suggestions` выявляет нечеткие совпадения и опечатки операторов СКУД, выводя рекомендации для кадровой службы в блоке «💡 Предложения ИИ по сопоставлению ФИО». - **Расширение CLI-утилиты (`scripts/db_cli.py`)**: - Добавлены команды управления связками: `python scripts/db_cli.py mapping [list|add|del]`. #### 🔧 Изменено: - **`services/scud_etl/anomaly_detector.py`**: - Добавлено авто-детектирование задвоенных карточек СКУД (`DUPLICATE_SCUD_CARD`) с передачей информации в ИИ-сводку. - **`main_etl.py`**: - Восстановлена передача сырых датасетов (`raw_scud_df`, `raw_staff_df`, `raw_absent_df`) в ИИ-аудитор и генерация диагностического дампа `СКУД_Сырые_данные_ДД.ММ.ГГГГ.xlsx`. --- ## [3.1.0] — 2026-08-25 ### 🛡️ Реляционный реестр исключений, Белый список и отказоустойчивость выгрузок #### ✨ Добавлено: - **Реляционный реестр исключений (`exceptions_registry`)**: - Перенос исключений (`departments`, `positions`, `fio`, `position_keywords`) и белого списка (`include_fio`) из статического JSON в базу данных SQLite (`core/schema.py`). - Репозиторий `services/exceptions_repo.py` с функциями CRUD и авто-миграцией из `exceptions.json`. - **Белый список (`include_fio`)**: - Поддержка явного включения сотрудников в расчет контроллинга в обход должностных и отдельских фильтров (Тарасенко А.А., Журиков М.Н.). - **Управление исключениями в CLI (`scripts/db_cli.py`)**: - Добавлены команды `exceptions list`, `exceptions add -c ... -v ...`, `exceptions del`, `exceptions sync`. - **Резервный загрузчик кадровых отсутствий (`data_loader.py`)**: - Реализован каскадный fallback: `MS SQL 1C:ЗУП` (таймаут 30с) $\rightarrow$ резервный парсинг скопированных Excel-файлов `Отсутствия_*.xlsx` $\rightarrow$ `static_reason_workers.csv`. #### 🔧 Изменено: - **Структура отчетов Excel (`excel_exporter.py`)**: - Изменен базовый путь сохранения отчетов на `output/reports/ГОД/МЕСЯЦ/`. - В Ежедневной сводке блок «В том числе на удаленной работе» вынесен под «Итого на работе», а блок «Исключения» размещен в самом низу с поддержкой группировки. - Добавлена защита от блокировок Excel (`PermissionError`/`OSError`): при занятости файла создается резервная копия с временной меткой. - **Подключение к СКУД (`services/scud_export.py`)**: - Актуализирован адрес сервера MS SQL Орион (`172.16.200.147\SQL`). - Добавлена защита инициализации файлового логгера от ошибок доступа прав пользователей. --- ## [3.0.0] — 2026-08-21 ### 🚀 Глубокий архитектурный рефакторинг (Unified Clean Architecture) #### Добавлено: - **Пакет ядра `core/`:** - `core/connection.py`: централизованный менеджер SQLite-подключений с поддержкой WAL-режима и row_factory. - `core/schema.py`: единая точка инициализации схемы данных и индексов. - `core/repositories/`: низкоуровневые репозитории `scud_repo.py` и `zup_repo.py`. - **Доменные сервисы `services/`:** - `services/tasks/`: полная изоляция логики задач (CRUD, Markdown-экспорт, генерация `ROADMAP.md`). - `services/prompts/`: доменный сервис системного промпта, поддержка превью, генерация HTML-Diff и пакетное удаление узлов (`BATCH_DELETE`). - `services/snapshots/`: бизнес-логика срезов СКУД с защитой финишных Y-снапшотов. - `services/knowledge/`: сервис базы знаний правил и синонимов отделов. - `services/scud_etl/`: модульный ETL-конвейер (`pipeline.py`, `anomaly_detector.py`, `merger.py`, `sql_queries.py`). - **ИИ-оркестратор `modules/ai_engine/`:** - Декомпозиция монолитного `agent.py` на узкие обработчики `handlers/` и динамический контекст-билдер `context_builder.py`. - Двухконтурная обработка: нативный Function Calling + семантический страхующий инжектор (`tool_injector.py`). - Интеллектуальный Topic Drift менеджер с вежливым напоминанием на 3-й шаг и автоочисткой эфемерных сообщений на 4-й. - **Интерфейс и UI:** - Кнопка «✏️ Редактировать» прямо в карточке просмотра системного промпта с инлайн-редактором. #### Исправлено: - Устранена утечка системного промпта в постоянный контекст (`chat_messages`). - Исправлены ошибки несоответствия сигнатур (`TypeError: create_prompt_preview`, `save_full_prompt_draft`, `get_snapshots_registry`) в Fast-Path. - Устранена галлюцинация слов-паразитов («Почемучка», «Почемучто») на уровне валидации ответа. - Исправлено устаревшее противоречивое правило 2.3 в базе данных, блокировавшее интерактивное удаление задач. #### Удалено: - Устаревшие файлы-дубли: `modules/web_api/llm/db/db_tasks.py`, `db_snapshots.py`, `prompt_merger.py`. --- ## [2026-08-19] — Инлайн-редактор задач, интеллектуальный ContextManager и стабилизация Function Calling ### ✨ Добавлено * **Инлайн-редактирование задач (`task_widget.js` / `tasks.py`)**: - Добавлена кнопка редактирования (`✏️`) на каждой карточке задачи. - Карточка трансформируется в инлайн-форму с тремя полями: текст задачи, HTML5-пикер календаря планируемого срока и выпадающий список важности (`LOW`, `MEDIUM`, `HIGH`, `CRITICAL`). - Добавлен REST API эндпоинт `PATCH /api/v1/tasks/{task_id}` с поддержкой комплексного обновления полей в SQLite. - В карточки выведено отображение даты создания задачи. * **Интеллектуальный ContextManager (`context_manager.py`)**: - Служебные запросы и карточки инструментов сохраняются синхронными парами (`is_ephemeral = 1`) и атомарно удаляются при завершении операций. - Свободные диалоги оператора (включая темы Topic Drift) сохраняются в постоянную историю (`is_ephemeral = 0`) и не стираются при закрытии сессий промпта/задач. * **Поддержка Y-снапшотов (`db_snapshots.py`)**: - Исправлен SQL-запрос `db_get_snapshots` для точного извлечения ночных и фоновых срезов с префиксом `Y` (например, `Y20260817-003`). ### 🔧 Изменено * **`modules/web_api/llm/agent.py`**: - Полностью удалены эвристические текстовые фильтры и принудительные сортировки инструментов. - Настроен нативный возврат и исполнение инструментов без зацикливания модели. - Устранена ошибка `UnboundLocalError` при вызове справочных инструментов. * **`modules/web_api/llm/schemas.py`**: - Очищены описания инструментов от агрессивных директив и капса, стабилизирована селективность Function Calling для Qwen 2.5. * **`modules/web_api/llm/core/ollama_client.py`**: - Оптимизированы параметры генерации для Function Calling (`repeat_penalty: 1.0`, `presence_penalty: 0.0`, `temperature: 0.0`), что исключило спам несколькими вызовами инструментов на один запрос. * **`modules/web_api/static/js/chat/task_widget.js`**: - Фильтр по умолчанию переведен на вкладку **«В работе»** (`IN_PROGRESS`). --- ## [2026-08-18] — Двухфазный жизненный цикл сессий, двусторонний Diff и Topic Drift Guard ### ✨ Добавлено * **Двусторонний клиентский Diff (`core.js`)**: Реализован алгоритм сравнения черновика с baseline-промптом. Удаленные строки остаются на экране с красным зачеркиванием `[УДАЛЕНИЕ]`, а добавленные/измененные строки выделяются красной рамкой с авто-отступами. * **Topic Drift Guard (`agent.py`)**: Внедрен двухуровневый контроль смены темы: - Мгновенный сброс стейта и зачистка эфемерных сообщений при вызове сторонних инструментов (задачи, снапшоты, база). - Мягкий счетчик отвлечений (`idle_turns` = 3) в свободном диалоге с выводом напоминания и кнопок из `tool_action_registry`. * **Команда `context purge` в CLI (`db_cli.py`)**: Добавлен флаг `--all` для полной очистки таблицы `chat_messages` и сброса стейтов сессий. --- ## [2026-08-17] — Внедрение CLI-инспекции контекста и переход на нативный Function Calling ### ✨ Добавлено * **`scripts/db_cli.py`**: Добавлена команда `context` для инспекции истории сообщений `chat_messages` по сессиям с визуальным отображением флагов `[ЭФЕМЕРНОЕ]`. * **`ROADMAP.md`**: Сформирована актуальная дорожная карта с планом отказа от регулярных выражений в пользу нативного Function Calling. --- ## [2026-08-15] — Реляционная архитектура системного промпта ### ✨ Добавлено * **`system_prompt_nodes`**: Создана таблица реляционных узлов промпта с индексацией по разделам и пунктам (`section_id`, `item_id`). * **`db_prompt_node_edit`**: Добавлен инструмент точечного добавления, изменения и удаления пунктов системного промпта. * **Инлайн-редактор**: Добавлен визуальный diff-просмотр изменений с подсветкой и кнопкой `[✏️ Редактировать]`. --- ## [2026-08-10] — Механизм эфемерных сообщений и очистки диалога ### ✨ Добавлено * **Эфемерные сообщения (`is_ephemeral`)**: Маркировка временных сервисных ответов и черновиков. * **`db_purge_ephemeral_messages`**: Механизм физической зачистки временных записей из SQLite при завершении операций. * **Интерактивные виджеты**: Поддержка карточек задач (`TASK_INTERACTIVE_CARD`) с кнопками быстрого действия.