администрирование · документы согласий
Полный паритет с консолью: тенант читает текущую версию каждого из двух документов, видит кто и когда принял какую версию, и публикует новую версию прямо с телефона. Экран открывается из «Ещё → Администрирование» и виден только оператору с правом site:configure.
Юридические формулировки на экранах ниже помечены «(пример)» и написаны только для макета. Реальный текст согласия пишет сам тенант; AGO его не сочиняет — в этом и смысл экрана публикации.
Две карточки, «Контактные данные» и «Маркетинг». У каждой — плашка со статусом привязки (что документ вообще требует), текущая версия с действиями «Открыть» и «Кто принял», свёрнутый список предыдущих версий и кнопка публикации. Плашка «Контактные данные» ссылается на «Виджет на сайте» — именно там включается сбор согласия, а не здесь.
Плашка привязки — тот же смысл, что в консоли: у «Контактных данных» она либо «виджет требует это согласие», либо (когда сбор выключен) danger «пока ничего не требует» со ссылкой на «Виджет на сайте». У «Маркетинга» — всегда info «ничего не требует».
Маркетинг здесь без единой версии: список пуст, остаётся только кнопка публикации. Это настоящее состояние, не ошибка — тенант ещё не написал текст.
Гейт совпадает с сервером: тот же site:configure и на строке в «Ещё», и внутри каждого хэндлера. Нет расхождения «видно, но сервер откажет», как у токен-каналов.
Когда contactConsentRequired = false, плашка становится danger и прямо называет экран, где это чинится. У каждой предыдущей версии — своя кнопка «Открыть» и свой список «Кто принял», привязанные к конкретному тексту.
«Кто принял» раскрывается прямо в карточке и привязан к одной версии: у кого две версии — у того два раздельных списка, не один слитый. Над таблицей всегда стоит оговорка о приватности: показаны только кто и когда, без IP и браузера — этих полей вообще нет на проводе.
Сервер отдаёт все согласия документа сразу; клиент фильтрует по documentVersion, как это делает AcceptancesList в консоли. Отдельного версионного эндпоинта нет и не нужно.
Идентификатор — 8 символов моноширинным, не весь GUID. На телефон 36 символов не влезают; короткого префикса хватает, чтобы сопоставить строки, а долгое нажатие копирует полный id. Столбец «версия» убран — список и так про одну версию.
Пока никто не принял эту версию.
Загруженный пустой список — законное состояние («ещё никто»), не сбой. Так же и обзор с пустым списком версий не рисует «ошибку», а честно говорит «ни одной версии».
«Открыть» ведёт на отдельный экран чтения. Текст версии живёт не в обзоре (там только метаданные), а на публичной поверхности документов — той же, что откроет будущая ссылка …/policies/{key}. Текущая версия читается по «текущему» маршруту, конкретная — по неизменяемому версионному.
Текст выделяется и прокручивается (SelectionContainer). Тело — обычный текст, без Markdown: именно так его показывает виджет посетителю. Заголовок экрана — название версии, подзаголовок — версия и дата.
Порт анонимный. Эта поверхность не требует ни сайта, ни токена — поэтому у неё свой порт PublishedDocumentApi, отдельно от тенантного: анонимный маршрут не должен видеть заголовок активного сайта и bearer.
Возможно, документ изменили в другом месте, пока открывался этот экран.
Строка версии была в обзоре, но к моменту чтения исчезла (Document.NotFound). Это не «повторить», а терминальное «версия недоступна» — отдельная ветка результата, не смешанная с транспортным сбоем.
Публикация — это всегда новая версия, а не правка старой: редактор открывается пустым, как и форма в консоли. Заголовок и текст, вставка из буфера (реальный путь на телефоне — готовый текст приходит в буфер), подтверждение перед публикацией, и защита от случайного выхода с непустым черновиком.
Редактор пустой при старте — правки существующей версии нет. Клиентская проверка вежливости повторяет сервер: заголовок непустой ≤200, текст непустой ≤100 000; счётчики у обоих полей. Авторитет всё равно сервер (Document.Invalid).
«Вставить из буфера» — явная кнопка поверх обычной вставки долгим нажатием, потому что вставка подготовленного текста из буфера — реальный путь на телефоне.
Подтверждение (Material AlertDialog, как у консольного диалога) называет документ и следующий номер версии. После Published — возврат на обзор и его перезагрузка (fetchOverview), один источник правды, без оптимистичной вставки.
Конфликт публикации — 409. Две публикации одного ключа гонятся → Conflict: сообщение «повторите», кнопка остаётся активной, потому что лекарство от 409 — повторить тот же запрос.
Сочинённый юридический текст стоит того, чтобы его беречь: выход с непустым черновиком спрашивает подтверждение, в отличие от одноразового токен-поля каналов. Пустой черновик уходит молча. Тот же приём, что у re-cut записи в navigation.md.
Строка «Документы согласий» — в разделе Администрирование экрана «Ещё», рисуется только под canConfigureSite (ADMINISTRATION_DOCUMENTS_ROW_ID). Три экрана — обзор, просмотр, редактор — переключаются внутренним состоянием (ConsentNav), как у openRowId в «Ещё» и шагов re-cut, а не вложенным NavHost. Системный «назад»: просмотр/редактор → обзор, обзор → список «Ещё».