После входа приложение перенаправляло на любой адрес из параметра next — ссылкой
вида /login?next=https://… можно было увести пользователя на чужой сайт.
- экспорт в JSON/CSV/PDF/PNG пускал любого вошедшего к любому расписанию, у которого
есть хоть одна ссылка-приглашение (достаточно перебрать id); теперь — только владелец
и редакторы, как и просмотр по id;
- три копии проверки прав сведены в app/access.py;
- без SECRET_KEY приложение не запускается (кроме отладки и тестов): со значением по
умолчанию cookie сессии можно было подделать и войти под любым пользователем;
- текст исключения от ИИ-провайдера больше не уходит в интерфейс, ошибка пишется в лог;
- DATABASE_URL как альтернатива DB_*; debug в run.py — из FLASK_DEBUG;
- неиспользуемые импорты и переменные удалены (ruff).
- период расписания вида 01.09–03.01 больше не даёт конец раньше начала: конец
относится к следующему году;
- занятия сортируются по времени начала как по числу, «9:00» больше не оказывается
после «10:00»;
- run.py запускает сервер без режима отладки.