Перейти к основному содержимому

Страница «Редакции конфигурации»

Дата: 2026-04-10 Статус: Design — ждёт ревью пользователя

Цель

Сделать красивую HTML-страницу с матрицей возможностей редакций СТАНДАРТ / ПРОФ / КОРП, которая:

  1. Показывает пользователю полную картину, что доступно в каждой редакции, с визуальным выделением текущей
  2. Открывается программно из кода, когда пользователь пытается использовать недоступную в его редакции функциональность — с подсветкой и скроллом к конкретной строке
  3. Служит единым источником правды «что где доступно» — как для людей, так и для LLM (макет читается глазами и парсится нейросетями без инструментов)
  4. Легко расширяется при добавлении новых редакций в будущем

Контекст

Существующая инфраструктура

  • СЛС.РедакцияКонфигурации() Module.bsl:461 возвращает Число: 1 (СТАНДАРТ), 2 (ПРОФ), 3 (КОРП) или Неопределено
  • СЛС.ВариантыРедакцийКонфигурации() Module.bsl:5028ТаблицаЗначений с колонками НомерРедакции, Наименование, Язык
  • СЛС.УстановитьФункционал() Module.bsl:5321 — источник правды по кодам функциональных опций и их доступности по редакциям (17 опций)
  • СЛС имеет флаг serverCall=true — вызывается с клиента напрямую, без прослойки СЛСВызовСервера
  • СЛСКлиент — клиентский модуль, уже существует (98 строк, 3 процедуры) — сюда добавим хелпер gating
  • CommonTemplate.РедакцииКонфигурации (TextDocument) — пустой макет, уже зарегистрирован в конфигурации
  • CommonForm.РедакцииКонфигурации — пустая форма, уже зарегистрирована в конфигурации и в правах БазовыеПраваУФ
  • ДоксинумПарсер.ОбработатьТекстMD() — CommonMark-совместимый парсер Markdown → HTML, подключён к проекту (Module.bsl:67)
  • РаботаСВебСервер — утилиты сборки HTML-документов из 1С (используются в СЛС.СформироватьОписаниеЗадачи() для документа «Задание»)
  • CommonTemplate.css_markdown_content — общие стили markdown-контента (списки, жирный, ссылки, таблицы); собирается из web/shared/markdown-content.css через gulp-pipeline. Готов к переиспользованию
  • Возможности УИТ 4.xlsx — исходный референс с матрицей возможностей (13 разделов, ~60 фич), будет однократно перенесён в макет вручную. Xlsx не становится источником правды — источник правды это макет Markdown

Связанные архитектурные решения

  • 2026-04-07-functional-options-architecture-design.md — трёхуровневая цепочка Редакция → Глобальная ФО → Проектный флаг. Текущая спецификация добавляет пользовательскую страницу, объясняющую верхний уровень этой цепочки

Сценарий использования (B)

Выбран вариант B (обсуждено с пользователем):

Форма открывается программно из кода, когда пользователь пытается использовать недоступную в его редакции функциональность. Форма получает параметр КодФункции = "ИспользоватьCRM", отображает всю матрицу возможностей и подсвечивает/скроллит к строке запрошенной фичи с пометкой «Недоступно в вашей редакции — требуется КОРП».

Это не отменяет автоматического отключения констант через СЛС.УстановитьФункционал(). В будущем часть механизмов может переключиться с «скрыть кнопку» на «показать форму при клике» — текущий API СЛСКлиент.ПроверитьДоступностьРедакции() готов к такому паттерну.

Форма также доступна как обычная информационная страница без параметра — показывает матрицу без подсветки конкретной строки.

Архитектура

Поток данных

ВЫЗЫВАЮЩИЙ КОД (клиент, &НаКлиенте)
Если НЕ СЛСКлиент.ПроверитьДоступностьРедакции("ИспользоватьCRM") Тогда
Возврат;
КонецЕсли;


СЛСКлиент.ПроверитьДоступностьРедакции(КодФункции):
1. Вызов сервера → СЛС.ФункциональностьДоступна(КодФункции)
2. Если Истина → Возврат Истина (вызывающий код продолжает работу)
3. Если Ложь → ОткрытьФорму("ОбщаяФорма.РедакцииКонфигурации", ПараметрыФормы)
Возврат Ложь


