### ✨ Features
- **Редактирование мигрированных шаутов**: Добавлена мутация `create_draft_from_shout` для создания черновика из существующего опубликованного шаута
- Создаёт черновик со всеми данными из шаута (title, body, lead, topics, authors, media, etc.)
- Проверяет авторство перед созданием черновика
- Переиспользует существующий черновик если он уже создан для этого шаута
- Копирует все связи: авторов и темы (включая main topic)
### 🔧 Fixed
- **NotificationEntity enum**: Исправлена ошибка `NotificationEntity.FOLLOWER` → `NotificationEntity.AUTHOR`
- В enum не было значения `FOLLOWER`, используется `AUTHOR` для уведомлений о подписчиках
### Technical Details
- `core/schema/mutation.graphql`: добавлена мутация `create_draft_from_shout(shout_id: Int!): CommonResult!`
- `core/resolvers/draft.py`: добавлен resolver `create_draft_from_shout` с валидацией авторства
- `core/resolvers/notifier.py`: исправлено использование `NotificationEntity.AUTHOR` вместо несуществующего `FOLLOWER`
- Add support for marking follower notifications as seen (thread='followers')
- Add support for marking new shout notifications as seen
- Use enum constants (NotificationAction, NotificationEntity) instead of strings
- Improve thread ID parsing to support different formats
- Remove obsolete TODO about notification_id offset
- Better error handling with logger.warning() instead of exceptions
Resolves TODOs on lines 253 and 286 in resolvers/notifier.py
🔧 Fixed cache invalidation for featured materials:
- Enhanced invalidate_shout_related_cache with featured keys
- Fixed set_featured/set_unfeatured functions with async cache invalidation
- Materials now correctly appear/disappear from main page on feature/unfeature
✅ Code Quality: Python Standards Compliance
- Ruff linting & formatting checks passed
- MyPy type checking passed
- All functions have proper type hints and docstrings
- Tests passing successfully
Version bump: 0.9.30
### 🍪 CRITICAL Cross-Origin Auth
- **🔧 SESSION_COOKIE_DOMAIN**: Добавлена поддержка поддоменов `.discours.io` для cross-origin cookies
- **🌐 Cross-Origin SSE**: Исправлена работа Server-Sent Events с httpOnly cookies между поддоменами
- **🔐 Unified Auth**: Унифицированы настройки cookies для OAuth, login, refresh, logout операций
- **📝 MyPy Compliance**: Исправлена типизация `SESSION_COOKIE_SAMESITE` с использованием `cast()`
### 🛠️ Technical Changes
- **settings.py**: Добавлен `SESSION_COOKIE_DOMAIN` с типобезопасной настройкой SameSite
- **auth/oauth.py**: Обновлены все `set_cookie` вызовы с `domain` параметром
- **auth/middleware.py**: Добавлена поддержка `SESSION_COOKIE_DOMAIN` в logout операциях
- **resolvers/auth.py**: Унифицированы cookie настройки в login/refresh/logout resolvers
- **auth/__init__.py**: Обновлены cookie операции с domain поддержкой
### 📚 Documentation
- **docs/auth/sse-httponly-integration.md**: Новая документация по SSE + httpOnly cookies интеграции
- **docs/auth/architecture.md**: Обновлены диаграммы для unified httpOnly cookie архитектуры
### 🎯 Impact
- ✅ **GraphQL API** (`v3.discours.io`) теперь работает с httpOnly cookies cross-origin
- ✅ **SSE сервер** (`connect.discours.io`) работает с теми же cookies
- ✅ **Безопасность**: httpOnly cookies защищают от XSS атак
- ✅ **UX**: Автоматическая аутентификация без управления токенами в JavaScript
### Fixed
- 🔧 **OAuth Callback URL**: Исправлено формирование callback URL - добавлен отсутствующий слеш между доменом и путем
- 🔒 **OAuth HTTPS**: Принудительное использование HTTPS для callback URL в продакшне (исправляет ошибку "redirect_uri is not associated")
### Changed
- 🔄 **OAuth Routes**: Возвращены к стандартному формату `/oauth/{provider}` - провайдеры не передают параметр provider в callback
### 🔧 Redis Connection Pool Fix
- **🐛 Fixed "max number of clients reached" error**: Исправлена критическая ошибка превышения лимита соединений Redis
- Добавлен `aioredis.ConnectionPool` с ограничением `max_connections=20` для 5 микросервисов
- Реализовано переиспользование соединений вместо создания новых для каждого запроса
- Добавлено правильное закрытие connection pool при shutdown приложения
- Улучшена обработка ошибок соединения с автоматическим переподключением
- **📊 Health Monitoring**: Добавлен `/health` endpoint для мониторинга состояния Redis
- Отображает количество активных соединений, использование памяти, версию Redis
- Помогает диагностировать проблемы с соединениями в production
- **🔄 Connection Management**: Оптимизировано управление соединениями
- Один connection pool для всех операций Redis
- Автоматическое переподключение при потере соединения
- Корректное закрытие всех соединений при остановке приложения
### 🧪 TypeScript Warnings Fix
- **🏷️ Type Annotations**: Добавлены явные типы для устранения implicit `any` ошибок
- Исправлены типы в `RolesModal.tsx` для параметров `roleName` и `r`
- Устранены все TypeScript warnings в admin panel
### 🚀 CI/CD Improvements
- **⚡ Mypy Optimization**: Исправлена проблема OOM (exit status 137) в CI
- Оптимизирован `mypy.ini` с исключением тяжелых зависимостей
- Добавлен `dmypy` с fallback на обычный `mypy`
- Ограничена область проверки типов только критичными модулями
- Добавлена проверка доступной памяти перед запуском mypy
- **🐳 Docker Build**: Исправлены проблемы с PyTorch зависимостями
- Увеличен `UV_HTTP_TIMEOUT=300` для загрузки больших пакетов
- Установлен `TORCH_CUDA_AVAILABLE=0` для предотвращения CUDA зависимостей
- Упрощены зависимости PyTorch в `pyproject.toml` для совместимости с Python 3.13
### 🚀 ML Models Runtime Preloading
- **🔧 models loading**: Перенесена предзагрузка ML моделей из Docker build в runtime startup
- Убрана предзагрузка из `Dockerfile` - модели теперь загружаются после монтирования `/dump` папки
- Добавлена async функция `preload_models()` в `services/search.py` для фоновой загрузки
- Интеграция предзагрузки в `lifespan` функцию `main.py`
- Использование `asyncio.run_in_executor()` для неблокирующей загрузки моделей
- Исправлена проблема с недоступностью `/dump` папки во время сборки Docker образа
### 🔍 Search System Redis Storage
- **💾 Redis-based vector index storage**: Переключились обратно на Redis для хранения векторного индекса
- Заменили файловое хранение в `/dump` на Redis ключи для надежности
- Исправлена проблема с правами доступа на `/dump` папку на сервере
- Векторный индекс теперь сохраняется по ключам `search_index:{name}:data` и `search_index:{name}:metadata`
- **🛠️ Improved reliability**: Убрали зависимость от файловой системы для критичных данных
- **⚡ Better performance**: Redis обеспечивает более быстрый доступ к индексу
- **🔧 Technical changes**:
- Заменили `save_index_to_file()` на `save_index_to_redis()`
- Заменили `load_index_from_file()` на `load_index_from_redis()`
- Обновили автосохранение для использования Redis вместо файлов
- Удалили неиспользуемые импорты (`gzip`, `pathlib`, `cast`)
### 👥 Author Statistics Enhancement
- **📊 Полная статистика авторов**: Добавлены все недостающие счётчики в AuthorStat
- `topics`: Количество уникальных тем, в которых участвовал автор
- `coauthors`: Количество соавторов
- `replies_count`: Количество вызванных комментариев
- `rating_shouts`: Рейтинг публикаций автора (сумма реакций LIKE/AGREE/ACCEPT/PROOF/CREDIT минус DISLIKE/DISAGREE/REJECT/DISPROOF)
- `rating_comments`: Рейтинг комментариев автора (реакции на его комментарии)
- `replies_count`: Количество вызванных комментариев
- `comments`: Количество созданных комментариев и цитат
- `viewed_shouts`: Общее количество просмотров всех публикаций автора
- **🔄 Улучшенная сортировка**: Поддержка сортировки по всем новым полям статистики
- **⚡ Оптимизированные запросы**: Batch-запросы для получения всей статистики одним вызовом
- **🧪 Подробное логирование**: Эмодзи-маркеры для каждого типа статистики
### 🔧 Technical Implementation
- **Resolvers**: Обновлён `load_authors_by` для включения всех счётчиков
- **Database**: Оптимизированные SQL-запросы с JOIN для статистики
- **Caching**: Интеграция с ViewedStorage для подсчёта просмотров
- **GraphQL Schema**: Обновлён тип AuthorStat с новыми полями
### 🔧 Fixed
- **🧾 Database Table Creation**: Унифицирован подход к созданию таблиц БД между продакшеном и тестами
- Исправлена ошибка "no such table: author" в тестах
- Обновлена функция `create_all_tables()` в `storage/schema.py` для использования стандартного SQLAlchemy подхода
- Улучшены фикстуры тестов с принудительным импортом всех ORM моделей
- Добавлена детальная диагностика создания таблиц в тестах
- Добавлены fallback механизмы для создания таблиц в проблемных окружениях
### 🧪 Testing
- Все RBAC тесты теперь проходят успешно
- Исправлены фикстуры `test_engine`, `db_session` и `test_session_factory`
- Добавлены функции `ensure_all_tables_exist()` и `ensure_all_models_imported()` для диагностики
### 📝 Technical Details
- Заменен подход `create_table_if_not_exists()` на стандартный `Base.metadata.create_all()`
- Улучшена обработка ошибок при создании таблиц
- Добавлена проверка регистрации всех критических таблиц в metadata
- Remove alembic/ directory and alembic.ini file
- Remove Alembic references from pyproject.toml, mypy.ini
- Remove migration logic from main.py
- Update CHANGELOG.md with removal details
- Clean up all configuration files from Alembic settings
### 🚨 Исправлено
- **Удалено поле username из модели Author**: Поле `username` больше не является частью модели `Author`
- Убрано свойство `@property def username` из `orm/author.py`
- Обновлены все сервисы для использования `email` или `slug` вместо `username`
- Исправлены резолверы для исключения `username` при обработке данных автора
- Поле `username` теперь используется только в JWT токенах для совместимости
### 🧪 Исправлено
- **E2E тесты админ-панели**: Полностью переработаны E2E тесты для работы с реальным API
- Тесты теперь делают реальные HTTP запросы к GraphQL API
- Бэкенд для тестов использует выделенную тестовую БД (`test_e2e.db`)
- Создан фикстура `backend_server` для запуска тестового сервера
- Добавлен фикстура `create_test_users_in_backend_db` для регистрации пользователей через API
- Убраны несуществующие GraphQL запросы (`get_community_stats`)
- Тесты корректно работают с системой ролей и правами администратора
### �� Техническое
- **Рефакторинг аутентификации**: Упрощена логика работы с пользователями
- Убраны зависимости от несуществующих полей в ORM моделях
- Обновлены сервисы аутентификации для корректной работы без `username`
- Исправлены все места использования `username` в коде
- **Улучшена тестовая инфраструктура**:
- Тесты теперь используют реальный HTTP API вместо прямых DB проверок
- Правильная изоляция тестовых данных через отдельную БД
- Корректная работа с системой ролей и правами