Эффективный Daily Scrum: путь к собственному плагину Obsidian
Всем привет! Меня зовут Павел, и я занимаюсь разработкой корпоративных (enterprise) приложений более 15 лет. В этой статье я хочу поделиться опытом организации своего рабочего процесса, благодаря которому мои ежедневные доклады на Daily Scrum стали короткими, понятными и при этом дают команде возможность получить более подробную информацию при необходимости.
Daily Scrum
Daily Scrum — это короткая встреча для синхронизации команды, на которой обсуждаются три ключевых вопроса: что было сделано вчера, что планируется сделать сегодня и какие есть препятствия.
В нашей команде формат встречи упрощен и выглядит следующим образом:
Если запланированные задачи выполнены — докладчик подтверждает это и переходит к обсуждению планов на текущий день.
Если планы не были выполнены — докладчик обозначает возникшие проблемы, и совместно обсуждается план действий для их устранения. Как правило, это отдельная активность, которая проходит после Daily Scrum с участием заинтересованных коллег.
Подготовка к докладу
Подготовка к докладу на Daily Scrum может осуществляться по-разному. Обычно используют один из трех подходов:
Заранее записывать прогресс.
Вспоминать сделанное непосредственно перед докладом или во время встречи.
Систематизировать рабочий процесс с помощью инструментов.
У каждого из этих методов есть свои преимущества и недостатки. В этой статье я расскажу, как подошёл к автоматизации и упорядочиванию подготовки к Daily Scrum, какие инструменты для этого использовал и каких результатов удалось достичь.
Спринт с 11 мая по 21 мая
Рассмотрим теоретический пример ведения информации о докладах на основе двухнедельного спринта по продукту «Учёт табеля рабочего времени». В ходе спринта будет обнаружен критический баг в используемой библиотеке, отвечающей за необходимые расчёты.
Запланированный список задач:
[ЗАДАЧА01] Сотрудники
[ЗАДАЧА01.01] API CRUD для сотрудников
[ЗАДАЧА02] Производственный календарь
[ЗАДАЧА02.01] API для производственного календаря
[ЗАДАЧА03] Табель
[ЗАДАЧА03.01] API для CRUD операций с табелями (создание, чтение, обновление, удаление)
[ЗАДАЧА03.02] Разработка функционала автоматического подсчёта отработанных часов и вычисления итогов по периоду
Дополнительная задача:
По результатам выявленной ошибки будет добавлена подзадача в фичу [ЗАДАЧА03] Табель:
[ЗАДАЧА03.03] Реализация POC для выбора альтернативной библиотеки
Первая итерация
Первой попыткой систематизации была работа с файлом в формате Markdown, в который информация о текущем рабочем дне добавлялась в начало файла методом копирования данных из предыдущего дня. Далее данные обрабатывались: выполненные задачи удалялись, задачи из раздела «Планируется» переносились в разделы «Выполнено» или «Проблемы».
Пример файла первой итерации выглядел следующим образом:
# 2021-05-19
## что сделано вчера
1. [ЗАДАЧА03.03] Реализация POC для выбора библиотеки
## что планируется сегодня
1. [ЗАДАЧА03] Табель записи
2. [ЗАДАЧА02] Производственный календарь
## препятствия
1. [ЗАДАЧА03.02] Найдена ошибка в алгоритме расчете библиотеки N
...
...
...
# 2021-05-12
## что сделано вчера
1. ✅ 1.1 [ЗАДАЧА01.01] API crud
## что планируется сегодня
1. [ЗАДАЧА01] Cотрудники
2. [ЗАДАЧА02] Производственный календарь
3. [ЗАДАЧА02.01] API производственный календарь
## препятствия
-
# 2021-05-11
## что сделано вчера
## что планируется сегодня
1. [ЗАДАЧА01] Cотрудники
1.1 [ЗАДАЧА01.01] API crud
## препятствия
-
В целом этот подход работал, но имел серьёзные недостатки. Ручное копирование иногда приводило к ошибкам, а потеря информации по задачам вызывала длительные поиски и затрудняла их восстановление.
В связи с этим появилась идея автоматизировать процесс: исключить ручное удаление задач при переносе на следующий день и внедрить автоматическую генерацию даты с привязкой к производственному календарю. Это позволило бы сделать подготовку более управляемой и надежной.
Инструменты
Ранее я использовал сервис Notion, который был бесплатным, обладал богатым набором встроенных инструментов, поддерживал разные операционные системы и устройства, обеспечивал автоматическую синхронизацию данных и позволял экспортировать информацию. Однако Notion покинул рынок и заблокировал все учётные записи пользователей, что стало серьезной проблемой.
В связи с этим пришлось искать подходящую замену, и выбор остановился на Obsidian.
Я изучил множество плагинов для Obsidian, которые частично решали задачи, но ни один не подходил полностью под мои требования. Поэтому я решил разработать собственный плагин с функциями, включающими:
интеграцию с производственным календарем;
автоматический перенос невыполненных задач на следующий рабочий день с исключением выполненных задач;
возможность менять статус задач (выполнено/не выполнено) прямо из календаря;
различные виды отображения календаря (месяц, неделя, два дня, один день);
сбор и отображение статистики по задачам;
список задач в ожидании.
Задачи и их хранение
Хранение задач реализовано в формате Markdown. Задачи могут содержать подзадачи. Формат задачи:
- [ ] [TASK_ID](URL) DESCRIPTION
- [x] [TASK_ID](URL) DESCRIPTION (выполненная задача)
Для организации информации докладов на Daily Scrum было решено разделять данные по файлам — по одному на каждый день. Эта файловая структура фактически представляет собой файловую базу данных с вложенными папками и файлами:
Первый уровень — год заметок в формате YYYY
Второй уровень — месяц в формате MM
Третий уровень — файлы с именем в формате YYYY-MM-DD.md
Пример файловой структуры:
daily/
└── 2021/
├── 01/
├── 02/
├── 03/
├── 04/
├── 05/
│ ├── 2021-05-11.md
│ ├── 2021-05-12.md
│ ├── 2021-05-13.md
│ └── 2021-05-14.md
├── 06/
└── ...
Файл состоит из заголовков и вложенных в них задач. Заголовки могут иметь разные названия, например:
## Сегодня
- [ ] [ЗАДАЧА01](URL) Описание задачи
- [ ] [ПОДЗАДАЧА01](URL) Описание подзадачи
## Ожидание
- [ ] [ЗАДАЧА02](URL) Описание задачи
## Тестирование
- [ ] [ЗАДАЧА03](URL) Описание задачи
Календарь
Для удобного просмотра задач с учетом производственного календаря и исключением дней отпуска был разработан плагин визуализация календаря. Это позволяет мне видеть только рабочие дни и эффективно планировать работу.
Ниже приведён пример кода на DataviewJS, который реализует такую логику. В настройках указывается текущая дата, локализация, период просмотра (месяц) и папка с файлами задач. Массив vacations содержит отпускные периоды, которые исключаются из показа.
```dataviewjs
const DEFAULT_SETTINGS = {
date: new Date(),
locale: 'ru',
period: 'month',
folder: '/daily',
};
const vacations = [
{
start: new Date("2024-07-29"),
days: 26
}
]
renderCalendar(
this.container,
vacations,
() => load(),
(config, plugin) => save(config));
```
Визуально календарь для мая 2021 года выглядит следующим образом: все праздники и выходные дни выделены красным цветом, а отпускные дни — оранжевым с иконкой отдыха. При наведении курсора на выбранный день появляется меню с возможностями:
Копировать статус с предыдущего рабочего дня (при этом учитываются исключения: выходные, праздничные и отпускные дни).
Копировать с предыдущего периода с поиском потерянных задач.
Перейти в соответствующий файл с исходными данными.
Это существенно упрощает процесс планирования и ведения учёта задач с учетом рабочих и нерабочих дней.
Список незавершенных задач
В нашей команде используется подход фича-лид, поэтому важно постоянно отслеживать статус своих задач. Отображение списка незавершенных задач помогает контролировать те, которые находятся в различных состояниях: в Merge Request (MR), ожидании работы фронтенда или бэкенда, на тестировании у QA, на тестировании у аналитика или в состоянии уточнения.
Такое представление позволяет оперативно реагировать на зависшие задачи и предотвращать задержки в работе.
Пример кода на DataviewJS, выводящий список незавершённых задач:
```dataviewjs
const tasks = await loadTasks(DEFAULT_SETTINGS.folder, start, end);
const tasksInProgress = tasks
.history
.filter(x=>!x.done)
.map(task => [
`? ${getTaskIcon(task.done, task.group)} ${task.group}`,
pathToHtmlLink(task.source.at(-1).source.path),
`${markdownToHtmlLink(task.id)} ${task.description}`,
task.firstDay,
task.lastDay
]);
dv.table(
["", "День", "Задача", "Первый", "Последний"],
tasksInProgress
);
```
Это позволяет видеть ключевую информацию по каждой задаче: ее статус, ссылку на файл с описанием, описание самой задачи, дату первого и последнего упоминания.
Визуально данное представление выглядит следующим образом:
Статистика
Данное представление представляет собой сводную информацию по задачам за различные месяцы, сгруппированную по кварталам и годам. В таблице отображаются количественные показатели состояния задач: количество задач в ожидании, выполненных, созданных и общее количество.
Для каждого месяца показатели представлены в виде числовых значений с соответствующими иконками и дополнительно визуализированы цветными круговыми диаграммами.
Основная цель такой таблицы — наглядно и подробно показать состояние рабочих процессов или проектов, выделяя задачи в разных статусах. Это облегчает контроль, анализ и помогает принимать решения на основе данных.
Пример кода на DataviewJS:
```dataviewjs
const tasks = await loadTasks(DEFAULT_SETTINGS.folder, start, end);
const tableData = statistic.calculate(tasks)
const htmlTable = statistic.generateTable(tableData)
dv.span().innerHTML = htmlTable;
```
Визуальное представление:
Для наглядности в таблице используются следующие иконки:
⏳ — задачи в ожидании
✅ — выполненные задачи
? — добавленные задачи
? — общее количество задач
Заключение
Организация личного рабочего процесса — ключ к продуктивности и эффективному взаимодействию в команде. Систематический подход к подготовке к Daily Scrum помогает экономить время на встречах и обеспечивать прозрачность текущих задач и проблем.
Использование удобных инструментов и автоматизация рутинных операций делают планирование и отчётность проще и комфортнее. Создание собственного плагина позволило адаптировать процесс под мои конкретные потребности, что значительно повысило качество и скорость подготовки.
Надеюсь, мой опыт окажется полезным для вас в создании собственного эффективного рабочего процесса и улучшении командной работы.