Visibility и sandbox
Трёхуровневая видимость нод: фундамент, без которого DM не может «приготовить» энкаунтер заранее без спойлеров, а wiki не может иметь черновики. Номер спеки — 033 (роадмап 030+, NEXT.md).
Проблема сегодня
Сейчас всё, что DM создаёт в системе, немедленно видно игрокам в каталоге и графе нод. DM не может написать «Патруль Культа · Тяжёлый» на следующую сессию без того, чтобы любой игрок, зашедший в каталог, увидел название и описание. Обходной путь: DM ничего не пишет в систему до начала сессии (всё на бумаге / Google Docs). Это нарушает принцип «мир как лог наблюдений».
Три состояния видимости
Целевая модель — новое поле nodes.visibility (text, индексируемый):
| Значение | Кто видит |
|---|---|
private | Только автор (создавший ноду) |
party_draft | Все участники кампании (member), кроме: игроки без dm-роли видят нодy как существующую, но без контента; owner + dm видят полностью |
published | Все участники + spectator'ы |
Default для новых нод —
published(backward-compat). Существующие ноды мигрируются вpublishedоднимUPDATE.
private — для DM-заметок «только для меня». party_draft — черновик,
который DM готовит, а потом публикует. Игроки видят что нода «есть»
(чтобы не было загадочных рёбер в никуда), но не видят контент.
RLS rewrite
Текущие политики на nodes проверяют только campaign_id и role.
После spec-033:
-- SELECT: участник видит ноду если:
-- 1) visibility = 'published'
-- 2) visibility = 'party_draft' (имя/id — да; контент поля — в зависимости от role)
-- 3) visibility = 'private' AND created_by = auth.uid()
-- 4) role IN ('owner', 'dm') — видят всё
Рёбра edges от draft-нод тоже скрыты от игроков — иначе игрок видит
«загадочное ребро в никуда».
Approval queue для нод
Паттерн из spec-014 (approval flow для транзакций) переносится на ноды.
Когда party_draft нода готова к публикации — DM нажимает «Опубликовать»
→ нода уходит в published. В более сложном сценарии (игрок создаёт
лор-нода, DM одобряет):
- Игрок создаёт ноду
privateилиparty_draft. - Запись в очередь одобрения (или DM видит в sandbox).
- DM апрувит →
published.
Детали механизма — на уровне Plan спеки. Паттерн аппрувов реализован:
features/accounting/approval-queue.md.
Sandbox-страница DM
Роут /c/[slug]/sandbox — сетка черновых нод: энкаунтеры, NPC,
локации, плот-нити. DM видит свои private и все party_draft
кампании. Визуальный маркер черновика в сайдбаре и каталоге.
Кнопка «Опубликовать» прямо на ноде.
После encounter rework (spec-032) encounter-ноды в party_draft —
это «подготовленные сессии»: DM создаёт Патруль заранее, запускает
в момент встречи.
Концепт-редактор поверх sandbox
node_types + nodes.fields JSONB + edges = zettelkasten без
миграций (новые типы создаются из UI через createCustomType).
Базовый Markdown-редактор уже есть (components/markdown-content.tsx).
Концепт-редактор дозревает четырьмя слоями поверх visibility-флага:
- Supabase Storage — bucket
concept-images, RLS поcampaign_id, paste/drag-and-drop в редактор. - Wikilinks
[[Title]]— remark-плагин, резолв наnodes.titleper-campaign, автокомплит. Backlinks-панель бесплатно. - Структурированные поля per
node_type— расширитьdefault_fieldsсхемой (тип поля:number,markdown,enum). - Editor v2 (опционально) — тулбар / slash-commands.
Суть и детали редактора — wiki-editor.md.
Миграция существующих нод
UPDATE nodes SET visibility = 'published'
WHERE visibility IS NULL;
ALTER TABLE nodes
ALTER COLUMN visibility SET DEFAULT 'published';
Backward-compat: весь существующий контент получает published,
поведение для игроков не меняется.
Фундамент для
wiki-editor.md(spec-021). Связь сconcepts/visibility.md,features/accounting/approval-queue.md.