Материал учебного циклаОткрытый материал

Как собрать BPMN, UML, ERD, C4 и API в одну проектную документацию

Практическое руководство по сборке проектной документации информационной системы. Показываем, как связать BPMN, UML, ERD, State Machine, DFD, C4, API Contracts и Event-Driven Modeling так, чтобы каждая модель отвечала на свой вопрос и не дублировала остальные.

Продукт и интерфейсы #BPMN #C4 Model #ERD #UML #архитектура #проектная документация #системный анализ
Учебный цикл Моделирование и проектирование информационных систем Материал 9 из 9

Как собрать BPMN, UML, ERD, C4 и API в одну проектную документацию

После знакомства с BPMN, UML, ERD, State Machine, DFD, C4 и API Contracts возникает следующая проблема.

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

Можно нарисовать:

  • BPMN бизнес-процесса;
  • ERD базы данных;
  • несколько UML-диаграмм;
  • C4 архитектуры;
  • OpenAPI;
  • DFD;
  • State Machine.

Но если эти документы существуют независимо друг от друга, проектная документация быстро превращается в набор схем, между которыми нет явной связи.

В хорошей документации должно быть понятно не только:

Как выглядит каждая модель?

но и:

Как требование проходит путь от бизнес-процесса до конкретного API, данных и архитектурных компонентов?

Для одной функции системы этот путь может выглядеть так:

Бизнес-процесс -> требование -> сущности и состояния -> API -> runtime interaction -> архитектурные компоненты -> физическая реализация

Разные модели описывают разные участки этого пути.

Главная задача проектной документации - не создать как можно больше диаграмм, а собрать несколько представлений одной системы так, чтобы они дополняли друг друга.

Одна система - несколько вопросов

У каждой модели должен быть свой вопрос.

Практическую карту можно представить так:

Что происходит в бизнес-процессе? -> BPMN
Кто взаимодействует с системой и зачем? -> UML Use Case
Какие сущности существуют и как они связаны? -> ERD
Как объект меняет состояние? -> State Machine
Как движутся данные? -> DFD
Кто кого вызывает во время конкретного сценария? -> Sequence Diagram
Из каких приложений состоит система? -> C4
Как выглядит точный HTTP-контракт? -> OpenAPI
Как компоненты обмениваются асинхронными событиями? -> Event-Driven Model

Это принципиально важнее выбора конкретного редактора или способа рисования.

Перед созданием любой диаграммы полезно сначала спросить:

Какой вопрос я пытаюсь решить?

Если нужно понять бизнес-процесс, C4 не поможет.

Если нужно определить таблицы PostgreSQL, BPMN не является подходящим инструментом.

Если нужно понять точную структуру JSON request, недостаточно Sequence Diagram.

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

Сквозной пример

Возьмём одну функцию CRM образовательной программы:

Подача и обработка заявки

Пользователь выбирает программу, заполняет форму и отправляет заявку.

Оператор проверяет данные.

Если данные некорректны, заявка возвращается пользователю.

Если всё заполнено правильно, заявка передаётся руководителю на согласование.

После согласования система создаёт участника программы и отправляет уведомление.

Один и тот же сценарий можно посмотреть с нескольких сторон.

И именно здесь становится понятно, зачем существует несколько моделей.

BPMN - что происходит в процессе

Сначала можно описать бизнес-процесс.

Например:

Подать заявку -> Проверить заявку -> Данные корректны?
Да -> Согласовать -> Создать участника -> Отправить уведомление
Нет -> Вернуть на исправление -> Получить исправления -> Проверить повторно

BPMN позволяет добавить участников:

Applicant - подаёт заявку
Operator - проверяет
Manager - согласовывает
Information System - выполняет автоматические операции

Здесь нас пока не интересует:

какой endpoint вызывается
какая таблица изменяется
какой Python class выполняет действие

BPMN отвечает на бизнес-вопрос:

Как проходит процесс?

Из неё начинают появляться требования к системе.

Use Case - что пользователь может делать

Теперь можно посмотреть на систему со стороны возможностей пользователей.

Например:

Applicant -> Create Application
Applicant -> Edit Application
Applicant -> Submit Application
Operator -> Review Application
Manager -> Approve Application
Manager -> Reject Application

Use Case не повторяет BPMN.

BPMN показывает последовательность процесса.

Use Case фиксирует:

Actor -> цель взаимодействия с системой

Например, BPMN может содержать Task:

Проверить заявку

Из него появляется Use Case:

Operator -> Review Application

Но это не механическое правило вида:

каждый BPMN Task = отдельный Use Case

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

От BPMN к требованиям

BPMN можно использовать как один из источников требований.

Некоторые связи действительно прослеживаются довольно естественно:

