Как писать user story правильно: шаблон и примеры

Проверь себя · 1/3разбор после ответа
Нужно построить график регистраций по часам из таблицы пользователей со столбцом created_at типа timestamp. Какой бакет лучше использовать?

Зачем вообще user story

Историю придумали, чтобы команда разработки не забывала, что код пишется ради человека. Без user story тикет звучит как «добавить флаг is_paid в users». Что это даёт пользователю — непонятно. Кто-то решит, что флаг нужен на странице профиля, кто-то — что в админке, и оба будут правы и неправы одновременно.

История разворачивает контекст: для кого, что и зачем. Дальше команда сама докручивает «как» — это её работа.

Главный тест истории: если её прочитал новый разработчик и понял, что и почему делается, — история нормальная. Если нужен пятиминутный пересказ от продакта — переписывать.

Ещё одна причина — командная память. Через полгода никто не помнит, зачем делали фичу. Если в тикете осталось «как пользователь премиума, я хочу скачивать историю ответов в CSV, чтобы анализировать слабые темы», команда хотя бы понимает контекст и может решить, расширять или удалять. Если осталось «добавить кнопку Export» — это чёрный ящик.

Шаблон: как, что, зачем

Классический шаблон одной строчкой:

Как [роль], я хочу [действие], чтобы [результат/польза].

Пример:

Как новый пользователь, я хочу войти через Telegram, чтобы не вводить телефон и не ждать СМС.

Три части:

  • Роль. Кто пользователь. Не «пользователь» вообще, а конкретный сегмент: новый пользователь, премиум-подписчик, админ команды. Если роль слишком широкая — история размытая.
  • Действие. Что хочется сделать. На уровне пользы, не реализации. «Войти через Telegram» — да. «Кликнуть на кнопку Telegram-логина в правом верхнем углу» — нет, это уже про реализацию.
  • Результат. Зачем это нужно. Часто пропускают, и зря — без этого нельзя оценить, решена ли проблема. «Чтобы быстрее зарегистрироваться» — это критерий успеха.

Если роль одна, а пользы в одной истории несколько — это две истории. Разделяй.

Шаблон хорошо работает, когда «зачем» формулируется через бизнес-боль или эмоцию, а не через техническое следствие. Сравни:

Плохое «зачем» Хорошее «зачем»
Чтобы в БД появилась запись Чтобы я мог в любой момент вернуться к прошлой тренировке
Чтобы дёргался эндпоинт /me Чтобы я видел, сколько дней подряд занимаюсь, и не сорвался
Чтобы выполнялось требование задачи Чтобы я не вводил пароль каждый раз и не отвлекался

Если «зачем» можно дословно подставить в любую другую историю — оно слишком общее.

Критерии INVEST

Хорошая история проходит чек-лист INVEST.

  • Independent — независимая от других историй (можно делать в любом порядке).
  • Negotiable — обсуждаемая, не финальная спецификация.
  • Valuable — даёт пользу пользователю, а не «красивый код».
  • Estimable — команда может оценить трудозатраты.
  • Small — помещается в спринт, в идеале в несколько дней.
  • Testable — можно проверить, что сделано.

Если история не Small — её надо разбить. Если не Testable — не сформулирована польза или критерий приёмки. Если не Independent — переплетена с другой, надо распутать.

Пример быстрой проверки. История: «Как пользователь, я хочу получать пуш о потере стрика, чтобы вернуться и продолжить». Прогоняем:

  • Independent: можно сделать без других задач — да.
  • Negotiable: текст пуша и условия можно обсуждать — да.
  • Valuable: вернёт часть оттекающих — да.
  • Estimable: бэк, фронт, текст — оцениваемо.
  • Small: помещается в неделю — да.
  • Testable: проверяем, что пользователь без активности 23 часа получает пуш и retention растёт — да.

Если хоть одна буква проседает — переписываем до того, как уйдёт в разработку.

Примеры: плохие и хорошие

Плохо:

Сделать новый профиль.

Не история, а заголовок задачи. Кто? Что? Зачем?

Лучше:

Как пользователь, я хочу видеть свой прогресс в профиле, чтобы понимать, как продвигаюсь.

Уже история, но «прогресс» расплывчато. Что именно — XP, дни стрика, % курса?

Хорошо:

Как пользователь, который занимается каждый день, я хочу видеть в профиле длину текущего стрика и лучший стрик, чтобы видеть свой прогресс и не сорваться.

Конкретная роль, конкретное действие, конкретная польза. Команда может оценить, протестировать, проверить.

Плохо:

Как пользователь, я хочу красивую анимацию, чтобы было приятно.

«Красивую» — не testable. «Приятно» — не measurable. Не история, а пожелание.

Хорошо:

Как пользователь премиума, я хочу скачивать историю своих ответов в CSV, чтобы анализировать слабые темы.

Роль — премиум, действие — скачать CSV, польза — анализ. Понятно, тестируемо, ценно.

Ещё пара антипатернов из реальной жизни:

  • «Как продакт, я хочу видеть дашборд по retention» — это не пользовательская история, это рабочий инструмент команды. Нормально, но писать стоит как задачу, без шаблона.
  • «Как пользователь, я хочу, чтобы приложение работало быстро» — слишком общо. Лучше: «как пользователь на медленном интернете, я хочу видеть первый экран за 2 секунды, чтобы не закрывать приложение».
  • «Как пользователь, я хочу вход через Telegram, Google и Apple» — три истории в одной. Разделить.

Story vs задача vs acceptance criteria

Часто путают три понятия.

