Logo
Overview

Функциональные и нефункциональные требования: шаблоны, примеры и типичные ошибки

May 22, 2026
13 min read

Функциональные и нефункциональные требования: шаблоны, примеры и типичные ошибки

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

Функциональное требование — это не описание мечты заказчика и не пересказ ТЗ своими словами. Это контракт между продуктом и реализацией, который должен читаться одинаково аналитиком, разработчиком, тестировщиком и юристом (последний — на случай, если что-то пойдёт не так). И раз уж от этого контракта зависит, поедет ли заказчик в отпуск спокойным, давайте разберёмся, как писать ФТ так, чтобы их не пришлось переписывать на следующем спринте.

Раньше мы уже говорили о том, что такое нефункциональные требования и зачем они вообще нужны, а также подробно разбирали примеры ФТ и НФТ по доменам. Сегодня — глубже в практику: шаблоны формулировок, готовые примеры по типам систем и подборка ошибок, на которых я и мои коллеги набивали шишки годами.

Что такое функциональное требование на самом деле

Начнём с базы, без академических определений из учебников.

Функциональное требование (ФТ, FR — Functional Requirement) — это утверждение о том, какое конкретное поведение должна демонстрировать система в ответ на действие пользователя, внешнее событие или наступление условия.

Главное слово здесь — поведение. Не «фича», не «модуль», не «возможность». Поведение. Если требование нельзя проверить наблюдением за системой («сделали действие — система ответила так-то») — это не функциональное требование, это пожелание.

Сравним:

Не требованиеТребование
Система должна быть удобной для пользователяПользователь может зарегистрироваться, указав email и пароль; после регистрации он автоматически авторизуется и переходит на главную страницу
Должна работать корзинаПользователь может добавить товар в корзину; в корзине одновременно находится не более 100 позиций; повторное добавление того же товара увеличивает количество, а не создаёт новую строку
Поддержка интеграции с 1ССистема ежедневно в 03:00 МСК выгружает новые заказы во внешнюю 1С через REST API; в случае ошибки повторяет попытку 3 раза с интервалом 10 минут

Видна разница? Левая колонка — это маркетинговая брошюра. Правая — то, что можно положить в Jira, оценить в часах и проверить тестом.

Структура хорошего ФТ: что обязательно входит

Чтобы требование можно было реализовать без угадывания, в нём должны быть пять элементов. Один пропустите — получите вопросы на код-ревью. Два — получите баг в проде. Три — получите письмо от заказчика.

100%
graph LR
  FR["Функциональное<br/>требование"]
  FR --> ACTOR["Актор<br/>(кто инициирует)"]
  FR --> ACTION["Действие<br/>(что делает)"]
  FR --> OBJECT["Объект<br/>(над чем)"]
  FR --> COND["Условие<br/>(при каких обстоятельствах)"]
  FR --> RESULT["Результат<br/>(чем заканчивается)"]

  ACTOR --> A1["Пользователь<br/>Администратор<br/>Внешняя система<br/>Cron-задача"]
  ACTION --> AC1["Создаёт<br/>Изменяет<br/>Удаляет<br/>Запрашивает"]
  OBJECT --> O1["Заказ<br/>Профиль<br/>Документ<br/>Транзакция"]
  COND --> C1["При наличии прав<br/>В рабочее время<br/>При валидных данных"]
  RESULT --> R1["Создан объект<br/>Изменён статус<br/>Отправлено уведомление"]

  style FR fill:#4a90d9,stroke:#2c5f8a,color:#fff
  style ACTOR fill:#50c878,stroke:#3a9a5c,color:#fff
  style ACTION fill:#50c878,stroke:#3a9a5c,color:#fff
  style OBJECT fill:#50c878,stroke:#3a9a5c,color:#fff
  style COND fill:#f0a500,stroke:#c88400,color:#fff
  style RESULT fill:#7b68ee,stroke:#5a4db2,color:#fff
  style A1 fill:#e0e0e0,stroke:#999,color:#333
  style AC1 fill:#e0e0e0,stroke:#999,color:#333
  style O1 fill:#e0e0e0,stroke:#999,color:#333
  style C1 fill:#e0e0e0,stroke:#999,color:#333
  style R1 fill:#e0e0e0,stroke:#999,color:#333