BPMN Task -> операция пользователя или системы
BPMN Lane -> роль или зона ответственности
BPMN Gateway -> business rule
BPMN Message Event -> интеграция или обмен сообщением
BPMN Timer Event -> отложенная операция
BPMN Service Task -> автоматизированная операция
BPMN Error Event -> сценарий обработки ошибки

Например:

Manager Lane
+
Approve Application Task

подсказывают:

существует роль Manager
+
у неё должна быть операция Approve Application

Gateway:

Документы проверены?

может породить business rule:

Application может перейти в Approved только если documents_verified = true

Timer Event:

через 3 дня отправить напоминание

может привести к требованию:

система должна уметь планировать delayed notification

Message Event:

получить результат оплаты

может означать необходимость:

webhook
API callback
message broker event

BPMN не определяет конкретную реализацию.

Она помогает найти то, что системе необходимо уметь делать.

Из процесса появляются сущности

После описания сценария можно перейти к данным.

В исходном требовании встречаются понятия:

Applicant
Application
Program
Document
Participant

Это кандидаты в сущности.

Но сущности не стоит выделять простым правилом:

нашёл существительное -> создал таблицу

Нужно проверить:

  • имеет ли объект собственный смысл;
  • нужно ли хранить его отдельно;
  • существует ли у него идентификатор;
  • есть ли жизненный цикл;
  • какие отношения существуют с другими объектами.

Например:

Application

явно является самостоятельной сущностью.

А:

Approval

может оказаться либо отдельной сущностью, либо просто переходом состояния Application.

Это уже решение модели данных и требований к истории.

ERD - какие данные существуют

Для нашего процесса ERD может начинаться так:

Applicant 1:N Application N:1 Program
Application 1:N Document
Application 0..1:1 Participant

Сразу появляются Primary Key и Foreign Key.

Например:

Application

id
applicant_id
program_id
status
created_at
submitted_at

Теперь бизнес-понятие:

пользователь подаёт заявку на программу

формализовано в модели данных:

Applicant 1:N Application N:1 Program

Это уже другая сторона того же требования.

BPMN показывала действие.

ERD показывает данные, которые позволяют этому действию существовать.

ERD не должна содержать процесс

Одна из распространённых ошибок - пытаться перенести в ERD всё, что было в BPMN.

Например:

SubmitApplication
ReviewApplication
ApproveApplication

начинают превращать в таблицы только потому, что эти элементы есть в процессе.

Но:

Application - данные
ApproveApplication - действие над данными

Они относятся к разным моделям.

Если историю переходов действительно нужно сохранять, тогда может появиться:

ApplicationStatusHistory

Но это уже отдельное требование к данным, а не копирование BPMN Task в таблицу.

State Machine - как живёт сущность

В BPMN видно, что заявка проходит несколько этапов.

Теперь можно формализовать именно жизненный цикл Application.

Например:

Draft -> Submitted -> UnderReview -> Approved

и альтернативно:

UnderReview -> Rejected

или:

UnderReview -> NeedsCorrection -> Submitted

Получается State Machine:

Draft -> Submit -> Submitted
Submitted -> StartReview -> UnderReview
UnderReview -> Approve -> Approved
UnderReview -> RequestCorrection -> NeedsCorrection
NeedsCorrection -> Resubmit -> Submitted
UnderReview -> Reject -> Rejected

Теперь система знает не только множество статусов, но и допустимые transitions.

Например:

Draft -> Approved

может быть запрещён.

BPMN объясняет:

почему в процессе вообще происходит согласование

State Machine объясняет:

в каком состоянии Application должна находиться, чтобы согласование было допустимо

Из State Machine появляются бизнес-правила

Например, переход:

UnderReview -> Approved

может иметь Guard:

documents_verified == true

и требование к actor:

role == manager

Теперь появляется конкретное правило:

Application может быть согласована только Manager, если она находится в UnderReview и документы проверены

Это уже не просто нарисованная стрелка.

Такое правило влияет на:

  • backend;
  • permissions;
  • API;
  • тесты;
  • интерфейс;
  • audit log.

От State Machine к API

После определения бизнес-операций можно проектировать API.

Для Application могут существовать обычные resource endpoints:

GET /applications
POST /applications
GET /applications/{id}
PATCH /applications/{id}

Но State Machine показывает, что некоторые изменения являются отдельными бизнес-командами.

Например:

POST /applications/{id}/submit
POST /applications/{id}/start-review
POST /applications/{id}/approve
POST /applications/{id}/reject

Теперь переход:

UnderReview -> Approved

связан с:

POST /applications/{id}/approve

Backend проверяет:

authentication -> authorization -> current state -> guards -> transition -> persistence -> side effects

Так между State Machine и API появляется явная связь.

API Contract - точная граница системы

На уровне требований можно сказать:

