# Отчет: Исследование багов уведомлений при согласовании заявлений ## 📋 Проблема Пользователи жалуются, что **автор заявления не получает уведомление, когда согласующий одобряет или отклоняет заявление**. ## 🔍 Анализ истории коммитов ### Найденная причина: Коммит `c0b659f9` от 29 декабря 11:02 **Сообщение коммита:** ``` fix: исключен approver из получателей уведомлений о решении - Approver (тот кто принял решение) не получает уведомление о своем действии - Исключены employee.id и approver_id из recipients при approve/reject - Упрощен signal create_request_notifications (убран лишний запрос в БД) - Теперь передается актуальный request_obj с установленным approver_id ``` ### Проблемный код **Файл:** `backend/requests_app/notification_signals.py` **Функция:** `notify_status_change()` (строки 356-362) ```python # ID пользователей которых НЕ нужно уведомлять при approve/reject exclude_ids = set() if new_status in ("approved", "rejected"): # Не уведомляем автора заявки (он видит результат на странице) exclude_ids.add(request_obj.employee.id) # ❌ ПРОБЛЕМА! # Не уведомляем того кто принял решение (он сам нажал кнопку) if request_obj.approver_id: exclude_ids.add(request_obj.approver_id) ``` ### Цепочка исключения 1. `exclude_ids` содержит `employee.id` (автора) и `approver_id` 2. Эти ID исключаются на строках **370, 375, 390** при фильтрации: - Recipients (основные получатели) - CC users (в копии) - Сотрудники отделов (если `sent_to_all_department=True`) ### Ошибочное предположение Комментарий в коде указывает на ошибочное предположение: ``` # Не уведомляем автора заявки (он видит результат на странице) ``` **Это неверно, потому что:** - Автор может не находиться на странице в момент согласования - Коммит `935c12a` от 29 декабря 11:19 показывает, что alert был убран - Поэтому уведомление становится **единственным способом уведомить автора** ## 📅 Временная шкала | Дата/время | Коммит | Описание | |-----------|--------|---------| | 29 дек, 11:02 | `c0b659f9` | **Добавлена логика исключения автора из уведомлений** | | 29 дек, 11:19 | `935c12a` | Убран `alert()` и `reload` при approve/reject на странице списка | | 29 дек, 11:26 | `a178fcd` | Улучшены уведомления (эмодзи, описания и т.д.) | ## 🔗 Связанные коммиты - **`a178fcd`** - "feat(requests): улучшены уведомления о заявлениях" - Добавлены эмодзи и детализация уведомлений - Но логика исключения автора осталась нетронутой - **`935c12a`** - "fix(requests): убраны alert и немедленный reload при approve/reject" - Изменилась логика UI (alert → modal close + delayed reload) - Это сделало уведомление критически важным для информирования автора ## 🐛 Почему это стало проблемой? 1. **До коммита `c0b659f9`:** - Автор видел результат через `alert()` на странице - Уведомление было "бонусом" 2. **После коммита `c0b659f9` + `935c12a`:** - `alert()` убран → нет синхронного уведомления - Автор исключен из уведомлений → нет асинхронного уведомления - **Результат: автор вообще ничего не узнает!** ## ✅ Решение **Статус:** ИСПРАВЛЕНО в коммите `de0caea` Был удален автор из `exclude_ids`, чтобы он получал уведомления о решениях: ```python # ID пользователей которых НЕ нужно уведомлять при approve/reject exclude_ids = set() if new_status in ("approved", "rejected"): # ВАЖНО: Уведомляем автора заявки о решении - это единственный способ # информировать его, так как alert() был убран из UI (коммит 935c12a) # Не уведомляем только того кто принял решение (он сам нажал кнопку) if request_obj.approver_id: exclude_ids.add(request_obj.approver_id) # 1. Автор - УВЕДОМЛЯЕМ всегда (даже при approved/rejected, это важно!) recipients_to_notify.add(request_obj.employee) ``` ### Что изменилось: 1. **Удалено:** `exclude_ids.add(request_obj.employee.id)` - автор больше не исключается 2. **Упрощена логика:** - Старое: `if new_status not in (...): recipients_to_notify.add(request_obj.employee)` - Новое: `recipients_to_notify.add(request_obj.employee)` (всегда добавляем) 3. **Сохранено:** `exclude_ids.add(request_obj.approver_id)` - approver остается исключенным (правильно) ## ✅ Решение (ИСПРАВЛЕНО) ## 📊 Дополнительные замечания ### Логика исключения approver верна ✅ - `approver_id` должен быть исключен (он сам нажал кнопку, не нужно ему уведомление) ### Логика исключения employee неверна ❌ - Была добавлена с ошибочным предположением о том, что пользователь видит результат на странице - После убрания `alert()` это предположение больше не верно - Пользователь должен получать уведомление ## 🔗 Файлы для исправления 1. `backend/requests_app/notification_signals.py` (строки 356-362) - Функция: `notify_status_change()` - Действие: Удалить `exclude_ids.add(request_obj.employee.id)` --- ## 📝 Коммит с исправлением **Hash:** `de0caea` **Дата:** 5 января 2026 **Сообщение:** ``` fix: автор заявления должен получать уведомления о решении (approve/reject) - Удалено исключение employee.id из notify_status_change() - Коммит c0b659f9 ошибочно исключал автора, предполагая что он видит результат на странице - После удаления alert() в коммите 935c12a уведомление стало единственным способом информирования - Теперь автор получает уведомление о одобрении/отклонении заявления - Approver остается исключенным (он сам нажал кнопку, не нужно ему уведомление) ``` ## ✔️ Проверочный список - [x] **Найдена причина:** Коммит c0b659f9 добавил ошибочное исключение автора - [x] **Проанализирована цепочка:** 935c12a убрал alert → уведомление стало критичным - [x] **Реализовано решение:** Удаление автора из exclude_ids - [x] **Создан коммит:** de0caea с исправлением - [x] **Документировано:** Этот отчет ## 🧪 Как проверить исправление? 1. Создать заявление через интерфейс (автор = Current User) 2. От другого аккаунта (approver) одобрить заявление 3. **Ожидаемый результат:** - ✅ Автор заявления получит уведомление об одобрении - ✅ Approver НЕ получит уведомление о своем решении - ✅ Recipients и CC users получат уведомления ## 📌 Важные замечания ### Почему approver остается исключенным? - Он сам нажал кнопку "Одобрить/Отклонить" - Он видит результат немедленно - Ему не нужно уведомление о собственном действии ### Почему employee ДОЛЖЕН быть включен? - Коммит 935c12a убрал `alert()` с синхронным уведомлением - Автор может не находиться на странице в момент согласования - Уведомление - это единственный способ информировать его результат