diff --git a/backend/docs/reports/ENDPOINTS_LIST.md b/backend/docs/reports/ENDPOINTS_LIST.md new file mode 100644 index 00000000..aa0b289b --- /dev/null +++ b/backend/docs/reports/ENDPOINTS_LIST.md @@ -0,0 +1,372 @@ +# Список всех эндпоинтов Django проекта EUSRR + +**Дата:** 26 декабря 2025 г. + +--- + +## 🔐 Аутентификация (`/auth/`) + +### Frontend Auth +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET/POST | `/auth/login/` | Вход по email или телефону | `EmailOrPhoneLoginView` | +| GET/POST | `/auth/logout/` | Подтверждение выхода | `ConfirmLogoutView` | +| GET/POST | `/auth/register/` | Регистрация | `register_view` | +| GET/POST | `/auth/verify-email/` | Подтверждение email | `verify_email_view` | +| POST | `/auth/resend-email/` | Повторная отправка email | `resend_email_view` | +| GET/POST | `/auth/password-reset/` | Сброс пароля | `PasswordResetView` | +| GET | `/auth/password-reset/done/` | Подтверждение отправки | `PasswordResetDoneView` | +| GET/POST | `/auth/reset///` | Подтверждение сброса | `PasswordResetConfirmView` | +| GET | `/auth/reset/done/` | Завершение сброса | `PasswordResetCompleteView` | + +--- + +## 📄 Документы (`/documents/`) + +### Frontend +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/documents/` | Список документов | `DocumentView` | +| POST | `/documents/ack//` | Подтверждение прочтения | `acknowledge_document` | + +--- + +## 📝 Заявки (`/requests/`) + +### Frontend +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/requests/` | Список заявок (основной view) | `RequestsView` | +| GET | `/requests/my/` | Мои заявки | `my_requests` | +| GET | `/requests/all/` | Все заявки | `all_requests` | +| GET/POST | `/requests/new/` | Создать заявку | `request_create` | +| GET | `/requests//` | Детали заявки | `request_detail` | +| POST | `/requests//process/` | Обработать заявку | `request_process` | +| POST | `/requests//cancel/` | Отменить заявку | `request_cancel` | +| GET | `/requests/comments//` | Комментарии к заявке | `request_comments` | +| POST | `/requests/comments//add/` | Добавить комментарий | `request_comment_add` | +| POST | `/requests//comments/add/` | Добавить комментарий (альт.) | `request_comment_add` | +| POST | `/requests//comments//delete/` | Удалить комментарий | `request_comment_delete` | + +--- + +## 👥 Сотрудники (`/employees/`) + +### Frontend +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/employees/list/` | Список сотрудников | `employee_list` | +| GET | `/employees/me/` | Мой профиль | `employee_profile` | +| GET/POST | `/employees/me/edit/` | Редактировать профиль | `employee_edit_me` | +| GET | `/employees//` | Профиль сотрудника | `employee_profile` | +| GET/POST | `/employees//edit/` | Редактировать сотрудника | `employee_edit` | +| GET/POST | `/employees/create/` | Создать сотрудника | `employee_create` | +| GET/POST | `/employees/create/modal/` | Создать (модальное окно) | `employee_create_modal` | + +#### Группы +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| POST | `/employees/employees//groups/bulk/` | Массовое управление группами | `employee_groups_bulk` | +| POST | `/employees/groups/create/` | Создать группу | `group_create` | +| POST | `/employees/groups/delete/` | Удалить группу | `group_delete` | + +#### Отделы +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/employees/departments/` | Список отделов | `department_list` | +| GET | `/employees/departments//` | Детали отдела | `department_detail` | +| POST | `/employees/departments/create/` | Создать отдел | `department_create` | +| GET/POST | `/employees/departments//edit/` | Редактировать отдел | `department_edit` | +| POST | `/employees/departments//set-head/` | Назначить руководителя | `department_set_head` | +| POST | `/employees/departments//roles/edit/` | Изменить роль в отделе | `edit_department_role` | +| POST | `/employees//departments//set-role/` | Установить роль члена | `set_member_role` | +| POST | `/employees/departments//add-member/` | Добавить сотрудника | `department_add_member` | +| POST | `/employees/departments//remove-member/` | Удалить сотрудника | `department_remove_member` | + +#### Навыки +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| POST | `/employees//skill/add/` | Добавить навык | `skill_add` | +| POST | `/employees//skill/remove/` | Удалить навык | `skill_remove` | + +#### Должности +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| POST | `/employees/positions/create/` | Создать должность | `position_create_front` | +| GET | `/employees/positions//` | Детали должности | `position_detail_front` | +| POST | `/employees/positions//update/` | Обновить должность | `position_update_front` | +| POST | `/employees//set-position/` | Установить должность | `employee_set_position_front` | +| POST | `/employees/me/set-position/` | Установить свою должность | `employee_set_position_me_front` | + +--- + +## 💬 Мессенджер (`/communications/`) + +### Frontend +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/communications/chats/` | Список чатов | `ChatListView` | +| GET | `/communications/chats//` | Детали чата | `ChatDetailView` | +| GET | `/communications/test/websocket-events/` | Тестирование WebSocket | TemplateView | +| POST | `/communications/chats/start//` | Начать приватный чат | `start_private_chat` | +| POST | `/communications/start/private//` | Начать приватный чат (альт.) | `start_private_chat` | +| POST | `/communications/chats//mark-read/` | Отметить как прочитанное | `chat_mark_read` | + +--- + +## 🔔 Уведомления (`/notifications/`) + +### Frontend +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/notifications/` | Список уведомлений | `notification_list` | +| GET/POST | `/notifications/settings/` | Настройки уведомлений | `notification_settings` | +| POST | `/notifications/test/create/` | Создать тестовое уведомление | `create_test_notification` | + +--- + +## 🔍 Поиск (`/search/`) + +### Frontend +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/search/` | Глобальный поиск | `search_view` | + +--- + +## 💰 Финансы (`/finance/`) + +### Frontend +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/finance/` | Панель финансов | `finance_dashboard` | + +--- + +## 📰 Лента новостей (`/` - feed) + +### Frontend +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/` | Главная лента | `feed_list` | +| GET | `/departments//` | Лента отдела | `department_feed` | +| GET | `/employees//` | Лента сотрудника | `employee_feed` | +| GET | `/post//` | Детали поста | `post_detail` | +| POST | `/post//pin/` | Закрепить пост | `pin_post` | +| POST | `/post//like/` | Лайк/дизлайк поста | `toggle_like` | + +--- + +## 🔌 API (`/api/`) + +### Аутентификация API +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| POST | `/api/auth/token/` | Получить JWT токен | `PhoneOrEmailTokenObtainPairView` | +| POST | `/api/auth/token/refresh/` | Обновить JWT токен | `TokenRefreshView` | + +--- + +## 🔌 API v1 (`/api/v1/`) + +### Аутентификация +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| POST | `/api/v1/auth/register/` | Регистрация | `RegisterAPIView` | +| POST | `/api/v1/auth/resend-email/` | Повторная отправка email | `ResendEmailAPIView` | +| POST | `/api/v1/auth/verify-email/` | Подтверждение email | `VerifyEmailAPIView` | + +### Календарь +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/calendar/events/` | Список/создание событий | `CalendarEventsViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/calendar/events//` | CRUD события | `CalendarEventsViewSet` | + +### Документы +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/documents/` | Список/создание документов | `DocumentViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/documents//` | CRUD документа | `DocumentViewSet` | + +### Заявки +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/requests/` | Список/создание заявок | `RequestViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/requests//` | CRUD заявки | `RequestViewSet` | + +### Отделы +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/departments/` | Список/создание отделов | `DepartmentViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/departments//` | CRUD отдела | `DepartmentViewSet` | + +### Сотрудники +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/employees/` | Список/создание сотрудников | `EmployeeViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/employees//` | CRUD сотрудника | `EmployeeViewSet` | +| GET/POST | `/api/v1/employee-actions/` | Действия сотрудников | `EmployeeActionViewSet` | + +### Должности +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/positions/` | Список/создание должностей | `PositionViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/positions//` | CRUD должности | `PositionViewSet` | + +### Роли в отделах +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/department-roles/` | Список/создание ролей | `DepartmentRoleViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/department-roles//` | CRUD роли | `DepartmentRoleViewSet` | + +### Навыки +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/skills/` | Список/создание навыков | `SkillViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/skills//` | CRUD навыка | `SkillViewSet` | + +### Группы +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/groups/` | Список/создание групп | `GroupViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/groups//` | CRUD группы | `GroupViewSet` | + +### Лента +| Метод | URL | Описание | ViewSet | +|-------|-----|----------|---------| +| GET/POST | `/api/v1/posts/` | Список/создание постов | `PostViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/posts//` | CRUD поста | `PostViewSet` | +| GET/POST | `/api/v1/comments/` | Список/создание комментариев | `CommentViewSet` | +| GET/PUT/PATCH/DELETE | `/api/v1/comments//` | CRUD комментария | `CommentViewSet` | + +### Мессенджер API +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/api/v1/communications/chats/` | Список чатов пользователя | `get_user_chats` | +| POST | `/api/v1/communications/chats/create/` | Создать чат | `create_chat` | +| GET | `/api/v1/communications/chats//messages/` | Загрузить сообщения чата | `load_chat_messages` | +| POST | `/api/v1/communications/chats//pin/` | Закрепить/открепить чат | `pin_chat` | +| POST | `/api/v1/communications/upload-message/` | Отправить сообщение с файлами | `upload_message_with_attachments` | + +#### Реакции +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/api/v1/communications/reactions/available/` | Доступные реакции | `get_available_reactions` | +| GET | `/api/v1/communications/messages//reactions/` | Реакции на сообщение | `get_message_reactions` | +| POST | `/api/v1/communications/messages//react/` | Добавить реакцию | `add_reaction` | +| DELETE | `/api/v1/communications/messages//unreact/` | Удалить реакцию | `remove_reaction` | + +#### Операции с сообщениями +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| PUT/PATCH | `/api/v1/communications/messages//edit/` | Редактировать сообщение | `edit_message` | +| DELETE | `/api/v1/communications/messages//delete/` | Удалить сообщение | `delete_message` | +| POST | `/api/v1/communications/messages/forward/` | Переслать сообщения | `forward_messages` | +| POST | `/api/v1/communications/messages/bulk-delete/` | Массовое удаление | `bulk_delete_messages` | + +#### Опросы +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| POST | `/api/v1/communications/polls/create/` | Создать опрос | `create_poll` | +| POST | `/api/v1/communications/polls//vote/` | Проголосовать | `vote_poll` | +| POST | `/api/v1/communications/polls//close/` | Закрыть опрос | `close_poll` | +| GET | `/api/v1/communications/polls//results/` | Результаты опроса | `get_poll_results` | + +### Уведомления API +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/api/notifications/` | Список уведомлений | `get_notifications` | +| GET | `/api/notifications/count/` | Количество непрочитанных | `get_unread_count` | +| POST | `/api/notifications//read/` | Отметить как прочитанное | `mark_as_read` | +| POST | `/api/notifications/read-all/` | Отметить все прочитанными | `mark_all_as_read` | +| DELETE | `/api/notifications//` | Удалить уведомление | `delete_notification` | +| GET | `/api/notifications/categories/` | Категории уведомлений | `get_categories` | +| GET | `/api/notifications/settings/` | Получить настройки | `get_user_settings` | +| PUT | `/api/notifications/settings/update/` | Обновить настройки | `update_user_settings` | +| PUT | `/api/notifications/settings/category/update/` | Обновить настройки категории | `update_category_settings` | + +#### Telegram интеграция +| Метод | URL | Описание | View | +|-------|-----|----------|------| +| GET | `/api/notifications/telegram/status/` | Статус привязки Telegram | `get_telegram_link_status` | +| POST | `/api/notifications/telegram/generate-code/` | Сгенерировать код привязки | `generate_telegram_link_code` | +| POST | `/api/notifications/telegram/unlink/` | Отвязать Telegram аккаунт | `unlink_telegram` | + +--- + +## 🎯 Админка + +| URL | Описание | +|-----|----------| +| `/admin/` | Django Admin Panel | + +--- + +## 📊 Статистика + +**Всего эндпоинтов:** ~158+ + +### По разделам: +- **Аутентификация (Frontend):** 9 +- **Аутентификация (API):** 5 +- **Документы:** 2 +- **Заявки (Frontend):** 11 +- **Заявки (API):** ViewSet (5 методов) +- **Сотрудники (Frontend):** 24 +- **Сотрудники (API):** 3 ViewSets + endpoints +- **Мессенджер (Frontend):** 6 +- **Мессенджер (API):** 19 +- **Уведомления (Frontend):** 3 +- **Уведомления (API):** 12 (9 основных + 3 Telegram) +- **Поиск:** 1 +- **Финансы:** 1 +- **Лента (Frontend):** 6 +- **Лента (API):** 2 ViewSets +- **Календарь (API):** 1 ViewSet +- **Прочие ViewSets:** 7 +- **WebSocket:** 1 endpoint + +--- + +## 🔗 WebSocket + +### Realtime (Django Channels) +- **URL Pattern:** `ws://your-domain/ws/` (WebSocket) +- **Consumer:** `UserConsumer` (realtime.consumers) +- **Функции:** + - Чаты и сообщения в реальном времени + - Уведомления в реальном времени + - Обновление бейджей + - Онлайн-статус пользователей + - Другие real-time события + +--- + +## 📝 Примечания + +1. **ViewSet endpoints** включают стандартные операции CRUD: + - `list` (GET на коллекцию) + - `create` (POST на коллекцию) + - `retrieve` (GET на элемент) + - `update` (PUT на элемент) + - `partial_update` (PATCH на элемент) + - `destroy` (DELETE на элемент) + +2. **Namespace structure:** + ``` + api:v1:endpoint_name + auth_front:login + employees:profile + communications:chat_list + etc. + ``` + +3. **API Authentication:** + - JWT токены для API (`/api/auth/token/`) + - Session auth для Frontend views + +4. **Media files:** Доступны по `/media/` (настроено через `static()`) + +--- + +**Сгенерировано:** 26 декабря 2025 г. diff --git a/backend/docs/reports/NOTIFICATION_URLS_AUDIT.md b/backend/docs/reports/NOTIFICATION_URLS_AUDIT.md new file mode 100644 index 00000000..1b44fb78 --- /dev/null +++ b/backend/docs/reports/NOTIFICATION_URLS_AUDIT.md @@ -0,0 +1,271 @@ +# Аудит URL в уведомлениях + +**Дата проверки:** 26 декабря 2025 г. + +## 🔍 Цель проверки + +Сверить URL-адреса, которые генерируются в `action_url` уведомлений, с реальными эндпоинтами проекта. + +--- + +## ❌ Найденные проблемы + +### 1. **Feed (Лента новостей)** - НЕКОРРЕКТНЫЕ URL + +#### Проблема в файле: `backend/feed/notification_signals.py` + +**Генерируемые URL:** +```python +action_url=f'/feed/post/{post.id}/' # ❌ НЕПРАВИЛЬНО (строки 61, 99, 175) +``` + +**Реальные эндпоинты:** +- ✅ `/post/{pk}/` - правильный URL (согласно `feed/urls_front.py`) + +**Необходимое исправление:** +```python +action_url=f'/post/{post.id}/' # ✅ ПРАВИЛЬНО +``` + +**Файлы для исправления:** +- `backend/feed/notification_signals.py` (строки 61, 99, 175) + +--- + +### 2. **Calendar (Календарь)** - СПЕЦИФИЧНАЯ ЛОГИКА + +#### Файл: `backend/calendar_app/notification_signals.py` + +**Генерируемый URL:** +```python +action_url=f'/?event_id={event.id}' # Редирект на главную с параметром +``` + +**Реальные API эндпоинты:** +- API: `/api/v1/calendar/events/` (ViewSet) +- Frontend: Нет отдельных frontend views для календаря + +**Статус:** ⚠️ **УСЛОВНО ПРАВИЛЬНО** +- Календарь не имеет отдельной frontend страницы +- Используется модальное окно на главной странице +- URL корректен для текущей реализации +- **Рекомендация:** Если в будущем добавится страница календаря, изменить на `/calendar/?event_id={event.id}` + +--- + +### 3. **Documents (Документы)** - URL МОГУТ БЫТЬ НЕТОЧНЫМИ + +#### Файл: `backend/documents/notification_signals.py` + +**Генерируемые URL:** +```python +action_url=f'/documents/{document.id}/' # ❌ ВОЗМОЖНО НЕПРАВИЛЬНО (строки 345, 464) +``` + +**Реальные эндпоинты:** +- ✅ `/documents/` - список документов +- ✅ `/documents/ack/{pk}/` - подтверждение ознакомления +- ❌ `/documents/{pk}/` - **НЕ СУЩЕСТВУЕТ** + +**Проблема:** +Нет эндпоинта для просмотра отдельного документа. Есть только список. + +**Возможные решения:** + +1. **Вариант А:** Вести на список документов с якорем + ```python + action_url=f'/documents/#document-{document.id}' + ``` + +2. **Вариант Б:** Создать view для детального просмотра документа + ```python + # В documents/urls.py добавить: + path('/', DocumentDetailView.as_view(), name='document_detail'), + ``` + +3. **Вариант В:** Открывать модальное окно с параметром + ```python + action_url=f'/documents/?doc_id={document.id}' + ``` + +**Статус:** ❌ **ТРЕБУЕТ ИСПРАВЛЕНИЯ** + +--- + +### 4. **Requests (Заявки)** - НЕКОРРЕКТНЫЕ URL + +#### Файл: `backend/requests_app/notification_signals.py` + +**Генерируемые URL:** +```python +action_url=f'/requests/{request_obj.id}/' # ❌ НЕПРАВИЛЬНО (строки 122, 231, 315) +``` + +**Реальные эндпоинты:** +- ✅ `/requests/` - главная страница заявок (RequestsView) +- ✅ `/requests/my/` - мои заявки +- ✅ `/requests/all/` - все заявки +- ✅ `/requests/{pk}/` - ✅ **ПРАВИЛЬНО** - детали заявки (request_detail) + +**Статус:** ✅ **ПРАВИЛЬНО** +Эндпоинт существует согласно `requests_app/urls.py` (строка в urls_front.py: path("/", ...)) + +--- + +### 5. **Communications (Мессенджер)** - ПРАВИЛЬНЫЕ URL + +#### Файл: `backend/communications/notification_signals.py` + +**Генерируемые URL:** +```python +action_url=f'/communications/chats/{chat.id}/?message={instance.id}' # ✅ (строки 63, 87) +action_url=f'/communications/chats/{chat.id}/' # ✅ (строки 117, 136, 180) +``` + +**Реальные эндпоинты:** +- ✅ `/communications/chats/{pk}/` - детали чата (ChatDetailView) + +**Статус:** ✅ **ПРАВИЛЬНО** + +--- + +## 📊 Сводная таблица проверки + +| Приложение | Генерируемый URL | Реальный эндпоинт | Статус | Действие | +|------------|------------------|-------------------|--------|----------| +| **feed** | ~~`/feed/post/{id}/`~~ → `/post/{id}/` | `/post/{id}/` | ✅ | **Исправлено** | +| **calendar** | `/?event_id={id}` | Нет отдельной страницы | ⚠️ | Мониторить | +| **documents** | ~~`/documents/{id}/`~~ → `/documents/` | `/documents/` (список) | ✅ | **Исправлено** | +| **requests** | `/requests/{id}/` | `/requests/{pk}/` | ✅ | Нет действий | +| **communications** | `/communications/chats/{id}/` | `/communications/chats/{pk}/` | ✅ | Нет действий | + +--- + +## 🔧 Требуемые исправления + +### ✅ ИСПРАВЛЕНО: Критичные ошибки + +#### ✅ 1.1 Feed - Исправлены URL постов + +**Файл:** `backend/feed/notification_signals.py` + +**Выполненные замены:** +- ✅ Строка 61: `'/feed/post/{post.id}/'` → `'/post/{post.id}/'` +- ✅ Строка 99: `'/feed/post/{post.id}/'` → `'/post/{post.id}/'` +- ✅ Строка 175: `'/feed/post/{post.id}/'` → `'/post/{post.id}/'` + +**Статус:** ✅ ВЫПОЛНЕНО + +#### ✅ 1.2 Documents - Исправлены URL документов + +**Выбрано решение:** Изменить на список документов (так как DetailView не существует) + +**Файл:** `backend/documents/notification_signals.py` + +**Выполненные замены:** +- ✅ Строка 345: `'/documents/{document.id}/'` → `'/documents/'` +- ✅ Строка 464: `'/documents/{document.id}/'` → `'/documents/'` + +**Обоснование:** +- У Documents нет отдельной страницы для просмотра одного документа +- Список документов показывает все доступные документы +- Пользователь сможет найти нужный документ в списке + +**Статус:** ✅ ВЫПОЛНЕНО + +--- + +## ✅ Проверенные и корректные модули + +1. **Communications** - все URL корректны +2. **Requests** - все URL корректны (есть view для детального просмотра) +3. **Calendar** - работает через модальные окна на главной странице + +--- + +## 📝 Рекомендации + +### 1. Централизованное управление URL + +Создать утилиту для генерации URL уведомлений: + +```python +# notifications/url_builders.py + +def get_post_url(post_id): + """Генерирует URL для поста в ленте""" + return f'/post/{post_id}/' + +def get_document_url(document_id): + """Генерирует URL для документа""" + return f'/documents/?doc_id={document_id}' + +def get_request_url(request_id): + """Генерирует URL для заявки""" + return f'/requests/{request_id}/' + +def get_chat_url(chat_id, message_id=None): + """Генерирует URL для чата""" + url = f'/communications/chats/{chat_id}/' + if message_id: + url += f'?message={message_id}' + return url +``` + +**Преимущества:** +- Единая точка изменения URL +- Проще тестировать +- Легче поддерживать + +### 2. Автоматическая проверка URL + +Добавить тесты для проверки корректности URL в уведомлениях: + +```python +# notifications/tests/test_urls.py + +def test_notification_urls_are_valid(): + """Проверяет, что URL в уведомлениях существуют""" + from django.urls import resolve, Resolver404 + + test_urls = [ + '/post/1/', + '/documents/', + '/requests/1/', + '/communications/chats/1/', + ] + + for url in test_urls: + try: + resolve(url) + except Resolver404: + assert False, f"URL {url} не существует" +``` + +### 3. Документация URL паттернов + +Создать файл с описанием всех URL паттернов для уведомлений в `docs/`. + +--- + +## 🎯 План действий + +### ✅ Выполнено: +1. ✅ Исправлены URL в `feed/notification_signals.py` (3 места) +2. ✅ Исправлены URL в `documents/notification_signals.py` (2 места) + +### В ближайшее время: +3. ⚠️ Создать утилиту для генерации URL (`notifications/url_builders.py`) +4. ⚠️ Добавить тесты для проверки URL +5. ⚠️ Обновить все signals для использования новой утилиты + +### Долгосрочно: +6. 📝 Добавить проверку URL в CI/CD +7. 📝 Создать документацию по URL паттернам +8. 📝 Рассмотреть создание DetailView для documents (если потребуется) + +--- + +**Итого найдено проблем:** 2 критичные (✅ исправлены), 1 предупреждение +**Проверено модулей:** 5 +**Общий статус:** ✅ **Все критичные проблемы исправлены** diff --git a/backend/documents/notification_signals.py b/backend/documents/notification_signals.py index 164d4035..d1085615 100644 --- a/backend/documents/notification_signals.py +++ b/backend/documents/notification_signals.py @@ -342,7 +342,7 @@ def check_all_acknowledged(sender, instance, created, **kwargs): f'"{document.title}"' ), content_object=document, - action_url=f'/documents/{document.id}/', + action_url='/documents/', metadata={ 'document_id': document.id, 'total_recipients': total_recipients, @@ -461,7 +461,7 @@ def create_document_ready_notification(document, recipient, send_immediately=Tru f'Требуется ознакомление.' ), content_object=document, - action_url=f'/documents/{document.id}/', + action_url='/documents/', metadata={ 'document_id': document.id, 'uploaded_by_id': ( diff --git a/backend/feed/notification_signals.py b/backend/feed/notification_signals.py index a739ae40..1bf202db 100644 --- a/backend/feed/notification_signals.py +++ b/backend/feed/notification_signals.py @@ -58,7 +58,7 @@ def create_comment_notification(sender, instance, created, **kwargs): f' прокомментировал: {truncate_text(comment.text, 80)}' ), content_object=post, - action_url=f'/feed/post/{post.id}/', + action_url=f'/post/{post.id}/', metadata={ 'post_id': post.id, 'post_title': post.title, @@ -96,7 +96,7 @@ def notify_new_post(post): title=f'Новая публикация {context}', message=f'{post.title}', content_object=post, - action_url=f'/feed/post/{post.id}/', + action_url=f'/post/{post.id}/', metadata={ 'post_id': post.id, 'post_type': post.type, @@ -172,7 +172,7 @@ def notify_post_reaction(post, user): f'понравилась публикация "{post.title}"' ), content_object=post, - action_url=f'/feed/post/{post.id}/', + action_url=f'/post/{post.id}/', metadata={ 'post_id': post.id, 'post_title': post.title, diff --git a/backend/notifications/api_urls.py b/backend/notifications/api_urls.py index cdd7f764..8e519a55 100644 --- a/backend/notifications/api_urls.py +++ b/backend/notifications/api_urls.py @@ -33,4 +33,20 @@ urlpatterns = [ api_views.update_category_settings, name='category_settings_update' ), + # Telegram integration + path( + 'notifications/telegram/status/', + api_views.get_telegram_link_status, + name='telegram_status' + ), + path( + 'notifications/telegram/generate-code/', + api_views.generate_telegram_link_code, + name='telegram_generate_code' + ), + path( + 'notifications/telegram/unlink/', + api_views.unlink_telegram, + name='telegram_unlink' + ), ]