Manager должен иметь возможность согласовать Application

Но consumer API нужен точный контракт.

Например:

POST /applications/42/approve
Authorization: Bearer <token>
Content-Type: application/json
{
  "comment": "Documents verified"
}

Successful response:

200 OK
{
  "id": 42,
  "status": "approved",
  "approved_at": "2026-09-29T10:00:00Z"
}

Ошибки:

401 - пользователь не authenticated
403 - пользователь не имеет права согласования
404 - Application не существует
409 - Application находится в недопустимом состоянии
422 - данные запроса не проходят validation

Теперь требование стало техническим контрактом.

Путь можно проследить:

BPMN Approve Application
-> State Machine UnderReview -> Approved
-> API POST /applications/{id}/approve
-> OpenAPI operation

Это и есть связность документации.

OpenAPI фиксирует контракт

После проектирования endpoint его можно формализовать в OpenAPI.

OpenAPI описывает:

method
path
parameters
request schema
response schema
status codes
authentication

Теперь frontend и backend могут работать относительно одного контракта.

При этом OpenAPI не должна повторять BPMN.

В ней не нужно объяснять весь бизнес-процесс обработки заявки.

Она отвечает на более узкий вопрос:

Как именно вызвать конкретную операцию через HTTP?

Sequence Diagram - как операция выполняется во времени

API говорит:

POST /applications/{id}/approve

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

Для этого можно построить Sequence Diagram.

Например:

React -> Django API: POST /applications/42/approve
Django API -> Keycloak/JWT validation: проверить identity
Django API -> PostgreSQL: получить Application
Django API -> Application Service: проверить transition
Application Service -> PostgreSQL: сохранить Approved
Application Service -> Outbox: сохранить ApplicationApproved
Django API -> React: 200 OK
Outbox Publisher -> RabbitMQ: publish ApplicationApproved

Теперь видно runtime interaction.

Sequence Diagram отвечает:

кто -> кого вызывает -> в каком порядке

Это другой вопрос, чем OpenAPI.

OpenAPI показывает внешний контракт.

Sequence показывает выполнение конкретного сценария.

C4 - какие компоненты вообще существуют

Sequence Diagram показывает один сценарий во времени.

Но архитектура системы существует постоянно.

Для этого нужна C4 Model.

Container Diagram может выглядеть так:

React SPA -> Django API -> PostgreSQL
Django API -> Redis
Django API -> RabbitMQ -> Celery Worker
Django API -> MinIO
Django API -> Keycloak

Теперь видно:

  • какие приложения существуют;
  • какие хранилища используются;
  • какие крупные зависимости есть у системы.

Это статическая архитектурная карта.

Sequence Diagram показывает:

что произошло во время Approve Application

C4 Container Diagram:

какие элементы системы вообще существуют и связаны между собой

C4 Component Diagram связывает архитектуру с backend

Если Django API слишком крупный для понимания как один блок, можно раскрыть его:

Applications API
Application Service
Application State Machine
Document Service
Notification Service
Reporting Service
Repositories

Тогда Sequence Diagram можно связать уже с этими компонентами:

Applications API -> Application Service -> State Machine -> Repository

Так архитектура постепенно приближается к реализации, но ещё не превращается в список Python-файлов.

От API к C4

API также помогает находить архитектурные границы.

Например, существует endpoint:

POST /documents

который:

принимает metadata -> выдаёт presigned upload URL -> сохраняет информацию о Document

Это может показать необходимость:

Document component
Object Storage

Но здесь тоже нет автоматического правила:

endpoint = component

Десятки endpoints могут принадлежать одному component.

Граница component определяется ответственностью, а не количеством HTTP routes.

DFD - как данные проходят через архитектуру

C4 показывает:

React SPA -> Django API -> PostgreSQL

Но иногда этого недостаточно.

Нужно понять:

Какие именно данные проходят по этим связям?

Тогда используется DFD.

Например:

Applicant -> Application data -> Application Processing
Application Processing -> Application record -> Applications Store
Manager -> Review decision -> Application Processing
Application Processing -> Application status -> Applicant

Если нужно перейти к физическому уровню:

React SPA -> Application JSON -> Django API
Django API -> Application row -> PostgreSQL

DFD особенно полезна там, где важны:

  • чувствительные данные;
  • PII;
  • внешние интеграции;
  • trust boundaries;
  • security analysis.

DFD и C4 не дублируют друг друга

Представим связь:

Django API -> Payment Provider

На C4 этого может быть достаточно.

DFD добавляет:

Django API -> Payment request -> Payment Provider
Payment Provider -> Payment result -> Django API

То есть:

C4 -> между какими компонентами существует связь
DFD -> какие данные по этой связи проходят

Event-Driven Modeling - что происходит после события

Теперь представим, что после:

