Фича: режим --my-tasks -- список открытых задач, назначенных на меня #71

Closed
opened 2026-10-28 13:21:30 +07:00 by artem.kokos · 1 comment
Owner

Суть

Второй режим работы утилиты: список открытых задач, назначенных на текущего пользователя, отсортированный по срочности. Существующий режим (отчёт по затраченному времени) не меняется.

Зачем: утренний обзор "что мне делать" без открытия веб-интерфейса Redmine, сразу с приоритетами и горящими сроками версий.

Вызов и совместимость

redmine-reporter --my-tasks
  • Необязательные флаги юзера работают как обычно: --user-id, --user-login, --user-name (посмотреть чужой список), а также --url, --api-key, --config.
  • Дефолтный юзер -- владелец API-ключа (текущий пользователь).
  • Совмещение с отчётными флагами (--date, --output, --compact, --summary, --by-activity, --no-time, --commit, --send) -- явная ошибка с сообщением, по образцу валидации --init-config (cli.py:355-375).

Пайплайн

  1. Загрузка конфига и Config.validate() -- без изменений.
  2. Резолв юзера: _get_current_user_id() (client.py) по умолчанию или _resolve_user_id() при заданном флаге.
  3. Один запрос redmine.issue.filter(assigned_to_id=<uid>, status_id='open') -- по всем проектам.
  4. Сбор уникальных fixed_version.id из результата -> дозагрузка due_date этих версий (обычно их единицы). В выдаче списка задач fixed_version содержит только {id, name}, без срока. Недоступная версия не валит вывод: срок пустой, сортируется как задача без срока.
  5. Сортировка, саммари, таблица (ниже).

Сортировка

Ключ: (ранг приоритета, срок версии, id).

  • Приоритет: меньше число -- срочнее (P1 -> P5). Неизвестное имя приоритета -- низший ранг.
  • Внутри приоритета: due_date версии по возрастанию; задачи без версии или в версии без срока -- в конец своей приоритетной группы.
  • id по возрастанию -- стабильный tie-break.

Саммари

Одна строка в stderr над таблицей (служебное -- в stderr, таблица -- в stdout: pipes-friendly, --my-tasks | grep даёт чистую таблицу):

Открытых: 12 | просроченных: 2 | без версии: 3 | без срока: 1 | потрачено: 21.5h | оценка: 34h (по 4 из 12)
  • Открытых -- всего назначенных открытых задач.
  • Просроченных -- срок версии раньше сегодняшнего дня (та же метрика, что пометка в таблице).
  • Без версии -- нет fixed_version; без срока -- версия есть, due_date пуст.
  • Потрачено -- сумма spent_hours (поле приходит всегда).
  • Оценка -- сумма estimated_hours; в этом Redmine оценки ставят не везде, поэтому с пометкой покрытия (по N из M). Если оценок нет совсем -- кусок опускается.

Таблица

Колонки: ID | Тема | Статус | Приор. | Версия | Срок.

  • ID обёрнут в OSC 8-гиперссылку на <redmine_url>/issues/<id>: в современных терминалах номер кликабелен, без поддержки остаётся просто номер. Ссылка только на номер, tablefmt простой -- tabulate не ANSI-aware, fancy-рамки съедут.
  • Статус -- русский перевод из STATUS_TRANSLATION (report_builder.py) + YAML-переопределения.
  • Срок -- ISO (2026-11-27); просроченный помечается (!) в конце.
  • Колонки "Проект" нет (имя версии несёт контекст, строка и так длинная).
  • Пустой список: Открытых задач нет, exit 0.

Пример (данные синтетические):

Открытых: 4 | просроченных: 1 | без версии: 1 | без срока: 0 | потрачено: 12.5h | оценка: 8h (по 2 из 4)

 ID   Тема                                  Статус     Приор.  Версия           Срок
101   Подготовить сборку релиза             В работе   P1      v1.0 (Develop)   2026-10-15 (!)
102   Исправить падение импорта конфига     В работе   P1      v1.0 (Develop)   2026-11-27
103   Обновить пользовательскую документацию Решена     P2      v1.1 (Develop)   2026-11-10
104   Разобрать бэклог мелких правок        В работе   P4      -

Принятые решения

  • Режим -- флаг в стиле --init-config (ответвление до отчётного пайплайна), без перехода на подкоманды.
  • Отдельное YAML-поле "мой юзер" не добавляется: дефолт -- владелец ключа, переопределение существующими CLI-флагами.
  • --compact в этом режиме не поддерживается (только таблица).
  • Приоритет не переводится на русский (P1..P5 самодостаточны).
  • Часы в формате :g (21.5h); done_ratio в саммари не используется (псевдоточная метрика).

Тесты (TDD)

  • Сортировка: ранжирование приоритетов (P1..P5, неизвестные -- низший), None-версии и версии без срока в конец группы, tie-break по id.
  • Фетч: issue.filter с assigned_to_id/status_id, дозагрузка due_date уникальных версий, недоступная версия (моки Redmine).
  • CLI-ветка: несовместимость с отчётными флагами, дефолтный юзер и резолв по флагу, пустой список -> exit 0.
  • Вывод: OSC 8-обёртка номера, русские статусы с YAML-оверрайдами, пометка просрочки, саммари с покрытием оценок и без оценок.
