Сервис генеалогического древа выглядит как экран с карточками и линиями. На практике это продукт со сложной предметной областью: повторные браки, сводные семьи, несколько поколений, питомцы, публичные ссылки, импорт и правила видимости.
Мы столкнулись с этой задачей при разработке Sims Dynasty Tree — веб-сервиса, в котором игроки The Sims сохраняют истории больших династий. В статье разберём инженерные решения, которые применимы не только к игре, но и к любым продуктам со сложной сетью связей.
Полный список реализованных функций и подтверждённый стек собраны в кейсе Sims Dynasty Tree.
Чем специализированный сервис отличается от обычного семейного дерева
Российские генеалогические продукты обычно ориентированы на реальных родственников, архивный поиск и совместное ведение истории семьи. Например, FamilySpace сочетает дерево, семейный календарь и материалы по генеалогии.
У династии The Sims другой контекст:
- пользователь ведёт историю игрового мира;
- за короткое время появляются десятки персонажей;
- повторные браки и сводные ветви встречаются часто;
- важны питомцы, наследники и статус умершего персонажа;
- оформление является частью сторителлинга;
- одно дерево может расти много поколений;
- готовой историей хочется поделиться с сообществом.
Поэтому копировать интерфейс классической генеалогической программы недостаточно. Сначала нужно описать правила именно этой предметной области.
Почему семейные связи — это граф
Простую иерархию можно представить деревом: у элемента есть родитель и дочерние элементы. Семья сложнее. У персонажа может быть несколько партнёров в разные периоды, дети в разных отношениях и связи с несколькими ветвями.
Удобная модель рассматривает данные как граф:
- узлы — персонажи, питомцы и сами династии;
- связи — родитель, ребёнок, партнёр, владелец питомца и другие отношения;
- атрибуты узла — имя, фотография, даты, биография, статус;
- атрибуты связи — тип, порядок, видимость, дополнительные параметры.
Важно: графовая модель не требует графовой базы данных. В Sims Dynasty Tree данные хранятся в PostgreSQL, а связи представлены отдельными типизированными записями. Выбор хранилища зависит от запросов, объёма и опыта команды, а не от модного термина.
Как описать предметную область до кода
Начните со словаря сущностей и инвариантов — правил, которые система не должна нарушать.
Для генеалогического сервиса вопросы могут быть такими:
- может ли персонаж входить в несколько деревьев;
- как представлены биологические и приёмные родители;
- можно ли создать связь без обратной связи;
- что происходит при удалении персонажа;
- допускаются ли циклы;
- как хранится порядок партнёров и детей;
- является ли питомец отдельным типом или вариантом персонажа;
- кто владеет деревом и кто может его редактировать;
- какие данные видны по публичной ссылке.
Эти решения влияют на базу, API, редактор, импорт и тесты одновременно. Если оставить их «на потом», интерфейс начнёт исправлять противоречия данных костылями.
Как хранить персонажей и отношения
Базовая модель может включать:
- пользователя;
- дерево;
- участника дерева;
- профиль персонажа;
- типизированную связь;
- медиафайл;
- настройки отображения;
- тариф или право доступа;
- журнал изменений.
Связь лучше хранить как самостоятельную сущность. Тогда можно проверять её тип, направление и допустимость до сохранения.
Например, команда добавляет отношение «родитель → ребёнок». Сервер должен проверить:
- Оба персонажа существуют.
- Они принадлежат доступному пользователю дереву.
- Связь ещё не создана.
- Новая связь не нарушает запрещённый инвариант.
- У пользователя есть право на изменение.
После этого API возвращает обновлённый фрагмент, а не заставляет клиент заново загружать всю династию.
Как спроектировать интерактивный редактор
Главная задача редактора — не нарисовать красивые линии, а помочь пользователю безопасно менять сложную структуру.
Добавление персонажа
Контекст важнее универсальной кнопки. Если пользователь добавляет ребёнка из карточки конкретной пары, часть связи уже известна. Если создаёт персонажа отдельно, система не должна автоматически придумывать родство.
Редактирование связи
Пользователь должен понимать:
- какие два объекта связываются;
- какой тип отношения создаётся;
- какие связанные отношения появятся автоматически;
- что изменится на схеме;
- можно ли отменить действие.
Удаление
Удалить карточку и удалить персонажа из данных — разные операции. Перед необратимым действием полезно показать, сколько связей и материалов будет затронуто. Для работающего продукта лучше предусмотреть мягкое удаление и журнал событий.
Большое дерево
Когда персонажей много, весь граф не помещается на экран. Нужны:
- масштабирование;
- перемещение рабочей области;
- переход к выбранному персонажу;
- сворачивание ветвей;
- визуальное выделение активной карточки;
- сохранение позиции или быстрого возврата;
- постепенная загрузка тяжёлых материалов.
Пользователь должен видеть контекст и при этом не терять точку, с которой начал навигацию.
Почему автоматическая раскладка — отдельная задача
Данные отвечают на вопрос «кто с кем связан», но не говорят, где расположить карточку на экране.
Алгоритм раскладки должен учитывать:
- поколения;
- парт нёров;
- общих и разных детей;
- пересечения ветвей;
- размер карточек;
- подписи и фотографии;
- ширину экрана;
- пользовательские настройки.
У любой автоматической схемы есть компромисс между компактностью, минимальным количеством пересечений и стабильностью. Если после каждого изменения всё дерево полностью перестраивается, пользователь теряет пространственную память.
Поэтому полезно разделять:
- структуру данных;
- вычисленную раскладку;
- ручные пользовательские корректировки;
- параметры отображения.
Так можно улучшать визуальный алгоритм, не меняя родственные данные.
Как работать с импортом
В Sims Dynasty Tree предусмотрен перенос существующих деревьев из PlumTreeApp. Импорт — не просто чтение файла. Это миграция между двумя моделями данных.
Надёжный процесс включает:
- Загрузку и техническую проверку файла.
- Сопоставление типов персонажей и связей.
- Поиск неподдерживаемых полей.
- Предварительный отчёт пользователю.
- Создание данных в транзакции.
- Протокол ошибок и возможность повторить импорт.
Неизвестное поле лучше сохранить в отчёте, чем молча отбросить. Для больших деревьев особенно важно проверить количество персонажей и связей до и после переноса.
Если продукт рассчитан на долгую историю, стоит также продумать экспорт. Пользователь должен понимать, сможет ли забрать собственные данные и в каком формате.
Публичные и приватные деревья
Публичная ссылка — удобная функция, но она расширяет модель доступа.
Разделите как минимум четыре действия:
- видеть дерево;
- видеть подробную карточку;
- редактировать данные;
- управлять доступом.
Для публичного режима определите:
- индексируется ли страница поисковиками;
- какие поля скрываются;
- видны ли изображения;
- можно ли найти дерево без прямой ссылки;
- что происходит после переключения обратно в приватный режим;
- как отозвать ранее выданную ссылку.
Даже если в дереве находятся вымышленные персонажи, архитектуру доступа лучше строить так, будто данные важны. Эта дисциплина пригодится при создании социальных и корпоративных графов.
Как связать кастомизацию и подписку
В Sims Dynasty Tree пользователь может менять фон, прозрачность, линии отношений и способ отображения персонажей. Часть вариантов оформления связана с премиальными возможностями.
Чтобы подписка не ломала базовый продукт, бесплатный уровень должен позволять решить основную задачу — создать и сохранить понятное дерево. Платная часть может расширять:
- количество вариантов оформления;
- набор фонов;
- дополнительные параметры карточек;
- расширенные сценарии публикации;
- другие функции для активных авторов.
Права на премиальные функции нужно проверять на сервере, а не только скрывать кнопку в интерфейсе. Отдельно задаются правила окончания подписки: данные не должны исчезать только потому, что пользователь не продлил тариф.
Какие тесты особенно важны
Обычных тестов форм недостаточно. Для сервиса связей нужны проверки предметной области.
Тесты инвариантов
- нельзя создать дублирующую связь;
- нельзя изменить чужое дерево;
- удаление не оставляет повреждённые ссылки;
- типы отношений образуют согласованную структуру;
- циклический сценарий обрабатывается предсказуемо.
Тесты визуализации
- одиночный персонаж;
- пара без детей;
- несколько поколений;
- повторный брак;
- сводные дети;
- большая разветвлённая династия;
- длинные имена и отсутствующие фотографии;
- мобильный экран.
Тесты импорта
- полный корректный файл;
- частично поддерживаемые поля;
- повреждённый файл;
- повторная загрузка;
- очень большое дерево;
- отмена операции.
Хороший набор фикстур полезнее десятков случайных примеров: он фиксирует реальные сложные семьи и не даёт сломать их при следующем изменении алгоритма.
Где ещё применяется такая архитектура
Тот же подход подходит для систем, в которых объект связан сразу с несколькими другими:
- организационные структуры с проектными ролями;
- карты компаний и бенефициаров;
- социальные связи;
- базы знаний;
- зависимости оборудования;
- каталоги совместимости;
- маршруты согласований;
- карты персонажей и сюжетов.
Меняется предметная область, но последовательность остаётся: описать типы узлов и связей, сформулировать инварианты, спроектировать безопасный редактор и только потом выбирать визуальную библиотеку.
Чек-лист перед разработкой сервиса генеалогического древа
- Описаны сущности и типы связей.
- Зафиксированы запрещённые состояния.
- Понятно, как удаляются персонажи и отношения.
- Модель доступа отделяет просмотр от редактирования.
- Большой граф остаётся управляемым.
- Автоматическая раскладка не меняет данные.
- Импорт показывает потери до сохранения.
- Есть план экспорта и резервного копирования.
- Платные права проверяются на сервере.
- Мобильный интерфейс протестирован на сложном дереве.
Sims Dynasty Tree показывает важный принцип: сложность такого продукта находится не в линии между двумя карточками, а в правилах, которые эта линия означает.
Если вы проектируете сервис со сложными связями, начните с предпроектной ан алитики и описания процессов, а затем переходите к разработке веб-сервиса.
Теги: Генеалогическое древо, Граф данных, Веб-сервис, The Sims, Next.js Дата обновления: 25 сентября 2026