Application -> Approved

система должна:

  • создать Participant;
  • сформировать документы;
  • отправить уведомление;
  • обновить аналитику.

Можно выполнить всё синхронно.

Но если используется event-driven архитектура:

ApplicationApproved -> RabbitMQ

а затем:

ApplicationApproved -> Participant Consumer
ApplicationApproved -> Document Consumer
ApplicationApproved -> Notification Consumer
ApplicationApproved -> Analytics Consumer

Появляется ещё один слой документации.

State Machine говорит:

UnderReview -> Approved

Event model:

этот transition порождает ApplicationApproved

C4:

Django API -> RabbitMQ -> Workers

Sequence:

в каком порядке выполняется конкретный сценарий

Каждая модель снова отвечает на свой вопрос.

Один сценарий во всех моделях

Теперь можно собрать всё вместе.

Сценарий:

Applicant подаёт Application

BPMN

Заполнить заявку -> Отправить заявку -> Проверить заявку

Показывает бизнес-процесс.

Use Case

Applicant -> Submit Application

Показывает цель пользователя.

ERD

Applicant 1:N Application N:1 Program

Показывает структуру данных.

State Machine

Draft -> Submit -> Submitted

Показывает изменение состояния Application.

API Contract

POST /applications/{id}/submit

Показывает техническую операцию на границе системы.

Sequence Diagram

React -> Django API -> Application Service -> PostgreSQL

Показывает runtime interaction.

DFD

Applicant -> Application data -> Application Processing -> Application Store

Показывает движение данных.

C4

React SPA -> Django API -> PostgreSQL

Показывает архитектурные элементы.

Event-Driven Model

ApplicationSubmitted -> RabbitMQ -> Review Notification Consumer

Показывает асинхронные реакции.

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

Не стройте модели независимо

Главная проблема плохой документации выглядит так:

аналитик отдельно нарисовал BPMN
архитектор отдельно нарисовал C4
backend отдельно написал OpenAPI
разработчик отдельно создал database schema

Через некоторое время оказывается:

в BPMN статус называется Approved
в backend status называется Accepted
в API используется confirmed
в базе хранится SUCCESS

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

Поэтому важна traceability - прослеживаемость между уровнями.

Traceability

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

Например:

Business requirement:
Manager approves Application

BPMN:
Approve Application

State Machine:
UnderReview -> Approved

Permission:
Manager

API:
POST /applications/{id}/approve

OpenAPI operationId:
approveApplication

ERD:
Application.status
ApplicationStatusHistory

Domain Event:
ApplicationApproved

C4:
Django API -> RabbitMQ

Sequence:
Frontend -> API -> Service -> DB -> Outbox

Это не значит, что нужно обязательно создавать одну огромную таблицу со всеми связями.

Но разработчик должен иметь возможность восстановить такую цепочку.

Если невозможно понять, какое бизнес-требование реализует endpoint:

POST /api/v1/action/173

документация потеряла связь с предметной областью.

От требований к ERD

Практический переход обычно начинается с бизнес-сценариев.

Например:

Абитуриент подаёт заявку на выбранную программу и прикладывает документы.

Выделяются потенциальные сущности:

Applicant
Application
Program
Document

Дальше определяются связи:

Applicant 1:N Application
Program 1:N Application
Application 1:N Document

Затем обязательность:

Application обязательно имеет Applicant
Application обязательно имеет Program
Application может не иметь Document

После этого ограничения:

Application.status NOT NULL
Program.start_date NOT NULL

История:

ApplicationStatusHistory

Получается путь:

Business scenario -> entities -> relationships -> constraints -> ERD -> database schema

От ERD и State Machine к API

ERD показывает ресурсы.

Например:

Application
Program
Document

Из них естественно появляются resource endpoints:

GET /applications
POST /applications
GET /applications/{id}

GET /programs
GET /programs/{id}

POST /documents
GET /documents/{id}

State Machine добавляет business commands:

POST /applications/{id}/submit
POST /applications/{id}/approve
POST /applications/{id}/reject

Получается полезное разделение:

ERD -> какие ресурсы существуют
State Machine -> какие переходы и действия над ними существуют
API -> как consumer выполняет эти операции

Но API не нужно генерировать механически из ERD.

Если в базе существует техническая таблица:

OutboxEvent

это не означает, что автоматически нужен:

GET /outbox-events

Database model и public API имеют разные границы.

От API к Sequence Diagram

После определения операции:

POST /applications/{id}/approve

можно разобрать её выполнение.

Например:

1. Frontend -> Django API: approve
2. Django API -> Auth: проверить identity
3. Django API -> Application Service: выполнить команду
4. Application Service -> PostgreSQL: получить Application
5. Application Service -> State Machine: проверить transition
6. Application Service -> PostgreSQL: сохранить Approved + Outbox Event
7. PostgreSQL -> Application Service: COMMIT
8. Django API -> Frontend: 200 OK
9. Outbox Publisher -> RabbitMQ: ApplicationApproved