ОбщаяФорма.РедакцииКонфигурации.ПриСозданииНаСервере(КодФункции):
1. ДанныеМакета = СЛС.ПрочитатьМакетРедакций()
2. ТекстHTML = СЛС.СформироватьHTMLРедакций(
ДанныеМакета,
СЛС.РедакцияКонфигурации(),
КодФункции)


ПолеHTMLДокумента на форме, ПриОткрытии → скролл к "#feature-" + КодФункции

Компоненты и их ответственность

КомпонентСлойОтветственность
СЛСКлиент.ПроверитьДоступностьРедакцииКлиентФасад для вызывающего кода: проверка + открытие формы в одном вызове
СЛС.ФункциональностьДоступнаСерверЧистая проверка: доступна ли фича с данным кодом в текущей редакции
СЛС.ПрочитатьМакетРедакцийСерверЧитает CommonTemplate.РедакцииКонфигурации, парсит в структуру данных
СЛС.СформироватьHTMLРедакцийСерверГенерирует полный HTML-документ с таблицей и подсветкой
ОбщаяФорма.РедакцииКонфигурацииКлиент/СерверКонтейнер: один реквизит ТекстHTML, один элемент ПолеHTMLДокумента, скролл на ПриОткрытии
CommonTemplate.РедакцииКонфигурацииРесурсMarkdown-макет (единственный источник правды по матрице возможностей)
CommonTemplate.css_editionsРесурсCSS для страницы редакций (новый макет)

Формат макета

Грамматика (BNF-подобная)

ДОКУМЕНТ       ::= ЗАГОЛОВОК ВВЕДЕНИЕ? РАЗДЕЛ+
ЗАГОЛОВОК ::= "# " Строка LF (ровно один, первая значимая строка)
ВВЕДЕНИЕ ::= МаркдаунТекст (всё до первого "##", рендерится через ДоксинумПарсер)
РАЗДЕЛ ::= "## " Строка LF ПОДРАЗДЕЛ+
ПОДРАЗДЕЛ ::= "### " Строка LF ФИЧА+
ФИЧА ::= "- " НазваниеФичи " | " МАСКА (" | " АТРИБУТ)* LF СТРОКА_ПРИМЕЧАНИЯ?
МАСКА ::= ТРИ_СИМВОЛА каждый символ ∈ {"С", "П", "К", "-"}
АТРИБУТ ::= "code=" ИмяФункциональнойОпции
СТРОКА_ПРИМ ::= SPACES "note: " Текст LF (опциональная, отступ ≥ 2 пробела)

Правила маски

  • Ровно 3 символа, фиксированный порядок: С=Стандарт(1), П=Проф(2), К=Корп(3)
  • Доступно → соответствующая буква. Недоступно → -
  • Примеры: СПК (во всех), -ПК (Проф и Корп), --К (только Корп), С-К (Стандарт и Корп)

Атрибуты фичи

АтрибутОбязательныйОписание
НазваниеДаЧасть перед первым | после -
МаскаДаЧасть после первого |
code=НетИмя константы функциональной опции (из СЛС.УстановитьФункционал). Нужен только для фич, которые могут быть переданы параметром формы
note:НетНа следующей строке с отступом ≥ 2 пробела. Одна строка текста

Задел под будущие атрибуты (не реализуем сейчас, но парсер должен игнорировать неизвестные): version=, deprecated=, docs=.

Пример макета (фрагмент)

# Возможности "Управление IT-отделом 8"

В программе **"Управление IT-отделом 8"** существует три редакции:
**Стандарт**, **Проф** и **Корп**. Редакции отличаются набором
доступных возможностей. Ниже — полная матрица функционала.

Если вы видите эту страницу, значит функция, к которой вы обратились,
недоступна в вашей редакции. Обратитесь к поставщику для перехода
на редакцию с нужной функциональностью.

## 1. Service Desk (управление инцидентами)

### 1.1. Документ "Задание"

