Факультативы
Трекинг внеосновных активностей персонажей: изучение языков, тренировки, социальные связи. Факультатив — нода типа
elective, привязанная к PC ребромhas_elective.
Модель данных
Миграция 029_electives.sql вводит два объекта для кампании:
node_type 'elective'— нода-факультатив. Поля вnodes.fields:kind(text) — тип: «Основной курс», «Факультатив», «Специальное» и т.п. Свободный текст, без хардкода под D&D.link(text, nullable) — ссылка на источник (например, dnd.su).comment(text, nullable) — заметка DM.
edge_type 'has_elective'— реброPC → elective. Поле вedges.meta:note(text, nullable) — пометка к строке таблицы (например, «Солинари», «элек»). Пустое для обычного «Да».
Миграция 110_backfill_electives_for_all_campaigns.sql ретроактивно сидирует
тип для всех существующих кампаний (029 хардкодил только mat-ucheniya).
Начиная с этой миграции, seedCampaignSrd тоже включает elective — новые
кампании получают его при создании.
Интерфейс
Вкладка факультативов — app/c/[slug]/electives/. Отображает таблицу: строки —
PC кампании, столбцы — все ноды типа elective. Клетки заполняются по рёбрам
has_elective; значение edges.meta.note отображается вместо «Да».
DM управляет как нодами-факультативами (создать, переименовать, удалить), так и рёбрами (проставить/снять PC — факультатив). Игрок видит ту же таблицу в режиме просмотра.
Отличие от обычной ноды
Нода elective — это просто нода с node_type='elective'. Семантику «PC
изучает X» несёт ребро has_elective, а не сама нода. Одну ноду-факультатив
могут взять несколько PC — граф, не иерархия.
Будущее
Механика бонусов к статам персонажа (IDEA-037) пока не реализована. В
перспективе факультатив будет не только трекером прогресса, но и источником
модификаторов в листе персонажа. Детали — в
roadmap/postponed.md.