Так обнаруживаются скрытые архитектурные вопросы.

Например:

где проверяются permissions?
где находится transaction boundary?
кто публикует событие?
что произойдёт при ошибке RabbitMQ?

Sequence Diagram становится инструментом проверки дизайна, а не просто красивой иллюстрацией.

От Sequence к C4

Если в Sequence постоянно появляются:

Frontend
Application API
Document Service
Notification Worker
PostgreSQL
RabbitMQ
MinIO

можно проверить Container и Component Diagram.

Архитектурная документация должна подтверждать, что эти элементы действительно существуют и имеют понятные обязанности.

Например:

Container: Django API
Component: Application Service

Container: Celery Worker
Component: Notification Handler

Container: PostgreSQL

Если Sequence Diagram ссылается на компонент, которого нигде больше нет, стоит проверить согласованность документации.

Что не нужно связывать один к одному

Очень важно не превратить эту методику в механический генератор.

Неверно:

каждый BPMN Task -> endpoint
каждая ERD entity -> API resource
каждый API endpoint -> отдельный component
каждый component -> отдельный microservice

Таких правил нет.

Например, один BPMN Task:

Проверить заявку

может внутри использовать:

GET /applications/{id}
POST /applications/{id}/start-review
POST /applications/{id}/approve
POST /applications/{id}/reject

Один backend Component может обслуживать десятки endpoints.

Один C4 Container может содержать десятки Components.

Одна ERD entity может вообще не иметь публичного API.

Модели связаны семантически, а не количеством элементов.

Минимальная документация небольшого проекта

Небольшой системе не нужно создавать полный каталог всех существующих типов диаграмм.

Для многих проектов достаточно:

System Context Diagram
Container Diagram
ERD
несколько ключевых BPMN
State Machine критичных сущностей
OpenAPI
несколько Sequence Diagram сложных сценариев

Дополнительно:

DFD -> если важны потоки данных, безопасность и внешние интеграции
Event-Driven Model -> если есть broker и сложные asynchronous flows
Deployment Diagram -> если инфраструктура уже имеет существенную сложность
Component Diagram -> если отдельный Container стал достаточно большим

Документация должна расти вместе со сложностью системы.

Не нужно заранее создавать:

40 diagrams

для приложения из одного Django backend и PostgreSQL.

Какие BPMN стоит документировать

Не обязательно рисовать BPMN для каждого действия.

Имеет смысл выбрать процессы, где присутствуют:

  • несколько участников;
  • бизнес-решения;
  • исключения;
  • ожидание;
  • внешние взаимодействия;
  • сложный жизненный цикл.

Например:

обработка заявки
оплата
выдача документов
возврат
регистрация участника

Простой CRUD:

пользователь изменил номер телефона

может вообще не требовать BPMN.

Какие State Machine стоит документировать

State Machine особенно полезны для сущностей:

Application
Order
Payment
Document
Deal
Task

где:

  • много статусов;
  • существуют запрещённые переходы;
  • важны права;
  • переходы вызывают side effects.

Для сущности:

Country

с полями:

id
name
code

State Machine, скорее всего, ничего не добавит.

Какие Sequence Diagram стоит документировать

Sequence Diagram полезны там, где невозможно сразу понять runtime interaction.

Например:

authentication
payment
file upload
report generation
webhook processing
event publication
distributed transaction

Не нужно рисовать Sequence Diagram для каждого:

GET /countries

если сценарий очевиден.

Документация должна концентрироваться на сложных участках.

OpenAPI обычно нужен целиком

В отличие от BPMN или Sequence Diagram, API-контракт лучше документировать системно.

Consumer должен иметь возможность узнать контракт любого поддерживаемого endpoint.

Поэтому OpenAPI естественно становится почти полной технической спецификацией HTTP API.

Но при этом OpenAPI не обязана подробно объяснять всю бизнес-логику.

Для этого остаются:

BPMN
State Machine
обычная документация

Архитектурные решения и ADR

Некоторые вопросы плохо выражаются диаграммами.

Например:

Почему для асинхронных задач выбран RabbitMQ?

или:

Почему используется модульный монолит вместо микросервисов?

или:

Почему документы хранятся в MinIO, а не в PostgreSQL?

Для таких решений полезны ADR - Architecture Decision Records.

ADR обычно фиксирует:

контекст
решение
рассмотренные альтернативы
последствия

Например:

ADR-005: Использовать Transactional Outbox для публикации domain events

C4 показывает:

Django -> PostgreSQL -> RabbitMQ

Но ADR объясняет:

