На первый взгляд сайт со статьями - один из самых простых цифровых продуктов. Есть текст, заголовок, обложка и кнопка публикации. Кажется, что достаточно сохранить все в базе данных и вывести на страницу.
Но как только появляется больше одного проекта, редакционная подборка, черновики и массовая загрузка материалов, возникают вопросы, на которые внешний вид сайта не отвечает.
Где хранится статус публикации? Кто определяет, какая статья относится к теме «Дизайн»? Что произойдет, если у двух материалов окажется одинаковый адрес? И почему запись, успешно созданная через импорт, может не открыться в редакторе?
При работе над True Creator мы убедились: архитектура контентного сайта начинается не с выбора технологии, а с согласования того, как живет материал.
Одна статья, несколько представлений
Один и тот же текст появляется в разных местах.
В редакторе у него есть содержимое, поля и статус. В списке материалов - заголовок, короткое описание и обложка. На странице проекта - контекст проекта. В блоке нового - дата публикации. В ручной подборке - позиция, назначенная редактором.
Если каждое представление хранит собственную независимую версию этих сведений, расхождения становятся почти неизбежными.
Поэтому полезно разделять сам материал и правила его показа. Статья должна иметь устойчивую идентичность. А главная страница, каталог и страница проекта лишь выбирают нужные материалы и отображают их разными способами.
Этот принцип особенно важен для редакционной подборки «Начните отсюда». Ее порядок - свойство подборки, а не неизменяемое свойство каждой статьи.
Метаданные - не менее важны, чем сам текст
Markdown хорошо подходит для хранения структуры статьи: абзацев, подзаголовков, списков, цитат. Но одного текста недостаточно, чтобы управлять публикацией.
Нужны отдельные поля: название, адрес, краткое описание, состояние публикации, видимость. Нужна и классификация - в нашей модели это одна тема и один проект.
Мы пришли к необходимости четкого контракта между исходным файлом и CMS. Метаданные находятся в начале файла, а его тело остается единым Markdown-документом.
Когда эти правила не были согласованы, импорт делил одну статью по подзаголовкам. После исправления разбиения обнаружились другие расхождения: редактор использовал устаревшее название связи, а состояние черновика отображалось не так, как ожидалось.
Это хорошо показывает, что структуру данных недостаточно описать в одном месте. Ее должны одинаково понимать импорт, база данных, редактор и публичная часть.
Связи должны отвечать реальным вопросам
В технических материалах об архитектуре часто встречается соблазн построить универсальную иерархию на все случаи: страницы внутри разделов, разделы внутри проектов, статьи внутри страниц.
Но видимая структура сайта не всегда совпадает с отношениями между материалами.
Для True Creator важно различать две вещи. Проект - контекст появления статьи. Тема - основной предмет разговора. Мы фиксируем обе характеристики как обязательную пару.
А редакционная подборка или список последних публикаций - уже не классификация, а отдельный способ отбора. Если смешать эти отношения в одном поле или дереве вложенности, изменение меню может неожиданно начать влиять на содержание.
Хорошая модель не обязана быть максимально универсальной. Она должна однозначно отвечать на те вопросы, которые реально задает продукт.
Предпросмотр - это часть архитектуры, а не украшение
Для массового импорта мы отдельно уточняли разницу между тем, что пользователь видит до операции, и тем, что система делает после нажатия кнопки.
Предпросмотр должен отражать будущий результат: сколько записей будет создано, какие у них адреса, какие поля заполнены, есть ли конфликты.
Если в предпросмотре один набор данных, а при сохранении появляются дополнительные проекты или происходит изменение статуса, доверять инструменту сложно.
Поэтому проверка должна проходить сквозь весь процесс, а не только через форму загрузки. Сначала разбираем файл, затем проверяем обязательные поля и существующие связи, обнаруживаем конфликты, и только после этого создаем материал.
При этом серверная проверка необходима даже тогда, когда интерфейс уже проверил все поля. Пользовательский экран и массовый импорт не должны иметь разные требования к одной и той же статье.
Не привязывать смысл продукта к конкретному стеку
В исходных инженерных заметках о портале много внимания уделено разделению фронтенда, серверной части и хранения данных. Это полезная рамка, но сами названия библиотек и технологий еще не объясняют, почему продукт устроен правильно.
Одну и ту же редакционную задачу можно реализовать разными способами. Важнее, чтобы были понятны границы ответственности: где создают содержимое, где проверяют права и статусы, где собирают выборки для сайта, где формируют страницу для читателя.
Когда эти границы определены, технологические решения можно менять без необходимости заново придумывать смысл темы, проекта или статуса публикации.
Поэтому мы стараемся описывать требования к поведению системы отдельно от конкретных вариантов реализации.
Архитектура проявляется в неприятных мелочах
Самые показательные моменты часто возникают не при открытии главной страницы, а при обычных рабочих действиях.
Редактор загружает материал повторно - система должна объяснить конфликт адреса. Сотрудник открыл черновик - он не должен внезапно оказаться опубликованным. Автор сменил тему статьи - все представления этого материала должны получить одинаковую классификацию.
Каждая такая мелочь требует согласованности между несколькими частями приложения.
Внешне спокойный контентный сайт может быть удобным именно потому, что внутри эти вопросы решены заранее.
Сначала правила, затем масштаб
Мы не стремимся строить максимально сложную CMS на вырост. У нас уже был опыт избыточной структуры даже на уровне папок с редакционными материалами: появилось множество разделов, для которых еще не существовало содержания.
С архитектурой продукта полезно поступать так же. Фиксировать необходимые инварианты, не добавляя сущностей просто на случай будущего применения.
Для True Creator это означает понятные правила: одна статья - один материал; одна тема и один проект; отдельное управление редакционными подборками; статусы, которым можно доверять; предсказуемые ошибки и единый контракт данных.
Продуманная архитектура нужна не для того, чтобы сделать простой сайт сложным. Она нужна, чтобы с ростом числа материалов простые действия не становились все более ненадежными.