- Создание, редактирование, выполнение заданий | СПК
- Шаблоны заданий/комментариев | -ПК
note: Убрано из Стандарта.
- Оценка заданий и лояльность пользователей | СПК

### 1.3. SLA (Service Level Agreement)

- Функционал SLA | -ПК | code=SLAСервисыРаботы
note: Сам функционал виден везде, в Стандарте скрыты только услуги.

### 1.4. CRM-подсистема

- Потенциальные клиенты | --К | code=ИспользоватьCRM

### 3.2. Подсистема Agile

- Покер планирования, Ежедневный стендап, Ретроспектива | --К | code=ИспользоватьПокерПланирование

Расширяемость по редакциям

Сейчас маска 3-символьная. При добавлении редакции «Энтерпрайз»:

  1. СЛС.ВариантыРедакцийКонфигурации() обновляется — добавляется запись
  2. Парсер расширяется — маска становится 4-символьной, добавляется буква Э
  3. Макет обновляется — во всех строках добавляется 4-й символ
  4. HTML-генератор добавляет колонку

Эти изменения согласованы и локализованы. Сейчас парсер валидирует длину ровно 3 и падает с понятной ошибкой — это сигнал «надо обновить код», а не «макет сломан случайно».

Источник редакций

Список редакций (код, номер, название) не хранится в макете. Он берётся из СЛС.ВариантыРедакцийКонфигурации(). Это единственный источник правды. Макет содержит только матрицу «фича → маска».

Парсер

Псевдокод

Функция ПрочитатьМакетРедакций():
Текст = ПолучитьМакет("РедакцииКонфигурации").ПолучитьТекст()
Строки = СтрРазделить(Текст, ПС, Ложь)

Результат = { Введение: "", Разделы: [] }
ТекущийРаздел = Неопределено
ТекущийПодраздел = Неопределено
ПоследняяФича = Неопределено
ВведениеНакапливаем = Истина
БуферВведения = []
НомерСтроки = 0

Для каждой Строки:
НомерСтроки += 1

Если НачинаетсяС(Строка, "# ") И ЗаголовокЕщёНеВстречался:
ПропуститьЗаголовок
Продолжить

Если НачинаетсяС(Строка, "## "):
ВведениеНакапливаем = Ложь
ТекущийРаздел = НовыйРаздел(Название из строки)
Результат.Разделы.Добавить(ТекущийРаздел)
ТекущийПодраздел = Неопределено
Продолжить

Если НачинаетсяС(Строка, "### "):
Если ТекущийРаздел = Неопределено Тогда
ВызватьИсключение("Подраздел вне раздела, строка " + НомерСтроки)
КонецЕсли;
ТекущийПодраздел = НовыйПодраздел(Название)
ТекущийРаздел.Подразделы.Добавить(ТекущийПодраздел)
Продолжить

Если НачинаетсяС(Строка, "- "):
Если ТекущийПодраздел = Неопределено Тогда
ВызватьИсключение("Фича вне подраздела, строка " + НомерСтроки)
КонецЕсли;
Фича = РазобратьСтрокуФичи(Строка, НомерСтроки)
ТекущийПодраздел.Фичи.Добавить(Фича)
ПоследняяФича = Фича
Продолжить

Если СодержитОтступИПрефикс(Строка, "note: "):
Если ПоследняяФича = Неопределено Тогда
ВызватьИсключение("note без фичи, строка " + НомерСтроки)
КонецЕсли;
ПоследняяФича.Примечание = ИзвлечьТекстПосле(Строка, "note: ")
Продолжить

Если ВведениеНакапливаем Тогда
БуферВведения.Добавить(Строка)
КонецЕсли
КонецЦикла

Результат.Введение = СтрСоединить(БуферВведения, ПС)
Возврат Результат

Функция РазобратьСтрокуФичи(Строка, НомерСтроки):
// "- Название фичи | СПК | code=ИспользоватьCRM"
ТелоСтроки = СокрЛ(Сред(Строка, 3))
Части = СтрРазделить(ТелоСтроки, "|", Ложь)
Если Части.Количество() < 2 Тогда
ВызватьИсключение("Ожидается '- Название | Маска', строка " + НомерСтроки)
КонецЕсли