На диаграмме — анатомия требования. Если выкинуть актора, неясно, кто инициирует действие. Если выкинуть условие — система разрешит делать что угодно и кому угодно (привет, нарушение прав доступа). Если выкинуть результат — нечего тестировать.

Канонические формулы

Существует три рабочие формулы, к которым сводится 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 / алерт]
Идемпотентность: [Да/Нет, как обеспечивается]

Шаблоны — не догма. Это страховка от того, что вы забудете описать обработку ошибок или постусловие. На своём примере могу сказать: половина инцидентов на проде случается потому, что в требовании не было ответа на вопрос «а что, если внешняя система не ответила?»

Жизненный цикл функционального требования

Требование рождается не из вакуума, и умирает оно тоже не сразу. Между «у нас идея» и «фича в проде» проходит путь, который полезно понимать целиком.

100%
flowchart TD
  IDEA["Идея от стейкхолдера"]
  CLARIFY["Уточнение<br/>с заказчиком"]
  DRAFT["Черновик ФТ"]
  REVIEW["Ревью<br/>(аналитик, ПМ, архитектор)"]
  APPROVE["Утверждение"]
  BACKLOG["В бэклог"]
  SPRINT["Взято в спринт"]
  DEV["Разработка"]
  TEST["Тестирование"]
  PROD["Релиз в прод"]
  CHANGE["Запрос на изменение"]
  ARCHIVE["Архив<br/>(требование закрыто)"]

  IDEA --> CLARIFY
  CLARIFY --> DRAFT
  DRAFT --> REVIEW
  REVIEW -->|"Замечания"| DRAFT
  REVIEW -->|"OK"| APPROVE
  APPROVE --> BACKLOG
  BACKLOG --> SPRINT
  SPRINT --> DEV
  DEV --> TEST
  TEST -->|"Баги"| DEV
  TEST -->|"OK"| PROD
  PROD --> ARCHIVE
  PROD --> CHANGE
  CHANGE --> DRAFT

  style IDEA fill:#f0a500,stroke:#c88400,color:#fff
  style CLARIFY fill:#f0a500,stroke:#c88400,color:#fff
  style DRAFT fill:#4a90d9,stroke:#2c5f8a,color:#fff
  style REVIEW fill:#4a90d9,stroke:#2c5f8a,color:#fff
  style APPROVE fill:#7b68ee,stroke:#5a4db2,color:#fff
  style BACKLOG fill:#7b68ee,stroke:#5a4db2,color:#fff
  style SPRINT fill:#50c878,stroke:#3a9a5c,color:#fff
  style DEV fill:#50c878,stroke:#3a9a5c,color:#fff
  style TEST fill:#50c878,stroke:#3a9a5c,color:#fff
  style PROD fill:#50c878,stroke:#3a9a5c,color:#fff
  style CHANGE fill:#f0a500,stroke:#c88400,color:#fff
  style ARCHIVE fill:#e0e0e0,stroke:#999,color:#333

Диаграмма показывает, что любое требование может вернуться на доработку с любого этапа — это нормально. Ненормально, когда оно возвращается на этапе прода (привет, инциденты). Чтобы минимизировать такие возвраты, существует ревью — и его не стоит пропускать, даже если все спешат. На своём примере могу сказать: один час совместного чтения требования экономит две недели переписывания фичи.

Примеры функциональных требований по типам систем

Теория без живых примеров быстро забывается. Ниже — реальные формулировки из проектов, в которых я участвовал. Названия систем и цифры изменены, суть — нет.

Веб-приложение (личный кабинет клиента банка)

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, и его легко читать как разработчику, так и заказчику.

ПолеЗначение
IDFR-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. Если вы дочитали до конца и подумали «у меня в проекте все требования уже такие» — обновите резюме, вас наверняка где-то ждут. Если подумали «надо переписать половину бэклога» — обновите резюме чуть позже, сначала перепишите бэклог.