Как выводить схему БД из user stories, сущностей и workflow
Пошагово разберём, как из user stories, сущностей и workflow получить схему БД: таблицы, связи, ключи и ограничения — и где помогает AI‑рассуждение.

Зачем выводить схему БД из историй и процессов
Схема базы данных — это не просто набор таблиц. Это зафиксированные решения о том, какие данные хранятся, как они связаны и какие правила нельзя нарушать. Обычно в схему входят таблицы (сущности), поля (атрибуты), первичные и внешние ключи, ограничения (уникальность, обязательность, допустимые значения), а также правила удаления/обновления связанных записей.
Если строить схему «с головы» или только по доменным терминам, легко пропустить критичные детали: статусы, исключения, роли, условия видимости данных. Когда же схема выводится из user stories и workflow, она опирается на реальные сценарии — то есть на то, что пользователи действительно делают и что бизнес обязан проверять.
Как истории, сущности и процессы дополняют друг друга
User stories отвечают на вопрос «зачем и какую ценность даёт функция» и часто содержат проверки: «пользователь видит только свои заявки», «нельзя оплатить дважды». Сущности и атрибуты дают «что именно хранить» (Заявка, Платёж, Клиент). Workflow показывает «когда и как данные меняются»: какие состояния возможны, какие переходы разрешены, какие события должны фиксироваться.
Вместе это превращает схему из абстрактной модели в инструмент исполнения требований: ограничения и связи отражают правила бизнеса, а не вкусовые предпочтения команды.
Что нужно на входе
Минимальный набор артефактов:
- бэклог с user stories и acceptance criteria;
- черновой словарь данных (термины, определения, примеры значений);
- описания процессов: шаги, статусы, исключения (в виде диаграммы или текста).
Критерии качества результата
Хорошая схема проверяется четырьмя критериями:
- полнота — для каждой истории понятно, где хранятся нужные данные;
- непротиворечивость — одно правило не ломает другое (например, статусы и права доступа);
- расширяемость — новые сценарии добавляются без переписывания половины модели;
- проверяемость — ограничения можно подтвердить тестами и запросами, а не «на словах».
Как читать user stories так, чтобы из них получались данные
User story — это не только про интерфейсы и функции. В ней почти всегда спрятаны будущие таблицы, поля и ограничения. Задача — читать историю «как аналитик данных»: что хранить, как отличать сущности, и где нужны статусы и правила.
Держим в голове структуру истории
Удобный формат: роль → цель → ценность плюс критерии приёмки. Именно критерии часто содержат «точные слова» для модели данных: какие поля обязательны, какие проверки выполняются, когда что считается успешным.
Пример (схематично):
Как менеджер, я хочу подтверждать заявку, чтобы зафиксировать решение и уведомить клиента.
Из одной фразы уже видно: есть объект «заявка», действие «подтверждать», и результат «решение/уведомление» (а значит — событие, статус или запись истории изменений).
Как извлекать данные из формулировок
Быстрый разбор текста:
- Существительные → кандидаты в сущности (Заявка, Клиент, Платёж, Договор).
- Глаголы → операции и намёки на связи/события (создать, подтвердить, отменить, назначить).
- Свойства и уточнения → атрибуты (номер заявки, дата подтверждения, причина отказа, сумма).
Полезный вопрос к каждой истории: «Что нужно показать, найти, отфильтровать или доказать аудитору?» Всё это почти всегда требует хранения данных.
Ищем неоднозначности: «это поле или статус?»
Слова вроде «активный», «подтверждённый», «черновик» часто маскируют разные варианты:
- Статус (одно поле
statusсо справочником значений). - Флаг (например,
is_active), если вариантов ровно два и это не этап процесса. - Отдельная сущность/событие, если важна история переходов: кто и когда подтвердил.
Проверка: если в критериях приёмки есть «показать список всех изменений» или «откатить», одного поля статуса обычно недостаточно.
Мини‑шаблон фиксации, чтобы ничего не потерять
Используйте короткую карточку на каждую найденную сущность:
- Сущность: Заявка
- Поля: id, created_at, customer_id, status, approved_at, approved_by
- Правила:
customer_idобязателен;approved_atзаполняется только приstatus=approved - Примеры значений: status = draft/approved/rejected; approved_by = user_id
Такой шаблон дисциплинирует чтение историй: вы не спорите «про таблицы», вы уточняете смысл слов — и модель данных получается естественным продолжением требований.
Сущности и атрибуты: от терминов к таблицам
На этом шаге вы переводите «слова из требований» в структуру данных. Хороший ориентир: если предметное слово фигурирует в историях как объект действий (создать, изменить, отправить, согласовать), скорее всего это кандидат в сущность (таблицу). Если слово описывает свойства объекта (дата, сумма, статус), это атрибут (поле).
Список кандидатов в сущности
Начните с выписки существительных из user stories и экранов: «заявка», «пользователь», «комментарий», «платёж». Затем разделите их на две группы.
Основные сущности — живут долго и участвуют в процессах: Заказ, Заявка, Клиент, Документ.
Справочники — ограниченные наборы значений, которые удобно стандартизировать: статусы, типы, категории, причины отмены, валюты. Справочники полезны тем, что уменьшают разнобой («Отменён», «отмена», «cancelled») и упрощают отчёты.
Проверка здравого смысла: если значение меняется редко и используется в разных местах — это почти всегда справочник.
Атрибуты: что именно хранить и как описать
Для каждого поля фиксируйте не только название, но и «правила хранения»:
- Обязательность: можно ли сохранять запись без этого значения?
- Тип данных и формат: дата/время, строка, число; формат телефона, маска, часовой пояс.
- Диапазоны и единицы: сумма ≥ 0, вес в кг, длина строки, количество знаков после запятой.
Это превращает расплывчатое «пользователь указывает сумму» в конкретику: amount NUMERIC(12,2) NOT NULL CHECK (amount >= 0).
Уникальность и идентификаторы
Дальше решите, чем однозначно «называется» запись.
- Естественный ключ (например, ИНН или номер паспорта) хорош, когда он действительно стабилен и гарантированно уникален.
- Суррогатный ключ (ID) проще в связях и миграциях, особенно когда «естественный» идентификатор может поменяться или отсутствовать на старте.
На практике часто используют ID как первичный ключ, а естественные уникальные значения — как отдельные поля с ограничением уникальности.
События vs состояния
Если объект просто «находится в статусе», достаточно поля status_id. Но если важно отвечать на вопросы «когда и кто изменил», «сколько времени был на этапе», «сколько раз возвращали на доработку» — храните историю изменений отдельной таблицей (например, request_status_history), где каждая строка — событие: статус, время, инициатор, комментарий.
Правило: состояние — для текущей картины, события — для аудита, аналитики и спорных ситуаций.
Связи между сущностями и правила целостности
Связи — это место, где требования перестают быть «про тексты» и становятся про данные: кто с кем связан, сколько раз, можно ли «без пары», и что происходит при удалении или изменении.
Кардинальности: 1:1, 1:N, M:N — как их увидеть в требованиях
Ищите в user stories формулировки, которые намекают на количество:
- 1:1: «у пользователя есть один профиль», «каждому договору соответствует один акт». Часто это признак разделения по доступу/редкости полей.
- 1:N: «у заказа много позиций», «у проекта много задач». Обычно «родитель» живёт дольше «детей».
- M:N: «пользователь состоит в нескольких командах, и в команде много пользователей». Если звучит «много к многим» — почти всегда нужна отдельная связь.
Проверяйте, не скрыта ли кардинальность в исключениях: «обычно один, но иногда несколько» — это уже 1:N.
Таблицы связей для M:N и атрибуты связи
Для M:N почти всегда создают таблицу связей (join table). Важно: связь часто имеет собственные атрибуты, которые нельзя корректно хранить ни в одной из сторон:
- роль участника в команде,
- дата вступления/выхода,
- статус (активен, приглашён, заблокирован).
Тогда таблица связи становится «полноценной сущностью» (например, team_membership).
Опциональность связи и правила удаления/архивации
Опциональность отвечает на вопрос: может ли запись существовать без связанной записи?
- «Черновик заказа может быть без оплаты» → связь
order -> paymentопциональна. - «Позиция не может существовать без заказа» → связь
order_item -> orderобязательна.
Дальше — поведение при удалении: в бизнес‑системах часто правильнее архивировать (soft delete), чем физически удалять. Если удаление разрешено, заранее определите правило: запрещаем, каскадно удаляем или «отвязываем».
Ссылочная целостность: внешние ключи и каскадные действия
Внешние ключи нужны там, где связь должна быть истинной всегда (чтобы не появлялись «сироты»). Каскады применяйте осознанно:
ON DELETE RESTRICT/NO ACTION— безопасно для важных сущностей (нельзя удалить родителя, пока есть дети).ON DELETE CASCADE— уместно для явно зависимых данных (например, позиции черновика).ON DELETE SET NULL— подходит, если связь опциональна и запись может жить дальше без привязки.
Хорошее правило: каскад — это про техническую зависимость, а не про «удобно удалить всё одним махом».
Workflow как источник требований к состояниям и событиям
Workflow — это не только «как работает процесс», но и точная подсказка, какие данные должны появляться, меняться и сохраняться во времени. Если читать шаги процесса последовательно, становится видно жизненный цикл объекта: что считается созданием, что — обновлением, где нужен след аудита, а где достаточно текущего состояния.
Шаги процесса = обязательные данные
Каждый шаг отвечает на вопросы: какие поля нужны прямо сейчас и какие должны быть заполнены обязательно. Например, если шаг «Отправить заявку» возможен только после выбора тарифа и адреса, значит эти атрибуты либо обязательны в записи, либо фиксируются как отдельные связанные сущности до финальной отправки.
Практический приём: рядом с каждым шагом workflow выпишите минимальный набор данных, без которых шаг невозможен. Это быстро выявляет:
- обязательные поля (NOT NULL),
- значения по умолчанию,
- справочники (статусы, причины).
Точки создания/изменения/удаления
Workflow подсказывает, какие таблицы затрагиваются на каждом этапе. Часто выясняется, что «одна сущность» на словах на деле распадается на несколько таблиц: основная запись + события + вложения/комментарии.
Важно различать «удаление» как действие пользователя и физическое удаление в БД. Если в процессе есть «Отмена» или «Архивирование», обычно нужна логическая деактивация (например, deleted_at, canceled_at) и запрет на дальнейшие переходы.
Состояния и переходы
Статусы в workflow — это требования к модели данных. Минимальный набор:
- текущее состояние (
status), - кто изменил (
updated_by), - когда изменил (
updated_at).
Если бизнесу важно объяснять, почему состояние сменилось, добавляется status_reason (справочник) и/или таблица событий состояния (журнал переходов). Журнал полезен, когда нужны отчёты «сколько времени было в статусе» или разбор спорных случаев.
Исключения: отмена, возврат, повтор
Исключения почти всегда означают дополнительные данные:
- «Возврат на шаг» → хранить причину возврата и ссылку на предыдущую версию/попытку.
- «Повторная отправка» → модель попыток (
attempt_no) или отдельная сущность «попытка/версия заявки». - «Отмена» → фиксировать инициатора, причину, дату; иногда — отдельное событие, а не просто статус.
Так workflow превращается в набор проверяемых требований: какие статусы допустимы, какие переходы разрешены, и какие метки времени/авторы должны фиксироваться для каждого изменения.
Нормализация без усложнений: как избежать дубликатов
Нормализация — это не про «академические правила», а про понятную цель: чтобы одно и то же значение хранилось в одном месте и не расходилось в разных строках и таблицах. Тогда проще обновлять данные, меньше ошибок в отчётах и яснее границы ответственности сущностей.
Нормальные формы простыми словами
На практике достаточно держать в голове три шага:
- 1НФ: в колонке — одно значение, а не список. Если у заказа «товары через запятую», это сигнал выделить строки позиций заказа.
- 2НФ: атрибут зависит от всей сущности, а не от «части ключа». Например, в таблице позиций заказа не должно быть «телефона клиента» — он относится к клиенту.
- 3НФ: атрибут зависит только от сущности, а не от другого атрибута. Если «город» определяется «индексом», то город лучше вынести в справочник или вычислять.
Типовые «запахи» в схемах
Чаще всего дубликаты появляются из-за двух ошибок:
-
Повторяющиеся группы:
phone1/phone2/phone3,address_1/address_2или «10 колонок под характеристики». Обычно это отдельная сущность (Телефон, Адрес, Характеристика). -
Смешение разных сущностей в одной таблице: когда в «Пользователе» лежат и реквизиты компании, и параметры доставки, и настройки уведомлений. Лучше разделить: Пользователь, Компания, Адрес, Настройки — и связать ключами.
Когда денормализация допустима и как её контролировать
Денормализация уместна, когда чтение важнее записи: витрины для отчётов, агрегаты для быстрых списков, кэшируемые поля (например, order_total). Контроль простой:
- помечайте такие поля как производные (в словаре данных);
- определяйте, кто и когда пересчитывает (триггер, фоновая задача, транзакция приложения);
- добавляйте проверочные запросы/тесты, которые ловят расхождения.
Проверка на примерах из user stories
Возьмите 3–5 сценариев и «прогоните» их по схеме:
- «Клиент меняет номер телефона» — обновление должно быть в одном месте.
- «Оформить заказ с несколькими товарами» — должны существовать Заказ и Позиции заказа.
- «Переименовать товар» — история продаж не должна ломаться (позиции заказа хранят ссылку на товар и/или снимок нужных полей).
Если для сценария приходится обновлять одно и то же значение в нескольких таблицах — вы нашли источник будущих дубликатов.
Где помогает AI‑рассуждение и как им пользоваться безопасно
AI может ускорить проектирование схемы БД, если использовать его как «второго аналитика», а не как источник истины. Самая полезная роль — быстро разложить пользовательские истории и workflow на структурированные сущности, связи и ограничения, а затем помочь проверить, не пропущено ли что-то важное.
Отдельно полезно, когда AI встроен не «в вакуумный чат», а в рабочий контур продукта: с планированием, версиями и быстрым прототипированием. Например, TakProsto.AI как vibe‑coding платформа позволяет в режиме диалога набросать структуру сущностей, затем сразу поднять черновой backend (часто на Go + PostgreSQL) и проверить модель на реальных сценариях — запросами, формами, ролями. Это не отменяет аналитики, но сильно сокращает цикл «требование → схема → прототип → уточнение».
Уровни рассуждения: от понятий к проверке
Практичный режим работы выглядит так:
-
Извлечение понятий: из текстов историй AI предлагает кандидатов на сущности, атрибуты, словарь терминов и синонимы (например, «клиент» vs «покупатель»).
-
Построение связей: предлагает кардинальности (один-ко-многим, многие-ко-многим), ключи и справочники, подсказывает места, где нужна отдельная таблица для связей.
-
Проверка противоречий: ищет конфликтующие формулировки («заказ можно отменить после оплаты» vs «после оплаты нельзя»), несогласованность статусов и событий.
-
Генерация вариантов: предлагает несколько моделей (например, статусы как enum/справочник/таблица истории событий) с плюсами и рисками.
Какие вопросы задавать AI
Формулируйте запросы так, чтобы ответ был проверяемым:
- «Составь список сущностей/атрибутов из этих 5 историй и укажи, какой фразой это подтверждается».
- «Какие данные нужны, чтобы поддержать шаги workflow? Какие поля/таблицы будут обновляться на каждом шаге?»
- «Предложи статусы и ограничения целостности (NOT NULL, уникальность, внешние ключи) и объясни, какой бизнес‑правилом они вызваны».
- «Какие вопросы к заказчику остаются открытыми, чтобы завершить модель?»
Как фиксировать допущения
Ведите рядом со схемой короткий журнал: вопрос → принятое решение по умолчанию → риск → кому уточнить. Это снижает вероятность, что «удобная догадка» незаметно станет требованием.
Ограничения AI и человеческий контроль
AI может уверенно «додумывать» отсутствующие правила, путать термины и предлагать ограничения, которые ломают реальные процессы. Поэтому каждую рекомендацию стоит привязывать к источнику: истории, регламенту, примеру данных. Финальный контроль — за вами: проверка на реальные сценарии, тестовые записи и согласование с владельцем процесса (см. также раздел про трассируемость требований: /blog/traceability).
Трассируемость: связываем требования и элементы схемы
Трассируемость нужна, чтобы в любой момент ответить на два вопроса: «почему это поле/таблица существует?» и «какие требования сломаются, если мы это изменим?». В проектировании БД она превращает набор user stories и описаний процесса в проверяемую структуру: история → данные → правила → тесты.
Цепочка «история → таблица/поле → правило → тест»
Практичный формат — фиксировать для каждого элемента схемы его источник и связанные ограничения.
Пример:
- US-12: «Пользователь может отменить заказ до передачи в доставку»
- Таблица/поля:
orders.status,orders.cancelled_at,orders.cancel_reason - Правило: отмена разрешена, если
status IN ('new','paid'); при отменеcancelled_at NOT NULL - Тест: попытка отменить при
status='shipped'должна вернуть ошибку; успешная отмена должна проставить дату и причину
- Таблица/поля:
Так вы связываете смысл (история) с моделью (поля) и проверкой (тесты), а не держите это в голове.
Матрица соответствия: покрытие в обе стороны
Сделайте простую матрицу (в таблице или wiki):
- История → элементы схемы: какие таблицы/поля/ограничения нужны, чтобы историю реализовать.
- Таблица → истории: какие user stories оправдывают существование таблицы и критичных полей.
Если находится таблица/поле без историй — это сигнал: либо забыли требование, либо это «лишнее». Если есть история без данных — значит, модель не покрывает сценарий.
Мини‑проверки качества
Введите правило ревью: каждое поле должно иметь источник (история / шаг workflow / бизнес‑правило / требование безопасности). Быстрые проверки:
- у каждого NOT NULL/UNIQUE/FOREIGN KEY есть ссылка на требование;
- у каждого справочника (статусы, типы) есть источник в workflow;
- вычисляемые/служебные поля (например,
created_at) помечены как технические и объяснены.
Управление изменениями
Трассируемость особенно помогает при правках:
- версионируйте схему (тег релиза + номер миграции);
- в описании миграции фиксируйте: какие истории изменились и какие элементы схемы затронуты;
- обновляйте матрицу в том же PR/задаче, что и миграцию.
Так изменение requirements не превращается в «тихую» поломку данных: вы видите последствия до выката и можете заранее обновить тесты и ограничения.
Безопасность и соответствие требованиям на уровне модели данных
Модель данных — это не только «как хранить», но и «кому можно видеть и менять». Если заложить безопасность в схему сразу, вы уменьшите риск утечек и упростите проверку соответствия требованиям.
Управление доступом: роли, права, аудит
Начните с ролей из user stories: «оператор видит заявки», «менеджер утверждает», «админ настраивает справочники». Это напрямую превращается в матрицу доступа (CRUD по сущностям).
На уровне БД стоит закрепить:
- отдельные роли (например,
app_readonly,app_operator,app_admin), - права на таблицы/представления,
- доступ через представления для «урезанных» данных (например, без персональных полей).
Аудит нужен там, где по процессу важно доказать «кто сделал действие». Для этого в ключевых таблицах держат поля created_at, created_by, updated_at, updated_by (ссылки на пользователя/сервис).
Персональные данные: минимизация, согласия, сроки, маскирование
Из требований выделите, какие поля действительно нужны процессу. Если поле не влияет на решения и коммуникации — не храните его.
Для согласий и правовых оснований удобна отдельная сущность, например consent, где фиксируются: тип согласия, дата/канал получения, версия текста, срок действия/отзыва.
Сроки хранения лучше выражать явно: retention_until или статус «к удалению», чтобы можно было автоматизировать очистку.
Маскирование/псевдонимизация отражается в схеме через:
- разделение идентифицирующих данных в отдельную таблицу с более строгими правами,
- хранение «публичного отображаемого» значения отдельно от полного (например, последние 4 цифры документа).
Логирование изменений: кто, когда и что поменялось
Если важно видеть «что именно», одного updated_at мало. Добавьте журнал изменений (audit_log) с полями: сущность, record_id, операция, автор, время, а также снимок изменённых полей (часто в JSON). Так проще разбирать инциденты и спорные ситуации.
Где проверять целостность: БД или приложение
Правило: всё, что защищает данные от противоречий, лучше закреплять в БД.
- В БД: внешние ключи,
NOT NULL, уникальность, базовые проверки (CHECK, допустимые статусы), каскады. - В приложении: сложные правила процесса (например, «можно отменить только до отправки»), зависящие от контекста и ролей.
Так схема становится частью контроля требований, а не просто хранилищем.
Производительность: индексы и запросы из пользовательских сценариев
Производительность лучше всего «вытаскивается» не из абстрактных правил, а из пользовательских сценариев: какие экраны открываются чаще, что люди ищут, как сортируют, какие списки обновляются каждые секунды. Поэтому индексы — это продолжение user stories в виде конкретных шаблонов запросов.
Индексы: выбираем по реальным запросам
Соберите 10–20 ключевых запросов из сценариев и макетов экранов. Для каждого зафиксируйте: таблицы, условия WHERE, сортировку ORDER BY, соединения JOIN, пагинацию.
Например, история «менеджер видит список заказов клиента за период» обычно означает фильтр по customer_id и диапазону дат. Индекс под такой запрос — не «на всякий случай», а ровно под условие: (customer_id, created_at).
Поиск и фильтры: сортировки и составные индексы
Составные индексы работают, когда порядок колонок совпадает с типичным использованием:
- Сначала самый селективный/обязательный фильтр (например,
tenant_idв мультиарендности). - Затем частый дополнительный фильтр (например,
status). - В конце — поле сортировки (например,
created_at), если сортировка почти всегда одинаковая.
Если экран допускает «поиск по строке», решите заранее: это префиксный поиск (подойдёт индекс по полю) или подстрока/морфология (нужен отдельный поисковый механизм или полнотекстовый индекс). Не пытайтесь лечить любой поиск обычным B-tree индексом.
Объёмы и рост: «горячие» таблицы и партиционирование
Из workflow видно, где будет много записей: события, логи статусов, история изменений, таблицы «многие-ко-многим». Это кандидаты в «горячие» — частые вставки и чтения.
Партиционирование имеет смысл как идея, когда сценарии почти всегда ограничены по времени (например, «показать события за неделю»), а объём растёт быстро. Тогда партиция по дате может упростить обслуживание и ускорить запросы.
Компромиссы: чтение vs запись и ограничения
Каждый индекс ускоряет чтение, но замедляет запись и увеличивает стоимость обновлений. Поэтому правило простое: индекс создаётся под конкретный сценарий и измеримый выигрыш.
Также помните про целостность: уникальные индексы и внешние ключи помогают данным оставаться правильными, но тоже стоят ресурсов. Важно согласовать ожидания: что критичнее в продукте — скорость списков или надёжность данных при массовых операциях.
Как оформить результат: ER‑диаграмма и словарь данных
Хорошо выведенная схема БД ценна ровно настолько, насколько её можно проверить и согласовать. Поэтому результат важно упаковать так, чтобы его одинаково понимали аналитик, разработчик и бизнес.
ER‑диаграмма: минимум обозначений, понятный бизнесу
Сделайте ER‑диаграмму «читаемой» без обучения нотациям. Достаточно трёх вещей:
- Сущности (прямоугольники): Клиент, Заказ, Платёж.
- Связи (линии): с подписью кратности 1–N, N–M.
- Ключи: помечайте PK (первичный ключ) и FK (внешний ключ), а также уникальность, если она критична для смысла.
Если нужно показать сложный кусок (например, N–M), лучше явно добавить связующую сущность (например, OrderItem) и подписать, какие поля составляют уникальность. Больше символов обычно только мешают обсуждению. Базовые принципы можно вынести в отдельную заметку: /blog/er-diagram-basics.
Словарь данных: что означает каждое поле
Словарь данных снимает 80% вопросов на ревью. Для каждого поля фиксируйте:
- Определение (человеческими словами)
- Тип/формат (строка, число, дата‑время, перечисление)
- Примеры значений (2–3 штуки)
- Правила: обязательность, допустимые диапазоны, уникальность, источник (кто заполняет) и важные ограничения целостности
Например: order.status — перечисление; значения: draft, paid, cancelled; правило: переходы только по workflow; нельзя вернуть из paid в draft.
Рекомендуемая структура документации
Чтобы не потерять логику вывода «из требований в данные», держите один сквозной шаблон:
цель → сущности → связи → ограничения → сценарии.
В конце добавьте короткий раздел «как этим пользоваться»: где лежит диаграмма, где словарь, кто утверждает изменения и как обновлять при новых user stories. Если вы оформляете это как часть платного пакета работ, уместно дать ссылку на условия: /pricing.
Итоговый чек‑лист перед утверждением схемы
Перед тем как «заморозить» схему, полезно провести короткую проверку на полноту и непротиворечивость. Это дешевле, чем чинить миграции после старта разработки, и понятнее для бизнеса, чем обсуждение таблиц «на глаз».
1) Сущности, поля и ответственность
Проверьте, что каждую таблицу можно объяснить одной фразой из предметной области (а не из реализации), и что за неё есть владелец в требованиях.
Чек‑лист:
- все сущности имеют владельца (кто использует/отвечает), ключ (PK/уникальный идентификатор) и понятное имя;
- определены обязательные поля (NOT NULL) и дефолты там, где это бизнес‑правило, а не «чтобы было»;
- зафиксированы правила: уникальность (например, email в рамках организации), допустимые значения (справочники), форматы, валюты/единицы измерения;
- описано, что считается «источником правды» для каждого факта (например, сумма заказа — из позиций или из итогового поля?).
2) Статусы, переходы и крайние случаи
Workflow чаще всего ломается не на основных ветках, а на отменах, возвратах, повторных попытках и параллельных действиях.
Чек‑лист:
- нет противоречий в статусах и переходах: каждый переход разрешён правилами и не ведёт в «тупик»;
- определены крайние случаи: отмена, истечение, дублирование события, повторная отправка, частичный успех;
- решено, что хранится как текущее состояние (поле
status), а что — как история событий (таблица аудита/событий).
3) Отчёты и аналитика (чтобы потом не «достраивать» данные)
Если заранее не проверить отчётные сценарии, может выясниться, что нужных разрезов и дат в данных нет.
Чек‑лист:
- покрыты ключевые отчёты: какие агрегации нужны (по дням/неделям/месяцам), какие периоды важны;
- определены даты и их смысл: «создано», «оплачено», «закрыто» — это разные метрики;
- согласован «источник правды» для показателей и правила пересчёта (например, возвраты, корректировки).
План следующего шага
Сделайте небольшой прототип запросов по 5–10 главным пользовательским сценариям, сгенерируйте тестовые данные (в том числе крайние случаи) и проведите короткое ревью схемы со стейкхолдерами: бизнес, разработка, аналитика, безопасность. Это обычно выявляет последние пробелы до утверждения.
Если хочется ускорить этот этап, удобно совмещать проектирование и прототипирование: в TakProsto.AI можно в «режиме планирования» описать сущности, статусы и правила из историй, затем быстро собрать рабочий черновик приложения (web/сервер/мобильное) и проверить схему реальными запросами и ролями. А когда модель стабилизируется — выгрузить исходники, включить деплой/хостинг, настроить свой домен и держать под рукой снапшоты с откатом (rollback) для безопасных итераций.