Фича = Новый Структура("Название, Маска, Код, Примечание", "", "---", "", "")
Фича.Название = СокрЛП(Части[0])
Фича.Маска = ВалидироватьМаску(СокрЛП(Части[1]), НомерСтроки)

Для Индекс = 2 По Части.ВГраница() Цикл
Атрибут = СокрЛП(Части[Индекс])
Если СтрНачинаетсяС(Атрибут, "code=") Тогда
Фича.Код = СокрЛП(Сред(Атрибут, 6))
КонецЕсли
// Неизвестные атрибуты молча игнорируются (задел под будущее)
КонецЦикла

Возврат Фича

Характеристики

  • Один проход по строкам, O(N)
  • Нет рекурсии и стеков — плоский state machine
  • ~80–100 строк BSL в области СлужебныеПроцедурыИФункции модуля СЛС
  • Публичный API (ПрограммныйИнтерфейс): ПрочитатьМакетРедакций, СформироватьHTMLРедакций, ФункциональностьДоступна, HTMLОшибкиМакетаРедакций
  • При нарушении грамматики — исключение с номером строки и описанием. В форме ловится в ПриСозданииНаСервере, показывается HTML-страница ошибки вместо падения формы

HTML-рендеринг

Структура страницы

┌──────────────────────────────────────────────────────────────────┐
│ ШАПКА (hero) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ Возможности "Управление IT-отделом 8" │ │
│ │ Ваша редакция: [● ПРОФ] ← бейдж с цветом │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
│ ВВЕДЕНИЕ (рендер Markdown через ДоксинумПарсер) │
│ │
│ МАТРИЦА ВОЗМОЖНОСТЕЙ │
│ ┌────────────────────────────────┬──────┬──────┬──────┐ │
│ │ Возможность │ Станд│ Проф │ Корп │ │
│ ├────────────────────────────────┴──────┴──────┴──────┤ │
│ │ 1. Service Desk │ ← раздел│
│ ├────────────────────────────────┬──────┬──────┬──────┤ │
│ │ 1.1. Документ «Задание» │ ← п/р │
│ ├────────────────────────────────┼──────┼──────┼──────┤ │
│ │ Создание, редактирование... │ ✓ │ ✓ │ ✓ │ │
│ │ Шаблоны заданий/комментариев │ — │ ✓ │ ✓ │ │
│ │ Оценка заданий и лояльность │ ✓ │ ✓ │ ✓ │ │
│ ... │
│ ┌────────────────────────────────┬──────┬──────┬──────┐ │
│ │ Потенциальные клиенты ⚠ │ — │ — │ ✓ │ HIGH │
│ │ Недоступно — требуется КОРП │ │ │ │ │
│ ... │
└──────────────────────────────────────────────────────────────────┘
▲ ▲
подсветка колонка текущей редакции
целевой фичи

HTML (упрощённо)

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>/* содержимое css_markdown_content + css_editions */</style>
</head>
<body>
<div class="editions-panel"
data-current-edition="2"
data-highlighted-feature="ИспользоватьCRM">

<header class="editions-hero">
<h1>Возможности "Управление IT-отделом 8"</h1>
<div class="current-edition-badge edition-prof">
Ваша редакция: <strong>ПРОФ</strong>
</div>
</header>

<section class="editions-intro">
<!-- вывод ДоксинумПарсер.ОбработатьТекстMD(Введение) -->
</section>

<table class="editions-matrix">
<thead>
<tr>
<th class="col-feature">Возможность</th>
<th class="col-edition">Стандарт</th>
<th class="col-edition col-current">Проф</th>
<th class="col-edition">Корп</th>
</tr>
</thead>
<tbody>
<tr class="row-section"><td colspan="4">1. Service Desk</td></tr>
<tr class="row-subsection"><td colspan="4">1.1. Документ "Задание"</td></tr>
<tr class="row-feature">
<td>Создание, редактирование, выполнение заданий</td>
<td class="check"></td>
<td class="check col-current"></td>
<td class="check"></td>
</tr>
<tr class="row-feature row-highlighted"
id="feature-ИспользоватьCRM">
<td>
Потенциальные клиенты
<div class="feature-unavailable-badge">
Недоступно в вашей редакции — требуется <strong>КОРП</strong>
</div>
</td>
<td class="dash"></td>
<td class="dash col-current"></td>
<td class="check"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>

