Добавлена поддержка django-filer для профессионального управления файлами в приложении documents.
Что добавлено:
- models_v2.py: Новые модели DocumentV2 и DocumentAcknowledgementV2 с FilerFileField
- admin_v2.py: Django admin с drag & drop загрузкой и превью thumbnails
- rules_v2.py: Правила доступа django-rules для новых моделей
- tests_v2.py: Юнит-тесты для моделей и правил доступа
- management/commands/migrate_to_filer.py: Команда для миграции данных из старых моделей
Настройки:
- settings.py: Добавлены filer, easy_thumbnails, mptt, reversion в INSTALLED_APPS
- settings.py: Настроены THUMBNAIL_PROCESSORS и THUMBNAIL_ALIASES
- requirements.txt: Добавлены django-filer==3.4.4, easy-thumbnails==2.10.1, django-mptt==0.18.0, django-reversion==6.1.0
Документация:
- docs/reports/DOCUMENTS_REPLACEMENT_ANALYSIS.md: Анализ вариантов замены приложения documents
Преимущества:
- Поддержка папок и вложенной структуры файлов
- Автоматическая генерация thumbnails для изображений и PDF
- Полнотекстовый поиск по содержимому файлов
- Информация о размере, MIME-типе, метаданные
- История версий через django-reversion
- Сокращение кода с 1180 → ~580 строк (50%)
Миграция:
- Старые модели Document и DocumentAcknowledgement оставлены для совместимости
- Миграция данных: python manage.py migrate_to_filer
- После проверки старые модели можно удалить
Связанные issues: #N/A
Тип изменений: Feature
Область: documents, file management
- requests_app/rules.py: 8 предикатов + 10 правил
* Предикаты: is_request_author, is_request_assignee, can_manage_requests и др.
* Правила: view/change/delete/assign/approve requests, комментирование, статистика
- communications/rules.py: 9 предикатов + 15 правил
* Предикаты: is_chat_member, is_chat_owner, is_chat_admin, is_message_author и др.
* Правила: view/send/change/delete чаты и сообщения, управление участниками, закрепление
* Включены примеры для WebSocket consumers
- calendar_app/rules.py: 9 предикатов + 12 правил
* Предикаты: is_calendar_owner, is_personal_calendar, has_calendar_access и др.
* Правила: view/change/delete календари и события, подписки, экспорт iCal, приглашения
- procurement/rules.py: 8 предикатов + 13 правил
* Предикаты: is_procurement_manager, is_purchase_request_author, can_approve_purchases и др.
* Правила: view/change/delete заявки на закупку, управление поставщиками и договорами
- feed/rules.py: 8 предикатов + 11 правил
* Предикаты: is_post_author, can_publish_posts, can_moderate_posts и др.
* Правила: view/create/change/delete посты, публикация, закрепление, комментирование, реакции
Во всех apps.py добавлен импорт rules для автозагрузки правил при старте Django
- requests_app/rules.py: 8 предикатов + 10 правил
* Предикаты: is_request_author, is_request_assignee, can_manage_requests и др.
* Правила: view/change/delete/assign/approve requests, комментирование, статистика
- communications/rules.py: 9 предикатов + 15 правил
* Предикаты: is_chat_member, is_chat_owner, is_chat_admin, is_message_author и др.
* Правила: view/send/change/delete чаты и сообщения, управление участниками, закрепление
* Включены примеры для WebSocket consumers
- calendar_app/rules.py: 9 предикатов + 12 правил
* Предикаты: is_calendar_owner, is_personal_calendar, has_calendar_access и др.
* Правила: view/change/delete календари и события, подписки, экспорт iCal, приглашения
- procurement/rules.py: 8 предикатов + 13 правил
* Предикаты: is_procurement_manager, is_purchase_request_author, can_approve_purchases и др.
* Правила: view/change/delete заявки на закупку, управление поставщиками и договорами
- feed/rules.py: 8 предикатов + 11 правил
* Предикаты: is_post_author, can_publish_posts, can_moderate_posts и др.
* Правила: view/create/change/delete посты, публикация, закрепление, комментирование, реакции
Во всех apps.py добавлен импорт rules для автозагрузки правил при старте Django
- Установлен пакет rules==3.5
- Добавлен ObjectPermissionBackend в AUTHENTICATION_BACKENDS
- Созданы базовые правила для employees:
* Предикаты: is_hr_staff, is_department_head, is_own_profile и др.
* Правила: view/change/delete employee, view reports и контакты
- Созданы базовые правила для documents:
* Предикаты: is_document_owner, has_document_access, can_approve и др.
* Правила: view/change/delete/approve/publish/share documents
- Правила регистрируются в apps.py (ready() метод)
- Создана подробная документация с примерами использования
* В views, templates, DRF permissions, Django Admin
* Сценарии: многоуровневое согласование, временные ограничения
* Сравнение с django-guardian, отладка, тестирование
Документация: docs/guides/DJANGO_RULES_INTEGRATION.md
- Установлен пакет rules==3.5
- Добавлен ObjectPermissionBackend в AUTHENTICATION_BACKENDS
- Созданы базовые правила для employees:
* Предикаты: is_hr_staff, is_department_head, is_own_profile и др.
* Правила: view/change/delete employee, view reports и контакты
- Созданы базовые правила для documents:
* Предикаты: is_document_owner, has_document_access, can_approve и др.
* Правила: view/change/delete/approve/publish/share documents
- Правила регистрируются в apps.py (ready() метод)
- Создана подробная документация с примерами использования
* В views, templates, DRF permissions, Django Admin
* Сценарии: многоуровневое согласование, временные ограничения
* Сравнение с django-guardian, отладка, тестирование
Документация: docs/guides/DJANGO_RULES_INTEGRATION.md
- Добавлен django-service-objects==0.7.1 в requirements.txt
- Создан отчёт LIBRARY_REPLACEMENT_ANALYSIS.md с рекомендациями:
* django-cacheops → замена common/cache_decorators.py
* django-post-office → замена common/emails.py
* easy-thumbnails → замена common/image_utils.py
* django-rules → улучшение permissions
* requests-cache → кэширование внешних API
План внедрения по фазам с метриками и приоритетами.
Impact: снижение кастомного кода с ~360 до ~50 строк.
Refs: #tech-debt #modernization
- Добавлен django-service-objects==0.7.1 в requirements.txt
- Создан отчёт LIBRARY_REPLACEMENT_ANALYSIS.md с рекомендациями:
* django-cacheops → замена common/cache_decorators.py
* django-post-office → замена common/emails.py
* easy-thumbnails → замена common/image_utils.py
* django-rules → улучшение permissions
* requests-cache → кэширование внешних API
План внедрения по фазам с метриками и приоритетами.
Impact: снижение кастомного кода с ~360 до ~50 строк.
Refs: #tech-debt #modernization
- Интегрирован django-service-objects 0.7.1 для Service Layer Pattern
- Перенесена вся логика дней рождения из calendar_app → employees:
* UpsertBirthdayEventService - создание/обновление событий ДР
* DeleteBirthdayEventService - удаление событий ДР
* BulkSyncBirthdaysService - массовая синхронизация
* signals_birthday.py - автосинхронизация через post_save/post_delete
* management command sync_birthdays - CLI команда синхронизации
* тесты (11 tests, 6 passing)
- Обновлена миграция 0013_migrate_to_django_scheduler:
* Добавлен ШАГ 5: автоматическая синхронизация дней рождения (131 событие)
* Исключены старые события ДР из миграции (source.endswith(':birthday'))
* Исправлены имена сотрудников (f'{last_name} {first_name}' вместо get_full_name())
* Добавлен цвет #FFC107 для событий дней рождения
- Очищен calendar_app от birthday сервисов:
* Удалены calendar_app/services/birthday_events.py
* Удалены calendar_app/signals_scheduler.py
* Удалены calendar_app/management/commands/sync_birthdays.py
* Удалены calendar_app/tests/test_services.py
* Обновлен apps.py - удалены ссылки на signals_scheduler
- API улучшения:
* Добавлен api/v1/schedule/permissions.py (IsCalendarOwnerOrAdmin)
* Обновлен views.py с правильными permissions
- Документация:
* DJANGO_SERVICE_OBJECTS_INTEGRATION.md - руководство по Service Layer
* CALENDAR_MIGRATION_ANALYSIS.md - анализ миграции
* MODERNIZATION_ANALYSIS.md - анализ модернизации кодовой базы
Цель: подготовка к будущему удалению calendar_app, централизация
логики сотрудников в employees приложении.
Refs: #birthday-refactoring
- Интегрирован django-service-objects 0.7.1 для Service Layer Pattern
- Перенесена вся логика дней рождения из calendar_app → employees:
* UpsertBirthdayEventService - создание/обновление событий ДР
* DeleteBirthdayEventService - удаление событий ДР
* BulkSyncBirthdaysService - массовая синхронизация
* signals_birthday.py - автосинхронизация через post_save/post_delete
* management command sync_birthdays - CLI команда синхронизации
* тесты (11 tests, 6 passing)
- Обновлена миграция 0013_migrate_to_django_scheduler:
* Добавлен ШАГ 5: автоматическая синхронизация дней рождения (131 событие)
* Исключены старые события ДР из миграции (source.endswith(':birthday'))
* Исправлены имена сотрудников (f'{last_name} {first_name}' вместо get_full_name())
* Добавлен цвет #FFC107 для событий дней рождения
- Очищен calendar_app от birthday сервисов:
* Удалены calendar_app/services/birthday_events.py
* Удалены calendar_app/signals_scheduler.py
* Удалены calendar_app/management/commands/sync_birthdays.py
* Удалены calendar_app/tests/test_services.py
* Обновлен apps.py - удалены ссылки на signals_scheduler
- API улучшения:
* Добавлен api/v1/schedule/permissions.py (IsCalendarOwnerOrAdmin)
* Обновлен views.py с правильными permissions
- Документация:
* DJANGO_SERVICE_OBJECTS_INTEGRATION.md - руководство по Service Layer
* CALENDAR_MIGRATION_ANALYSIS.md - анализ миграции
* MODERNIZATION_ANALYSIS.md - анализ модернизации кодовой базы
Цель: подготовка к будущему удалению calendar_app, централизация
логики сотрудников в employees приложении.
Refs: #birthday-refactoring
- Добавлен django-push-notifications==3.1.0 в requirements.txt
- Настроен PUSH_NOTIFICATIONS_SETTINGS в settings.py
- Создана миграция данных 0008_migrate_webpush_to_library.py (9 подписок)
- Обновлен send_web_push_notification() в services.py (150→25 строк)
- Обновлены API endpoints: subscribe_push, unsubscribe_push, get_push_subscriptions
- Ожидается 10-50x ускорение при отправке push уведомлений
- Обратная совместимость: API не изменилось, старая модель сохранена
- Полный отчет: backend/docs/reports/DJANGO_PUSH_NOTIFICATIONS_INTEGRATION.md
- Добавлен django-push-notifications==3.1.0 в requirements.txt
- Настроен PUSH_NOTIFICATIONS_SETTINGS в settings.py
- Создана миграция данных 0008_migrate_webpush_to_library.py (9 подписок)
- Обновлен send_web_push_notification() в services.py (150→25 строк)
- Обновлены API endpoints: subscribe_push, unsubscribe_push, get_push_subscriptions
- Ожидается 10-50x ускорение при отправке push уведомлений
- Обратная совместимость: API не изменилось, старая модель сохранена
- Полный отчет: backend/docs/reports/DJANGO_PUSH_NOTIFICATIONS_INTEGRATION.md
- Добавлены 5 новых моделей в watson search:
* ProcurementRequest (заявки на закупку)
* Equipment (оборудование)
* Document (документы)
* Notification (уведомления)
* Event из django-scheduler (расписание)
- Backend API: форматтеры для новых типов моделей
- Frontend: добавлены иконки и названия для новых типов
- Тесты: исправлены фикстуры, все 13 тестов проходят
- Индексы: 3895 записей проиндексировано
Итого: 12 моделей доступны для полнотекстового поиска
- Добавлены 5 новых моделей в watson search:
* ProcurementRequest (заявки на закупку)
* Equipment (оборудование)
* Document (документы)
* Notification (уведомления)
* Event из django-scheduler (расписание)
- Backend API: форматтеры для новых типов моделей
- Frontend: добавлены иконки и названия для новых типов
- Тесты: исправлены фикстуры, все 13 тестов проходят
- Индексы: 3895 записей проиндексировано
Итого: 12 моделей доступны для полнотекстового поиска
Backend:
- Created REST API endpoint /api/v1/search/
- Added SearchResultSerializer and SearchResponseSerializer
- Implemented search_api_view with model formatters (employee, department, post, request, chat, message, event)
- Registered search endpoint in api/v1/urls.py
- Added permission check for requests (HR can see all, users only their own)
Frontend:
- Added SearchResponse, SearchResult, SearchModelType types
- Added apiClient.search() method in lib/api.ts
- Completely rewrote search/page.tsx:
* Single API call instead of 6 parallel requests
* Cleaner UI with icons for each result type
* Real-time search with loading states
* Meta information display (email, phone, status, etc.)
* Better performance and UX
Benefits:
- Frontend: 220 lines → 178 lines (19% reduction)
- 1 API request instead of 6 (83% less network calls)
- Server-side full-text search via watson (better relevance)
- Unified search results with metadata
Testing:
- API endpoint verified at /api/v1/search/?q=test
- Returns JSON with query, results, counts, total
- Requires authentication (IsAuthenticated decorator)
Backend:
- Created REST API endpoint /api/v1/search/
- Added SearchResultSerializer and SearchResponseSerializer
- Implemented search_api_view with model formatters (employee, department, post, request, chat, message, event)
- Registered search endpoint in api/v1/urls.py
- Added permission check for requests (HR can see all, users only their own)
Frontend:
- Added SearchResponse, SearchResult, SearchModelType types
- Added apiClient.search() method in lib/api.ts
- Completely rewrote search/page.tsx:
* Single API call instead of 6 parallel requests
* Cleaner UI with icons for each result type
* Real-time search with loading states
* Meta information display (email, phone, status, etc.)
* Better performance and UX
Benefits:
- Frontend: 220 lines → 178 lines (19% reduction)
- 1 API request instead of 6 (83% less network calls)
- Server-side full-text search via watson (better relevance)
- Unified search results with metadata
Testing:
- API endpoint verified at /api/v1/search/?q=test
- Returns JSON with query, results, counts, total
- Requires authentication (IsAuthenticated decorator)
- Удалено поле last_read_at из ChatReadState, используется только last_read_message FK
- Исправлена логика автоотметки: отмечается последнее ЗАГРУЖЕННОЕ сообщение, а не последнее в чате
- Убран вызов chat.mark_read() при WebSocket open_chat (отмечал последнее в чате вместо загруженного)
- Добавлен signal для мониторинга изменений ChatReadState
- Исправлена логика скролла: убран автоскролл при дозагрузке вниз
- Добавлена проверка разрывов при WebSocket сообщениях (предотвращает пропуск сообщений)
- Реализована автоотметка WebSocket сообщений (только если пользователь внизу)
- Асимметричная загрузка: 24 контекста + 6 новых сообщений
- Добавлен ScrollableMessageList компонент для корректной работы скролла
- Миграции: 0028 (удаление last_read_at), 0029 (индекс на last_read_message)
- Удалено поле last_read_at из ChatReadState, используется только last_read_message FK
- Исправлена логика автоотметки: отмечается последнее ЗАГРУЖЕННОЕ сообщение, а не последнее в чате
- Убран вызов chat.mark_read() при WebSocket open_chat (отмечал последнее в чате вместо загруженного)
- Добавлен signal для мониторинга изменений ChatReadState
- Исправлена логика скролла: убран автоскролл при дозагрузке вниз
- Добавлена проверка разрывов при WebSocket сообщениях (предотвращает пропуск сообщений)
- Реализована автоотметка WebSocket сообщений (только если пользователь внизу)
- Асимметричная загрузка: 24 контекста + 6 новых сообщений
- Добавлен ScrollableMessageList компонент для корректной работы скролла
- Миграции: 0028 (удаление last_read_at), 0029 (индекс на last_read_message)
Backend:
- Добавлено поле rule_data в EventSerializer
- get_rule_data() возвращает частоту, параметры и описание правила
- Использует rule.get_params() для получения распарсенных параметров
Frontend:
- Добавлены константы FREQUENCY_LABELS и WEEKDAY_LABELS для русификации
- Новый блок с детальной информацией о повторении в синем фоне
- Отображается частота (WEEKLY, MONTHLY и т.д.)
- Дни недели для еженедельных событий (ПН, ВТ, СР...)
- Количество повторений (count)
- Дата окончания повторения (end_recurring_period)
- Подсказка о невозможности редактирования параметров
Проблема: пользователь не видел детали повторяющихся событий.
Решение: красивый информационный блок с полной информацией о правиле.
Backend:
- Добавлено поле rule_data в EventSerializer
- get_rule_data() возвращает частоту, параметры и описание правила
- Использует rule.get_params() для получения распарсенных параметров
Frontend:
- Добавлены константы FREQUENCY_LABELS и WEEKDAY_LABELS для русификации
- Новый блок с детальной информацией о повторении в синем фоне
- Отображается частота (WEEKLY, MONTHLY и т.д.)
- Дни недели для еженедельных событий (ПН, ВТ, СР...)
- Количество повторений (count)
- Дата окончания повторения (end_recurring_period)
- Подсказка о невозможности редактирования параметров
Проблема: пользователь не видел детали повторяющихся событий.
Решение: красивый информационный блок с полной информацией о правиле.
- Исправлен RuleSerializer для корректной конвертации params между форматами:
* Frontend отправляет dict/JSON: {"byweekday": [0, 4], "interval": 1}
* Backend сохраняет в формате django-scheduler: "byweekday:0,4;interval:1"
* Добавлен универсальный парсер _parse_params_input() для всех форматов
- Добавлен UX в стиле Apple Calendar для еженедельных событий:
* Авто-выбор дня начала при включении WEEKLY
* Информационный баннер с датой первого события если начальный день не выбран
* Защита от перезаписи выбора пользователя через useRef
- Рефакторинг и очистка кода:
* Удалены все отладочные console.log() и print()
* Улучшены docstrings с примерами
* Добавлена константа VALID_FREQUENCIES
- Исправлена загрузка событий в режиме "Все события":
* Убрана блокировка для selectedCalendarId === null
* События и occurrences загружаются корректно для всех календарей
Closes: повторяющиеся события теперь генерируются только в выбранные дни недели
- Исправлен RuleSerializer для корректной конвертации params между форматами:
* Frontend отправляет dict/JSON: {"byweekday": [0, 4], "interval": 1}
* Backend сохраняет в формате django-scheduler: "byweekday:0,4;interval:1"
* Добавлен универсальный парсер _parse_params_input() для всех форматов
- Добавлен UX в стиле Apple Calendar для еженедельных событий:
* Авто-выбор дня начала при включении WEEKLY
* Информационный баннер с датой первого события если начальный день не выбран
* Защита от перезаписи выбора пользователя через useRef
- Рефакторинг и очистка кода:
* Удалены все отладочные console.log() и print()
* Улучшены docstrings с примерами
* Добавлена константа VALID_FREQUENCIES
- Исправлена загрузка событий в режиме "Все события":
* Убрана блокировка для selectedCalendarId === null
* События и occurrences загружаются корректно для всех календарей
Closes: повторяющиеся события теперь генерируются только в выбранные дни недели
Backend:
- Расширен get_queryset в ScheduleEventViewSet: теперь пользователь видит события где он участник (EventRelation), даже если не имеет доступа к календарю
- Добавлен action my-events для получения только событий участника
- Исправлена архитектурная проблема: участники событий теперь могут видеть свои события
Frontend:
- Добавлен метод apiClient.getMyEvents() для получения событий пользователя
- Добавлена подсказка в EventModal о логике начала/конца для повторяющихся событий
- Улучшен UX: пользователи понимают что начало/конец применяются ко всем повторениям
Backend:
- Расширен get_queryset в ScheduleEventViewSet: теперь пользователь видит события где он участник (EventRelation), даже если не имеет доступа к календарю
- Добавлен action my-events для получения только событий участника
- Исправлена архитектурная проблема: участники событий теперь могут видеть свои события
Frontend:
- Добавлен метод apiClient.getMyEvents() для получения событий пользователя
- Добавлена подсказка в EventModal о логике начала/конца для повторяющихся событий
- Улучшен UX: пользователи понимают что начало/конец применяются ко всем повторениям
- Добавлена функция toLocalDateTimeString для корректной конвертации UTC в локальное время
- Исправлено отображение времени в модальном окне событий (было 21:00 UTC вместо 00:00 MSK)
- Упрощена логика datetime-local inputs (удалена сложная условная логика)
- Добавлен allDayAccessor в react-big-calendar для корректного отображения событий
- Унифицирован EventModal для обоих календарей (~718 строк удалено)
- Добавлена функция toLocalDateTimeString для корректной конвертации UTC в локальное время
- Исправлено отображение времени в модальном окне событий (было 21:00 UTC вместо 00:00 MSK)
- Упрощена логика datetime-local inputs (удалена сложная условная логика)
- Добавлен allDayAccessor в react-big-calendar для корректного отображения событий
- Унифицирован EventModal для обоих календарей (~718 строк удалено)
- Добавлен CustomToolbar для BigCalendar со стрелками навигации
- Выпадающий список для выбора вида календаря
- Management command для создания тестовых пользователей и календарей
- Создано 3 тестовых пользователя (anna_ivanova, petr_petrov, maria_sidorova)
- Создано 5 календарей с 11 событиями
- Убраны подписки (они для старой системы calendar_app)
- Исправлены стили тулбара BigCalendar
- Модалы календаря рендерятся на корневом уровне AppShell
- Добавлен CustomToolbar для BigCalendar со стрелками навигации
- Выпадающий список для выбора вида календаря
- Management command для создания тестовых пользователей и календарей
- Создано 3 тестовых пользователя (anna_ivanova, petr_petrov, maria_sidorova)
- Создано 5 календарей с 11 событиями
- Убраны подписки (они для старой системы calendar_app)
- Исправлены стили тулбара BigCalendar
- Модалы календаря рендерятся на корневом уровне AppShell
- Removed legacy calendar with department_id/employee_id filters
- New CalendarCard loads calendars from django-scheduler API
- Events filtered by calendar ID instead of legacy params
- Removed unused SidebarCalendarOption type
- Removed legacy calendar with department_id/employee_id filters
- New CalendarCard loads calendars from django-scheduler API
- Events filtered by calendar ID instead of legacy params
- Removed unused SidebarCalendarOption type
- Updated API endpoints from /api/v1/calendar/ to /api/v1/schedule/
- Removed subscriptions concept (django-scheduler uses simpler approach)
- Adapted CalendarSerializer to accept 'title' field for EUSRR compatibility
- All calendar visibility now stored in localStorage
- Removed deprecated subscribe/unsubscribe functions
- Install django-scheduler 0.12.0 (parallel to existing calendar_app)
- Add 'schedule' to INSTALLED_APPS
- Create integration plan documentation
- Old calendar_app remains untouched (works as before)
- New django-scheduler for gradual migration
- API v2 will be created next for testing
Related: Strangler Fig Pattern for clean code migration