Первый баг в новом проекте должен получить номер один. Обычно это не так.
Большинство инструментов, которые начинали с одного общего счётчика, так его и оставляют: поначалу проект один, и разницы не видно. Потом приходит второй клиент, открывает свой первый проект, заводит первый баг — и тот получает номер #913. Ничего не сломано. Просто кажется, будто зашёл в чужое здание.
На этой неделе я выкатил в BugDump нумерацию по проектам, и рассуждения за ней применимы не только к моему продукту. ID бага — одна из немногих частей модели данных, которые люди произносят вслух, и от этого меняются требования к нему.
Во что обходится глобальный счётчик
Он выдаёт лишнее. Номер из общей последовательности говорит любому, кто его видит, сколько примерно трафика у всей системы. Два бага, заведённые в вашем проекте с разницей в месяц, показывают, сколько багов за это время завели все остальные. Та же проблема была с последовательными номерами счетов, и поэтому сервисы для выставления счетов от них отказались.
Он читается как шум. #913 ничего не говорит тому, кто на него смотрит. Ни в одном списке, который он видит, это не 913-й баг. Число достаточно большое, чтобы его было трудно удержать в голове, и достаточно случайное, чтобы по нему ничего нельзя было прикинуть.
Он теряет информацию, которая досталась бы даром. Когда нумерация своя в каждом проекте, номер заодно служит грубым счётчиком. BD-6 значит, что в проекте было всего несколько багов. BD-2400 значит совсем другое, и это понятно без всякого дашборда.
Ничего из этого не смертельно. Многие хорошие инструменты годами живут с глобальным счётчиком. Но это маленький налог на каждый ID, навсегда, а исправить это дёшево.
Зачем нужен префикс
У нумерации по проектам появляется одна новая проблема: номера перестают быть уникальными. Задача 42 есть в каждом вашем проекте.
Путь в URL эту проблему уже решает, ведь в нём есть проект. Но у разговора нет URL. Кто-то пишет «глянь 42» в канале, где обсуждают три проекта, и фраза правда неоднозначна.
Короткий ключ перед номером решает это там, где неоднозначность и возникает, — в разговоре людей. BD-42 однозначен, а 42 — нет, и обходится это в три символа. Jira права в этом уже двадцать лет, а Linear, Shortcut и Sentry пришли к тому же независимо друг от друга.
Ключ стоит выводить, а не требовать. Просить человека придумать ключ проекта при регистрации — маленький налог в момент, когда он занят другим. Выведите ключ из названия проекта — из Bug Dump получается BD — и дайте поменять его потом в настройках, чего большинство никогда не сделает.
Три решения, от которых всё зависит
Когда вы выбрали номера по проектам с префиксом, три вопроса решают, будет результат приятным или раздражающим.
1. Используются ли номера повторно после удаления?
Нет. Никогда.
Если удаление последней задачи освобождает её номер для следующей, то ссылка, сообщение коммита или ветка в Slack про BD-9 могут молча начать указывать на другой баг. Сбой тихий и может проявиться когда угодно позже — худшее сочетание.
Держите счётчик, который только растёт. Пропуски в последовательности — не дефект, а видимое доказательство того, что старые ссылки по-прежнему значат то, что значили.
2. Префикс — часть адреса или украшение?
Это самый интересный вопрос, и оба ответа можно защитить.
Если префикс — украшение, BD-42 и 42 — два написания одного адреса, и оба открывают задачу. Тогда переименовать ключ проекта ничего не стоит: подписи везде обновятся, ссылки продолжат работать, никто ничего не заметит.
Если префикс — часть адреса, открывается только точная текущая подпись. Переименование ключа ломает все ссылки со старым ключом.
Я сознательно выбрал второй вариант, хотя начинал с первого. Победил такой довод: URL с префиксом, который не совпадает с ключом этого проекта, во всех реалистичных случаях — ошибка. Кто-то вставил ссылку не из того проекта, опечатался или идёт по устаревшей ссылке. Открыть задачу, у которой случайно такой же номер в этом проекте, — не помощь. Выглядит так, будто всё сработало, а на экране тихо оказывается не тот баг.
Поэтому неверный префикс получает 404, как и номер с ведущими нулями вроде BD-007, как и номер, которого нет ни у одной задачи. Голый номер остаётся постоянным адресом, который не сломает никакое переименование, и именно его продукт ставит в каждую ссылку, письмо и вебхук, которые генерирует.
Цена реальна, и о ней стоит сказать прямо: переименуйте ключ, и ссылки со старым перестанут открываться. Это плата за то, чтобы никогда никому не показать не тот баг.
3. Обе формы работают везде?
Должны. Люди копируют ту подпись, которую видят, а не ту, которую ваше приложение подставляет в ссылки.
Если интерфейс показывает BD-42 на карточке, то BD-42, вставленный в адресную строку, должен работать, иначе вы устроили маленькую ловушку для всех, кто делает очевидное. Принимайте оба написания, сохраняйте то, с которым пришёл посетитель, а каноническое генерируйте сами.
Что остаётся числом
Префикс — для людей. Машины должны и дальше получать целые числа.
Данные вебхуков, ответы API и аргументы инструментов MCP в BugDump по-прежнему содержат номер, а отображаемая подпись идёт рядом отдельным полем. Ничего из того, что уже разбирает эти данные, менять не пришлось, и никому не нужно писать парсер строкового формата, чтобы понять, к какому багу относится событие.
Это разделение стоит сознательно беречь по мере разработки. Подпись — вопрос отображения. Как только она просочится в контракты интеграций, переименование ключа проекта станет ломающим изменением API, а косметическая настройка превратится в то, что никто не решается трогать.
Миграция, которая не ломает уже отправленные ссылки
Неудобство в том, что ID уже существуют и уже в обращении: в письмах, в истории чатов, в чужих тикетах.
Перенумеровать существующие задачи, чтобы каждый проект аккуратно начинался с 1, — заманчиво и неправильно. Каждая старая ссылка молча начнёт указывать на другое. Альтернатива скучнее, зато верная: не трогать существующие номера, запустить счётчик каждого проекта с числа выше его собственного максимального номера и оставить старым проектам разреженные ID навсегда. Новые проекты получают чистую нумерацию с 1, старые ссылки значат то же, что значили, и никому ничего не нужно объяснять.
Нумерация — маленькая функция. Но каждый в команде касается её десятки раз в день, и это хороший довод потратить полдня и сделать её правильно, а не жить с #913 до бесконечности.
Читайте также
Машинное имя, которое было ещё и отображаемым — как стабильный ключ приоритета незаметно стал и значением для клиента и что пришлось найти, чтобы сделать приоритеты редактируемыми.
Пользовательские поля в баг-трекере: что добавить, а от чего отказаться — проверка, которая отделяет нужное поле от того, что через полтора месяца будет пустым.
Лёгкий баг-трекер для небольшой команды: когда Jira — это слишком — почему тяжёлые трекеры не приживаются в маленьких командах и что нужно от лёгкого.