CSS (CommonTemplate.css_editions)

Небольшой файл (~150–200 строк), содержит:

  • Layout: .editions-panel flex-column, max-width
  • Hero: заголовок, цветные бейджи редакций (.edition-standart, .edition-prof, .edition-corp)
  • Таблица: .editions-matrix с границами, чередующиеся строки, заметные row-section/row-subsection
  • Подсветка колонки: .col-current — более тёмный фон по всей высоте (явный класс, не :nth-child — в старом webkit медиа-запросы запрещены, но классы работают)
  • Подсветка строки: .row-highlighted — жёлтая подложка + левая красная граница 3px
  • .feature-unavailable-badge — бейдж с текстом требуемой редакции внутри ячейки названия

Переиспользуется существующий CommonTemplate.css_markdown_content для секции .editions-intro, чтобы введение (жирный, списки, ссылки) выглядело так же, как markdown-контент в описании задания. Ограничения среды те же, что у web/task — старый webkit 2015+: без let/const, без медиа-запросов, с -webkit- префиксами для flex.

Сборка HTML в коде

Используется тот же паттерн, что и в СЛС.СформироватьОписаниеЗадачи() — поток в памяти + ЗаписьТекста + массив стилей. Никакой конкатенации строк (см. 1c-rules.md → String Performance).

Функция СформироватьHTMLРедакций(ДанныеМакета, Знач ТекущаяРедакция, Знач ВыделеннаяФича) Экспорт

Стили = Новый Массив;
Стили.Добавить(РаботаСВебСервер.ПолучитьТекстОбщегоМакета("css_markdown_content"));
Стили.Добавить(РаботаСВебСервер.ПолучитьТекстОбщегоМакета("css_editions"));

ПотокДанных = Новый ПотокВПамяти;
Запись = Новый ЗаписьТекста(ПотокДанных, КодировкаТекста.UTF8);

Заголовок = НСтр("ru = 'Редакции конфигурации'");
РаботаСВебСервер.ОткрытьДокумент(Запись, Заголовок, Стили);

РаботаСВебСервер.НачатьОткрытиеТега(Запись, "div", "editions-panel");
РаботаСВебСервер.ДобавитьСвойствоЗначениеТега(Запись, "data-current-edition",
Формат(ТекущаяРедакция, "ЧН=0; ЧГ=0"));
Если ЗначениеЗаполнено(ВыделеннаяФича) Тогда
РаботаСВебСервер.ДобавитьСвойствоЗначениеТега(Запись, "data-highlighted-feature",
ВыделеннаяФича);
КонецЕсли;
РаботаСВебСервер.ЗакрытьОткрытиеТега(Запись);

СобратьШапкуРедакций(Запись, ТекущаяРедакция);
СобратьВведениеРедакций(Запись, ДанныеМакета.Введение); // через ДоксинумПарсер
СобратьТаблицуРедакций(Запись, ДанныеМакета, ТекущаяРедакция, ВыделеннаяФича);

РаботаСВебСервер.ЗакрытьDiv(Запись);
РаботаСВебСервер.ЗакрытьДокумент(Запись);

Запись.Закрыть();
ПотокДанных.Позиция = 0;
Чтение = Новый ЧтениеТекста(ПотокДанных, КодировкаТекста.UTF8);
Возврат Чтение.Прочитать();

КонецФункции

Все необходимые методы РаботаСВебСервер существуют в проекте (Module.bsl:16–270): ОткрытьДокумент, ЗакрытьДокумент, ОткрытьDiv/ЗакрытьDiv, НачатьОткрытиеТега, ДобавитьСвойствоЗначениеТега, ЗакрытьОткрытиеТега, ДобавитьHTML, ПолучитьТекстОбщегоМакета.

