diff --git a/.claude/skills/epf-validate/scripts/epf-validate.ps1 b/.claude/skills/epf-validate/scripts/epf-validate.ps1
index f9092d1bc..b565be9bd 100644
--- a/.claude/skills/epf-validate/scripts/epf-validate.ps1
+++ b/.claude/skills/epf-validate/scripts/epf-validate.ps1
@@ -1,4 +1,4 @@
-# epf-validate v1.6 — Validate 1C external data processor / report structure
+# epf-validate v1.7 — Validate 1C external data processor / report structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# Works for both EPF (ExternalDataProcessor) and ERF (ExternalReport) — auto-detects
[CmdletBinding(PositionalBinding=$false)]
@@ -135,7 +135,8 @@ $classIds = @{
"ExternalReport" = "e41aff26-25cf-4bb6-b6c1-3f478a75f374"
}
-$allowedChildTypes = @("Attribute","TabularSection","Form","Template","Command")
+# Команд объекта у внешней обработки/отчёта нет: платформа выбрасывает их при сборке (#108).
+$allowedChildTypes = @("Attribute","TabularSection","Form","Template")
# Expected order of child types in ChildObjects
$childTypeOrder = @{
@@ -143,7 +144,6 @@ $childTypeOrder = @{
"TabularSection" = 1
"Form" = 2
"Template" = 3
- "Command" = 4
}
$validPropertyValues = @{
@@ -410,6 +410,11 @@ if ($childObjNode) {
if ($child.NodeType -ne 'Element') { continue }
$childTag = $child.LocalName
+ if ($childTag -eq "Command") {
+ Report-Error "4. ChildObjects: Command — у внешней обработки/отчёта команд объекта нет, платформа выбросит его при сборке"
+ $check4Ok = $false
+ continue
+ }
if ($allowedChildTypes -notcontains $childTag) {
Report-Error "4. ChildObjects: disallowed element '$childTag'"
$check4Ok = $false
@@ -424,7 +429,7 @@ if ($childObjNode) {
# Check ordering
$thisOrder = $childTypeOrder[$childTag]
if ($thisOrder -lt $lastOrder -and $orderOk) {
- Report-Warn "4. ChildObjects: '$childTag' appears after higher-order elements (expected: Attribute, TabularSection, Form, Template, Command)"
+ Report-Warn "4. ChildObjects: '$childTag' appears after higher-order elements (expected: Attribute, TabularSection, Form, Template)"
$orderOk = $false
}
$lastOrder = $thisOrder
@@ -665,14 +670,13 @@ if ($script:stopped) { & $finalize; exit 1 }
$check8Ok = $true
-# Collect all names: attributes + tabular sections + forms + templates + commands
+# Collect all names: attributes + tabular sections + forms + templates
$allNames = @{}
if ($childObjNode) {
$nameKinds = @(
@{ XPath = "md:Attribute"; Kind = "Attribute" },
- @{ XPath = "md:TabularSection"; Kind = "TabularSection" },
- @{ XPath = "md:Command"; Kind = "Command" }
+ @{ XPath = "md:TabularSection"; Kind = "TabularSection" }
)
foreach ($nk in $nameKinds) {
@@ -777,6 +781,13 @@ if (Test-Path $objModule) {
$filesChecked++
}
+# Модуля менеджера у внешней обработки/отчёта нет: платформа выбрасывает файл без сообщения.
+$mgrModule = Join-Path (Join-Path $objDir "Ext") "ManagerModule.bsl"
+if (Test-Path $mgrModule) {
+ Report-Error "9. Ext/ManagerModule.bsl — у внешней обработки/отчёта нет модуля менеджера, платформа выбросит его молча"
+ $check9Ok = $false
+}
+
if ($check9Ok) {
if ($filesChecked -gt 0) {
Report-OK "9. File existence: $filesChecked files verified"
diff --git a/.claude/skills/epf-validate/scripts/epf-validate.py b/.claude/skills/epf-validate/scripts/epf-validate.py
index ecf4af0ba..be043e9ae 100644
--- a/.claude/skills/epf-validate/scripts/epf-validate.py
+++ b/.claude/skills/epf-validate/scripts/epf-validate.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# epf-validate v1.6 — Validate 1C external data processor / report structure
+# epf-validate v1.7 — Validate 1C external data processor / report structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# Works for both EPF (ExternalDataProcessor) and ERF (ExternalReport) — auto-detects
@@ -49,14 +49,14 @@ CLASS_IDS = {
"ExternalReport": "e41aff26-25cf-4bb6-b6c1-3f478a75f374",
}
-ALLOWED_CHILD_TYPES = {"Attribute", "TabularSection", "Form", "Template", "Command"}
+# Команд объекта у внешней обработки/отчёта нет: платформа выбрасывает их при сборке (#108).
+ALLOWED_CHILD_TYPES = {"Attribute", "TabularSection", "Form", "Template"}
CHILD_TYPE_ORDER = {
"Attribute": 0,
"TabularSection": 1,
"Form": 2,
"Template": 3,
- "Command": 4,
}
@@ -381,6 +381,10 @@ def main():
continue
child_tag = localname(child)
+ if child_tag == "Command":
+ report_error("4. ChildObjects: Command — у внешней обработки/отчёта команд объекта нет, платформа выбросит его при сборке")
+ check4_ok = False
+ continue
if child_tag not in ALLOWED_CHILD_TYPES:
report_error(f"4. ChildObjects: disallowed element '{child_tag}'")
check4_ok = False
@@ -390,7 +394,7 @@ def main():
this_order = CHILD_TYPE_ORDER.get(child_tag, -1)
if this_order < last_order and order_ok:
- report_warn(f"4. ChildObjects: '{child_tag}' appears after higher-order elements (expected: Attribute, TabularSection, Form, Template, Command)")
+ report_warn(f"4. ChildObjects: '{child_tag}' appears after higher-order elements (expected: Attribute, TabularSection, Form, Template)")
order_ok = False
last_order = this_order
@@ -597,7 +601,6 @@ def main():
name_kinds = [
("Attribute", f"{{{MD_NS}}}Attribute"),
("TabularSection", f"{{{MD_NS}}}TabularSection"),
- ("Command", f"{{{MD_NS}}}Command"),
]
for kind, xpath in name_kinds:
@@ -678,6 +681,12 @@ def main():
if os.path.isfile(obj_module):
files_checked += 1
+ # Модуля менеджера у внешней обработки/отчёта нет: платформа выбрасывает файл без сообщения.
+ mgr_module = os.path.join(obj_dir, "Ext", "ManagerModule.bsl")
+ if os.path.isfile(mgr_module):
+ report_error("9. Ext/ManagerModule.bsl — у внешней обработки/отчёта нет модуля менеджера, платформа выбросит его молча")
+ check9_ok = False
+
if check9_ok:
if files_checked > 0:
report_ok(f"9. File existence: {files_checked} files verified")
diff --git a/.claude/skills/meta-edit/scripts/meta-edit.ps1 b/.claude/skills/meta-edit/scripts/meta-edit.ps1
index 5f6db278a..e76481581 100644
--- a/.claude/skills/meta-edit/scripts/meta-edit.ps1
+++ b/.claude/skills/meta-edit/scripts/meta-edit.ps1
@@ -1705,6 +1705,9 @@ $script:validChildTypes = @{
"Task" = @("attributes","tabularSections","forms","templates","commands")
"Report" = @("attributes","tabularSections","forms","templates","commands")
"DataProcessor" = @("attributes","tabularSections","forms","templates","commands")
+ # Внешняя обработка/отчёт: команд объекта нет — платформа выбрасывает их при сборке.
+ "ExternalDataProcessor" = @("attributes","tabularSections","forms","templates")
+ "ExternalReport" = @("attributes","tabularSections","forms","templates")
"Enum" = @("enumValues","forms","templates","commands")
"InformationRegister" = @("dimensions","resources","attributes","forms","templates","commands")
"AccumulationRegister" = @("dimensions","resources","attributes","forms","templates","commands")
diff --git a/.claude/skills/meta-edit/scripts/meta-edit.py b/.claude/skills/meta-edit/scripts/meta-edit.py
index ff918a758..c95e2a150 100644
--- a/.claude/skills/meta-edit/scripts/meta-edit.py
+++ b/.claude/skills/meta-edit/scripts/meta-edit.py
@@ -1693,6 +1693,9 @@ valid_child_types = {
"Task": ["attributes", "tabularSections", "forms", "templates", "commands"],
"Report": ["attributes", "tabularSections", "forms", "templates", "commands"],
"DataProcessor": ["attributes", "tabularSections", "forms", "templates", "commands"],
+ # Внешняя обработка/отчёт: команд объекта нет — платформа выбрасывает их при сборке.
+ "ExternalDataProcessor": ["attributes", "tabularSections", "forms", "templates"],
+ "ExternalReport": ["attributes", "tabularSections", "forms", "templates"],
"Enum": ["enumValues", "forms", "templates", "commands"],
"InformationRegister": ["dimensions", "resources", "attributes", "forms", "templates", "commands"],
"AccumulationRegister": ["dimensions", "resources", "attributes", "forms", "templates", "commands"],
diff --git a/tests/skills/cases/epf-validate/error-command.json b/tests/skills/cases/epf-validate/error-command.json
new file mode 100644
index 000000000..baf0df60e
--- /dev/null
+++ b/tests/skills/cases/epf-validate/error-command.json
@@ -0,0 +1,9 @@
+{
+ "name": "Валидатор находит ошибку: команда объекта у внешней обработки (#108)",
+ "setup": "fixture:epf-command",
+ "params": { "objectPath": "Тест.xml" },
+ "expectError": true,
+ "expect": {
+ "stdoutContains": ["у внешней обработки/отчёта команд объекта нет"]
+ }
+}
diff --git a/tests/skills/cases/epf-validate/fixtures/epf-command/Тест.xml b/tests/skills/cases/epf-validate/fixtures/epf-command/Тест.xml
new file mode 100644
index 000000000..ca5f37907
--- /dev/null
+++ b/tests/skills/cases/epf-validate/fixtures/epf-command/Тест.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+ c3831ec8-d8d5-4f93-8a22-f9bfae07327f
+ f11ff676-8870-4887-ab9c-f10bc177997c
+
+
+ 2a7c8bf5-ca61-4bf0-a3b7-3051c28e9fb5
+ 6f3614a7-6fd0-4463-bdec-56f81f410c90
+
+
+
+ Тест
+
+
+ ru
+ Тест
+
+
+
+
+
+
+
+
+
+ ПробнаяКоманда
+
+
+ ru
+ Пробная команда
+
+
+
+ FormNavigationPanelGoTo
+
+ Single
+ false
+ Auto
+
+
+
+ Auto
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/epf-validate/fixtures/epf-command/Тест/Commands/ПробнаяКоманда/Ext/CommandModule.bsl b/tests/skills/cases/epf-validate/fixtures/epf-command/Тест/Commands/ПробнаяКоманда/Ext/CommandModule.bsl
new file mode 100644
index 000000000..bc4c02ce6
--- /dev/null
+++ b/tests/skills/cases/epf-validate/fixtures/epf-command/Тест/Commands/ПробнаяКоманда/Ext/CommandModule.bsl
@@ -0,0 +1,6 @@
+&НаКлиенте
+Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды)
+
+ // Вставьте обработчик команды.
+
+КонецПроцедуры
diff --git a/tests/skills/cases/epf-validate/fixtures/epf-command/Тест/Ext/ObjectModule.bsl b/tests/skills/cases/epf-validate/fixtures/epf-command/Тест/Ext/ObjectModule.bsl
new file mode 100644
index 000000000..788ebdbd8
--- /dev/null
+++ b/tests/skills/cases/epf-validate/fixtures/epf-command/Тест/Ext/ObjectModule.bsl
@@ -0,0 +1,11 @@
+#Область ОписаниеПеременных
+
+#КонецОбласти
+
+#Область ПрограммныйИнтерфейс
+
+#КонецОбласти
+
+#Область СлужебныеПроцедурыИФункции
+
+#КонецОбласти
\ No newline at end of file
diff --git a/tests/skills/cases/erf-validate/error-manager-module.json b/tests/skills/cases/erf-validate/error-manager-module.json
new file mode 100644
index 000000000..56d2573f7
--- /dev/null
+++ b/tests/skills/cases/erf-validate/error-manager-module.json
@@ -0,0 +1,20 @@
+{
+ "name": "Валидатор находит ошибку: модуль менеджера у внешнего отчёта (#108)",
+ "preRun": [
+ {
+ "script": "erf-init/scripts/init",
+ "args": { "-Name": "ТестовыйОтчёт", "-SrcDir": "{workDir}" }
+ },
+ {
+ "writeFile": {
+ "path": "ТестовыйОтчёт/Ext/ManagerModule.bsl",
+ "content": "Процедура Тест() Экспорт\nКонецПроцедуры\n"
+ }
+ }
+ ],
+ "params": { "objectPath": "ТестовыйОтчёт.xml" },
+ "expectError": true,
+ "expect": {
+ "stdoutContains": ["нет модуля менеджера"]
+ }
+}
diff --git a/tests/skills/cases/meta-edit/epf-add-command-denied.json b/tests/skills/cases/meta-edit/epf-add-command-denied.json
new file mode 100644
index 000000000..b4037b52f
--- /dev/null
+++ b/tests/skills/cases/meta-edit/epf-add-command-denied.json
@@ -0,0 +1,22 @@
+{
+ "name": "Внешняя обработка: команду объекта не добавлять — платформа её выбросит (#108)",
+ "setup": "none",
+ "skipValidation": true,
+ "preRun": [
+ {
+ "script": "epf-init/scripts/init",
+ "args": { "-Name": "Проба", "-SrcDir": "{workDir}" }
+ }
+ ],
+ "params": { "objectPath": "Проба.xml", "objectName": "Проба" },
+ "input": {
+ "add": {
+ "commands": ["ПробнаяКоманда"]
+ }
+ },
+ "expect": {
+ "stdoutContains": ["commands not allowed for ExternalDataProcessor", "Validation OK"],
+ "fileNotContains": [{ "file": "Проба.xml", "text": ["
+
+
+
+
+ UUID-002
+ UUID-003
+
+
+ UUID-004
+ UUID-005
+
+
+
+ Проба
+
+
+ ru
+ Проба
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/meta-edit/snapshots/epf-add-command-denied/Проба/Ext/ObjectModule.bsl b/tests/skills/cases/meta-edit/snapshots/epf-add-command-denied/Проба/Ext/ObjectModule.bsl
new file mode 100644
index 000000000..15543d277
--- /dev/null
+++ b/tests/skills/cases/meta-edit/snapshots/epf-add-command-denied/Проба/Ext/ObjectModule.bsl
@@ -0,0 +1,11 @@
+#Область ОписаниеПеременных
+
+#КонецОбласти
+
+#Область ПрограммныйИнтерфейс
+
+#КонецОбласти
+
+#Область СлужебныеПроцедурыИФункции
+
+#КонецОбласти
\ No newline at end of file