Почему архитектура устроена именно так.

Диаграмма и архитектурное решение выполняют разные функции.

Документация должна иметь источник истины

Одна из самых неприятных ситуаций:

Confluence говорит одно
README другое
OpenAPI третье
реальный backend четвёртое

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

Для каждого типа информации полезно определить source of truth.

Например:

API contract -> OpenAPI
database schema -> migrations + ERD
architecture -> C4 diagrams
business process -> BPMN
architecture decisions -> ADR
state transitions -> State Machine specification / code

Это не означает, что модель обязана генерироваться автоматически.

Но должно быть понятно, какой источник считается актуальным при расхождении.

Documentation as Code

Для технической документации часто удобно хранить исходники рядом с кодом.

Например:

/docs
    /architecture
        context.puml
        containers.puml
    /bpmn
        application-review.bpmn
    /erd
        domain.dbml
    /adr
        ADR-001.md
        ADR-002.md
    openapi.yaml

Преимущества:

  • version control;
  • code review;
  • история изменений;
  • связь документации с release;
  • возможность обновлять её в том же pull request.

Например, разработчик изменяет:

Application State Machine

и в том же PR обновляет:

state diagram
OpenAPI
Sequence Diagram

Документация становится частью изменения системы, а не отдельной задачей "обновить когда-нибудь потом".

Но не всё нужно хранить рядом с кодом

Бизнес-документация может жить:

  • в базе знаний;
  • BPM-системе;
  • Confluence;
  • внутреннем портале.

Важно не конкретное место хранения.

Важно, чтобы было понятно:

где находится актуальная версия
кто отвечает за неё
когда она должна изменяться

Документация должна иметь владельца

Документ без владельца почти гарантированно устареет.

Например:

BPMN -> Business/System Analyst
OpenAPI -> Backend Team
ERD -> Backend/Data Team
C4 -> Tech Lead / Architect
ADR -> команда, принявшая решение

Это не означает, что только один человек имеет право вносить изменения.

Речь о том, кто отвечает за актуальность модели.

Когда нужно обновлять документацию

Хорошее правило:

Если изменение системы делает существующую схему неверной, документацию нужно менять вместе с системой.

Например, изменился:

API contract -> обновить OpenAPI

Добавился новый:

Application state -> обновить State Machine

Появилась новая внешняя система:

Payment Provider -> обновить System Context

Появился новый Container:

Notification Service -> обновить Container Diagram

Изменился бизнес-процесс:

появилось дополнительное согласование -> обновить BPMN

Не обязательно обновлять всё при каждом commit.

Обновляются модели, смысл которых действительно изменился.

Не документируйте нестабильные детали без причины

Если внутренний код постоянно меняется:

ApplicationService
ApplicationCommandHandler
ApplicationFacade
ApplicationManager

может не иметь смысла поддерживать C4 Component Diagram, где каждый такой класс показан отдельно.

Именно поэтому документация должна оставаться на достаточно стабильном уровне абстракции.

Например:

Application Management Component

может существовать месяцами, даже если внутри него были десятки рефакторингов.

Хорошая документация описывает устойчивую структуру системы.

Изменение требования должно распространяться по моделям

Представим новое требование:

После согласования Application должна пройти проверку службой безопасности.

Раньше:

UnderReview -> Approved

Теперь:

UnderReview -> SecurityReview -> Approved

Изменение проходит по документации.

BPMN

Добавляется:

Проверить заявку -> Проверка безопасности -> Согласовать

State Machine

Изменяется:

UnderReview -> SecurityReview -> Approved

Roles

Появляется:

Security Officer

API

Возможно появляются:

POST /applications/{id}/start-security-review
POST /applications/{id}/approve-security-review

ERD

Может потребоваться:

security_reviewed_at
security_reviewed_by

или отдельная:

SecurityReview

если проверка имеет собственный жизненный цикл.

Sequence Diagram

Добавляется взаимодействие с новым компонентом или ролью.

C4

Если появляется отдельный сервис:

Security Verification Service

изменяется Container Diagram.

Events

Могут появиться:

SecurityReviewStarted
SecurityReviewCompleted

Так одно бизнес-изменение проходит через несколько представлений системы.

Именно поэтому документация должна быть связанной.

Documentation change impact

Полезно привыкнуть задавать вопрос:

Какие модели затрагивает это изменение?

Например:

Добавили поле comment -> ERD + API
Добавили статус -> State Machine + API + возможно BPMN
Добавили новую роль -> Use Case + BPMN + authorization
Добавили новый сервис -> C4 + возможно Sequence
Добавили интеграцию -> Context + Container + DFD + API/Event Contract
Изменили бизнес-процесс -> BPMN + возможно State Machine + API

Так документация становится инструментом impact analysis.

