Факультативы

Трекинг внеосновных активностей персонажей: изучение языков, тренировки, социальные связи. Факультатив — нода типа 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.