XBSL Skills AI-инструменты для 1С:Элемент
СкиллPython 3.10+

xbsl-pattern-rls

Реализует полный паттерн RLS (Row-Level Security) — разграничение доступа к строкам данных — для объектов конфигурации 1С:Элемент (Справочник, Документ и др.). За один вызов создаёт все необходимые артефакты: КлючДоступа (.yaml + .xbsl), обновляет YAML объекта (КонтрольДоступа + РасчетРазрешенийПо) и дописывает в .xbsl объекта два обработчика — уровень 1 (доступ к таблице) и уровень 2 (доступ к конкретным строкам). Вызывай когда пользователь хочет: настроить RLS на справочник или документ; ограничить видимость записей по владельцу/ответственному/организации; реализовать «каждый видит только свои записи»; настроить доступ группы пользователей к записям по контекстному параметру. Паттерны: P0 — доступ без построчной фильтрации (РазрешеноАутентифицированным / РазрешеноАдминистраторам, без обработчиков); P1 — пользователь видит только свои записи (предопределённый ключ, файлы не создаются); P2 — группа по параметру (собственный КлючДоступа + обработчик ПроверитьНаличиеКлючейДоступа); P2-б — ролевой ключ без параметров; P3 — два участника с разными правами на один объект.

Во всех командах ниже {python} означает python в Windows и python3 в macOS/Linux/WSL. Выбирай команду сразу по текущей ОС, не запускай оба варианта.

RLS-паттерн для объектов 1С:Элемент

Перед созданием или дополнением .xbsl прочитай .claude/xbsl-spec.md. Прочитай references/rls-паттерны.md — там точные шаблоны YAML и XBSL для обоих паттернов.

Шаг 1: Определи целевой объект

Из запроса пользователя извлеки тип (Справочник, Документ) и имя объекта. Если имя не указано — спроси пользователя.

Шаг 2: Разведка объекта

Запусти rls_state:

{python} .claude/skills/xbsl-pattern-rls/scripts/rls_state.py --name <ИмяОбъекта> --root .

Из результата возьми: - object_path — папка, куда класть файлы ключа - yaml_file — имя YAML-файла объекта - xbsl_file / xbsl_exists — путь к .xbsl-файлу и признак его существования - pattern_hints — подсказки по паттерну на основе типов реквизитов - control_access — текущее состояние секции КонтрольДоступа (используй на шаге 7) - handlers — наличие обработчиков уровня 1/2 (используй на шаге 8)

Если скрипт вернул error с несколькими matches — покажи список и попроси уточнить имя.

⚠️ RLS-обработчики записываются в <Имя>.xbsl (без суффикса .Объект). Файл <Имя>.Объект.xbsl предназначен только для lifecycle-событий (ПослеЗаписи, ДоЗаписи) — туда RLS не кладётся. Если rls_state вернул xbsl_file: null — создай файл <ИмяОбъекта>.xbsl.

Шаг 3: Выбери паттерн

Сначала спроси пользователя: нужна ли построчная фильтрация? Если нет — используй P0 и завершай на шаге 7 (только YAML).

Для построчной фильтрации проанализируй fields из шага 2:

Признак Паттерн
Не нужна фильтрация по строкам (все видят всё) P0 — Без RLS
Один реквизит типа Пользователи.Ссылка? P1 — По пользователю
Два реквизита-участника, каждый → свой справочник со встроенным полем Пользователь P3 — Несколько участников
Реквизит типа <Справочник>.Ссылка?, доступ — по роли (нет прямой связи с пользователем) P2 — По параметру
Роль без привязки к объекту (все руководители видят всё) P2-б — Ключ без параметров

Если признак не очевиден — спроси пользователя и объясни разницу: - P0: «Все вошедшие пользователи видят все записи. Никаких обработчиков и ключей.» - P1: «Каждый пользователь видит только свои записи. Не нужно создавать дополнительных объектов.» - P2: «Группа пользователей видит записи по общему контексту (организация, регион). Создаётся собственный КлючДоступа.» - P2-б: «Все пользователи с определённой ролью видят все записи. Собственный ключ, но без параметров.» - P3: «Две роли на один объект с разными правами (например, автор — полные права, соисполнитель — только чтение).»

Шаг 4: Уточни детали [только P2, P2-б, P3]

P2 и P2-б — уточни у пользователя:

  1. Имя ключа — дефолт: КлючДоступа<ИмяОбъектаРодительный> (например КлючДоступаЗадач). Стиль: PascalCase, начинается с КлючДоступа, суффикс отражает контекст.

  2. P2: Поле-контекст — реквизит из fields, по значению которого группируются строки. P2-б: поле не нужно — ключ без параметров, выдаётся всем с нужной ролью.

  3. Таблица связи — справочник или регистр, где хранится связь «пользователь ↔ контекст» (P2) или «пользователь ↔ роль» (P2-б).

P3 — уточни оба поля-участника и какие права у каждого.

P1 — уточни только поле-пользователь из fields.

Шаг 5: Сгенерируй UUID [только P2, P2-б]