Форма ОбщаяФорма.РедакцииКонфигурации

Реквизиты формы

ИмяТипНазначение
ТекстHTMLСтрокаHTML-содержимое страницы
КодФункцииСтрокаПараметр открытия, код функциональной опции для подсветки

Элементы формы

  • ПолеHTMLДокумента — привязан к реквизиту ТекстHTML, растянут по горизонтали и вертикали, без рамки, заголовок скрыт

Обработчики модуля формы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Свойство("КодФункции") Тогда
КодФункции = Параметры.КодФункции;
КонецЕсли;

Попытка
ДанныеМакета = СЛС.ПрочитатьМакетРедакций();
ТекстHTML = СЛС.СформироватьHTMLРедакций(
ДанныеМакета,
СЛС.РедакцияКонфигурации(),
КодФункции);
Исключение
ТекстHTML = СЛС.HTMLОшибкиМакетаРедакций(ИнформацияОбОшибке());
КонецПопытки;

КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)

Если ЗначениеЗаполнено(КодФункции) Тогда
ВыполнитьСкроллККодуФункции();
КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ВыполнитьСкроллККодуФункции()

Если Элементы.ПолеHTMLДокумента.Документ = Неопределено Тогда
Возврат;
КонецЕсли;

Элемент = Элементы.ПолеHTMLДокумента.Документ.getElementById(
"feature-" + КодФункции);

Если Элемент <> Неопределено Тогда
Элемент.scrollIntoView();
КонецЕсли;

КонецПроцедуры

Заголовок формы и все строковые литералы — через НСтр().

API gating для вызывающего кода

Серверная часть (СЛС.Module.bsl)

// Возвращает Истина, если функция доступна в текущей редакции конфигурации.
//
// Параметры:
// КодФункции - Строка - Имя константы функциональной опции
// (например, "ИспользоватьCRM").
// Если пустая строка - возврат Истина.
//
// Возвращаемое значение:
// Булево - Истина, если функция доступна.
//
Функция ФункциональностьДоступна(Знач КодФункции) Экспорт

Если НЕ ЗначениеЗаполнено(КодФункции) Тогда
Возврат Истина;
КонецЕсли;

МетаданныеКонстанты = Метаданные.Константы.Найти(КодФункции);
Если МетаданныеКонстанты = Неопределено Тогда
Возврат Истина; // Неизвестный код - не блокируем
КонецЕсли;

УстановитьПривилегированныйРежим(Истина);
Значение = Константы[КодФункции].Получить();
УстановитьПривилегированныйРежим(Ложь);

Возврат Значение = Истина;

КонецФункции

Клиентская часть (СЛСКлиент.Module.bsl)

// Проверяет доступность функции в текущей редакции. Если функция недоступна,
// открывает форму "Редакции конфигурации" с подсветкой этой функции.
//
// Паттерн использования в коде вызова:
//
// Если НЕ СЛСКлиент.ПроверитьДоступностьРедакции("ИспользоватьCRM") Тогда
// Возврат;
// КонецЕсли;
//
// Параметры:
// КодФункции - Строка - Имя константы функциональной опции.
//
// Возвращаемое значение:
// Булево - Истина, если функция доступна (вызывающий код продолжает работу).
//
Функция ПроверитьДоступностьРедакции(Знач КодФункции) Экспорт

Если СЛС.ФункциональностьДоступна(КодФункции) Тогда
Возврат Истина;
КонецЕсли;

ПараметрыФормы = Новый Структура("КодФункции", КодФункции);
ОткрытьФорму("ОбщаяФорма.РедакцииКонфигурации", ПараметрыФормы);

Возврат Ложь;

КонецФункции

СЛС имеет флаг serverCall=true, поэтому вызов СЛС.ФункциональностьДоступна() с клиента работает напрямую — прослойка СЛСВызовСервера не нужна.

План файлов