User story — описание ценности для пользователя на естественном языке. «Как X, я хочу Y, чтобы Z».

Задача (task) — техническая работа. «Добавить эндпоинт /api/streak», «Сверстать карточку профиля». Задачи живут внутри истории.

Acceptance criteria — условия приёмки. Что должно быть выполнено, чтобы считать историю готовой. Пишется в формате Given-When-Then или списком условий.

Структура:

Story: Как пользователь, я хочу видеть свой стрик в профиле,
       чтобы понимать, сколько дней подряд занимаюсь.

Acceptance criteria:
- В профиле есть блок «Стрик»
- Показывается текущий стрик в днях
- Показывается лучший стрик в днях
- Если стрика нет (0 дней), показывается заглушка с CTA «Начать»
- Числа обновляются в течение часа после события

Tasks:
- API: эндпоинт /me/streak
- UI: компонент StreakCard
- Аналитика: событие streak_card_viewed

История — про «зачем», AC — про «что считать готовым», задачи — про «как сделать».

Сравнительная таблица:

Уровень Кто пишет Когда финализируется Пример
Story Продакт До груминга Как новый пользователь, я хочу…
Acceptance criteria Продакт + QA На груминге В профиле есть блок «Стрик»
Task Тимлид/разработчик На планировании API: эндпоинт /me/streak

Если в задачах появляется «зачем» — значит, история написана плохо или её там нет.

Готовься к собесу аналитика как в Duolingo
10 минут в день — SQL, Python, A/B, метрики. 1700+ вопросов в Telegram
Открыть Карьерник в Telegram

Как разбивать большие истории

Если история не помещается в спринт, она не Small. Разбивать можно по нескольким осям:

  • По шагам пользователя. Регистрация = «ввести телефон» + «получить код» + «придумать пароль». Каждый шаг — отдельная история, каждую можно выкатить и собрать обратную связь.
  • По сегментам. Сначала история для веба, потом для мобильного. Сначала для русского рынка, потом для Казахстана.
  • По данным. Сначала простой случай (один продукт в корзине), потом сложный (несколько продуктов с разными комиссиями).
  • По CRUD. Сначала read (просмотр), потом create (добавление), потом edit/delete.
  • По happy path и краям. Сначала основной сценарий, потом обработка ошибок, оффлайн, ретраи.

Ориентир по размеру: одна история — 1–5 рабочих дней команды. Меньше — слишком мелко, объединить с соседней. Больше — разбить.

Антипатерн разбиения: «бэк-история» и «фронт-история» отдельно. Технически удобно, но ни одна из них не несёт ценности пользователю по отдельности. Лучше резать вертикально — кусок, который можно показать живьём.

Когда user story не нужен

Не всё в беклоге — история. Есть исключения.

  • Технический долг. «Переписать модуль X на TypeScript» — это не история, это задача рефакторинга.
  • Баги. «Кнопка не нажимается на iOS Safari» — баг, не история.
  • Compliance. «Добавить экран согласия на cookies по требованию закона» — задача, не история.
  • Платёжные интеграции и подобные «обязательные» работы — формально они дают ценность, но шаблон «как пользователь…» только маскирует то, что фичу нельзя не делать.

Заставлять команду оборачивать всё в шаблон «как пользователь...» — пустая работа. История нужна там, где есть пользовательская ценность, и она не очевидна.

Частые ошибки

  • Описание реализации в разделе «действие». «Я хочу нажать кнопку» — это реализация, а не желание пользователя.
  • Размытая роль. «Как пользователь» без сегментации даёт неточные истории.
  • Нет «зачем». Без пользы непонятно, как тестировать ценность.
  • История на месяц работы. Не Small — не история.
  • AC внутри истории. Раздувают строчку до простыни.
  • История = задача в Jira. История — это контейнер для задач, не сама задача.
  • Несколько польз в одной истории. «Чтобы быстрее регистрироваться и видеть рекомендации» — это две разные ценности и почти наверняка две разные фичи.
  • История без метрики успеха. Если ты не понимаешь, как поймёшь, что история сработала, — она ещё не готова уйти в разработку.

Связанные темы

FAQ

Кто пишет user story — продакт или аналитик?

Обычно продакт. Аналитик помогает с метриками успеха, дизайнер — с интерфейсом, разработчик — с реализацией.

Можно ли использовать другой шаблон вместо «как-хочу-чтобы»?

Можно — Job Stories («когда X, я хочу Y, чтобы Z»), пользовательские сценарии. Главное, чтобы был контекст, действие и польза.

Сколько acceptance criteria нормально?

3–7. Меньше — недоопределили, больше — стоит разбить историю.

Должна ли история помещаться в один спринт?

Да. Если не помещается — не Small, разбивай на несколько.

Что делать с историями, которые требуют дизайна?

Перед разработкой — отдельная задача на дизайн с теми же AC. История одна, дизайн и разработка — разные шаги.

Нужна ли история для админки или внутреннего инструмента?

Можно писать с ролью «модератор» или «оператор саппорта» — это тоже пользователи. Если внутренний инструмент совсем технический, шаблон необязателен, достаточно описать задачу.

Стоит ли указывать в истории метрику успеха?

Да, это полезная привычка. Хотя бы строчкой: «успех — рост активации D1 на 2 п.п.». Без этого через два месяца не получится оценить, сработала ли фича.

Как поступать, если история отрисована в Figma, но в Jira её ещё нет?

Сначала формулируется история и AC, потом дизайнер раскрашивает. Иначе вы получите красивый макет под несуществующую проблему.