Не дублируйте одну информацию во всех документах

Если точная request schema уже находится в OpenAPI, нет смысла копировать полный JSON schema в:

BPMN
C4
ERD
Sequence Diagram

Можно показать только нужную часть:

Sequence:
React -> API: CreateApplicationRequest

а точное определение CreateApplicationRequest оставить в OpenAPI.

Аналогично:

если связи таблиц уже описаны в ERD, C4 не должна повторять все Foreign Keys.

Принцип:

каждая информация имеет основной источник
остальные модели только ссылаются на неё на нужном уровне

Это уменьшает риск расхождения.

Проектная документация как граф знаний

Вместо представления:

у нас есть 15 файлов документации

полезнее думать:

у нас есть одна модель системы с несколькими представлениями

Например:

Application

связана с:

BPMN Process
State Machine
ERD Entity
API Resource
Domain Events
Backend Component
Sequence Diagrams

А:

Manager

связан с:

BPMN Lane
Use Case Actor
Role
API permissions

Система становится не набором схем, а сетью взаимосвязанных понятий.

Уровни проектной документации

Всю документацию удобно условно разделить на несколько уровней.

Бизнес-уровень

Отвечает:

что делает организация и зачем

Инструменты:

BPMN
Use Cases
business rules

Доменный уровень

Отвечает:

какие понятия существуют и как они себя ведут

Инструменты:

ERD / Domain Model
State Machine
Event Model

Контрактный уровень

Отвечает:

как части системы взаимодействуют через формальные границы

Инструменты:

OpenAPI
Webhook Contracts
Event Contracts

Архитектурный уровень

Отвечает:

какие программные элементы существуют

Инструменты:

C4
Component Diagram

Runtime-уровень

Отвечает:

как проходит конкретный технический сценарий

Инструменты:

Sequence Diagram
C4 Dynamic Diagram

Инфраструктурный уровень

Отвечает:

где система физически работает

Инструменты:

C4 Deployment
UML Deployment
Infrastructure diagrams

Так становится намного проще понимать, где должна находиться конкретная информация.

Практическая структура документации проекта

Для реального проекта документацию можно организовать примерно так:

1. Overview
2. Business Processes
3. Domain Model
4. Architecture
5. API and Integration Contracts
6. Runtime Scenarios
7. Deployment
8. Architecture Decisions

Например:

Overview
-> System Context

Business Processes
-> BPMN

Domain Model
-> ERD
-> State Machines
-> Domain Events

Architecture
-> C4 Container
-> C4 Component

API and Integrations
-> OpenAPI
-> Webhook Contracts
-> Event Contracts

Runtime Scenarios
-> Sequence Diagrams

Deployment
-> Deployment Diagram

Decisions
-> ADR

Такая структура лучше, чем отдельные папки:

UML
BPMN
ERD

без связи с задачами проекта.

Пользователю документации обычно важнее вопрос:

Где посмотреть архитектуру?

чем:

Где у нас лежат все UML-диаграммы?

Как читать документацию нового проекта

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

Сначала:

System Context

Чтобы понять, что это вообще за система.

Затем:

Container Diagram

Чтобы увидеть основные приложения и хранилища.

После этого:

ключевые BPMN

Чтобы понять бизнес-процессы.

Дальше:

ERD + State Machines

Чтобы понять данные и жизненный цикл сущностей.

Потом:

OpenAPI

Чтобы увидеть внешние контракты.

Для сложных сценариев:

Sequence Diagram

И уже после этого есть смысл глубоко читать исходный код.

Так архитектурная документация сокращает время, необходимое для построения ментальной модели проекта.

Типичные ошибки проектной документации

Первая ошибка - пытаться описать систему одной диаграммой.

Получается:

users + business process + APIs + tables + classes + servers

и никто не может её читать.

Вторая ошибка - создавать одну и ту же информацию в нескольких местах.

Например, request schema одновременно хранится:

в OpenAPI
в Markdown
в Confluence
в комментарии frontend

Через месяц четыре версии расходятся.

Третья ошибка - документы не связаны.

Есть BPMN и OpenAPI, но невозможно понять:

какой endpoint реализует конкретный Task

Четвёртая ошибка - документируется всё подряд.

Даже простейший CRUD получает:

BPMN
Use Case
Sequence
Activity
Component
State Machine

Стоимость поддержки документации становится выше её пользы.

Пятая ошибка - документация создаётся после разработки как отдельный формальный этап.

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

Шестая ошибка - слишком низкий уровень детализации.

Если архитектурная диаграмма содержит:

serializer.py
helpers.py
utils.py

она будет устаревать после каждого рефакторинга.

Седьмая ошибка - нет владельца документа.

Через несколько месяцев никто не знает:

эта схема ещё актуальна?

