refactor: период через period.from вместо last_used; дедуп удалён
Удалены last_used, precision, dynamic и дедупликация по created_on/updated_on. Период задаётся одним полем period.from (env FROM_DATE), окно -- от этой даты до сегодня. После успешного --commit/--send начало окна сдвигается на конец отчёта; datetime-границы --date приводятся к полным дням. Схема конфига ломающая: старые ключи игнорируются, миграция описана в документации.
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
- [Экспорт в файл](#экспорт-в-файл)
|
||||
- [Содержимое отчёта](#содержимое-отчёта)
|
||||
- [Отправка по email](#отправка-по-email)
|
||||
- [Ежемесячный цикл с --commit](#ежемесячный-цикл-с---commit)
|
||||
- [Скользящее окно периода](#скользящее-окно-периода)
|
||||
- [Справочник флагов](#справочник-флагов)
|
||||
- [Устранение неполадок](#устранение-неполадок)
|
||||
- [См. также](#см-также)
|
||||
@@ -68,16 +68,15 @@ redmine-reporter --init-config --config-path /etc/redmine-reporter/config.yml
|
||||
|
||||
## Выбор периода
|
||||
|
||||
Источник периода выбирается по приоритету (от высшего к низшему):
|
||||
Окно отчёта — диапазон дат `from..to`. Конец (`to`) всегда сегодняшняя дата,
|
||||
если диапазон не задан явно через `--date`.
|
||||
|
||||
1. `--date` — явный диапазон.
|
||||
2. `DEFAULT_FROM_DATE` (env/.env) — конец: `DEFAULT_TO_DATE` или сегодня. `DEFAULT_TO_DATE` без `DEFAULT_FROM_DATE` игнорируется.
|
||||
3. `period.dynamic: true` + `period.last_used` в YAML — следующий период после `last_used`:
|
||||
- последний период — полный календарный месяц → следующий полный месяц;
|
||||
- произвольный диапазон → та же длительность, начиная со дня после `last_used.to`;
|
||||
- при `precision: datetime` → та же длительность, сдвинутая на 1 секунду после `last_used.to`.
|
||||
4. `period.default_from` в YAML — конец: `default_to` или сегодня. `default_to` без `default_from` игнорируется.
|
||||
5. Ничего не задано → текущий месяц: с 1-го числа по сегодня.
|
||||
Приоритет начала окна (от высшего к низшему):
|
||||
|
||||
1. `--date` — явный диапазон (полностью переопределяет окно).
|
||||
2. `FROM_DATE` (env) — начало; конец — сегодня.
|
||||
3. `period.from` (YAML) — начало; конец — сегодня.
|
||||
4. Ничего не задано — текущий месяц: с 1-го числа по сегодня.
|
||||
|
||||
Форматы `--date`:
|
||||
|
||||
@@ -85,11 +84,18 @@ redmine-reporter --init-config --config-path /etc/redmine-reporter/config.yml
|
||||
# Даты
|
||||
redmine-reporter --date 2026-06-01--2026-06-30
|
||||
|
||||
# Дата-время
|
||||
# Дата-время (границы флорятся до полных дней)
|
||||
redmine-reporter --date 2026-06-01T09:00:00--2026-06-01T18:00:00
|
||||
```
|
||||
|
||||
Смешанная точность (дата + дата-время в одном диапазоне) и диапазон, где начало позже конца, отвергаются с ошибкой.
|
||||
Границы с временем округляются до дат — отчёт строится за полные дни диапазона.
|
||||
Границы можно смешивать (дата + дата-время). Начало позже конца
|
||||
(`start > end`) — ошибка.
|
||||
|
||||
Краевые случаи:
|
||||
|
||||
- `from` позже сегодняшней даты — окно «сегодня--сегодня».
|
||||
- `from` некорректна (не `YYYY-MM-DD`) — warning + текущий месяц.
|
||||
|
||||
## Отчёт за другого пользователя
|
||||
|
||||
@@ -206,6 +212,8 @@ redmine-reporter --send --commit
|
||||
Факты:
|
||||
|
||||
- Файл отчёта сохраняется на диск ДО отправки: при ошибке SMTP файл остаётся на месте.
|
||||
- Перед отправкой запрашивается подтверждение «Отправить? [y/N]»; ответ «y»/«yes» продолжает, иначе отправка отменяется (без сдвига периода, если не задан явный `--commit`).
|
||||
- При успешной отправке начало периода сдвигается (см. [Скользящее окно периода](#скользящее-окно-периода)); при отмене (если не задан явный `--commit`) или ошибке SMTP — без сдвига.
|
||||
- Секция `email` отсутствует или `smtp.host` пуст → ошибка «Email не настроен. Добавьте секцию 'email' в конфиг...», exit 1.
|
||||
- `email.html: true` → письмо `multipart/alternative`: plain-text + HTML-таблица отчёта в теле.
|
||||
- Файл прикрепляется при `attach: true`; MIME-тип определяется по расширению, неизвестное → `application/octet-stream`.
|
||||
@@ -220,41 +228,42 @@ redmine-reporter --send --commit
|
||||
- «Ошибка отправки письма: ...»
|
||||
- «Не удалось подключиться к SMTP-серверу host:port»
|
||||
|
||||
## Ежемесячный цикл с --commit
|
||||
## Скользящее окно периода
|
||||
|
||||
`--commit` сохраняет отчёт в файл (по `--output` или по шаблону `output.dir`/`output.filename`) и записывает `period.last_used` в YAML-конфиг.
|
||||
|
||||
Что пишется:
|
||||
|
||||
- `precision: datetime` → `last_used.from` = `last_used.to` = текущий момент UTC.
|
||||
- `precision: date` → фактические `from`/`to` использованного периода.
|
||||
- `dynamic: true` → `default_from`/`default_to` не меняются.
|
||||
- `dynamic: false` → дополнительно перезаписываются `default_from`/`default_to`.
|
||||
После успешного `--commit` (файл сохранён) или реальной отправки `--send`
|
||||
(подтверждение «y» + успех) окно отчёта сдвигается вперёд: в конфиг пишется
|
||||
`period.from = <конец окна>`. Следующий запуск без `--date`
|
||||
начинается с граничного дня последнего отчёта.
|
||||
|
||||
Типичный цикл:
|
||||
|
||||
```bash
|
||||
# 1. Отчёт за июнь 2026: сохранить файл, зафиксировать период
|
||||
# 1. Отчёт за июнь 2026: сохранить, отправить, сдвинуть начало на 30 июня
|
||||
redmine-reporter --date 2026-06-01--2026-06-30 --send --commit
|
||||
|
||||
# 2. Следующий запуск без --date возьмёт июль 2026 автоматически
|
||||
# (при dynamic: true и полном месяце)
|
||||
# 2. Следующий запуск без --date берёт окно с 30 июня по сегодня
|
||||
redmine-reporter --send --commit
|
||||
```
|
||||
|
||||
Защита от дублей при `precision: datetime`:
|
||||
Граничный день: начало следующего окна совпадает с днём коммита, поэтому этот
|
||||
день перечитывается. Записи дня коммита, уже попавшие в прошлый отчёт,
|
||||
повторятся (дедупликации по `created_on`/`updated_on` нет — это осознанное
|
||||
следствие), зато поздние записи, добавленные в Redmine в этот день после
|
||||
отправки, не теряются.
|
||||
|
||||
- Если в YAML есть `last_used.to` (cutoff), time entry сохраняется в отчёт, только если `created_on` И `updated_on` оба >= cutoff; если хотя бы одно поле раньше cutoff — запись исключается.
|
||||
- Записи, у которых оба поля (`created_on`, `updated_on`) отсутствуют, сохраняются; если задано только одно поле, решает оно.
|
||||
- Фильтр применяется всегда при `precision: datetime`, в том числе при явном `--date`.
|
||||
Повторный запуск `--commit`/`--send` в тот же день даёт окно
|
||||
«сегодня--сегодня», которое повторно включает уже отправленные записи этого
|
||||
дня.
|
||||
|
||||
Важно: `--commit` перезаписывает YAML через `yaml.dump` — пользовательские комментарии в файле теряются.
|
||||
Важно: `--commit`/`--send` перезаписывают только `period.from`; остальные
|
||||
ключи YAML сохраняются, но пользовательские комментарии теряются
|
||||
(перезапись через `yaml.dump`).
|
||||
|
||||
## Справочник флагов
|
||||
|
||||
| Флаг | Описание |
|
||||
| --- | --- |
|
||||
| `--date` | Диапазон периода: `YYYY-MM-DD--YYYY-MM-DD` или `YYYY-MM-DDTHH:MM:SS--YYYY-MM-DDTHH:MM:SS`. Смешанная точность и `start > end` отвергаются. |
|
||||
| `--date` | Явный диапазон: границы — дата `YYYY-MM-DD` или datetime `YYYY-MM-DDTHH:MM:SS`. Время отбрасывается (полные дни), границы можно смешивать; `start > end` — ошибка. |
|
||||
| `--compact` | Компактный текстовый вывод в консоль вместо таблицы. |
|
||||
| `--output` | Путь к файлу (`.odt`/`.csv`/`.md`/`.html`/`.json`/`.xlsx`) или bare-формат — тогда путь берётся из YAML-шаблона; без флага — вывод в консоль (stdout). |
|
||||
| `--author` | Переопределить имя автора отчёта. |
|
||||
@@ -273,8 +282,8 @@ redmine-reporter --send --commit
|
||||
| `--init-config` | Сгенерировать YAML-конфиг из текущего `.env`/окружения и выйти. |
|
||||
| `--force` | Перезаписать существующий YAML-конфиг (только с `--init-config`). |
|
||||
| `--config-path` | Путь к YAML-конфигу: загрузка, запись `--init-config` и `--commit`. По умолчанию `~/.config/redmine-reporter/config.yml`. |
|
||||
| `--commit` | Сохранить отчёт в файл и зафиксировать период (`period.last_used`) в YAML. |
|
||||
| `--send` | Отправить отчёт по email после сохранения файла. |
|
||||
| `--commit` | Сохранить отчёт в файл и сдвинуть начало периода (`period.from` = конец окна) в YAML. |
|
||||
| `--send` | Отправить отчёт по email после сохранения файла; при подтверждении и успехе сдвинуть начало периода. |
|
||||
|
||||
## Устранение неполадок
|
||||
|
||||
|
||||
Reference in New Issue
Block a user