From 2c96c90d450ba7652fb0a0f9cf7fd9016560ffcc Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 9 Feb 2026 21:06:01 +0300 Subject: [PATCH 1/5] Add 1C role XML format specification Complete reference: file structure, rights catalog by object type, nested object rights, RLS conditions, restriction templates. Verified across platform versions 8.3.20/8.3.24/8.3.27 and both ACC and ERP configurations. Co-Authored-By: Claude Opus 4.6 --- docs/1c-role-spec.md | 845 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 845 insertions(+) create mode 100644 docs/1c-role-spec.md diff --git a/docs/1c-role-spec.md b/docs/1c-role-spec.md new file mode 100644 index 00000000..2f32582a --- /dev/null +++ b/docs/1c-role-spec.md @@ -0,0 +1,845 @@ +# Спецификация формата ролей 1С:Предприятия 8.3 + +Полное описание XML-формата ролей в выгрузке конфигурации. Версии формата: 2.17 (платформа 8.3.20–8.3.24), 2.20 (8.3.27+). Структура идентична, отличается только атрибут `version`. + +## Файловая структура + +Каждая роль состоит из двух файлов: + +``` +Roles/ + ИмяРоли.xml ← метаданные (uuid, имя, синоним) + ИмяРоли/ + Ext/ + Rights.xml ← определение прав +``` + +## Регистрация роли в конфигурации + +При создании роли необходимо прописать ссылки в следующих местах: + +### Configuration.xml — ChildObjects + +Регистрация объекта в составе конфигурации: + +```xml + + ... + ИмяРоли + ... + +``` + +Элементы `` располагаются среди других объектов конфигурации в секции ``. + +### Configuration.xml — DefaultRoles (опционально) + +Если роль должна назначаться новым пользователям по умолчанию: + +```xml + + Role.ИмяРоли + +``` + +### Form.xml — права редактирования реквизитов (опционально) + +В формах роль может упоминаться для ограничения редактирования реквизитов: + +```xml + + + false + true + + +``` + +--- + +## Файл метаданных: Roles/ИмяРоли.xml + +```xml + + + + + ИмяРоли + + + ru + Отображаемое имя роли + + + + + + +``` + +### Элементы + +| Элемент | Обязательный | Описание | +|---------|:------------:|----------| +| `Role/@uuid` | да | UUID роли (формат `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`) | +| `Name` | да | Программное имя роли (идентификатор, латиница/кириллица) | +| `Synonym` | да | Мультиязычное отображаемое имя (один или несколько `v8:item`) | +| `Comment` | да | Комментарий (может быть пустым ``) | + +### Namespace + +Основной: `http://v8.1c.ru/8.3/MDClasses` +Мультиязычные строки: `v8` = `http://v8.1c.ru/8.1/data/core` + +--- + +## Файл прав: Roles/ИмяРоли/Ext/Rights.xml + +### Корневой элемент + +```xml + + + false + true + false + + ... + ... + + ... + ... + +``` + +### Namespace + +`http://v8.1c.ru/8.2/roles` (NB: 8.2, а не 8.3 — исторически) + +### Глобальные флаги + +| Флаг | Тип | По умолчанию | Описание | +|------|-----|:------------:|----------| +| `setForNewObjects` | boolean | false | Устанавливать права для новых объектов конфигурации | +| `setForAttributesByDefault` | boolean | true | Устанавливать права для реквизитов по умолчанию | +| `independentRightsOfChildObjects` | boolean | false | Независимые права подчинённых объектов | + +### Структура блока `` + +```xml + + ТипОбъекта.ИмяОбъекта + + ИмяПрава + true + + + ИмяПрава + true + + Текст условия RLS + + + +``` + +| Элемент | Обязательный | Описание | +|---------|:------------:|----------| +| `object/name` | да | Полное имя объекта метаданных (dot-нотация) | +| `right/name` | да | Имя права (см. таблицы ниже) | +| `right/value` | да | `true` или `false` | +| `right/restrictionByCondition` | нет | Ограничение на уровне записей (RLS) | +| `restrictionByCondition/condition` | да | Текст условия на языке шаблонов ограничений | + +### Именование объектов (dot-нотация) + +Объекты адресуются иерархически через точку: + +``` +ТипОбъекта.ИмяОбъекта[.ТипВложенного[.ИмяВложенного[...]]] +``` + +#### Верхний уровень — объекты метаданных + +``` +Catalog.Контрагенты +Document.РеализацияТоваровУслуг +InformationRegister.ЦеныНоменклатуры +DataProcessor.ЗагрузкаДанных +Report.АнализПродаж +Configuration.ИмяКонфигурации +``` + +#### Стандартные реквизиты + +``` +Catalog.Контрагенты.StandardAttribute.Code +Catalog.Контрагенты.StandardAttribute.Description +Catalog.Контрагенты.StandardAttribute.DeletionMark +Catalog.Контрагенты.StandardAttribute.Predefined +Catalog.Контрагенты.StandardAttribute.PredefinedDataName +Catalog.Контрагенты.StandardAttribute.Ref +Catalog.Контрагенты.StandardAttribute.IsFolder +Catalog.Контрагенты.StandardAttribute.Parent +Catalog.Контрагенты.StandardAttribute.Owner +Document.Реализация.StandardAttribute.Posted +Document.Реализация.StandardAttribute.Date +Document.Реализация.StandardAttribute.Number +``` + +#### Реквизиты + +``` +Catalog.Контрагенты.Attribute.ИНН +Document.Реализация.Attribute.Организация +``` + +#### Табличные части и их реквизиты + +``` +Document.Реализация.TabularSection.Товары +Document.Реализация.TabularSection.Товары.Attribute.Номенклатура +Document.Реализация.TabularSection.Товары.StandardAttribute.LineNumber +``` + +#### Измерения, ресурсы, реквизиты регистров + +``` +InformationRegister.Цены.Dimension.Номенклатура +InformationRegister.Цены.Resource.Цена +AccumulationRegister.Остатки.Attribute.ДатаОперации +AccountingRegister.Хозрасчетный.Dimension.Организация +``` + +#### Команды + +``` +Catalog.Контрагенты.Command.ОткрытьКарточку +DataProcessor.Обработка.Command.Выполнить +CommonCommand.УправлениеОборудованием +``` + +#### Реквизиты адресации (бизнес-процессы/задачи) + +``` +Task.ЗадачаИсполнителя.AddressingAttribute.Исполнитель +Task.ЗадачаИсполнителя.AddressingAttribute.ОсновнойОбъектАдресации +``` + +#### Операции веб-сервисов + +``` +WebService.Exchange.Operation.GetIBParameters +HTTPService.ЭДО.URLTemplate.Документы.Method.POST +``` + +#### Вложенные подсистемы + +``` +Subsystem.Администрирование.Subsystem.Пользователи +``` + +--- + +## Полный каталог прав по типам объектов + +### Права объектов верхнего уровня + +#### Configuration + +Права конфигурации в целом. Объект: `Configuration.ИмяКонфигурации`. + +| Право | Описание | +|-------|----------| +| `Administration` | Администрирование | +| `DataAdministration` | Администрирование данных | +| `UpdateDataBaseConfiguration` | Обновление конфигурации БД | +| `ConfigurationExtensionsAdministration` | Администрирование расширений | +| `ActiveUsers` | Активные пользователи | +| `EventLog` | Журнал регистрации | +| `ExclusiveMode` | Монопольный режим | +| `ThinClient` | Тонкий клиент | +| `ThickClient` | Толстый клиент | +| `WebClient` | Веб-клиент | +| `MobileClient` | Мобильный клиент | +| `ExternalConnection` | Внешнее соединение | +| `Automation` | Automation (COM) | +| `Output` | Вывод (печать, сохранение, копирование) | +| `SaveUserData` | Сохранение данных пользователя | +| `TechnicalSpecialistMode` | Режим технического специалиста | +| `InteractiveOpenExtDataProcessors` | Интерактивное открытие внешних обработок | +| `InteractiveOpenExtReports` | Интерактивное открытие внешних отчётов | +| `AnalyticsSystemClient` | Клиент системы аналитики | +| `CollaborationSystemInfoBaseRegistration` | Регистрация ИБ в системе взаимодействия | +| `MainWindowModeNormal` | Режим обычного окна | +| `MainWindowModeWorkplace` | Режим рабочего места | +| `MainWindowModeEmbeddedWorkplace` | Режим встроенного рабочего места | +| `MainWindowModeFullscreenWorkplace` | Режим полноэкранного рабочего места | +| `MainWindowModeKiosk` | Режим киоска | + +#### Catalog + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Insert` | Добавление | +| `Update` | Изменение | +| `Delete` | Удаление | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `InputByString` | Ввод по строке | +| `InteractiveInsert` | Интерактивное добавление | +| `InteractiveSetDeletionMark` | Интерактивная пометка удаления | +| `InteractiveClearDeletionMark` | Интерактивное снятие пометки удаления | +| `InteractiveDelete` | Интерактивное удаление | +| `InteractiveDeleteMarked` | Интерактивное удаление помеченных | +| `InteractiveDeletePredefinedData` | Интерактивное удаление предопределённых | +| `InteractiveSetDeletionMarkPredefinedData` | Пометка удаления предопределённых | +| `InteractiveClearDeletionMarkPredefinedData` | Снятие пометки удаления предопределённых | +| `InteractiveDeleteMarkedPredefinedData` | Удаление помеченных предопределённых | +| `ReadDataHistory` | Чтение истории данных | +| `ViewDataHistory` | Просмотр истории данных | +| `UpdateDataHistory` | Обновление истории данных | +| `UpdateDataHistoryOfMissingData` | Обновление истории отсутствующих данных | +| `ReadDataHistoryOfMissingData` | Чтение истории отсутствующих данных | +| `UpdateDataHistorySettings` | Обновление настроек истории данных | +| `UpdateDataHistoryVersionComment` | Обновление комментария версии | +| `EditDataHistoryVersionComment` | Редактирование комментария версии | +| `SwitchToDataHistoryVersion` | Переход к версии истории данных | + +#### Document + +Все права Catalog (кроме предопределённых) плюс: + +| Право | Описание | +|-------|----------| +| `Posting` | Проведение | +| `UndoPosting` | Отмена проведения | +| `InteractivePosting` | Интерактивное проведение | +| `InteractivePostingRegular` | Интерактивное проведение (неоперативное) | +| `InteractiveUndoPosting` | Интерактивная отмена проведения | +| `InteractiveChangeOfPosted` | Интерактивное изменение проведённых | + +#### InformationRegister + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Update` | Изменение | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `TotalsControl` | Управление итогами (для периодических) | +| `ReadDataHistory` | Чтение истории данных | +| `ViewDataHistory` | Просмотр истории данных | +| `UpdateDataHistory` | Обновление истории данных | +| `UpdateDataHistoryOfMissingData` | Обновление истории отсутствующих данных | +| `ReadDataHistoryOfMissingData` | Чтение истории отсутствующих данных | +| `UpdateDataHistorySettings` | Настройки истории данных | +| `UpdateDataHistoryVersionComment` | Обновление комментария версии | +| `EditDataHistoryVersionComment` | Редактирование комментария версии | +| `SwitchToDataHistoryVersion` | Переход к версии | + +#### AccumulationRegister + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Update` | Изменение | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `TotalsControl` | Управление итогами | + +#### AccountingRegister + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Update` | Изменение | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `TotalsControl` | Управление итогами | + +#### CalculationRegister + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `View` | Просмотр | + +#### Constant + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Update` | Изменение | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `ReadDataHistory` | Чтение истории данных | +| `ViewDataHistory` | Просмотр истории данных | +| `UpdateDataHistory` | Обновление истории данных | +| `UpdateDataHistorySettings` | Настройки истории данных | +| `UpdateDataHistoryVersionComment` | Обновление комментария версии | +| `EditDataHistoryVersionComment` | Редактирование комментария версии | +| `SwitchToDataHistoryVersion` | Переход к версии | + +#### ChartOfAccounts + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Insert` | Добавление | +| `Update` | Изменение | +| `Delete` | Удаление | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `InputByString` | Ввод по строке | +| `InteractiveInsert` | Интерактивное добавление | +| `InteractiveSetDeletionMark` | Пометка удаления | +| `InteractiveClearDeletionMark` | Снятие пометки удаления | +| `InteractiveDelete` | Интерактивное удаление | +| `InteractiveDeletePredefinedData` | Удаление предопределённых | +| `InteractiveSetDeletionMarkPredefinedData` | Пометка удаления предопределённых | +| `InteractiveClearDeletionMarkPredefinedData` | Снятие пометки удаления предопределённых | +| `InteractiveDeleteMarkedPredefinedData` | Удаление помеченных предопределённых | +| `ReadDataHistory` | Чтение истории данных | +| `ReadDataHistoryOfMissingData` | Чтение истории отсутствующих данных | +| `UpdateDataHistory` | Обновление истории данных | +| `UpdateDataHistoryOfMissingData` | Обновление истории отсутствующих данных | +| `UpdateDataHistorySettings` | Настройки истории данных | +| `UpdateDataHistoryVersionComment` | Обновление комментария версии | + +#### ChartOfCharacteristicTypes + +Аналогично ChartOfAccounts, плюс: + +| Право | Описание | +|-------|----------| +| `InteractiveDeleteMarked` | Интерактивное удаление помеченных | +| `EditDataHistoryVersionComment` | Редактирование комментария версии | +| `SwitchToDataHistoryVersion` | Переход к версии | +| `ViewDataHistory` | Просмотр истории данных | + +#### ChartOfCalculationTypes + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Insert` | Добавление | +| `Update` | Изменение | +| `Delete` | Удаление | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `InputByString` | Ввод по строке | +| `InteractiveInsert` | Интерактивное добавление | +| `InteractiveSetDeletionMark` | Пометка удаления | +| `InteractiveClearDeletionMark` | Снятие пометки удаления | +| `InteractiveDelete` | Интерактивное удаление | +| `InteractiveDeletePredefinedData` | Удаление предопределённых | +| `InteractiveSetDeletionMarkPredefinedData` | Пометка удаления предопределённых | +| `InteractiveClearDeletionMarkPredefinedData` | Снятие пометки предопределённых | +| `InteractiveDeleteMarkedPredefinedData` | Удаление помеченных предопределённых | + +#### ExchangePlan + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Insert` | Добавление | +| `Update` | Изменение | +| `Delete` | Удаление | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `InputByString` | Ввод по строке | +| `InteractiveInsert` | Интерактивное добавление | +| `InteractiveSetDeletionMark` | Пометка удаления | +| `InteractiveClearDeletionMark` | Снятие пометки удаления | +| `InteractiveDelete` | Интерактивное удаление | +| `InteractiveDeleteMarked` | Удаление помеченных | +| `ReadDataHistory` | Чтение истории данных | +| `ViewDataHistory` | Просмотр истории данных | +| `UpdateDataHistory` | Обновление истории данных | +| `ReadDataHistoryOfMissingData` | Чтение истории отсутствующих | +| `UpdateDataHistoryOfMissingData` | Обновление истории отсутствующих | +| `UpdateDataHistorySettings` | Настройки истории данных | +| `UpdateDataHistoryVersionComment` | Обновление комментария версии | +| `EditDataHistoryVersionComment` | Редактирование комментария версии | +| `SwitchToDataHistoryVersion` | Переход к версии | + +#### BusinessProcess + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Insert` | Добавление | +| `Update` | Изменение | +| `Delete` | Удаление | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `InputByString` | Ввод по строке | +| `Start` | Старт | +| `InteractiveInsert` | Интерактивное добавление | +| `InteractiveSetDeletionMark` | Пометка удаления | +| `InteractiveClearDeletionMark` | Снятие пометки удаления | +| `InteractiveDelete` | Интерактивное удаление | +| `InteractiveActivate` | Интерактивная активация | +| `InteractiveStart` | Интерактивный старт | + +#### Task + +| Право | Описание | +|-------|----------| +| `Read` | Чтение | +| `Insert` | Добавление | +| `Update` | Изменение | +| `Delete` | Удаление | +| `View` | Просмотр | +| `Edit` | Редактирование | +| `InputByString` | Ввод по строке | +| `Execute` | Выполнение | +| `InteractiveInsert` | Интерактивное добавление | +| `InteractiveSetDeletionMark` | Пометка удаления | +| `InteractiveClearDeletionMark` | Снятие пометки удаления | +| `InteractiveDelete` | Интерактивное удаление | +| `InteractiveActivate` | Интерактивная активация | +| `InteractiveExecute` | Интерактивное выполнение | + +#### Простые типы (одно-два права) + +| Тип объекта | Права | +|-------------|-------| +| `DataProcessor` | Use, View | +| `Report` | Use, View | +| `CommonForm` | View | +| `CommonCommand` | View | +| `Subsystem` | View | +| `FilterCriterion` | View | +| `DocumentJournal` | Read, View | +| `Sequence` | Read, Update | +| `WebService` | Use | +| `HTTPService` | Use | +| `IntegrationService` | Use | +| `SessionParameter` | Get, Set | +| `CommonAttribute` | View, Edit | + +#### Типы объектов БЕЗ прав в ролях + +Следующие типы не фигурируют в Rights.xml (права не применимы или управляются иначе): + +- `Enum` (перечисления) +- `FunctionalOption` +- `DefinedType` +- `CommonModule` +- `CommonPicture` +- `CommonTemplate` +- `SettingsStorage` +- `ExternalDataSource` + +--- + +### Права вложенных объектов + +Права можно задавать не только на уровне объекта, но и на уровне его составных частей. + +#### Реквизиты и стандартные реквизиты + +Доступные права: `View`, `Edit` + +```xml + + Catalog.Контрагенты.StandardAttribute.PredefinedDataName + + View + false + + + Edit + false + + +``` + +Применимо к: +- `*.StandardAttribute.*` — стандартные реквизиты +- `*.Attribute.*` — реквизиты +- `*.TabularSection.*` — табличные части (целиком) +- `*.TabularSection.*.Attribute.*` — реквизиты табличных частей +- `*.TabularSection.*.StandardAttribute.*` — стандартные реквизиты табличных частей + +#### Измерения, ресурсы регистров + +Доступные права: `View`, `Edit` + +```xml + + InformationRegister.Цены.Dimension.Номенклатура + + Edit + false + + +``` + +Применимо к: +- `*Register.*.Dimension.*` +- `*Register.*.Resource.*` +- `*Register.*.Attribute.*` + +#### Команды + +Доступные права: `View` + +```xml + + Catalog.Контрагенты.Command.ОткрытьКарточку + + View + false + + +``` + +Применимо к: +- `*.Command.*` — команды любого объекта + +#### Реквизиты адресации (Task) + +Доступные права: `View`, `Edit` + +```xml + + Task.ЗадачаИсполнителя.AddressingAttribute.Исполнитель + + View + true + + +``` + +#### Полная таблица: вложенные объекты и их права + +| Тип вложенного | Родители | Права | +|----------------|----------|-------| +| `StandardAttribute` | Catalog, Document, ExchangePlan, ChartOf*, Task, BusinessProcess, *Register, DocumentJournal | View, Edit | +| `Attribute` | Catalog, Document, ExchangePlan, ChartOf*, Task, BusinessProcess, *Register, DataProcessor, Report | View, Edit | +| `TabularSection` | Catalog, Document, ExchangePlan, ChartOf*, Task, BusinessProcess, DataProcessor, Report | View, Edit | +| `TabularSection.*.Attribute` | (все с TabularSection) | View, Edit | +| `Dimension` | InformationRegister, AccumulationRegister, AccountingRegister | View, Edit | +| `Resource` | InformationRegister, AccumulationRegister, AccountingRegister | View, Edit | +| `Command` | Catalog, Document, DataProcessor, Report, *Register, DocumentJournal, ExchangePlan, BusinessProcess, Task | View | +| `AddressingAttribute` | Task | View, Edit | + +--- + +## Ограничения на уровне записей (RLS) + +### Структура + +```xml + + Read + true + + Текст условия + + +``` + +RLS добавляется внутрь `` как дочерний элемент ``. Условие содержит текст на языке шаблонов ограничений 1С. + +### Типичная структура условия + +``` +#Если &ОграничениеДоступаНаУровнеЗаписейУниверсально #Тогда +#ДляОбъекта("") +#Иначе +#ПоЗначениям("Документ.Реализация", "", "", +"Организации", "Организация", +"","", +...) +#КонецЕсли +``` + +Используются препроцессорные директивы (`#Если`, `#Тогда`, `#Иначе`, `#КонецЕсли`) и макросы шаблонов (`#ДляОбъекта`, `#ПоЗначениям`, `#ДляРегистра`, `#ПоЗначениямИНаборамРасширенный`). + +XML-кодирование: `&` → `&` в тексте условия. + +### Применимость + +RLS применяется к правам `Read`, `Update`, `Insert`, `Delete` объектов данных (Catalog, Document, Register и др.). Не применяется к интерактивным правам и правам конфигурации. + +--- + +## Шаблоны ограничений (restrictionTemplate) + +Располагаются в конце файла Rights.xml, после всех блоков ``. + +```xml + + ИмяШаблона(Параметр1, Параметр2, ...) + +// Комментарий с описанием параметров +// ... +Текст шаблона на языке запросов 1С + + +``` + +### Типичные шаблоны + +| Шаблон | Описание | +|--------|----------| +| `ДляОбъекта(Модификатор)` | Ограничение для ссылочных объектов (документы, справочники) | +| `ПоЗначениям(Таблица, -, Модификатор, В1,П1, ...)` | Ограничение по значениям видов доступа | +| `ДляРегистра(Регистр, Поле1, ..., Поле5)` | Ограничение для регистров | +| `ПоЗначениямИНаборамРасширенный(...)` | Расширенное ограничение по наборам и значениям | + +Шаблоны определяются в роли и вызываются из `` блоков RLS через макросы `#ИмяШаблона(...)`. + +--- + +## Примеры + +### Минимальная роль (без прав) + +**Roles/МояРоль.xml:** +```xml + + + + + МояРоль + + + ru + Моя роль + + + + + + +``` + +**Roles/МояРоль/Ext/Rights.xml:** +```xml + + + false + true + false + +``` + +### Роль для регламентного задания + +Типичный набор прав для фонового задания, работающего со справочниками и регистрами: + +```xml + + + false + true + false + + Catalog.Номенклатура + + Read + true + + + + Catalog.Контрагенты + + Read + true + + + + InformationRegister.ЦеныНоменклатуры + + Read + true + + + Update + true + + + + DataProcessor.ОбновлениеЦен + + Use + true + + + +``` + +### Роль с запретом редактирования полей + +```xml + + Document.РеализацияТоваровУслуг + + Read + true + + + View + true + + + + Document.РеализацияТоваровУслуг.StandardAttribute.Posted + + Edit + false + + + + Document.РеализацияТоваровУслуг.StandardAttribute.DeletionMark + + Edit + false + + +``` + +--- + +## Версии формата + +| Платформа | version (метаданные) | version (Rights.xml) | Изменения | +|-----------|:--------------------:|:--------------------:|-----------| +| 8.3.20 | 2.17 | 2.17 | Базовая | +| 8.3.24 | 2.17 | 2.17 | Без изменений | +| 8.3.27 | 2.20 | 2.20 | Только номер версии, структура идентична | + +Namespace Rights.xml (`http://v8.1c.ru/8.2/roles`) и namespace метаданных (`http://v8.1c.ru/8.3/MDClasses`) не менялись. From fc24524c75dc114b2be3ffc19319c718f51700e1 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 9 Feb 2026 21:16:00 +0300 Subject: [PATCH 2/5] Add /role-info and /role-compile skills role-info: PS1 script parsing Rights.xml into compact summary grouped by object type. Supports -ShowDenied and -OutFile for UTF-8 output. 78K lines XML -> 1924 lines for largest role, ~100 for typical ones. role-compile: Template-based SKILL.md (no script) with XML templates, rights catalog per object type, and typical right sets. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/role-compile/SKILL.md | 209 ++++++++++++++++ .claude/skills/role-info/SKILL.md | 74 ++++++ .../skills/role-info/scripts/role-info.ps1 | 231 ++++++++++++++++++ 3 files changed, 514 insertions(+) create mode 100644 .claude/skills/role-compile/SKILL.md create mode 100644 .claude/skills/role-info/SKILL.md create mode 100644 .claude/skills/role-info/scripts/role-info.ps1 diff --git a/.claude/skills/role-compile/SKILL.md b/.claude/skills/role-compile/SKILL.md new file mode 100644 index 00000000..41a069db --- /dev/null +++ b/.claude/skills/role-compile/SKILL.md @@ -0,0 +1,209 @@ +--- +name: role-compile +description: Создание роли 1С — метаданные и Rights.xml из описания прав +argument-hint: +allowed-tools: + - Bash + - Read + - Write + - Glob +--- + +# /role-compile — создание роли 1С + +Создаёт файлы роли (метаданные + Rights.xml) по описанию прав. Скрипта нет — агент генерирует XML по шаблонам ниже. + +## Использование + +``` +/role-compile +``` + +- **RoleName** — программное имя роли (например, `ВыполнениеРегламентныхЗаданий`) +- **RolesDir** — каталог `Roles/` в исходниках конфигурации или обработки + +## Что создать + +### 1. Файл метаданных: `Roles/.xml` + +```xml + + + + + ИмяРоли + + + ru + Отображаемое имя роли + + + + + + +``` + +**UUID:** Сгенерируй через PowerShell: `[guid]::NewGuid().ToString()` + +**Namespace:** Минимальный набор — достаточно `xmlns`, `v8`, `xr`, `xs`, `xsi`. Полный набор из спецификации тоже корректен. + +### 2. Файл прав: `Roles//Ext/Rights.xml` + +```xml + + + false + true + false + + +``` + +### 3. Регистрация в Configuration.xml + +Добавь `ИмяРоли` в секцию `` файла `Configuration.xml`. + +## Формат блока прав + +Каждый объект — отдельный блок ``: + +```xml + + ТипОбъекта.ИмяОбъекта + + ИмяПрава + true + + +``` + +Несколько прав — несколько `` внутри одного ``. + +## Права по типам объектов (краткая справка) + +### Ссылочные объекты данных + +| Тип | Типичные права | +|-----|---------------| +| `Catalog` | Read, Insert, Update, Delete, View, Edit, InputByString, InteractiveInsert, InteractiveSetDeletionMark, InteractiveClearDeletionMark, InteractiveDelete | +| `Document` | (все Catalog) + Posting, UndoPosting, InteractivePosting, InteractivePostingRegular, InteractiveUndoPosting, InteractiveChangeOfPosted | +| `ChartOfAccounts` | (как Catalog) + предопределённые: InteractiveDeletePredefinedData и др. | +| `ChartOfCharacteristicTypes` | (как ChartOfAccounts) | +| `ChartOfCalculationTypes` | (как ChartOfAccounts) | +| `ExchangePlan` | (как Catalog) | +| `BusinessProcess` | (как Catalog) + Start, InteractiveStart, InteractiveActivate | +| `Task` | (как Catalog) + Execute, InteractiveExecute, InteractiveActivate | + +### Регистры + +| Тип | Права | +|-----|-------| +| `InformationRegister` | Read, Update, View, Edit, TotalsControl | +| `AccumulationRegister` | Read, Update, View, Edit, TotalsControl | +| `AccountingRegister` | Read, Update, View, Edit, TotalsControl | +| `CalculationRegister` | Read, View | + +### Простые типы + +| Тип | Права | +|-----|-------| +| `DataProcessor` | Use, View | +| `Report` | Use, View | +| `Constant` | Read, Update, View, Edit | +| `CommonForm` | View | +| `CommonCommand` | View | +| `Subsystem` | View | +| `DocumentJournal` | Read, View | +| `Sequence` | Read, Update | +| `SessionParameter` | Get, Set | +| `CommonAttribute` | View, Edit | +| `WebService` / `HTTPService` / `IntegrationService` | Use | + +### Вложенные объекты + +| Вложенный тип | Права | Пример | +|--------------|-------|--------| +| `*.StandardAttribute.*` | View, Edit | `Document.Реализация.StandardAttribute.Posted` | +| `*.Attribute.*` | View, Edit | `Catalog.Контрагенты.Attribute.ИНН` | +| `*.TabularSection.*` | View, Edit | `Document.Реализация.TabularSection.Товары` | +| `*Register.*.Dimension.*` | View, Edit | `InformationRegister.Цены.Dimension.Номенклатура` | +| `*Register.*.Resource.*` | View, Edit | `InformationRegister.Цены.Resource.Цена` | +| `*.Command.*` | View | `Catalog.Контрагенты.Command.Открыть` | + +### Configuration + +Права на конфигурацию в целом: `Configuration.ИмяКонфигурации` + +Ключевые: Administration, DataAdministration, ThinClient, WebClient, ThickClient, ExternalConnection, Output, SaveUserData, InteractiveOpenExtDataProcessors, InteractiveOpenExtReports + +## Типичные наборы прав + +### Чтение справочника + +```xml + + Catalog.Номенклатура + Readtrue + Viewtrue + InputByStringtrue + +``` + +### Полные права на документ + +```xml + + Document.РеализацияТоваровУслуг + Readtrue + Inserttrue + Updatetrue + Deletetrue + Postingtrue + UndoPostingtrue + Viewtrue + InteractiveInserttrue + Edittrue + InteractiveSetDeletionMarktrue + InteractiveClearDeletionMarktrue + InteractivePostingtrue + InteractivePostingRegulartrue + InteractiveUndoPostingtrue + InteractiveChangeOfPostedtrue + InputByStringtrue + +``` + +### Использование обработки + +```xml + + DataProcessor.ОбновлениеЦен + Usetrue + Viewtrue + +``` + +### Чтение/запись регистра + +```xml + + InformationRegister.ЦеныНоменклатуры + Readtrue + Updatetrue + Viewtrue + Edittrue + +``` + +## Полная спецификация + +См. [1c-role-spec.md](../../docs/1c-role-spec.md) — полный каталог прав, RLS, шаблоны ограничений, версии формата. diff --git a/.claude/skills/role-info/SKILL.md b/.claude/skills/role-info/SKILL.md new file mode 100644 index 00000000..9e3acfcd --- /dev/null +++ b/.claude/skills/role-info/SKILL.md @@ -0,0 +1,74 @@ +--- +name: role-info +description: Компактная сводка прав роли 1С из Rights.xml — объекты, права, RLS, шаблоны ограничений +argument-hint: +allowed-tools: + - Bash + - Read +--- + +# /role-info — анализ роли 1С + +Парсит `Rights.xml` роли и выдаёт компактную сводку: объекты сгруппированы по типу, показаны только разрешённые права. Сжатие: тысячи строк XML → 50–150 строк текста. + +## Использование + +``` +/role-info +``` + +**RightsPath** — путь к файлу `Rights.xml` роли (обычно `Roles/ИмяРоли/Ext/Rights.xml`). + +## Запуск скрипта + +```powershell +powershell.exe -File .claude\skills\role-info\scripts\role-info.ps1 -RightsPath -OutFile +``` + +### Параметры + +| Параметр | Обязательный | Описание | +|----------|:------------:|----------| +| `-RightsPath` | да | Путь к Rights.xml | +| `-ShowDenied` | нет | Показать запрещённые права (по умолчанию скрыты) | +| `-MaxPerGroup` | нет | Макс. объектов на группу (по умолчанию 20). `0` = без ограничений | +| `-OutFile` | нет | Записать результат в файл (UTF-8 BOM). Без этого — вывод в консоль | + +**Важно:** Всегда используй `-OutFile` и читай результат через Read tool. Прямой вывод в консоль через bash ломает кириллицу. + +## Формат вывода + +``` +=== Role: БазовыеПраваБП --- "Базовые права: Бухгалтерия предприятия" === + +Properties: setForNewObjects=false, setForAttributesByDefault=true, independentRightsOfChildObjects=false + +Allowed rights: + + Catalog (8): + Контрагенты: Read, View, InputByString + Банки: Read, View, InputByString + ... + + Document (12): + РеализацияТоваровУслуг: Read, View, Posting, InteractivePosting + ... + + InformationRegister (6): + ЦеныНоменклатуры: Read [RLS], Update + ... + +Denied: 18 rights (use -ShowDenied to list) + +RLS: 4 restrictions +Templates: ДляРегистра, ПоЗначениям + +--- +Total: 138 allowed, 18 denied +``` + +### Обозначения + +- `[RLS]` — право с ограничением на уровне записей (restrictionByCondition) +- `-View`, `-Edit` — запрещённые права (в секции Denied, при `-ShowDenied`) +- Вложенные объекты показываются с суффиксом: `Контрагенты.StandardAttribute.PredefinedDataName` diff --git a/.claude/skills/role-info/scripts/role-info.ps1 b/.claude/skills/role-info/scripts/role-info.ps1 new file mode 100644 index 00000000..86490178 --- /dev/null +++ b/.claude/skills/role-info/scripts/role-info.ps1 @@ -0,0 +1,231 @@ +param( + [Parameter(Mandatory=$true)][string]$RightsPath, + [switch]$ShowDenied, + [int]$MaxPerGroup = 20, + [string]$OutFile +) + +$ErrorActionPreference = 'Stop' + +# --- Output helper --- +$script:lines = @() +function Out([string]$text) { + if ($OutFile) { $script:lines += $text } + else { Write-Host $text } +} + +# --- Resolve paths --- +if (-not [System.IO.Path]::IsPathRooted($RightsPath)) { + $RightsPath = Join-Path (Get-Location).Path $RightsPath +} + +if (-not (Test-Path $RightsPath)) { + Out "[ERROR] File not found: $RightsPath" + exit 1 +} + +# --- Try to find metadata file for role name/synonym --- +$roleName = "" +$roleSynonym = "" +$extDir = Split-Path $RightsPath # .../Ext +$roleDir = Split-Path $extDir # .../RoleName +$rolesDir = Split-Path $roleDir # .../Roles +$roleFolderName = Split-Path $roleDir -Leaf +$metaPath = Join-Path $rolesDir "$roleFolderName.xml" + +if (Test-Path $metaPath) { + try { + [xml]$metaXml = Get-Content -Path $metaPath -Encoding UTF8 + $ns = New-Object System.Xml.XmlNamespaceManager($metaXml.NameTable) + $ns.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses") + $ns.AddNamespace("v8", "http://v8.1c.ru/8.1/data/core") + $nameNode = $metaXml.SelectSingleNode("//md:Role/md:Properties/md:Name", $ns) + if ($nameNode) { $roleName = $nameNode.InnerText } + $synNode = $metaXml.SelectSingleNode("//md:Role/md:Properties/md:Synonym/v8:item[v8:lang='ru']/v8:content", $ns) + if ($synNode) { $roleSynonym = $synNode.InnerText } + } catch { + # Ignore metadata parsing errors + } +} + +if (-not $roleName) { $roleName = $roleFolderName } + +# --- Parse Rights.xml --- +[xml]$xml = Get-Content -Path $RightsPath -Encoding UTF8 +$root = $xml.DocumentElement +$rightsNs = "http://v8.1c.ru/8.2/roles" + +# Global flags +$setForNew = $root.setForNewObjects +$setForAttrs = $root.setForAttributesByDefault +$independentChild = $root.independentRightsOfChildObjects + +# --- Collect objects --- +# Structure: grouped by type prefix, then by object short name +$allowed = [ordered]@{} # type -> [ordered]@{ shortName -> [list of rights] } +$denied = [ordered]@{} # type -> [ordered]@{ shortName -> [list of rights] } +$rlsObjects = @() +$totalAllowed = 0 +$totalDenied = 0 + +$objects = $root.GetElementsByTagName("object", $rightsNs) +foreach ($obj in $objects) { + $objName = "" + $rights = @() + + foreach ($child in $obj.ChildNodes) { + if ($child.LocalName -eq "name" -and $child.NamespaceURI -eq $rightsNs) { + $objName = $child.InnerText + } + if ($child.LocalName -eq "right" -and $child.NamespaceURI -eq $rightsNs) { + $rName = "" + $rValue = "" + $hasRLS = $false + foreach ($rc in $child.ChildNodes) { + if ($rc.LocalName -eq "name") { $rName = $rc.InnerText } + if ($rc.LocalName -eq "value") { $rValue = $rc.InnerText } + if ($rc.LocalName -eq "restrictionByCondition") { $hasRLS = $true } + } + if ($rName -and $rValue) { + $rights += @{ name = $rName; value = $rValue; rls = $hasRLS } + } + } + } + + if (-not $objName -or $rights.Count -eq 0) { continue } + + # Split into type prefix and short name + $dotIdx = $objName.IndexOf(".") + if ($dotIdx -lt 0) { continue } + $typePrefix = $objName.Substring(0, $dotIdx) + $shortName = $objName.Substring($dotIdx + 1) + + foreach ($r in $rights) { + if ($r.value -eq "true") { + $totalAllowed++ + if (-not $allowed.Contains($typePrefix)) { + $allowed[$typePrefix] = [ordered]@{} + } + if (-not $allowed[$typePrefix].Contains($shortName)) { + $allowed[$typePrefix][$shortName] = @() + } + $suffix = $r.name + if ($r.rls) { + $suffix += " [RLS]" + $rlsObjects += "$typePrefix.$shortName ($($r.name))" + } + $allowed[$typePrefix][$shortName] += $suffix + } + else { + $totalDenied++ + if (-not $denied.Contains($typePrefix)) { + $denied[$typePrefix] = [ordered]@{} + } + if (-not $denied[$typePrefix].Contains($shortName)) { + $denied[$typePrefix][$shortName] = @() + } + $denied[$typePrefix][$shortName] += $r.name + } + } +} + +# --- Restriction templates --- +$templates = @() +$tplNodes = $root.GetElementsByTagName("restrictionTemplate", $rightsNs) +foreach ($tpl in $tplNodes) { + foreach ($child in $tpl.ChildNodes) { + if ($child.LocalName -eq "name") { + $tName = $child.InnerText + # Extract just the name part before parentheses + $parenIdx = $tName.IndexOf("(") + if ($parenIdx -gt 0) { $tName = $tName.Substring(0, $parenIdx) } + $templates += $tName + } + } +} + +# --- Output --- +$header = "=== Role: $roleName" +if ($roleSynonym) { $header += " --- `"$roleSynonym`"" } +$header += " ===" +Out $header +Out "" + +Out "Properties: setForNewObjects=$setForNew, setForAttributesByDefault=$setForAttrs, independentRightsOfChildObjects=$independentChild" +Out "" + +# Helper: output group with truncation +function OutGroup($objMap, [string]$prefix, [switch]$isDenied) { + $keys = @($objMap.Keys) + $shown = 0 + foreach ($shortName in $keys) { + if ($MaxPerGroup -gt 0 -and $shown -ge $MaxPerGroup) { + $remaining = $keys.Count - $shown + Out " ... ещё $remaining (используй -MaxPerGroup 0 для полного списка)" + break + } + if ($isDenied) { + $rightsList = ($objMap[$shortName] | ForEach-Object { "-$_" }) -join ", " + } else { + $rightsList = $objMap[$shortName] -join ", " + } + Out " ${shortName}: $rightsList" + $shown++ + } +} + +# Allowed rights grouped by type +if ($allowed.Count -gt 0) { + Out "Allowed rights:" + Out "" + foreach ($typePrefix in $allowed.Keys) { + $objMap = $allowed[$typePrefix] + Out " $typePrefix ($($objMap.Count)):" + OutGroup $objMap $typePrefix + Out "" + } +} +else { + Out "(no allowed rights)" + Out "" +} + +# Denied rights +if ($ShowDenied -and $denied.Count -gt 0) { + Out "Denied rights:" + Out "" + foreach ($typePrefix in $denied.Keys) { + $objMap = $denied[$typePrefix] + Out " $typePrefix ($($objMap.Count)):" + OutGroup $objMap $typePrefix -isDenied + Out "" + } +} +elseif ($totalDenied -gt 0) { + Out "Denied: $totalDenied rights (use -ShowDenied to list)" + Out "" +} + +# RLS summary +if ($rlsObjects.Count -gt 0) { + Out "RLS: $($rlsObjects.Count) restrictions" +} + +# Templates +if ($templates.Count -gt 0) { + Out "Templates: $($templates -join ', ')" +} + +Out "" +Out "---" +Out "Total: $totalAllowed allowed, $totalDenied denied" + +# --- Write to file if requested --- +if ($OutFile) { + if (-not [System.IO.Path]::IsPathRooted($OutFile)) { + $OutFile = Join-Path (Get-Location).Path $OutFile + } + $utf8 = New-Object System.Text.UTF8Encoding($true) + [System.IO.File]::WriteAllLines($OutFile, $script:lines, $utf8) + Write-Host "Output written to $OutFile" +} From d27dfbf8e1fbcad38f7d5446d4d4f3e52c4cb60c Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 9 Feb 2026 21:22:14 +0300 Subject: [PATCH 3/5] Add role-guide.md and update README with role skills Co-Authored-By: Claude Opus 4.6 --- .claude/skills/role-compile/SKILL.md | 250 ++++++++-------- .claude/skills/role-info/SKILL.md | 12 +- .../skills/role-info/scripts/role-info.ps1 | 277 +++++++++--------- README.md | 11 +- docs/role-guide.md | 69 +++++ 5 files changed, 357 insertions(+), 262 deletions(-) create mode 100644 docs/role-guide.md diff --git a/.claude/skills/role-compile/SKILL.md b/.claude/skills/role-compile/SKILL.md index 41a069db..5df23c48 100644 --- a/.claude/skills/role-compile/SKILL.md +++ b/.claude/skills/role-compile/SKILL.md @@ -19,12 +19,22 @@ allowed-tools: /role-compile ``` -- **RoleName** — программное имя роли (например, `ВыполнениеРегламентныхЗаданий`) -- **RolesDir** — каталог `Roles/` в исходниках конфигурации или обработки +- **RoleName** — программное имя роли +- **RolesDir** — каталог `Roles/` в исходниках конфигурации -## Что создать +## Файловая структура и регистрация -### 1. Файл метаданных: `Roles/.xml` +``` +Roles/ + ИмяРоли.xml ← метаданные (uuid, имя, синоним) + ИмяРоли/ + Ext/ + Rights.xml ← определение прав +``` + +В `Configuration.xml` добавить `ИмяРоли` в секцию ``. + +## Шаблон метаданных: Roles/ИмяРоли.xml ```xml @@ -49,11 +59,9 @@ allowed-tools: ``` -**UUID:** Сгенерируй через PowerShell: `[guid]::NewGuid().ToString()` +**UUID:** `powershell.exe -Command "[guid]::NewGuid().ToString()"` -**Namespace:** Минимальный набор — достаточно `xmlns`, `v8`, `xr`, `xs`, `xsi`. Полный набор из спецификации тоже корректен. - -### 2. Файл прав: `Roles//Ext/Rights.xml` +## Шаблон прав: Roles/ИмяРоли/Ext/Rights.xml ```xml @@ -64,146 +72,136 @@ allowed-tools: false true false - + ``` -### 3. Регистрация в Configuration.xml - -Добавь `ИмяРоли` в секцию `` файла `Configuration.xml`. +NB: namespace `http://v8.1c.ru/8.2/roles` (исторически 8.2, не 8.3). ## Формат блока прав -Каждый объект — отдельный блок ``: - -```xml - - ТипОбъекта.ИмяОбъекта - - ИмяПрава - true - - -``` - -Несколько прав — несколько `` внутри одного ``. - -## Права по типам объектов (краткая справка) - -### Ссылочные объекты данных - -| Тип | Типичные права | -|-----|---------------| -| `Catalog` | Read, Insert, Update, Delete, View, Edit, InputByString, InteractiveInsert, InteractiveSetDeletionMark, InteractiveClearDeletionMark, InteractiveDelete | -| `Document` | (все Catalog) + Posting, UndoPosting, InteractivePosting, InteractivePostingRegular, InteractiveUndoPosting, InteractiveChangeOfPosted | -| `ChartOfAccounts` | (как Catalog) + предопределённые: InteractiveDeletePredefinedData и др. | -| `ChartOfCharacteristicTypes` | (как ChartOfAccounts) | -| `ChartOfCalculationTypes` | (как ChartOfAccounts) | -| `ExchangePlan` | (как Catalog) | -| `BusinessProcess` | (как Catalog) + Start, InteractiveStart, InteractiveActivate | -| `Task` | (как Catalog) + Execute, InteractiveExecute, InteractiveActivate | - -### Регистры - -| Тип | Права | -|-----|-------| -| `InformationRegister` | Read, Update, View, Edit, TotalsControl | -| `AccumulationRegister` | Read, Update, View, Edit, TotalsControl | -| `AccountingRegister` | Read, Update, View, Edit, TotalsControl | -| `CalculationRegister` | Read, View | - -### Простые типы - -| Тип | Права | -|-----|-------| -| `DataProcessor` | Use, View | -| `Report` | Use, View | -| `Constant` | Read, Update, View, Edit | -| `CommonForm` | View | -| `CommonCommand` | View | -| `Subsystem` | View | -| `DocumentJournal` | Read, View | -| `Sequence` | Read, Update | -| `SessionParameter` | Get, Set | -| `CommonAttribute` | View, Edit | -| `WebService` / `HTTPService` / `IntegrationService` | Use | - -### Вложенные объекты - -| Вложенный тип | Права | Пример | -|--------------|-------|--------| -| `*.StandardAttribute.*` | View, Edit | `Document.Реализация.StandardAttribute.Posted` | -| `*.Attribute.*` | View, Edit | `Catalog.Контрагенты.Attribute.ИНН` | -| `*.TabularSection.*` | View, Edit | `Document.Реализация.TabularSection.Товары` | -| `*Register.*.Dimension.*` | View, Edit | `InformationRegister.Цены.Dimension.Номенклатура` | -| `*Register.*.Resource.*` | View, Edit | `InformationRegister.Цены.Resource.Цена` | -| `*.Command.*` | View | `Catalog.Контрагенты.Command.Открыть` | - -### Configuration - -Права на конфигурацию в целом: `Configuration.ИмяКонфигурации` - -Ключевые: Administration, DataAdministration, ThinClient, WebClient, ThickClient, ExternalConnection, Output, SaveUserData, InteractiveOpenExtDataProcessors, InteractiveOpenExtReports - -## Типичные наборы прав - -### Чтение справочника - ```xml Catalog.Номенклатура Readtrue Viewtrue - InputByStringtrue ``` -### Полные права на документ +Имя объекта — dot-нотация: `ТипОбъекта.Имя[.ТипВложенного.ИмяВложенного]`. + +## Практические наборы прав + +### Catalog / ExchangePlan + +| Набор | Права | +|-------|-------| +| Чтение | Read, View, InputByString | +| Полные | Read, Insert, Update, Delete, View, Edit, InputByString, InteractiveInsert, InteractiveSetDeletionMark, InteractiveClearDeletionMark | + +### Document + +| Набор | Права | +|-------|-------| +| Чтение | Read, View, InputByString | +| Полные | Read, Insert, Update, Delete, View, Edit, InputByString, Posting, UndoPosting, InteractiveInsert, InteractiveSetDeletionMark, InteractiveClearDeletionMark, InteractivePosting, InteractivePostingRegular, InteractiveUndoPosting, InteractiveChangeOfPosted | + +### InformationRegister / AccumulationRegister / AccountingRegister + +| Набор | Права | +|-------|-------| +| Чтение | Read, View | +| Полные | Read, Update, View, Edit | + +TotalsControl — только для управления итогами, обычно не нужно. + +### Простые типы + +| Тип | Права | +|-----|-------| +| `DataProcessor` / `Report` | Use, View | +| `Constant` | Read, Update, View, Edit (чтение: Read, View) | +| `CommonForm` / `CommonCommand` / `Subsystem` / `FilterCriterion` | View | +| `DocumentJournal` | Read, View | +| `Sequence` | Read, Update | +| `SessionParameter` | Get (+ Set если пишет) | +| `CommonAttribute` | View (+ Edit если редактирует) | +| `WebService` / `HTTPService` / `IntegrationService` | Use | +| `CalculationRegister` | Read, View | + +### Редкие ссылочные типы + +| Тип | Особенности (относительно Catalog) | +|-----|-------| +| `ChartOfAccounts`, `ChartOfCharacteristicTypes`, `ChartOfCalculationTypes` | + Predefined-права (InteractiveDeletePredefinedData и др.) | +| `BusinessProcess` | + Start, InteractiveStart, InteractiveActivate | +| `Task` | + Execute, InteractiveExecute, InteractiveActivate | + +### Типы БЕЗ прав в ролях + +Enum, FunctionalOption, DefinedType, CommonModule, CommonPicture, CommonTemplate — не фигурируют в Rights.xml. + +### Вложенные объекты (права: View, Edit) + +``` +Catalog.Контрагенты.Attribute.ИНН +Document.Реализация.StandardAttribute.Posted +Document.Реализация.TabularSection.Товары +InformationRegister.Цены.Dimension.Номенклатура +InformationRegister.Цены.Resource.Цена +Catalog.Контрагенты.Command.ОткрытьКарточку ← только View +Task.Задача.AddressingAttribute.Исполнитель +``` + +Используются для точечного запрета: `false` на конкретный реквизит. + +### Configuration + +Объект: `Configuration.ИмяКонфигурации`. Ключевые права: Administration, DataAdministration, ThinClient, WebClient, ThickClient, MobileClient, ExternalConnection, Output, SaveUserData, InteractiveOpenExtDataProcessors, InteractiveOpenExtReports, MainWindowModeNormal, MainWindowModeWorkplace, MainWindowModeEmbeddedWorkplace, MainWindowModeFullscreenWorkplace, MainWindowModeKiosk, AnalyticsSystemClient. + +> DataHistory-права (ReadDataHistory, UpdateDataHistory и др.) существуют у Catalog, Document, Register, Constant — но используются крайне редко, в типовых ролях практически не встречаются. + +## RLS (ограничения на уровне записей) + +Внутрь ``, после ``. Применяется к Read, Update, Insert, Delete. + +```xml + + Read + true + + #ИмяШаблона("Параметр1", "Параметр2") + + +``` + +Шаблоны — в конце Rights.xml, после всех ``: + +```xml + + ИмяШаблона(Параметр1, Параметр2) + Текст шаблона + +``` + +`&` в условии → `&`. Типичные шаблоны: ДляОбъекта, ПоЗначениям, ДляРегистра. + +## Пример: роль для регламентного задания ```xml - Document.РеализацияТоваровУслуг + Catalog.Валюты Readtrue - Inserttrue - Updatetrue - Deletetrue - Postingtrue - UndoPostingtrue - Viewtrue - InteractiveInserttrue - Edittrue - InteractiveSetDeletionMarktrue - InteractiveClearDeletionMarktrue - InteractivePostingtrue - InteractivePostingRegulartrue - InteractiveUndoPostingtrue - InteractiveChangeOfPostedtrue - InputByStringtrue -``` - -### Использование обработки - -```xml - DataProcessor.ОбновлениеЦен - Usetrue - Viewtrue - -``` - -### Чтение/запись регистра - -```xml - - InformationRegister.ЦеныНоменклатуры + InformationRegister.КурсыВалют Readtrue Updatetrue - Viewtrue - Edittrue + + + Constant.ОсновнаяВалюта + Readtrue ``` -## Полная спецификация - -См. [1c-role-spec.md](../../docs/1c-role-spec.md) — полный каталог прав, RLS, шаблоны ограничений, версии формата. +Фоновые задания не требуют Interactive/View/Edit-прав и прав конфигурации (ThinClient, WebClient и др.) — только программные (Read, Insert, Update, Delete, Posting). diff --git a/.claude/skills/role-info/SKILL.md b/.claude/skills/role-info/SKILL.md index 9e3acfcd..98c38cc9 100644 --- a/.claude/skills/role-info/SKILL.md +++ b/.claude/skills/role-info/SKILL.md @@ -31,11 +31,17 @@ powershell.exe -File .claude\skills\role-info\scripts\role-info.ps1 -RightsPath |----------|:------------:|----------| | `-RightsPath` | да | Путь к Rights.xml | | `-ShowDenied` | нет | Показать запрещённые права (по умолчанию скрыты) | -| `-MaxPerGroup` | нет | Макс. объектов на группу (по умолчанию 20). `0` = без ограничений | +| `-Limit` | нет | Макс. строк вывода (по умолчанию `150`). `0` = без ограничений | +| `-Offset` | нет | Пропустить N строк — для пагинации (по умолчанию `0`) | | `-OutFile` | нет | Записать результат в файл (UTF-8 BOM). Без этого — вывод в консоль | **Важно:** Всегда используй `-OutFile` и читай результат через Read tool. Прямой вывод в консоль через bash ломает кириллицу. +Для большой роли при усечении вывода: +```powershell +... -Offset 150 # пагинация: пропустить первые 150 строк +``` + ## Формат вывода ``` @@ -65,8 +71,12 @@ Templates: ДляРегистра, ПоЗначениям --- Total: 138 allowed, 18 denied + +[TRUNCATED] Shown 150 of 220 lines. Use -Offset 150 to continue. ``` +Используйте `-Offset N` и `-Limit N` для постраничного просмотра. + ### Обозначения - `[RLS]` — право с ограничением на уровне записей (restrictionByCondition) diff --git a/.claude/skills/role-info/scripts/role-info.ps1 b/.claude/skills/role-info/scripts/role-info.ps1 index 86490178..4c93908c 100644 --- a/.claude/skills/role-info/scripts/role-info.ps1 +++ b/.claude/skills/role-info/scripts/role-info.ps1 @@ -1,27 +1,25 @@ param( - [Parameter(Mandatory=$true)][string]$RightsPath, - [switch]$ShowDenied, - [int]$MaxPerGroup = 20, - [string]$OutFile + [Parameter(Mandatory=$true)][string]$RightsPath, + [switch]$ShowDenied, + [int]$Limit = 150, + [int]$Offset = 0, + [string]$OutFile ) $ErrorActionPreference = 'Stop' -# --- Output helper --- +# --- Output helper (always collect, paginate at the end) --- $script:lines = @() -function Out([string]$text) { - if ($OutFile) { $script:lines += $text } - else { Write-Host $text } -} +function Out([string]$text) { $script:lines += $text } # --- Resolve paths --- if (-not [System.IO.Path]::IsPathRooted($RightsPath)) { - $RightsPath = Join-Path (Get-Location).Path $RightsPath + $RightsPath = Join-Path (Get-Location).Path $RightsPath } if (-not (Test-Path $RightsPath)) { - Out "[ERROR] File not found: $RightsPath" - exit 1 + Write-Host "[ERROR] File not found: $RightsPath" + exit 1 } # --- Try to find metadata file for role name/synonym --- @@ -34,18 +32,18 @@ $roleFolderName = Split-Path $roleDir -Leaf $metaPath = Join-Path $rolesDir "$roleFolderName.xml" if (Test-Path $metaPath) { - try { - [xml]$metaXml = Get-Content -Path $metaPath -Encoding UTF8 - $ns = New-Object System.Xml.XmlNamespaceManager($metaXml.NameTable) - $ns.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses") - $ns.AddNamespace("v8", "http://v8.1c.ru/8.1/data/core") - $nameNode = $metaXml.SelectSingleNode("//md:Role/md:Properties/md:Name", $ns) - if ($nameNode) { $roleName = $nameNode.InnerText } - $synNode = $metaXml.SelectSingleNode("//md:Role/md:Properties/md:Synonym/v8:item[v8:lang='ru']/v8:content", $ns) - if ($synNode) { $roleSynonym = $synNode.InnerText } - } catch { - # Ignore metadata parsing errors - } + try { + [xml]$metaXml = Get-Content -Path $metaPath -Encoding UTF8 + $ns = New-Object System.Xml.XmlNamespaceManager($metaXml.NameTable) + $ns.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses") + $ns.AddNamespace("v8", "http://v8.1c.ru/8.1/data/core") + $nameNode = $metaXml.SelectSingleNode("//md:Role/md:Properties/md:Name", $ns) + if ($nameNode) { $roleName = $nameNode.InnerText } + $synNode = $metaXml.SelectSingleNode("//md:Role/md:Properties/md:Synonym/v8:item[v8:lang='ru']/v8:content", $ns) + if ($synNode) { $roleSynonym = $synNode.InnerText } + } catch { + # Ignore metadata parsing errors + } } if (-not $roleName) { $roleName = $roleFolderName } @@ -70,78 +68,78 @@ $totalDenied = 0 $objects = $root.GetElementsByTagName("object", $rightsNs) foreach ($obj in $objects) { - $objName = "" - $rights = @() + $objName = "" + $rights = @() - foreach ($child in $obj.ChildNodes) { - if ($child.LocalName -eq "name" -and $child.NamespaceURI -eq $rightsNs) { - $objName = $child.InnerText - } - if ($child.LocalName -eq "right" -and $child.NamespaceURI -eq $rightsNs) { - $rName = "" - $rValue = "" - $hasRLS = $false - foreach ($rc in $child.ChildNodes) { - if ($rc.LocalName -eq "name") { $rName = $rc.InnerText } - if ($rc.LocalName -eq "value") { $rValue = $rc.InnerText } - if ($rc.LocalName -eq "restrictionByCondition") { $hasRLS = $true } - } - if ($rName -and $rValue) { - $rights += @{ name = $rName; value = $rValue; rls = $hasRLS } - } - } - } + foreach ($child in $obj.ChildNodes) { + if ($child.LocalName -eq "name" -and $child.NamespaceURI -eq $rightsNs) { + $objName = $child.InnerText + } + if ($child.LocalName -eq "right" -and $child.NamespaceURI -eq $rightsNs) { + $rName = "" + $rValue = "" + $hasRLS = $false + foreach ($rc in $child.ChildNodes) { + if ($rc.LocalName -eq "name") { $rName = $rc.InnerText } + if ($rc.LocalName -eq "value") { $rValue = $rc.InnerText } + if ($rc.LocalName -eq "restrictionByCondition") { $hasRLS = $true } + } + if ($rName -and $rValue) { + $rights += @{ name = $rName; value = $rValue; rls = $hasRLS } + } + } + } - if (-not $objName -or $rights.Count -eq 0) { continue } + if (-not $objName -or $rights.Count -eq 0) { continue } - # Split into type prefix and short name - $dotIdx = $objName.IndexOf(".") - if ($dotIdx -lt 0) { continue } - $typePrefix = $objName.Substring(0, $dotIdx) - $shortName = $objName.Substring($dotIdx + 1) + # Split into type prefix and short name + $dotIdx = $objName.IndexOf(".") + if ($dotIdx -lt 0) { continue } + $typePrefix = $objName.Substring(0, $dotIdx) + $shortName = $objName.Substring($dotIdx + 1) - foreach ($r in $rights) { - if ($r.value -eq "true") { - $totalAllowed++ - if (-not $allowed.Contains($typePrefix)) { - $allowed[$typePrefix] = [ordered]@{} - } - if (-not $allowed[$typePrefix].Contains($shortName)) { - $allowed[$typePrefix][$shortName] = @() - } - $suffix = $r.name - if ($r.rls) { - $suffix += " [RLS]" - $rlsObjects += "$typePrefix.$shortName ($($r.name))" - } - $allowed[$typePrefix][$shortName] += $suffix - } - else { - $totalDenied++ - if (-not $denied.Contains($typePrefix)) { - $denied[$typePrefix] = [ordered]@{} - } - if (-not $denied[$typePrefix].Contains($shortName)) { - $denied[$typePrefix][$shortName] = @() - } - $denied[$typePrefix][$shortName] += $r.name - } - } + foreach ($r in $rights) { + if ($r.value -eq "true") { + $totalAllowed++ + if (-not $allowed.Contains($typePrefix)) { + $allowed[$typePrefix] = [ordered]@{} + } + if (-not $allowed[$typePrefix].Contains($shortName)) { + $allowed[$typePrefix][$shortName] = @() + } + $suffix = $r.name + if ($r.rls) { + $suffix += " [RLS]" + $rlsObjects += "$typePrefix.$shortName ($($r.name))" + } + $allowed[$typePrefix][$shortName] += $suffix + } + else { + $totalDenied++ + if (-not $denied.Contains($typePrefix)) { + $denied[$typePrefix] = [ordered]@{} + } + if (-not $denied[$typePrefix].Contains($shortName)) { + $denied[$typePrefix][$shortName] = @() + } + $denied[$typePrefix][$shortName] += $r.name + } + } } # --- Restriction templates --- $templates = @() $tplNodes = $root.GetElementsByTagName("restrictionTemplate", $rightsNs) foreach ($tpl in $tplNodes) { - foreach ($child in $tpl.ChildNodes) { - if ($child.LocalName -eq "name") { - $tName = $child.InnerText - # Extract just the name part before parentheses - $parenIdx = $tName.IndexOf("(") - if ($parenIdx -gt 0) { $tName = $tName.Substring(0, $parenIdx) } - $templates += $tName - } - } + foreach ($child in $tpl.ChildNodes) { + if ($child.LocalName -eq "name") { + $tName = $child.InnerText + # Extract just the name part before parentheses + $parenIdx = $tName.IndexOf("(") + if ($parenIdx -gt 0) { $tName = $tName.Substring(0, $parenIdx) } + $templates += $tName + } + } } # --- Output --- @@ -154,78 +152,91 @@ Out "" Out "Properties: setForNewObjects=$setForNew, setForAttributesByDefault=$setForAttrs, independentRightsOfChildObjects=$independentChild" Out "" -# Helper: output group with truncation +# Helper: output group function OutGroup($objMap, [string]$prefix, [switch]$isDenied) { - $keys = @($objMap.Keys) - $shown = 0 - foreach ($shortName in $keys) { - if ($MaxPerGroup -gt 0 -and $shown -ge $MaxPerGroup) { - $remaining = $keys.Count - $shown - Out " ... ещё $remaining (используй -MaxPerGroup 0 для полного списка)" - break - } - if ($isDenied) { - $rightsList = ($objMap[$shortName] | ForEach-Object { "-$_" }) -join ", " - } else { - $rightsList = $objMap[$shortName] -join ", " - } - Out " ${shortName}: $rightsList" - $shown++ - } + foreach ($shortName in @($objMap.Keys)) { + if ($isDenied) { + $rightsList = ($objMap[$shortName] | ForEach-Object { "-$_" }) -join ", " + } else { + $rightsList = $objMap[$shortName] -join ", " + } + Out " ${shortName}: $rightsList" + } } # Allowed rights grouped by type if ($allowed.Count -gt 0) { - Out "Allowed rights:" - Out "" - foreach ($typePrefix in $allowed.Keys) { - $objMap = $allowed[$typePrefix] - Out " $typePrefix ($($objMap.Count)):" - OutGroup $objMap $typePrefix - Out "" - } + Out "Allowed rights:" + Out "" + foreach ($typePrefix in $allowed.Keys) { + $objMap = $allowed[$typePrefix] + Out " $typePrefix ($($objMap.Count)):" + OutGroup $objMap $typePrefix + Out "" + } } else { - Out "(no allowed rights)" - Out "" + Out "(no allowed rights)" + Out "" } # Denied rights if ($ShowDenied -and $denied.Count -gt 0) { - Out "Denied rights:" - Out "" - foreach ($typePrefix in $denied.Keys) { - $objMap = $denied[$typePrefix] - Out " $typePrefix ($($objMap.Count)):" - OutGroup $objMap $typePrefix -isDenied - Out "" - } + Out "Denied rights:" + Out "" + foreach ($typePrefix in $denied.Keys) { + $objMap = $denied[$typePrefix] + Out " $typePrefix ($($objMap.Count)):" + OutGroup $objMap $typePrefix -isDenied + Out "" + } } elseif ($totalDenied -gt 0) { - Out "Denied: $totalDenied rights (use -ShowDenied to list)" - Out "" + Out "Denied: $totalDenied rights (use -ShowDenied to list)" + Out "" } # RLS summary if ($rlsObjects.Count -gt 0) { - Out "RLS: $($rlsObjects.Count) restrictions" + Out "RLS: $($rlsObjects.Count) restrictions" } # Templates if ($templates.Count -gt 0) { - Out "Templates: $($templates -join ', ')" + Out "Templates: $($templates -join ', ')" } Out "" Out "---" Out "Total: $totalAllowed allowed, $totalDenied denied" -# --- Write to file if requested --- -if ($OutFile) { - if (-not [System.IO.Path]::IsPathRooted($OutFile)) { - $OutFile = Join-Path (Get-Location).Path $OutFile - } - $utf8 = New-Object System.Text.UTF8Encoding($true) - [System.IO.File]::WriteAllLines($OutFile, $script:lines, $utf8) - Write-Host "Output written to $OutFile" +# --- Pagination and output --- +$totalLines = $script:lines.Count +$lines = $script:lines + +if ($Offset -gt 0) { + if ($Offset -ge $totalLines) { + Write-Host "[INFO] Offset $Offset exceeds total lines ($totalLines). Nothing to show." + exit 0 + } + $lines = $lines[$Offset..($totalLines - 1)] +} + +if ($Limit -gt 0 -and $lines.Count -gt $Limit) { + $shown = $lines[0..($Limit - 1)] + $remaining = $totalLines - $Offset - $Limit + $shown += "" + $shown += "[TRUNCATED] Shown $Limit of $totalLines lines. Use -Offset $($Offset + $Limit) to continue." + $lines = $shown +} + +if ($OutFile) { + if (-not [System.IO.Path]::IsPathRooted($OutFile)) { + $OutFile = Join-Path (Get-Location).Path $OutFile + } + $utf8 = New-Object System.Text.UTF8Encoding($true) + [System.IO.File]::WriteAllLines($OutFile, $lines, $utf8) + Write-Host "Output written to $OutFile" +} else { + foreach ($l in $lines) { Write-Host $l } } diff --git a/README.md b/README.md index 2cb9d208..4a788d95 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,8 @@ |--------|--------|----------|------| | Внешние обработки (EPF) | 10 навыков `/epf-*` | Создание, модификация, сборка обработок из XML-исходников | [Подробнее](docs/epf-guide.md) | | Табличный документ (MXL) | 4 навыка `/mxl-*` | Анализ, создание, компиляция макетов печатных форм | [Подробнее](docs/mxl-guide.md) | -| Управляемые формы (Form) | 4 навыка `/form-*` | Анализ, генерация, модификация, валидация управляемых форм | [Подробнее](docs/form-guide.md) | +| Управляемые формы (Form) | 5 навыков `/form-*` | Анализ, генерация, модификация, валидация управляемых форм | [Подробнее](docs/form-guide.md) | +| Роли (Role) | 2 навыка `/role-*` | Анализ прав роли, создание роли из описания | [Подробнее](docs/role-guide.md) | | Утилиты | `/img-grid` | Наложение сетки на изображение для определения пропорций колонок | — | ## Требования @@ -38,6 +39,7 @@ - [Табличный документ (MXL)](docs/1c-spreadsheet-spec.md) — XML-формат SpreadsheetDocument, совместимость версий - [MXL DSL](docs/mxl-dsl-spec.md) — JSON-формат описания макета для `/mxl-compile` и `/mxl-decompile` - [Form DSL](docs/form-dsl-spec.md) — JSON-формат описания формы для `/form-compile` +- [Роли (Rights.xml)](docs/1c-role-spec.md) — XML-формат прав роли, типы объектов, RLS ## Структура репозитория @@ -61,16 +63,21 @@ ├── form-compile/ # Компиляция формы из JSON ├── form-validate/ # Валидация формы ├── form-add/ # Добавление элементов в форму +├── form-patterns/ # Справочник паттернов компоновки форм +├── role-info/ # Анализ прав роли +├── role-compile/ # Создание роли из описания └── img-grid/ # Сетка для анализа изображений docs/ ├── epf-guide.md # Гайд: внешние обработки ├── mxl-guide.md # Гайд: табличный документ ├── form-guide.md # Гайд: управляемые формы +├── role-guide.md # Гайд: роли ├── 1c-xml-format-spec.md # Спецификация XML-формата ├── 1c-form-spec.md # Спецификация управляемых форм ├── 1c-help-spec.md # Спецификация встроенной справки ├── build-spec.md # Спецификация сборки/разборки ├── 1c-spreadsheet-spec.md # Спецификация табличного документа ├── mxl-dsl-spec.md # Спецификация MXL DSL -└── form-dsl-spec.md # Спецификация Form DSL +├── form-dsl-spec.md # Спецификация Form DSL +└── 1c-role-spec.md # Спецификация ролей (Rights.xml) ``` diff --git a/docs/role-guide.md b/docs/role-guide.md new file mode 100644 index 00000000..ff40e964 --- /dev/null +++ b/docs/role-guide.md @@ -0,0 +1,69 @@ +# Роли (Role) + +Навыки группы `/role-*` позволяют анализировать и создавать роли 1С — XML-файлы прав доступа (Rights.xml) и метаданных. + +## Навыки + +| Навык | Параметры | Описание | +|-------|-----------|----------| +| `/role-info` | `` | Компактная сводка прав: объекты по типам, только разрешённые, RLS, шаблоны | +| `/role-compile` | ` ` | Создание роли: метаданные + Rights.xml по описанию прав | + +## Сценарии использования + +### Анализ существующей роли + +``` +> Проанализируй права роли Roles/БазовыеПраваБП/Ext/Rights.xml +``` + +Claude вызовет `/role-info`, получит компактную сводку (тысячи строк XML → 50–300 строк текста) и опишет: +- какие объекты доступны и с какими правами +- где есть ограничения RLS +- какие шаблоны ограничений используются + +### Создание роли для регламентного задания + +``` +> Проанализируй модуль регламентного задания ОбновлениеКурсовВалют +> и создай роль с минимальными правами для его выполнения +``` + +Claude проанализирует код, определит используемые объекты метаданных, и вызовет `/role-compile` для создания роли с нужными правами (Read, Update, Posting и т.д.). + +### Создание роли по описанию + +``` +> Создай роль МенеджерПродаж с правами: +> - Документ РеализацияТоваровУслуг: полные права +> - Справочник Контрагенты: чтение +> - Справочник Номенклатура: чтение +> - Регистр ЦеныНоменклатуры: чтение +``` + +Рабочий цикл: +1. Claude генерирует `Roles/МенеджерПродаж.xml` (метаданные с UUID) +2. Claude генерирует `Roles/МенеджерПродаж/Ext/Rights.xml` (права) +3. Регистрирует роль в `Configuration.xml` (``) +4. Проверяет результат через `/role-info` + +## Структура файлов роли + +``` +Roles/ +├── ИмяРоли.xml # Метаданные (UUID, синоним) +└── ИмяРоли/ + └── Ext/ + └── Rights.xml # Права доступа +``` + +Регистрация в `Configuration.xml`: +```xml + + ИмяРоли + +``` + +## Спецификация + +Полная спецификация формата: [1c-role-spec.md](1c-role-spec.md) — типы объектов, права, RLS, шаблоны ограничений, версии формата. From 89f0788585ac7aa4bb4ead3b1e55a71b42436969 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 9 Feb 2026 22:05:33 +0300 Subject: [PATCH 4/5] Rename form-add to form-edit for clarity The skill modifies existing forms (adds elements/attributes/commands), not creates new ones. "form-edit" better reflects its purpose. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/{form-add => form-edit}/SKILL.md | 12 ++++++------ .../form-add.ps1 => form-edit/scripts/form-edit.ps1} | 2 +- README.md | 2 +- docs/form-guide.md | 12 ++++++------ 4 files changed, 14 insertions(+), 14 deletions(-) rename .claude/skills/{form-add => form-edit}/SKILL.md (91%) rename .claude/skills/{form-add/scripts/form-add.ps1 => form-edit/scripts/form-edit.ps1} (97%) diff --git a/.claude/skills/form-add/SKILL.md b/.claude/skills/form-edit/SKILL.md similarity index 91% rename from .claude/skills/form-add/SKILL.md rename to .claude/skills/form-edit/SKILL.md index 9b93eb05..ab9f0a4c 100644 --- a/.claude/skills/form-add/SKILL.md +++ b/.claude/skills/form-edit/SKILL.md @@ -1,5 +1,5 @@ --- -name: form-add +name: form-edit description: Добавление элементов, реквизитов и команд в существующую управляемую форму 1С (Form.xml) argument-hint: allowed-tools: @@ -9,14 +9,14 @@ allowed-tools: - Glob --- -# /form-add — Добавление в форму +# /form-edit — Редактирование формы Добавляет элементы, реквизиты и/или команды в существующий Form.xml. Автоматически выделяет ID из правильного пула, генерирует companion-элементы (ContextMenu, ExtendedTooltip, и др.) и обработчики событий. ## Использование ``` -/form-add +/form-edit ``` ## Параметры @@ -29,7 +29,7 @@ allowed-tools: ## Команда ```powershell -powershell.exe -NoProfile -File .claude\skills\form-add\scripts\form-add.ps1 -FormPath "<путь>" -JsonPath "<путь>" +powershell.exe -NoProfile -File .claude\skills\form-edit\scripts\form-edit.ps1 -FormPath "<путь>" -JsonPath "<путь>" ``` ## JSON формат @@ -99,7 +99,7 @@ powershell.exe -NoProfile -File .claude\skills\form-add\scripts\form-add.ps1 -Fo ## Вывод ``` -=== form-add: Форма === +=== form-edit: Форма === Added elements (into ГруппаШапка, after Контрагент): + [Input] Склад -> Объект.Склад {OnChange} @@ -122,6 +122,6 @@ Run /form-validate to verify. 1. `/form-info` — посмотреть текущую структуру формы 2. Создать JSON с описанием добавлений -3. `/form-add` — добавить в форму +3. `/form-edit` — добавить в форму 4. `/form-validate` — проверить корректность 5. `/form-info` — убедиться что добавилось правильно diff --git a/.claude/skills/form-add/scripts/form-add.ps1 b/.claude/skills/form-edit/scripts/form-edit.ps1 similarity index 97% rename from .claude/skills/form-add/scripts/form-add.ps1 rename to .claude/skills/form-edit/scripts/form-edit.ps1 index 9f8cc0b6..ebc4366f 100644 --- a/.claude/skills/form-add/scripts/form-add.ps1 +++ b/.claude/skills/form-edit/scripts/form-edit.ps1 @@ -54,7 +54,7 @@ if ($parentDir) { } } -Write-Host "=== form-add: $formName ===" +Write-Host "=== form-edit: $formName ===" Write-Host "" # === 4. Scan max IDs per pool === diff --git a/README.md b/README.md index 4a788d95..f2486658 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ ├── form-info/ # Анализ структуры управляемой формы ├── form-compile/ # Компиляция формы из JSON ├── form-validate/ # Валидация формы -├── form-add/ # Добавление элементов в форму +├── form-edit/ # Добавление элементов в форму ├── form-patterns/ # Справочник паттернов компоновки форм ├── role-info/ # Анализ прав роли ├── role-compile/ # Создание роли из описания diff --git a/docs/form-guide.md b/docs/form-guide.md index 4c3b7124..64efa2f6 100644 --- a/docs/form-guide.md +++ b/docs/form-guide.md @@ -9,7 +9,7 @@ | `/form-info` | `` | Компактная сводка: дерево элементов, реквизиты, команды, события | | `/form-compile` | ` ` | Генерация Form.xml из компактного JSON-определения | | `/form-validate` | `` | Валидация: уникальность ID, companions, DataPath, команды | -| `/form-add` | ` ` | Добавление элементов, реквизитов, команд в существующую форму | +| `/form-edit` | ` ` | Добавление элементов, реквизитов, команд в существующую форму | | `/form-patterns` | (без параметров) | Справочник паттернов: архетипы, конвенции именования, продвинутые приёмы | ## Сценарии использования @@ -55,13 +55,13 @@ Commands: ### Добавление элементов в существующую форму -`/form-add` добавляет элементы, реквизиты и команды в существующий Form.xml. Автоматически назначает ID, генерирует companion-элементы и обработчики событий. +`/form-edit` добавляет элементы, реквизиты и команды в существующий Form.xml. Автоматически назначает ID, генерирует companion-элементы и обработчики событий. ``` > Добавь поле "Склад" в шапку формы после "Контрагент" ``` -Claude вызовет `/form-info` для анализа структуры, создаст JSON и вызовет `/form-add`: +Claude вызовет `/form-info` для анализа структуры, создаст JSON и вызовет `/form-edit`: ```json { @@ -193,7 +193,7 @@ Claude создаст JSON-определение и вызовет `/form-compi > /form-info upload/acc_8.3.24/Documents/РеализацияТоваровУслуг/Forms/ФормаДокумента/Ext/Form.xml > /form-info src/МояОбработка/Forms/Форма/Ext/Form.xml > /form-compile src/form.json src/МояОбработка/Forms/Форма/Ext/Form.xml -> /form-add src/МояОбработка/Forms/Форма/Ext/Form.xml src/additions.json +> /form-edit src/МояОбработка/Forms/Форма/Ext/Form.xml src/additions.json > /form-validate src/МояОбработка/Forms/Форма/Ext/Form.xml ``` @@ -203,7 +203,7 @@ Claude создаст JSON-определение и вызовет `/form-compi 1. `/epf-add-form` — создать форму (каркас) 2. `/form-compile` — сгенерировать Form.xml из JSON-определения -3. `/form-add` — добавить элементы/реквизиты/команды в существующую форму +3. `/form-edit` — добавить элементы/реквизиты/команды в существующую форму 4. `/form-validate` — проверить корректность 5. `/form-info` — проанализировать результат 6. `/epf-build` — собрать EPF @@ -211,5 +211,5 @@ Claude создаст JSON-определение и вызовет `/form-compi ## Спецификации - [Управляемая форма](1c-form-spec.md) — Form.xml, элементы, команды, реквизиты, система типов -- [Form DSL](form-dsl-spec.md) — JSON-формат описания формы для `/form-compile` и `/form-add` +- [Form DSL](form-dsl-spec.md) — JSON-формат описания формы для `/form-compile` и `/form-edit` - [Паттерны компоновки](form-patterns.md) — типовые архетипы форм, конвенции именования, примеры DSL From 6681758121b11e5b8d0d5fee87468a7bb7a44ef4 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 9 Feb 2026 22:53:13 +0300 Subject: [PATCH 5/5] Add /form-add skill for configuration objects Create forms (metadata XML + Form.xml + Module.bsl) for Document, Catalog, InformationRegister and other configuration object types. Supports Object/List/Choice/Record purposes with automatic ChildObjects registration and DefaultForm setup. Co-Authored-By: Claude Opus 4.6 --- .claude/skills/form-add/SKILL.md | 91 ++++ .claude/skills/form-add/scripts/form-add.ps1 | 435 +++++++++++++++++++ README.md | 3 +- docs/1c-form-spec.md | 151 +++++++ docs/form-guide.md | 29 +- 5 files changed, 707 insertions(+), 2 deletions(-) create mode 100644 .claude/skills/form-add/SKILL.md create mode 100644 .claude/skills/form-add/scripts/form-add.ps1 diff --git a/.claude/skills/form-add/SKILL.md b/.claude/skills/form-add/SKILL.md new file mode 100644 index 00000000..af103fec --- /dev/null +++ b/.claude/skills/form-add/SKILL.md @@ -0,0 +1,91 @@ +--- +name: form-add +description: Добавить управляемую форму к объекту конфигурации 1С +argument-hint: [Purpose] [--set-default] +allowed-tools: + - Bash + - Read + - Write + - Edit + - Glob + - Grep +--- + +# /form-add — Добавление формы к объекту конфигурации + +Создаёт управляемую форму (metadata XML + Form.xml + Module.bsl) и регистрирует её в корневом XML объекта конфигурации (Document, Catalog, InformationRegister и др.). + +## Usage + +``` +/form-add [Purpose] [Synonym] [--set-default] +``` + +| Параметр | Обязательный | По умолчанию | Описание | +|-------------|:------------:|--------------|----------------------------------------------| +| ObjectPath | да | — | Путь к XML-файлу объекта (Documents/Док.xml) | +| FormName | да | — | Имя формы (ФормаДокумента) | +| Purpose | нет | Object | Назначение: Object, List, Choice, Record | +| Synonym | нет | = FormName | Синоним формы | +| --set-default | нет | авто | Установить как форму по умолчанию | + +## Команда + +```powershell +powershell.exe -NoProfile -File .claude\skills\form-add\scripts\form-add.ps1 -ObjectPath "" -FormName "" [-Purpose ""] [-Synonym ""] [-SetDefault] +``` + +## Purpose — назначение формы + +| Purpose | Допустимые типы объектов | Основной реквизит | DefaultForm-свойство | +|---------|-------------------------|-------------------|---------------------| +| Object | Document, Catalog, DataProcessor, Report, ChartOf*, ExchangePlan, BusinessProcess, Task | Объект (тип: *Object.Имя) | DefaultObjectForm (DefaultForm для DataProcessor/Report) | +| List | Все кроме DataProcessor | Список (DynamicList) | DefaultListForm | +| Choice | Document, Catalog, ChartOf*, ExchangePlan, BusinessProcess, Task | Список (DynamicList) | DefaultChoiceForm | +| Record | InformationRegister | Запись (InformationRegisterRecordManager) | DefaultRecordForm | + +## Что создаётся + +``` +/Forms/ +├── .xml # Метаданные формы (UUID) +└── / + └── Ext/ + ├── Form.xml # Описание формы (logform namespace) + └── Form/ + └── Module.bsl # BSL-модуль с 5 регионами + ПриСозданииНаСервере +``` + +## Что модифицируется + +- `` — добавляется `
` в `ChildObjects` (перед `