Функциональные и нефункциональные требования: шаблоны, примеры и типичные ошибки
Если вам когда-нибудь возвращали ТЗ с комментарием «непонятно, что именно нужно сделать» — поздравляю, вы попали в клуб аналитиков, чьи функциональные требования живут своей жизнью отдельно от разработки. Клуб большой. Туда приходят все, кто хоть раз писал «система должна корректно обрабатывать запросы» и искренне верил, что это требование.
Функциональное требование — это не описание мечты заказчика и не пересказ ТЗ своими словами. Это контракт между продуктом и реализацией, который должен читаться одинаково аналитиком, разработчиком, тестировщиком и юристом (последний — на случай, если что-то пойдёт не так). И раз уж от этого контракта зависит, поедет ли заказчик в отпуск спокойным, давайте разберёмся, как писать ФТ так, чтобы их не пришлось переписывать на следующем спринте.
Раньше мы уже говорили о том, что такое нефункциональные требования и зачем они вообще нужны, а также подробно разбирали примеры ФТ и НФТ по доменам. Сегодня — глубже в практику: шаблоны формулировок, готовые примеры по типам систем и подборка ошибок, на которых я и мои коллеги набивали шишки годами.
Что такое функциональное требование на самом деле
Начнём с базы, без академических определений из учебников.
Функциональное требование (ФТ, FR — Functional Requirement) — это утверждение о том, какое конкретное поведение должна демонстрировать система в ответ на действие пользователя, внешнее событие или наступление условия.
Главное слово здесь — поведение. Не «фича», не «модуль», не «возможность». Поведение. Если требование нельзя проверить наблюдением за системой («сделали действие — система ответила так-то») — это не функциональное требование, это пожелание.
Сравним:
| Не требование | Требование |
|---|---|
| Система должна быть удобной для пользователя | Пользователь может зарегистрироваться, указав email и пароль; после регистрации он автоматически авторизуется и переходит на главную страницу |
| Должна работать корзина | Пользователь может добавить товар в корзину; в корзине одновременно находится не более 100 позиций; повторное добавление того же товара увеличивает количество, а не создаёт новую строку |
| Поддержка интеграции с 1С | Система ежедневно в 03:00 МСК выгружает новые заказы во внешнюю 1С через REST API; в случае ошибки повторяет попытку 3 раза с интервалом 10 минут |
Видна разница? Левая колонка — это маркетинговая брошюра. Правая — то, что можно положить в Jira, оценить в часах и проверить тестом.
Структура хорошего ФТ: что обязательно входит
Чтобы требование можно было реализовать без угадывания, в нём должны быть пять элементов. Один пропустите — получите вопросы на код-ревью. Два — получите баг в проде. Три — получите письмо от заказчика.
На диаграмме — анатомия требования. Если выкинуть актора, неясно, кто инициирует действие. Если выкинуть условие — система разрешит делать что угодно и кому угодно (привет, нарушение прав доступа). Если выкинуть результат — нечего тестировать.
Канонические формулы
Существует три рабочие формулы, к которым сводится 95% всех функциональных требований. Знаете эти три — выживете в любом проекте.
Формула 1. Классическая (для пользовательских сценариев):
«Актор может выполнить действие над объектом, при условии условие. После этого результат.»
Пример: «Авторизованный пользователь может удалить свой комментарий, при условии, что с момента публикации прошло не более 15 минут. После удаления комментарий не отображается в ленте, но сохраняется в БД с флагом deleted.»
Формула 2. Системная (для внутренних процессов и интеграций):
«При наступлении триггер, система выполняет действие с объектом, в результате результат.»
Пример: «При получении webhook от платёжного шлюза со статусом success, система меняет статус заказа на „оплачен“ и отправляет покупателю email с электронным чеком в течение 30 секунд.»
Формула 3. Сценарная (для use case с альтернативами):
«Если условие 1 — система делает A. Если условие 2 — система делает B. Иначе — C.»
Пример: «Если у клиента есть активная подписка — система применяет скидку 20%. Если подписка истекла менее 7 дней назад — система предлагает продление с сохранением старой цены. Иначе — клиент видит стандартный прайс.»
Шаблоны ФТ: готовые формы для типовых сценариев
Ниже — несколько шаблонов, которые я использую в реальных проектах. Их можно копировать, заполнять плейсхолдеры и получать на выходе требование, к которому не придерётся даже самый дотошный разработчик.
Шаблон 1. CRUD-операция
ID: FR-XXXНазвание: [Создание/Чтение/Обновление/Удаление] [сущности]Актор: [Роль пользователя]Предусловие: [Что должно быть верно до начала действия]Основной сценарий: 1. Актор инициирует действие [как именно] 2. Система проверяет [список проверок] 3. Система выполняет [конкретные шаги] 4. Система возвращает [результат]Альтернативные сценарии: - Если [условие], то [действие системы]Постусловие: [Что должно быть верно после действия]Связанные НФТ: [ссылки на FR-NFT-XXX]Шаблон 2. Бизнес-правило
ID: BR-XXXНазвание: [Что регулирует правило]Триггер: [Когда правило применяется]Условия: [Список условий, при которых правило срабатывает]Действие: [Что делает система]Исключения: [Когда правило НЕ применяется]Источник: [Кто утвердил правило — заказчик/закон/регулятор]Шаблон 3. Интеграция с внешней системой
ID: INT-XXXНазвание: Интеграция с [система]Направление: [Входящая / Исходящая / Двусторонняя]Триггер: [Что запускает обмен]Протокол: [REST/SOAP/gRPC/Kafka/файл]Контракт: [ссылка на OpenAPI/Avro/proto]Частота: [Real-time / каждые N минут / по расписанию]Обработка ошибок: - Timeout: [сколько ждём + что делаем] - Невалидный ответ: [retry / DLQ / алерт]Идемпотентность: [Да/Нет, как обеспечивается]Шаблоны — не догма. Это страховка от того, что вы забудете описать обработку ошибок или постусловие. На своём примере могу сказать: половина инцидентов на проде случается потому, что в требовании не было ответа на вопрос «а что, если внешняя система не ответила?»
Жизненный цикл функционального требования
Требование рождается не из вакуума, и умирает оно тоже не сразу. Между «у нас идея» и «фича в проде» проходит путь, который полезно понимать целиком.
Диаграмма показывает, что любое требование может вернуться на доработку с любого этапа — это нормально. Ненормально, когда оно возвращается на этапе прода (привет, инциденты). Чтобы минимизировать такие возвраты, существует ревью — и его не стоит пропускать, даже если все спешат. На своём примере могу сказать: один час совместного чтения требования экономит две недели переписывания фичи.
Примеры функциональных требований по типам систем
Теория без живых примеров быстро забывается. Ниже — реальные формулировки из проектов, в которых я участвовал. Названия систем и цифры изменены, суть — нет.
Веб-приложение (личный кабинет клиента банка)
FR-101. Просмотр истории операций
Авторизованный клиент может просмотреть список своих операций по выбранному счёту за период от 1 дня до 24 месяцев. Список отсортирован по дате в порядке убывания, по умолчанию отображается за последние 30 дней. На странице — 20 операций, навигация постраничная. Доступна фильтрация по типу (поступление, списание, комиссия) и сумме (от/до).
FR-102. Экспорт выписки
Клиент может экспортировать историю операций в формате PDF или CSV. Экспортируется не более 5 000 операций за один запрос. Файл доступен для скачивания в течение 1 часа после генерации, затем удаляется. Имя файла:
vypiska_{account}_{period_from}_{period_to}.{ext}.
Мобильное приложение (доставка еды)
FR-201. Оформление заказа
Покупатель может оформить заказ, если в корзине минимум один товар и сумма не меньше минимального заказа (зависит от ресторана, передаётся API ресторана). Заказ создаётся со статусом
created, ему присваивается уникальный 7-значный код. При недоступности оплаты онлайн — статусawaiting_payment, ожидание до 15 минут, затем автоотмена.
FR-202. Отмена заказа покупателем
Покупатель может отменить заказ, если он находится в статусе
createdилиawaiting_payment. После статусаaccepted_by_restaurantотмена возможна только через службу поддержки. При успешной отмене — статусcancelled, средства возвращаются на карту в течение 3 рабочих дней.
Внутренняя ERP-система (склад)
FR-301. Приёмка товара по накладной
Кладовщик может оформить приёмку товара, отсканировав QR-код накладной. Система загружает позиции из ЭДО и предлагает подтвердить фактическое количество по каждой строке. При расхождении более чем на 5% — создаётся акт расхождения, требующий подписи двух сотрудников. После подтверждения остатки на складе увеличиваются, а накладная переходит в статус
accepted.
Интеграционный сервис (API-Gateway)
FR-401. Проксирование запросов к внешнему провайдеру
При получении HTTP-запроса по маршруту
/external/{provider}/*система валидирует JWT (см. статью об OAuth и JWT), проверяет квоту клиента и перенаправляет запрос на upstream провайдера. Ответ кэшируется по правилам провайдера (если есть заголовокCache-Control). При HTTP 5xx от провайдера — retry до 2 раз с экспоненциальной задержкой (1с, 3с). Если провайдер недоступен — ответ 503 сRetry-After: 30.
Шаблон ФТ в табличном виде
Один из самых удобных форматов — табличный. Он хорошо ложится в Confluence, Notion, Jira, и его легко читать как разработчику, так и заказчику.
| Поле | Значение |
|---|---|
| ID | FR-501 |
| Название | Создание заявки на возврат товара |
| Приоритет | High |
| Актор | Авторизованный покупатель |
| Предусловие | Заказ оплачен, статус delivered, с момента доставки прошло не более 14 дней |
| Основной сценарий | 1. Покупатель открывает страницу заказа 2. Выбирает позиции для возврата (одну или несколько) 3. Указывает причину из справочника + опциональный комментарий 4. Прикрепляет до 5 фото (jpg/png, до 5 МБ каждое) 5. Подтверждает заявку 6. Система присваивает заявке номер R-{YYYYMMDD}-{NNN} |
| Альтернативы | Если выбрано 0 позиций — кнопка «Подтвердить» неактивна. Если файл превышает лимит — ошибка с указанием размера |
| Постусловие | Заявка создана со статусом pending, отправлено email-уведомление покупателю и менеджеру магазина |
| Связанные НФТ | NFR-12 (время отклика), NFR-15 (хранение фото 90 дней), NFR-22 (PII-шифрование) |
| Источник | Стейкхолдер: Анна, руководитель CX. Документ: BRD-2025-08 |
Такой формат хорошо работает в команде, где требования читают и аналитик, и разработчик, и тестировщик, и поддержка. Каждый видит свою колонку. Каждый ничего не пропускает (теоретически).
Связь функциональных и нефункциональных требований
Самая частая ошибка начинающих аналитиков — описать ФТ и забыть про НФТ. Или наоборот: написать килотонну НФТ к фиче, которую никто не использует. Оба подхода ведут к одинаковому результату — невнятный продукт.
Правильная практика: к каждому ФТ привязывать релевантные НФТ. Не наоборот. Это даёт прослеживаемость: вы всегда можете спросить «а зачем нам это требование о времени отклика?» — и найти конкретное ФТ, к которому оно относится.
| ФТ | Какие НФТ к нему обычно привязаны |
|---|---|
| Авторизация пользователя | Время отклика < 1 сек, защита от brute-force, шифрование TLS, GDPR/152-ФЗ |
| Поиск по каталогу | Время отклика < 500 мс при базе до 10 млн товаров, поддержка опечаток, релевантность |
| Загрузка документа | Размер до 50 МБ, антивирусная проверка, хранение в зашифрованном виде |
| Платёж онлайн | PCI DSS, идемпотентность, аудит-логирование, 99.95% uptime платёжного шлюза |
Подробнее о том, как формулировать НФТ и какие категории вообще существуют, читайте в статье про нефункциональные требования. Здесь же — ключевая мысль: ФТ без НФТ — это половина контракта. А половина контракта в суде стоит ноль.
Типичные ошибки в функциональных требованиях
Я собирал эти ошибки годами — частично из своих, частично из тех, что разбирал на code review чужих документов. Список не претендует на полноту, но если избежать хотя бы половины — уже большая победа.
Ошибка 1. Размытые формулировки
«Система должна быстро отвечать на запросы пользователя.»
Что значит «быстро»? Что значит «отвечать»? Кому «отвечать»? Если вы написали такое — поздравьте себя, вы написали пожелание, а не требование. Правильно: «Время отклика API на запрос /search не превышает 500 мс при нагрузке до 1000 RPS, измеренное на уровне 95-го перцентиля».
Ошибка 2. Смешение ФТ и НФТ в одном пункте
«Пользователь может авторизоваться через SMS-код, который приходит за 5 секунд, шифруется и хранится не более 24 часов.»
Здесь в одну строчку запихнули ФТ (авторизация по SMS), часть НФТ по производительности (5 секунд), безопасности (шифрование) и хранению (24 часа). Разделите. Каждое требование — атомарно. Иначе при изменении одного аспекта вы будете переписывать половину документа.
Ошибка 3. Требование без актора
«Создаётся заказ.»
Кем создаётся? Покупателем через сайт? Менеджером через CRM? Cron-задачей раз в час? Внешней системой через API? Это четыре разных требования с четырьмя разными сценариями. Указывайте актора всегда.
Ошибка 4. Описание UI вместо поведения
«На странице заказа есть синяя кнопка „Отменить“ в правом верхнем углу.»
Это макет, а не требование. Кнопка может стать красной, переехать в меню, превратиться в свайп — а суть требования останется: пользователь может отменить заказ. Описывайте что система делает, а не как это выглядит. Дизайн — отдельный артефакт.
Ошибка 5. Игнорирование ошибок и крайних случаев
«Пользователь вводит номер карты и нажимает „Оплатить“. Происходит оплата.»
А что, если карта заблокирована? Если на ней недостаточно средств? Если шлюз не ответил за 30 секунд? Если пользователь нажал «Оплатить» дважды? Если параллельно идёт другая транзакция? Каждое из этих условий — отдельный сценарий, который надо описать. Иначе разработчик придумает поведение сам. И вам не понравится.
Ошибка 6. Использование пассивного залога без актора
«Должно быть реализовано отображение списка заказов.»
Кем реализовано? Кто отображает? Кому отображается? Это формулировка из учебника по канцеляриту, а не требование. Перепишите в активном залоге: «Менеджер видит список заказов своего магазина в разделе „Заказы“».
Ошибка 7. Отсутствие критериев приёмки
Требование без критериев — это пожелание. Критерии приёмки — это набор проверок, по которым тестировщик и заказчик решат, что фича готова. Без них вы рискуете услышать «это не то, что мы имели в виду» на демо. Это не серебряная пуля, но процентов 70 споров на демо снимает сразу.
Ошибка 8. «Мы потом перепишем»
Знакомая фраза с любого митинга? Когда требование пишется «на черновик» и в спешке отправляется в разработку — оно не переписывается потом. Оно становится тем, что есть. Лучше потратить лишние два часа сейчас, чем неделю разгребать последствия позже. Работает — не трогай, но если ещё не работает — пиши нормально сразу.
Чеклист для проверки готовности ФТ
Перед тем как отдать требование в разработку, прогоните его через быстрый чеклист. Это занимает 3 минуты. Это спасает 3 недели.
- Есть уникальный ID и название
- Указан актор (роль), а не абстрактный «пользователь»
- Есть предусловие — что должно быть верно ДО действия
- Описан основной сценарий по шагам
- Описаны альтернативы и обработка ошибок
- Есть постусловие — что верно ПОСЛЕ действия
- Привязаны релевантные НФТ
- Нет элементов UI/дизайна (это в макетах, не в ФТ)
- Нет слов «удобно», «быстро», «современно», «надёжно» без конкретики
- Указан источник (кто заказчик, какой документ)
- Сформулированы критерии приёмки
- Требование атомарно (одно ФТ — одно поведение)
Где хранить и как версионировать ФТ
Краткий обзор инструментов и подходов — без религиозных войн.
| Инструмент | Плюсы | Минусы |
|---|---|---|
| Confluence | Удобные таблицы, комментарии, история | Тяжело автоматизировать выгрузку, поиск так себе |
| Notion | Симпатичный UI, базы данных | Версионирование слабое, доступ извне ограничен |
| Markdown + Git | Полное версионирование, diff, ревью | Нужно учить команду работать с git (наш гайд) |
| Jira (Epic + Story) | Связь с разработкой, прозрачный workflow | Требования размазаны по тикетам, общая картина теряется |
| Word/Excel | Все умеют | Сложно работать в команде, мерж-конфликты, версии вручную |
На своём примере: связка Confluence (для обзорных страниц и навигации) + Jira (для атомарных требований в виде Story) — вполне рабочая схема для команд от 5 до 50 человек. Markdown в Git хорош, если в команде сильные инженеры и аналитики не боятся git merge.
Заключение
Хорошее функциональное требование — это документ, который можно прочитать вслух разработчику, тестировщику и заказчику, и все трое поймут одинаково. Если кто-то из троих переспросил — требование надо переписывать. Если переспросили все трое — надо переписывать и автора (шучу, ну почти).
Шаблоны и формулы из этого поста — не священное писание. Это леса, на которые опираются, пока не научились ходить без них. Со временем вы начнёте писать ФТ интуитивно. Просто помните: за каждой строчкой требования стоит человек, который будет это реализовывать. Уважайте его — пишите так, чтобы у него не было вопросов.
PS. Если вы дочитали до конца и подумали «у меня в проекте все требования уже такие» — обновите резюме, вас наверняка где-то ждут. Если подумали «надо переписать половину бэклога» — обновите резюме чуть позже, сначала перепишите бэклог.