← К списку версий
v0.87.0
30.09.2026
MINOR
Отчёты за период: только задачи, закрытые внутри него
ТЗ «Отчёты перестали повторять старые задачи». Список выполненных в отчётах больше не строится как «все completed, limit(5)»: добавлена дата закрытия задачи tasks.completed_at, которая проставляется в момент реального перехода в статус «выполнена». В письмо попадает только то, что закрыто внутри выбранного периода — недели, месяца, календарного сезона или года. Каждое отсеяние объясняется причиной, администратор видит состав отчёта в предпросмотре и может снять задачу вручную, а повторная отправка за тот же период больше не дублирует уже отправленные задачи. Версия v0.87.0.
Что сделано
- Дата закрытия - В таблицу задач добавлено поле completed_at. Оно заполняется только в момент фактического перехода задачи в статус «выполнена», а не при каждом сохранении: иначе любая пересинхронизация старой задачи проставила бы ей сегодняшнее число и отчёт за тот период втянул бы чужую работу.
- Отчётный период - Появился сервис периодов: неделя (пн–вс), месяц, календарный сезон (зима — декабрь–февраль через два года, весна — март–май, лето — июнь–август, осень — сентябрь–ноябрь) и год. Период письма хранится в его метаданных, поэтому пересборка и предпросмотр старого письма не «уезжают» на текущий период.
- Прозрачный отбор - Новый отборщик возвращает и включённые задачи, и отсеянные с причиной: завершена вне периода, скрыта от клиента, нет задач на платформе, нет даты завершения, уже была в отправленном отчёте, снята вручную. Причина показывается и в CLI, и в предпросмотре в админке.
- Ручное исключение - В предпросмотре «Итоги недели» появилась панель «Состав отчёта»: задачи с галочками уходят клиенту, снятая галочка сохраняется в письме и учитывается как при предпросмотре, так и при реальной отправке.
- Защита от повторов - Уже отправленные за этот же период задачи не попадают в новое письмо повторно. Учитываются только реально отправленные письма, поэтому пересборка письма не исключает задачи по собственным же данным этого письма.
- Команды - mail:send-reports получил параметры --period (week|month|season|year) и --at, а --dry-run теперь показывает состав отчёта с причинами отсечения. Месячное письмо 1-го числа подписывается итогами прошлого месяца: 1 октября — это итоги сентября.
Что важно знать
- Старые закрытые задачи - Даты закрытия у них достоверно восстановить нельзя: в базе нет ни одного источника точной даты, а updated_at перезаписывается синхронизацией (все 605 закрытых задач лежат на 5 датах запусков синка). Автоматически проставлять им дату нельзя — весь бэклог попал бы в отчёт за сентябрь. Поэтому у них completed_at остаётся пустым: в отчёт они не попадают и видны в предпросмотре с причиной «Нет даты завершения».
- Осознанное решение оператора - Новая команда tasks:assign-completed-at проставляет дату вручную: по конкретной дате или по концу периода, с ограничением по проекту и лимиту, с --dry-run.
Что не сломалось
- Письма обновлений - Рассылка обновлений проекта (task_update) не менялась: она по-прежнему строится по событиям синхронизации.
- Текущие в работе - Списки задач «в работе» и планы не фильтруются по периоду — период относится только к выполненным.
- Календарь отчётов - Поиск писем в календаре «Итоги недели» теперь учитывает оба типа служебных писем (report и reports), поэтому плановые и фактические письма больше не теряются из списка.
Результат
- Отчёт за неделю, месяц, сезон или год содержит ровно те задачи, которые закрыты внутри этого периода; каждое отсеяние объяснено причиной и видно до отправки, повторные рассылки не дублируют старую работу, а планировщик писем узнаёт свой период по дате отправки.