feat(role-edit): точечная правка существующей роли

Закрывает #43. Повторный role-compile перевыпускал UUID и переписывал
Rights.xml целиком, поэтому добавить права существующей роли было нечем —
оставалась ручная правка XML.

Операции: add-rights, set-rights, remove-rights, deny-rights, set-rls,
remove-rls, add/set/remove-template, modify-property, set-synonym,
set-comment. Пакет через ;;, значение из файла через @путь, отказ до
записи со всеми причинами разом, авто-вызов role-validate.

Грамматика имён и пресетов — та же, что у role-compile: копии таблиц и
валидаторов взяты побайтово, навык дописан в 16 семей реестра
check-inline-drift.

Правка держит инвариант «меняется только то, что просили»: узел встаёт на
своё место по uuid объекта, право — по канону типа, набор замыкается по
зависимостям, снятие и запрет идут каскадом в обратную сторону. Проверено
раундтрипом через платформу — выход обоих портов совпал с выгрузкой 1С
байт в байт, включая RLS с полями и двумя строками ограничений.

22 кейса на обоих портах, 17 снэпшотов приняты платформой.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FGkXwoXTuafcu1SXMsauFq
This commit is contained in:
Nick Shirokov
2026-09-13 17:39:12 +03:00
co-authored by Claude Opus 5
parent ce37fe6e53
commit 7bbacd8ef4
285 changed files with 21391 additions and 20 deletions
+44 -2
View File
@@ -169,8 +169,50 @@ Roles/
| `object/name` | да | Полное имя объекта метаданных (dot-нотация) |
| `right/name` | да | Имя права (см. таблицы ниже) |
| `right/value` | да | `true` или `false` |
| `right/restrictionByCondition` | нет | Ограничение на уровне записей (RLS) |
| `restrictionByCondition/condition` | да | Текст условия на языке шаблонов ограничений |
| `right/restrictionByCondition` | нет | Ограничение на уровне записей (RLS). Их может быть несколько на одно право |
| `restrictionByCondition/field` | нет | Поле, на которое действует ограничение. Может повторяться; порядок — ordinal |
| `restrictionByCondition/condition` | да | Текст условия на языке шаблонов ограничений. Пустой (`<condition/>`) = доступ без ограничения |
Ограничения права — это список строк, как таблица «Ограничения доступа к данным» в редакторе
ролей. Строка **без** `<field>` действует на все прочие поля, строка с `<field>` — только на
перечисленные. Строка без полей идёт первой. Типовой приём — закрыть таблицу целиком, оставив
ссылочные поля доступными, чтобы ссылки на объект не рвались:
```xml
<right>
<name>Read</name>
<value>true</value>
<restrictionByCondition>
<condition>ГДЕ ЛОЖЬ</condition>
</restrictionByCondition>
<restrictionByCondition>
<field>Ref</field>
<field>Date</field>
<field>Number</field>
<condition/>
</restrictionByCondition>
</right>
```
Стандартные реквизиты в `<field>` платформа пишет по-английски: `Ref`, `Code`, `Description`,
`Parent`, `Owner`, `Date`, `Number`, `DeletionMark`, `IsFolder`, `DataVersion`, `Posted`,
`Predefined`. Прикладные реквизиты — своими именами.
### Зависимые права
Платформа при загрузке доводит набор прав до замыкания: `Edit` тянет `Read`, `Update`, `View`;
интерактивные права — свой базовый набор; `View` у обработки и отчёта — `Use`. Запрет работает в
обратную сторону: `View=false` у реквизита тянет `Edit=false`. Файл, записанный без замыкания,
после первой же загрузки разойдётся с базой.
Права `Configuration` версионные: до формата 2.19 (платформа 8.3.26) любое из них взводило весь
блок `MainWindowMode*` и `AnalyticsSystemClient`, начиная с 2.19 — нет.
### Порядок узлов
Порядок `<right>` внутри `<object>` фиксирован для типа объекта, порядок самих `<object>`
по uuid объекта метаданных (у вложенного — по uuid самого реквизита или команды). Платформа
нормализует и то, и другое при выгрузке; порядок дерева конфигурации тут ни при чём.
### Именование объектов (dot-нотация)