ФайлДействиеОписание
it/src/CommonTemplates/РедакцииКонфигурации/Template.txtЗаполнитьMarkdown-макет с матрицей возможностей (перенос из xlsx вручную)
it/src/CommonTemplates/css_editions/css_editions.mdoСоздатьНовый общий макет (TextDocument)
it/src/CommonTemplates/css_editions/Template.txtСоздать~150–200 строк CSS
it/src/Configuration/Configuration.mdoИзменитьДобавить <commonTemplates>CommonTemplate.css_editions</commonTemplates> в алфавитном порядке
it/src/CommonForms/РедакцииКонфигурации/Form.formИзменитьДобавить реквизит ТекстHTML, реквизит КодФункции, элемент ПолеHTMLДокумента
it/src/CommonForms/РедакцииКонфигурации/Module.bslСоздатьПриСозданииНаСервере, ПриОткрытии, ВыполнитьСкроллККодуФункции
it/src/CommonModules/СЛС/Module.bslИзменитьНовые экспортные: ФункциональностьДоступна, ПрочитатьМакетРедакций, СформироватьHTMLРедакций, HTMLОшибкиМакетаРедакций + служебный парсер
it/src/CommonModules/СЛСКлиент/Module.bslИзменитьНовая экспортная: ПроверитьДоступностьРедакции
it/src/Roles/БазовыеПраваУФ/Rights.rightsПроверитьПраво View на CommonTemplate.РедакцииКонфигурации уже есть; добавить на CommonTemplate.css_editions

Тестирование

  1. MCP get_project_errors после каждого изменения BSL-кода — гарантия, что модуль компилируется
  2. Ручной тест (матрица без параметра): открыть ОбщаяФорма.РедакцииКонфигурации вручную — должна отрендериться полная матрица с подсветкой колонки текущей редакции
  3. Ручной тест (подсветка): вызвать в тестовом модуле СЛСКлиент.ПроверитьДоступностьРедакции("ИспользоватьCRM") в редакции, где CRM недоступна — страница должна открыться, проскроллиться к строке «Потенциальные клиенты», строка подсвечена, бейдж «требуется КОРП»
  4. Ручной тест (доступная фича): тот же вызов в КОРП — возвращает Истина, форма не открывается
  5. Невалидный макет: временно сломать грамматику (убрать | в одной строке) — вместо падения формы показывается HTML с текстом ошибки и номером строки
  6. Несуществующий код: вызов с КодФункции = "НеСуществует"ФункциональностьДоступна возвращает Истина (не блокируем неизвестное), форма не открывается
  7. Пустой параметр: открытие формы без параметра КодФункции — матрица без подсветки, без ошибок

Вне скоупа

  • Рефакторинг СЛС.УстановитьФункционал — существующий механизм отключения констант работает как раньше
  • Массовая расстановка gates в формах и командах — это отдельная задача. Текущая спецификация даёт только API (СЛСКлиент.ПроверитьДоступностьРедакции) и форму
  • Автогенерация макета из xlsx — макет заполняется вручную один раз; xlsx использован как референс и в дальнейшем не участвует
  • Мультиязычность макета — сейчас только русский. При добавлении языков макет можно будет вынести в ru/, en/ подпапки — отдельная задача
  • Обновление пользовательской документации docs/ — не требуется по умолчанию согласно CLAUDE.md
  • Обновление технической документации .docs/ — тоже не требуется, так как новая функциональность не меняет существующих подсистем, но если появится подходящий раздел (например, .docs/reference/editions.md), его можно добавить отдельной задачей
  • JavaScript в форме — не используется. Скролл делается через 1C-сторону (Элементы.ПолеHTMLДокумента.Документ.getElementById(...).scrollIntoView()), CommonTemplate.js_* макеты не создаются
  • Связь с формой «О программе» — текущая форма открывается независимо; интеграция с экраном «О программе» — отдельная задача

Deliverables

  1. Заполненный Markdown-макет РедакцииКонфигурации/Template.txt
  2. Новый CSS-макет CommonTemplate.css_editions
  3. Обновлённая CommonForm.РедакцииКонфигурации с модулем формы
  4. Новые экспортные функции в СЛС и СЛСКлиент
  5. Регистрация css_editions в Configuration.mdo и правах
  6. Ручная проверка всех сценариев из раздела «Тестирование»