From bdc38caffa8434d111173d3de82a2e92012b1801 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 25 Apr 2026 15:26:54 +0300 Subject: [PATCH] =?UTF-8?q?refactor(form-add):=20=D0=BE=D0=B1=D1=8A=D0=B5?= =?UTF-8?q?=D0=B4=D0=B8=D0=BD=D0=B8=D1=82=D1=8C=20=D1=81=20epf-add-form,?= =?UTF-8?q?=20=D1=83=D0=B4=D0=B0=D0=BB=D0=B8=D1=82=D1=8C=20=D1=81=D0=BF?= =?UTF-8?q?=D0=B5=D1=86=D0=B8=D1=84=D0=B8=D1=87=D0=BD=D1=8B=D0=B9=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B2=D1=8B=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit form-add теперь покрывает и объекты конфигурации, и standalone EPF/ERF source tree (тип определяется из корневого XML, маппинг типов уже был). Изменения form-add scaffold: - Module.bsl: пустые регионы вместо скелета процедуры ПриСозданииНаСервере - Form.xml: убран (раньше привязывал OnCreateAtServer к процедуре) - Form.xml: true теперь условный — ставится для Catalog/Document/etc (стандарт ERP, 99% форм), не ставится для DataProcessor/Report/External* (где у объекта нет состояния) Это согласуется с workflow: form-compile перегенерирует Form.xml целиком, поэтому привязки в scaffold могут стать orphan; пустые регионы + без Events — корректная стартовая точка, которую form-edit/form-compile наполняют атомарно. Удалён навык epf-add-form (директория + тесты), вызовы заменены на form-add в integration-тестах, в кейсах epf-validate/help-add, в description epf-init/epf-bsp-init, в docs и README. Перегенерированы snapshot'ы 5 навыков (form-add, form-compile, form-edit, form-info, form-validate). Платформенная верификация в 1С 8.3.24 прошла для всех 9 кейсов form-add. Bump form-add v1.3 → v1.4. --- .claude/skills/epf-add-form/SKILL.md | 60 ---- .../skills/epf-add-form/scripts/add-form.ps1 | 226 --------------- .../skills/epf-add-form/scripts/add-form.py | 272 ------------------ .claude/skills/epf-bsp-init/SKILL.md | 2 +- .claude/skills/epf-init/SKILL.md | 2 +- .claude/skills/form-add/SKILL.md | 2 +- .claude/skills/form-add/scripts/form-add.ps1 | 25 +- .claude/skills/form-add/scripts/form-add.py | 23 +- README.md | 1 - docs/epf-guide.md | 7 +- docs/form-guide.md | 2 +- tests/skills/cases/epf-add-form/_skill.json | 14 - tests/skills/cases/epf-add-form/basic.json | 11 - .../skills/cases/epf-add-form/main-form.json | 16 -- .../skills/cases/epf-add-form/named-form.json | 11 - .../cases/epf-add-form/second-form.json | 15 - .../cases/epf-validate/valid-with-form.json | 4 +- tests/skills/cases/form-add/epf-basic.json | 12 + .../skills/cases/form-add/epf-named-form.json | 12 + .../cases/form-add/epf-second-form.json | 16 ++ .../cases/form-add/epf-set-default.json | 17 ++ .../Товары/Forms/ФормаЭлемента/Ext/Form.xml | 3 - .../Forms/ФормаЭлемента/Ext/Form/Module.bsl | 5 - .../МояОбработка/Forms/Форма/Ext/Form.xml | 4 - .../Forms/Форма/Ext/Form/Module.bsl | 5 - .../Заказ/Forms/ФормаДокумента/Ext/Form.xml | 3 - .../Forms/ФормаДокумента/Ext/Form/Module.bsl | 5 - .../snapshots/epf-basic}/МояОбработка.xml | 0 .../МояОбработка/Ext/ObjectModule.bsl | 0 .../epf-basic}/МояОбработка/Forms/Форма.xml | 0 .../МояОбработка/Forms/Форма/Ext/Form.xml | 0 .../Forms/Форма/Ext/Form/Module.bsl | 0 .../epf-named-form}/ЗагрузкаДанных.xml | 0 .../epf-named-form/ЗагрузкаДанных}/Ext/ObjectModule.bsl | 0 .../ЗагрузкаДанных/Forms/ФормаНастроек.xml | 0 .../Forms/ФормаНастроек/Ext/Form.xml | 0 .../ЗагрузкаДанных/Forms/ФормаНастроек}/Ext/Form/Module.bsl | 0 .../epf-second-form}/МояОбработка.xml | 0 .../epf-second-form/МояОбработка}/Ext/ObjectModule.bsl | 0 .../МояОбработка/Forms/Форма.xml | 0 .../epf-second-form/МояОбработка/Forms/Форма}/Ext/Form.xml | 0 .../epf-second-form/МояОбработка/Forms/Форма}/Ext/Form/Module.bsl | 0 .../МояОбработка/Forms/ФормаНастроек.xml | 0 .../epf-second-form/МояОбработка/Forms/ФормаНастроек}/Ext/Form.xml | 0 .../МояОбработка}/Forms/ФормаНастроек/Ext/Form/Module.bsl | 0 .../epf-set-default}/МояОбработка.xml | 0 .../МояОбработка/Ext/ObjectModule.bsl | 0 .../МояОбработка/Forms/Форма1.xml | 0 .../epf-set-default/МояОбработка/Forms/Форма1}/Ext/Form.xml | 0 .../МояОбработка/Forms/Форма1}/Ext/Form/Module.bsl | 0 .../МояОбработка/Forms/ФормаОсновная.xml | 0 .../epf-set-default/МояОбработка/Forms/ФормаОсновная}/Ext/Form.xml | 0 .../МояОбработка/Forms/ФормаОсновная}/Ext/Form/Module.bsl | 0 .../Forms/ФормаСписка/Ext/Form.xml | 3 - .../Forms/ФормаСписка/Ext/Form/Module.bsl | 5 - .../Счет/Forms/ФормаДокумента/Ext/Form.xml | 3 - .../Forms/ФормаДокумента/Ext/Form/Module.bsl | 5 - .../Forms/ФормаСписка/Ext/Form/Module.bsl | 5 - .../Forms/ФормаЭлемента/Ext/Form/Module.bsl | 5 - .../Forms/ФормаСписка/Ext/Form/Module.bsl | 5 - .../Forms/ФормаЭлемента/Ext/Form/Module.bsl | 5 - .../Forms/ФормаСчета/Ext/Form/Module.bsl | 5 - .../Forms/ФормаСписка/Ext/Form/Module.bsl | 5 - .../Forms/ФормаДокумента/Ext/Form/Module.bsl | 5 - .../Forms/ФормаСписка/Ext/Form/Module.bsl | 5 - .../Forms/ФормаЭлемента/Ext/Form/Module.bsl | 5 - .../Forms/ФормаСписка/Ext/Form/Module.bsl | 5 - .../Forms/ФормаЗаписи/Ext/Form/Module.bsl | 5 - .../Forms/ФормаЗаписи/Ext/Form/Module.bsl | 5 - .../Типы/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Forms/ФормаЭлемента/Ext/Form/Module.bsl | 5 - .../Команды/Forms/Форма/Ext/Form/Module.bsl | 5 - .../События/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Forms/Форма/Ext/Form/Module.bsl | 5 - .../СГруппами/Forms/Форма/Ext/Form/Module.bsl | 5 - .../ПоляВвода/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Forms/Форма/Ext/Form/Module.bsl | 5 - .../Мастер/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Таблица/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Реквизиты/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Forms/Форма/Ext/Form/Module.bsl | 5 - .../Тест/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Группа/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Товары/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Инфо/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Простая/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Валидация/Forms/Форма/Ext/Form/Module.bsl | 5 - .../ВалТабл/Forms/Форма/Ext/Form/Module.bsl | 5 - .../Товары/Forms/Форма/Ext/Form/Module.bsl | 5 - .../cases/help-add/help-to-epf-with-form.json | 4 +- tests/skills/integration/build-epf.test.mjs | 8 +- .../skills/integration/platform-epf.test.mjs | 6 +- tests/skills/verify-snapshots.mjs | 6 +- 93 files changed, 93 insertions(+), 882 deletions(-) delete mode 100644 .claude/skills/epf-add-form/SKILL.md delete mode 100644 .claude/skills/epf-add-form/scripts/add-form.ps1 delete mode 100644 .claude/skills/epf-add-form/scripts/add-form.py delete mode 100644 tests/skills/cases/epf-add-form/_skill.json delete mode 100644 tests/skills/cases/epf-add-form/basic.json delete mode 100644 tests/skills/cases/epf-add-form/main-form.json delete mode 100644 tests/skills/cases/epf-add-form/named-form.json delete mode 100644 tests/skills/cases/epf-add-form/second-form.json create mode 100644 tests/skills/cases/form-add/epf-basic.json create mode 100644 tests/skills/cases/form-add/epf-named-form.json create mode 100644 tests/skills/cases/form-add/epf-second-form.json create mode 100644 tests/skills/cases/form-add/epf-set-default.json rename tests/skills/cases/{epf-add-form/snapshots/basic => form-add/snapshots/epf-basic}/МояОбработка.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/basic => form-add/snapshots/epf-basic}/МояОбработка/Ext/ObjectModule.bsl (100%) rename tests/skills/cases/{epf-add-form/snapshots/basic => form-add/snapshots/epf-basic}/МояОбработка/Forms/Форма.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/basic => form-add/snapshots/epf-basic}/МояОбработка/Forms/Форма/Ext/Form.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/basic => form-add/snapshots/epf-basic}/МояОбработка/Forms/Форма/Ext/Form/Module.bsl (100%) rename tests/skills/cases/{epf-add-form/snapshots/named-form => form-add/snapshots/epf-named-form}/ЗагрузкаДанных.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/main-form/МояОбработка => form-add/snapshots/epf-named-form/ЗагрузкаДанных}/Ext/ObjectModule.bsl (100%) rename tests/skills/cases/{epf-add-form/snapshots/named-form => form-add/snapshots/epf-named-form}/ЗагрузкаДанных/Forms/ФормаНастроек.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/named-form => form-add/snapshots/epf-named-form}/ЗагрузкаДанных/Forms/ФормаНастроек/Ext/Form.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/main-form/МояОбработка/Forms/Форма1 => form-add/snapshots/epf-named-form/ЗагрузкаДанных/Forms/ФормаНастроек}/Ext/Form/Module.bsl (100%) rename tests/skills/cases/{epf-add-form/snapshots/second-form => form-add/snapshots/epf-second-form}/МояОбработка.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/named-form/ЗагрузкаДанных => form-add/snapshots/epf-second-form/МояОбработка}/Ext/ObjectModule.bsl (100%) rename tests/skills/cases/{epf-add-form/snapshots/second-form => form-add/snapshots/epf-second-form}/МояОбработка/Forms/Форма.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/main-form/МояОбработка/Forms/Форма1 => form-add/snapshots/epf-second-form/МояОбработка/Forms/Форма}/Ext/Form.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/main-form/МояОбработка/Forms/ФормаОсновная => form-add/snapshots/epf-second-form/МояОбработка/Forms/Форма}/Ext/Form/Module.bsl (100%) rename tests/skills/cases/{epf-add-form/snapshots/second-form => form-add/snapshots/epf-second-form}/МояОбработка/Forms/ФормаНастроек.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/main-form/МояОбработка/Forms/ФормаОсновная => form-add/snapshots/epf-second-form/МояОбработка/Forms/ФормаНастроек}/Ext/Form.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/named-form/ЗагрузкаДанных => form-add/snapshots/epf-second-form/МояОбработка}/Forms/ФормаНастроек/Ext/Form/Module.bsl (100%) rename tests/skills/cases/{epf-add-form/snapshots/main-form => form-add/snapshots/epf-set-default}/МояОбработка.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/second-form => form-add/snapshots/epf-set-default}/МояОбработка/Ext/ObjectModule.bsl (100%) rename tests/skills/cases/{epf-add-form/snapshots/main-form => form-add/snapshots/epf-set-default}/МояОбработка/Forms/Форма1.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/second-form/МояОбработка/Forms/Форма => form-add/snapshots/epf-set-default/МояОбработка/Forms/Форма1}/Ext/Form.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/second-form/МояОбработка/Forms/Форма => form-add/snapshots/epf-set-default/МояОбработка/Forms/Форма1}/Ext/Form/Module.bsl (100%) rename tests/skills/cases/{epf-add-form/snapshots/main-form => form-add/snapshots/epf-set-default}/МояОбработка/Forms/ФормаОсновная.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/second-form/МояОбработка/Forms/ФормаНастроек => form-add/snapshots/epf-set-default/МояОбработка/Forms/ФормаОсновная}/Ext/Form.xml (100%) rename tests/skills/cases/{epf-add-form/snapshots/second-form/МояОбработка/Forms/ФормаНастроек => form-add/snapshots/epf-set-default/МояОбработка/Forms/ФормаОсновная}/Ext/Form/Module.bsl (100%) diff --git a/.claude/skills/epf-add-form/SKILL.md b/.claude/skills/epf-add-form/SKILL.md deleted file mode 100644 index 06618f6d..00000000 --- a/.claude/skills/epf-add-form/SKILL.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -name: epf-add-form -description: Добавить пустую управляемую форму к внешней обработке или отчёту (EPF/ERF). Используй когда нужно создать форму у внешней обработки или отчёта -argument-hint: [Synonym] -allowed-tools: - - Bash - - Read - - Write - - Edit - - Glob - - Grep ---- - -# /epf-add-form — Добавление формы - -Создаёт управляемую форму и регистрирует её в корневом XML обработки. - -## Usage - -``` -/epf-add-form [Synonym] [--main] -``` - -| Параметр | Обязательный | По умолчанию | Описание | -|---------------|:------------:|--------------|-------------------------------------------| -| ProcessorName | да | — | Имя обработки (должна существовать) | -| FormName | да | — | Имя формы | -| Synonym | нет | = FormName | Синоним формы | -| --main | нет | авто | Установить как форму по умолчанию (автоматически для первой формы) | -| SrcDir | нет | `src` | Каталог исходников | - -## Команда - -```powershell -powershell.exe -NoProfile -File .claude/skills/epf-add-form/scripts/add-form.ps1 -ProcessorName "" -FormName "" [-Synonym ""] [-Main] [-SrcDir ""] -``` - -## Что создаётся - -``` -//Forms/ -├── .xml # Метаданные формы (1 UUID) -└── / - └── Ext/ - ├── Form.xml # Описание формы (logform namespace) - └── Form/ - └── Module.bsl # BSL-модуль с 4 регионами -``` - -## Что модифицируется - -- `/.xml` — добавляется `
` в `ChildObjects`, обновляется `DefaultForm` (автоматически если это первая форма, или явно при `--main`) - -## Детали - -- FormType: Managed -- UsePurposes: PlatformApplication, MobilePlatformApplication -- AutoCommandBar с id=-1 -- Реквизит "Объект" с MainAttribute=true -- BSL-модуль содержит 5 регионов: ОбработчикиСобытийФормы, ОбработчикиСобытийЭлементовФормы, ОбработчикиКомандФормы, ОбработчикиОповещений, СлужебныеПроцедурыИФункции \ No newline at end of file diff --git a/.claude/skills/epf-add-form/scripts/add-form.ps1 b/.claude/skills/epf-add-form/scripts/add-form.ps1 deleted file mode 100644 index 3befdccc..00000000 --- a/.claude/skills/epf-add-form/scripts/add-form.ps1 +++ /dev/null @@ -1,226 +0,0 @@ -# epf-add-form v1.1 — Add managed form to 1C processor -# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills -param( - [Parameter(Mandatory)] - [string]$ProcessorName, - - [Parameter(Mandatory)] - [string]$FormName, - - [string]$Synonym = $FormName, - - [switch]$Main, - - [string]$SrcDir = "src" -) - -$ErrorActionPreference = "Stop" - -# --- Detect format version --- - -function Detect-FormatVersion([string]$dir) { - $d = $dir - while ($d) { - $cfgPath = Join-Path $d "Configuration.xml" - if (Test-Path $cfgPath) { - $head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length)) - if ($head -match ']+version="(\d+\.\d+)"') { return $Matches[1] } - } - $parent = Split-Path $d -Parent - if ($parent -eq $d) { break } - $d = $parent - } - return "2.17" -} - -$formatVersion = Detect-FormatVersion (Resolve-Path $SrcDir).Path - -# --- Проверки --- - -$rootXmlPath = Join-Path $SrcDir "$ProcessorName.xml" -if (-not (Test-Path $rootXmlPath)) { - Write-Error "Корневой файл обработки не найден: $rootXmlPath. Сначала выполните epf-init." - exit 1 -} - -$processorDir = Join-Path $SrcDir $ProcessorName -$formsDir = Join-Path $processorDir "Forms" -$formMetaPath = Join-Path $formsDir "$FormName.xml" - -if (Test-Path $formMetaPath) { - Write-Error "Форма уже существует: $formMetaPath" - exit 1 -} - -# --- Создание каталогов --- - -$formDir = Join-Path $formsDir $FormName -$formExtDir = Join-Path $formDir "Ext" -$formModuleDir = Join-Path $formExtDir "Form" - -New-Item -ItemType Directory -Path $formModuleDir -Force | Out-Null - -# --- Кодировка --- - -$encBom = New-Object System.Text.UTF8Encoding($true) -$encNoBom = New-Object System.Text.UTF8Encoding($false) - -# --- 1. Метаданные формы (Forms/.xml) --- - -$formUuid = [guid]::NewGuid().ToString() - -$formMetaXml = @" - - - - - $FormName - - - ru - $Synonym - - - - Managed - false - - PlatformApplication - MobilePlatformApplication - - - - - -"@ - -[System.IO.File]::WriteAllText($formMetaPath, $formMetaXml, $encBom) - -# --- 2. Описание формы (Forms//Ext/Form.xml) --- - -$formXmlPath = Join-Path $formExtDir "Form.xml" - -$formXml = @" - -
- - true - - - - - - cfg:ExternalDataProcessorObject.$ProcessorName - - true - - - -"@ - -[System.IO.File]::WriteAllText($formXmlPath, $formXml, $encBom) - -# --- 3. BSL-модуль (Forms//Ext/Form/Module.bsl) --- - -$modulePath = Join-Path $formModuleDir "Module.bsl" - -$moduleBsl = @" -#Область ОбработчикиСобытийФормы - -#КонецОбласти - -#Область ОбработчикиСобытийЭлементовФормы - -#КонецОбласти - -#Область ОбработчикиКомандФормы - -#КонецОбласти - -#Область ОбработчикиОповещений - -#КонецОбласти - -#Область СлужебныеПроцедурыИФункции - -#КонецОбласти -"@ - -[System.IO.File]::WriteAllText($modulePath, $moduleBsl, $encBom) - -# --- 4. Модификация корневого XML --- - -$rootXmlFull = Resolve-Path $rootXmlPath -$xmlDoc = New-Object System.Xml.XmlDocument -$xmlDoc.PreserveWhitespace = $true -$xmlDoc.Load($rootXmlFull.Path) - -$nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable) -$nsMgr.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses") - -$childObjects = $xmlDoc.SelectSingleNode("//md:ChildObjects", $nsMgr) -if (-not $childObjects) { - Write-Error "Не найден элемент ChildObjects в $rootXmlPath" - exit 1 -} - -# Добавить
перед первым