## Суть Второй режим работы утилиты: список открытых задач, назначенных на текущего пользователя, отсортированный по срочности. Существующий режим (отчёт по затраченному времени) не меняется. Зачем: утренний обзор "что мне делать" без открытия веб-интерфейса Redmine, сразу с приоритетами и горящими сроками версий. ## Вызов и совместимость ``` redmine-reporter --my-tasks ``` - Необязательные флаги юзера работают как обычно: `--user-id`, `--user-login`, `--user-name` (посмотреть чужой список), а также `--url`, `--api-key`, `--config`. - Дефолтный юзер -- владелец API-ключа (текущий пользователь). - Совмещение с отчётными флагами (`--date`, `--output`, `--compact`, `--summary`, `--by-activity`, `--no-time`, `--commit`, `--send`) -- явная ошибка с сообщением, по образцу валидации `--init-config` (cli.py:355-375). ## Пайплайн 1. Загрузка конфига и `Config.validate()` -- без изменений. 2. Резолв юзера: `_get_current_user_id()` (client.py) по умолчанию или `_resolve_user_id()` при заданном флаге. 3. Один запрос `redmine.issue.filter(assigned_to_id=<uid>, status_id='open')` -- по всем проектам. 4. Сбор уникальных `fixed_version.id` из результата -> дозагрузка `due_date` этих версий (обычно их единицы). В выдаче списка задач `fixed_version` содержит только `{id, name}`, без срока. Недоступная версия не валит вывод: срок пустой, сортируется как задача без срока. 5. Сортировка, саммари, таблица (ниже). ## Сортировка Ключ: (ранг приоритета, срок версии, id). - Приоритет: меньше число -- срочнее (P1 -> P5). Неизвестное имя приоритета -- низший ранг. - Внутри приоритета: `due_date` версии по возрастанию; задачи без версии или в версии без срока -- в конец своей приоритетной группы. - `id` по возрастанию -- стабильный tie-break. ## Саммари Одна строка в stderr над таблицей (служебное -- в stderr, таблица -- в stdout: pipes-friendly, `--my-tasks | grep` даёт чистую таблицу): ``` Открытых: 12 | просроченных: 2 | без версии: 3 | без срока: 1 | потрачено: 21.5h | оценка: 34h (по 4 из 12) ``` - Открытых -- всего назначенных открытых задач. - Просроченных -- срок версии раньше сегодняшнего дня (та же метрика, что пометка в таблице). - Без версии -- нет `fixed_version`; без срока -- версия есть, `due_date` пуст. - Потрачено -- сумма `spent_hours` (поле приходит всегда). - Оценка -- сумма `estimated_hours`; в этом Redmine оценки ставят не везде, поэтому с пометкой покрытия `(по N из M)`. Если оценок нет совсем -- кусок опускается. ## Таблица Колонки: `ID | Тема | Статус | Приор. | Версия | Срок`. - ID обёрнут в OSC 8-гиперссылку на `<redmine_url>/issues/<id>`: в современных терминалах номер кликабелен, без поддержки остаётся просто номер. Ссылка только на номер, tablefmt простой -- tabulate не ANSI-aware, fancy-рамки съедут. - Статус -- русский перевод из `STATUS_TRANSLATION` (report_builder.py) + YAML-переопределения. - Срок -- ISO (`2026-11-27`); просроченный помечается `(!)` в конце. - Колонки "Проект" нет (имя версии несёт контекст, строка и так длинная). - Пустой список: `Открытых задач нет`, exit 0. Пример (данные синтетические): ``` Открытых: 4 | просроченных: 1 | без версии: 1 | без срока: 0 | потрачено: 12.5h | оценка: 8h (по 2 из 4) ID Тема Статус Приор. Версия Срок 101 Подготовить сборку релиза В работе P1 v1.0 (Develop) 2026-10-15 (!) 102 Исправить падение импорта конфига В работе P1 v1.0 (Develop) 2026-11-27 103 Обновить пользовательскую документацию Решена P2 v1.1 (Develop) 2026-11-10 104 Разобрать бэклог мелких правок В работе P4 - ``` ## Принятые решения - Режим -- флаг в стиле `--init-config` (ответвление до отчётного пайплайна), без перехода на подкоманды. - Отдельное YAML-поле "мой юзер" не добавляется: дефолт -- владелец ключа, переопределение существующими CLI-флагами. - `--compact` в этом режиме не поддерживается (только таблица). - Приоритет не переводится на русский (P1..P5 самодостаточны). - Часы в формате `:g` (`21.5h`); `done_ratio` в саммари не используется (псевдоточная метрика). ## Тесты (TDD) - Сортировка: ранжирование приоритетов (P1..P5, неизвестные -- низший), None-версии и версии без срока в конец группы, tie-break по id. - Фетч: `issue.filter` с `assigned_to_id`/`status_id`, дозагрузка `due_date` уникальных версий, недоступная версия (моки Redmine). - CLI-ветка: несовместимость с отчётными флагами, дефолтный юзер и резолв по флагу, пустой список -> exit 0. - Вывод: OSC 8-обёртка номера, русские статусы с YAML-оверрайдами, пометка просрочки, саммари с покрытием оценок и без оценок.
Author
Owner

Дополнение (санкционировано владельцем): задачи в версии с именем "Wishlist" исключаются из списка --my-tasks целиком (строки и саммари); задачи без версии и задачи в обычных версиях без срока остаются. Причина: Wishlist -- постоянный бакет без срока (мусорный фон).

Дополнение (санкционировано владельцем): задачи в версии с именем "Wishlist" исключаются из списка --my-tasks целиком (строки и саммари); задачи без версии и задачи в обычных версиях без срока остаются. Причина: Wishlist -- постоянный бакет без срока (мусорный фон).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: artem.kokos/redmine-reporter#71