Для собственного ключа нужен 1 UUID (на объект; параметры Ид не имеют). Вызови скилл xbsl-uuid с числом 1.

Шаг 6: Создай файлы ключа [только P2, P2-б]

Создай <ИмяКлюча>.yaml в object_path по шаблону из references/rls-паттерны.md (раздел P2).

Создай <ИмяКлюча>.xbsl в той же папке — шаблон ПроверитьНаличиеКлючейДоступа. Подставь реальные имена из шага 4; оставь // TODO там, где нужна бизнес-логика запроса.

Проверка межподсистемной видимости: если тип параметра (Тип: <Справочник>.Ссылка?) относится к объекту из другой подсистемы — добавь Импорт: [<ПодсистемаИсточника>] в YAML ключа и убедись, что источник имеет ОбластьВидимости: ВПроекте.

Шаг 7: Обнови YAML объекта

Используй данные из шага 2: object_path + yaml_file. Состояние КонтрольДоступа уже известно из control_access.

Добавь или обнови секцию КонтрольДоступа. Точный формат — в references/rls-паттерны.md.

  • РасчетРазрешенийПо — укажи поле-пользователь (P1) или поле-контекст (P2)
  • ПоУмолчанию: РазрешенияВычисляютсяДляКаждогоОбъекта

Если секция уже существует с другим значением — сообщи пользователю и спроси подтверждение.

Шаг 8: Запиши обработчики в .xbsl объекта

Файл уже известен из шага 2: xbsl_file в object_path. Наличие обработчиков — в handlers.

  • Если handlers.level1 = true — предложи заменить или пропустить.
  • Если xbsl_exists = false — создай <ИмяОбъекта>.xbsl (новый файл, без суффикса .Объект).

Добавь оба обработчика: уровень 1 (ВычислитьРазрешенияДоступа) и уровень 2 (ВычислитьРазрешенияДоступаДляОбъектов) из шаблонов в references/rls-паттерны.md.

Подставь реальные имена: - <Объект> → имя объекта (например Задачи) - <ПолеПользователя> / <ПолеКонтекста> → реальное имя реквизита - <КлючИмя> → имя ключа (только P2)

⚠️ Правило уровней: все права из уровня 2 обязаны присутствовать и в уровне 1. Проверь перед записью.

Шаг 9: Итог и рекомендации

Перечисли созданные/изменённые файлы:

Создано:
  <object_path>/<КлючИмя>.yaml   — КлючДоступа с параметром Владелец  [только P2]
  <object_path>/<КлючИмя>.xbsl   — обработчик ПроверитьНаличиеКлючейДоступа  [только P2]

Обновлено:
  <object_path>/<ОбъектИмя>.yaml    — добавлен КонтрольДоступа
  <object_path>/<ОбъектИмя>.xbsl   — добавлены обработчики RLS

Добавь рекомендации по пересчёту прав:

Первый пересчёт после деплоя — добавь в Проект.xbsl метод с аннотацией. Если объект находится в подсистеме — добавь импорт <Подсистема> в начало файла:

импорт <Подсистема>   // если объект в подсистеме, а не в корне проекта

@ОбновлениеПроекта(Ид = "recalc_<Объект>_rls_v1", Номер = N)
метод ПересчитатьПрава<Объект>()
    <Объект>.ПересчитатьРазрешенияДоступа()
    <Объект>.ПересчитатьРазрешенияДоступаДляОбъектов()
;

Своевременный пересчёт при изменении данных (только P2) — в ПослеЗаписи объекта-источника при изменении поля-контекста:

если До.<ПолеКонтекста> <> Это.<ПолеКонтекста>
    исп КонтекстДоступа.Привилегированный()
        <КлючИмя>.ПересчитатьКлючи(<Параметр> = Это.Ссылка)
;

Чеклист перед передачей результата

  • [ ] КонтрольДоступа.Разрешения обновлено в YAML объекта
  • [ ] Для P0: обработчики не создаются, шаги 8–9 пропустить
  • [ ] Для P1, P2, P2-б, P3: указан обработчик уровня 1 (ВычислитьРазрешенияДоступа)
  • [ ] Для P1, P2, P2-б, P3: указан обработчик уровня 2 (ВычислитьРазрешенияДоступаДляОбъектов)
  • [ ] Все права из уровня 2 есть и в уровне 1
  • [ ] Добавлена проверка != Неопределено по полю в цикле уровня 2 (не = Неопределено — в XBSL = только присваивание)
  • [ ] Файл обработчика называется <Имя>.xbsl (без суффикса .Объект)
  • [ ] Поле в РасчетРазрешенийПо — не коллекция, не строка без ограничения, не stdlib-перечисление
  • [ ] Для P2, P2-б: написан ПроверитьНаличиеКлючейДоступа с TODO-комментариями
  • [ ] Для P2: параметры ключа в YAML не имеют поля Ид
  • [ ] Для P2-б: в YAML ключа раздел Параметры отсутствует
  • [ ] Для P3: для каждого участника — отдельный запрос и блок если