Восьмая ошибка - отсутствие ADR.

Диаграмма показывает:

что существует

но никто уже не помнит:

почему было принято именно такое решение

Как проверить комплект документации

Для небольшого проекта полезно пройти по нескольким вопросам.

Понятно ли:

  • что делает система;
  • кто её использует;
  • какие внешние системы существуют;
  • какие ключевые бизнес-процессы выполняются;
  • какие основные сущности хранятся;
  • как связаны сущности;
  • какие сущности имеют сложный жизненный цикл;
  • какие API доступны;
  • какие события и webhooks существуют;
  • какие приложения входят в систему;
  • как выполняются сложные runtime-сценарии;
  • где находятся архитектурные решения;
  • кто отвечает за актуальность каждого документа?

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

Что важно запомнить

BPMN, UML, ERD, C4, DFD, State Machine и OpenAPI не конкурируют друг с другом.

Они описывают разные стороны одной системы.

Основная карта:

BPMN -> бизнес-процесс
Use Case -> пользовательские цели
ERD -> структура данных
State Machine -> жизненный цикл объекта
DFD -> движение данных
Sequence Diagram -> взаимодействие во времени
C4 -> архитектурная структура
OpenAPI -> точный HTTP-контракт
Event Model -> асинхронные события и команды
Deployment -> физическое размещение
ADR -> причины архитектурных решений

Связь между ними можно представить как общий путь:

Бизнес-требование
-> BPMN / Use Case
-> Domain Model
-> ERD + State Machine
-> API / Event Contracts
-> Sequence
-> C4
-> реализация

При этом направление не всегда только сверху вниз.

Изменение API может обнаружить проблему в State Machine.

Изменение ERD может потребовать пересмотра API.

Новый Container может изменить Sequence Diagram.

Новая бизнес-ветка в BPMN может потребовать новой сущности, роли и события.

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

Главный принцип можно сформулировать так:

один вопрос -> одна подходящая модель -> один основной источник истины

А хорошая документация позволяет пройти путь:

зачем существует функция -> как работает бизнес-процесс -> какие данные и состояния нужны -> какой контракт предоставляет система -> какие компоненты участвуют -> как всё выполняется технически

Если этот путь прослеживается, документация действительно помогает проектировать и развивать систему, а не существует только ради наличия схем.

Продолжить

  1. 01 BPMN: от бизнес-процесса до требований к системе Что такое BPMN, зачем моделировать бизнес-процессы и как читать простую диаграмму от начала до результата.
  2. 02 UML: как описывать программную систему с разных сторон Введение в UML и основные виды диаграмм. Разбираем, зачем одной системе нужны разные представления, что показывают Use Case, Sequence, Class, Activity, State Machine, Component и Deployment Diagram и как выбрать подходящую диаграмму под задачу.
  3. 03 ERD и моделирование данных Подробное введение в ERD и моделирование данных. Разбираем сущности, атрибуты, первичные и внешние ключи, связи 1:1, 1:N и M:N, обязательность связей, нормализацию и переход от ERD к PostgreSQL и Django ORM.
  4. 04 State Machines: жизненный цикл сущностей Практическое введение в State Machine и моделирование жизненного цикла сущностей. Разбираем состояния, переходы, события, guard conditions, побочные эффекты и связь State Machine с BPMN, базой данных и API.
  5. 05 DFD: как данные проходят через систему Практическое введение в DFD и моделирование потоков данных. Разбираем внешние сущности, процессы, хранилища и потоки данных, Context Diagram, уровни декомпозиции, баланс между уровнями, связь DFD с API, безопасностью, BPMN и Sequence Diagram.
  6. 06 C4 Model: архитектура программной системы Практическое введение в C4 Model для описания архитектуры информационных систем. Разбираем уровни System Context, Container и Component, дополнительные Dynamic и Deployment Diagram, границы между ними и применение C4 для монолитов и микросервисов.
  7. 07 API Contracts: как системы договариваются о взаимодействии Практическое руководство по проектированию API-контрактов. Разбираем структуру HTTP API, ресурсы и action endpoints, request и response schemas, ошибки, OpenAPI, версионирование, совместимость, аутентификацию, авторизацию, webhook-контракты и безопасное изменение API для существующих consumers.
  8. 08 Event-Driven Modeling: события, очереди и асинхронные процессы Практическое руководство по Event-Driven Modeling и проектированию асинхронных взаимодействий. Разбираем команды и события, Producer, Broker и Consumer, очереди и routing, идемпотентность, порядок событий, retries, Dead Letter Queue, Transactional Outbox, eventual consistency и связь событий с BPMN и State Machine.

Обратная связь

Материал был полезен?

Нашли ошибку или неточность? Сообщить →

Начните вводить — найдём материал по всей библиотеке.