SES-009: add (Cron)
Техническое задание / Спецификация требований Настроить автоматическую очистку (Cron) устаревших и отозванных токенов
- Эпик: Авторизация и аутентификация (EPIC-10)
- Компонент: Postgres (Auth DB), DevOps / Linux OS Cron (или Kubernetes CronJob)
- Зависимости: SES-007 (Реализация логаута), SES-008 (Валидация токенов)
- Статус: Готово к реализации
- Ссылка на Jira: SES-009
1. Бизнес-контекст и цель (Business Context)
В ходе работы методов выдачи (/auth/login), ротации (/auth/refresh) и принудительного отзыва сессий (/auth/logout), в таблице refresh_tokens непрерывно накапливаются исторические данные. Токены, у которых истек срок действия (expires_at), либо которые уже были явно отозваны (is_revoked = true), более не имеют технической ценности.
Накопление миллионов мертвых записей приводит к деградации производительности базы данных, раздуванию индексов (B-Tree Bloat) и увеличению времени выполнения поисковых запросов при валидации сессий.
Цель задачи: Настроить фоновую периодическую задачу (Cron-скрипт / CronJob), которая раз в сутки автоматически и безвозвратно удаляет из базы данных Postgres устаревшие и невалидные токены.
2. Пользовательские истории (User Stories)
Как Системный администратор / DevOps-инженер платформы,
Я хочу чтобы база данных автоматически очищалась от невалидных сессионных данных по расписанию,
Чтобы поддерживать стабильно высокую скорость выполнения SQL-запросов и оптимизировать использование дискового пространства.
3. Системные требования и логика базы данных (Technical Requirements)
3.1. Критерии удаления записей (Бизнес-правила)
Запись из таблицы refresh_tokens подлежит гарантированному удалению, если она соответствует любому из следующих условий: 1. Токен просрочен: Текущее время сервера превышает срок действия токена (NOW() > expires_at). 2. Токен отозван: Флаг is_revoked переведен в состояние true (пользователь выполнил логаут), И с момента его создания/истечения прошло более 24 часов (для гарантированного отлова потенциальных Replay Attack в течение суток).
3.2. Оптимизированный SQL-запрос (DML)
Для минимизации нагрузки на базу данных и исключения блокировок живых сессий (Row Lock), удаление должно выполняться одним компактным запросом:
DELETE FROM refresh_tokens
WHERE expires_at < NOW()
OR (is_revoked = true AND expires_at < NOW() - INTERVAL '1 day');Если в таблице на момент первого запуска накопилось более 10 000 000 записей, прямой DELETE может вызвать всплеск нагрузки на CPU и диск (I/O Spike). Для первого запуска в продакшене рекомендуется выполнять удаление пачками (Batches) по 50 000 строк через LIMIT в цикле.
4. Требования к инфраструктуре и расписанию (DevOps / Deployment)
4.1. Настройка расписания (Cron Schedule)
Очистка должна запускаться ежедневно в период минимальной активности пользователей платформы (например, в 03:30 ночи по часовому поясу сервера).
- Выражение Cron:
30 3 * * *
4.2. Способ реализации (на выбор инженера)
В зависимости от текущей архитектуры деплоя микросервисов выбрать один из вариантов: * Вариант А (Если монолит/VPS): Вызов bash-скрипта через системный crontab демона Linux OS, выполняющий psql -c "DELETE...". * Вариант Б (Если Docker/Kubernetes): Запуск изолированного пода Kubernetes CronJob с образом Postgres-клиента и настроенными Environment Variables для доступа к Auth DB.
4.3. Логирование результатов
Скрипт очистки обязан логировать результаты выполнения в системный журнал (stdout / Loki):
[2026-05-29 03:30:01] [INFO] Starting SES-009: Refresh token table cleanup.
[2026-05-29 03:30:04] [INFO] Cleanup finished successfully. Removed rows: 142,503.
5. Критерии приемки и сценарии тестирования (QA Acceptance Criteria)
Сценарий 1: Проверка удаления просроченного токена
- Дано: В таблице
refresh_tokensесть записьID=101, гдеexpires_atравен вчерашнему дню, аis_revoked = false. - Когда: Наступает время
03:30и срабатывает Cron-задача. - Тогда:
- Запись
ID=101полностью удаляется из таблицы. - Индексы пересчитываются автоматически.
- Запись
Сценарий 2: Сохранение активных сессий (Негативный тест)
- Дано: В таблице есть запись
ID=102, где токен активен (is_revoked = false) и будет действовать еще 30 дней. - Когда: Срабатывает ежедневный скрипт очистки.
- Тогда: Запись
ID=102остается в базе данных без изменений. Пользовательская сессия в приложении AgroLaborApp не прерывается.