feat(meta-validate): валидация команд объекта — группа + правило параметра (Фаза 1.1, v1.7)

Check 15: команды в ChildObjects — Group обязателен и валиден (allowlist групп
раздела/формы + CommandGroup.<Имя>); секционная группа (NavigationPanel*/ActionsPanel*)
несовместима с commandParameterType; UUID/Name команды. Зеркало правил meta-compile v1.65
(команды раньше не валидировались вообще → пустой/неверный Group уходил в load-ошибку).
ps1+py идентично.

Тесты: valid-catalog-commands (preRun, группы раздела+формы) + 2 expectError-fixture
(пустая группа; секц.группа+параметр). meta-validate 16/16 ps1+py.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-07-11 20:15:57 +03:00
co-authored by Claude Opus 4.8
parent ca1c80e164
commit f8cd7dd681
14 changed files with 791 additions and 2 deletions
@@ -1,4 +1,4 @@
# meta-validate v1.6 — Validate 1C metadata object structure
# meta-validate v1.7 — Validate 1C metadata object structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -240,6 +240,11 @@ $childObjectRules = @{
"EventSubscription" = @()
}
# Группы командного интерфейса (зеркало meta-compile): раздела — без commandParameterType; формы — с параметром.
$sectionCommandGroups = @("NavigationPanelImportant","NavigationPanelOrdinary","NavigationPanelSeeAlso","ActionsPanelCreate","ActionsPanelReports","ActionsPanelTools")
$formCommandGroups = @("FormCommandBarImportant","FormCommandBarCreateBasedOn","FormNavigationPanelImportant","FormNavigationPanelGoTo","FormNavigationPanelSeeAlso")
$validCommandGroups = $sectionCommandGroups + $formCommandGroups
# Valid enum property values
$validPropertyValues = @{
"CodeType" = @("String","Number")
@@ -1346,6 +1351,46 @@ if ($mdType -eq "DocumentJournal" -and $childObjNode) {
}
}
if ($script:stopped) { & $finalize; exit 1 }
# --- Check 15: Commands — Group обязателен/валиден; секц.группа несовместима с CommandParameterType ---
if ($childObjNode) {
$commands = $childObjNode.SelectNodes("md:Command", $ns)
$check15Ok = $true
$cmdCount = 0
foreach ($cmd in $commands) {
if ($script:stopped) { break }
$cmdCount++
$cuuid = $cmd.GetAttribute("uuid")
$cmdProps = $cmd.SelectSingleNode("md:Properties", $ns)
$cmdNameNode = if ($cmdProps) { $cmdProps.SelectSingleNode("md:Name", $ns) } else { $null }
$cmdName = if ($cmdNameNode -and $cmdNameNode.InnerText) { $cmdNameNode.InnerText } else { "(unnamed)" }
if (-not $cuuid -or $cuuid -notmatch $guidPattern) {
Report-Error "15. Command '$cmdName': missing or invalid uuid"; $check15Ok = $false
}
if ($cmdName -eq "(unnamed)") {
Report-Error "15. Command (uuid=$cuuid): missing or empty Name"; $check15Ok = $false
}
$groupNode = if ($cmdProps) { $cmdProps.SelectSingleNode("md:Group", $ns) } else { $null }
$groupVal = if ($groupNode) { $groupNode.InnerText.Trim() } else { "" }
if (-not $groupVal) {
Report-Error "15. Command '$cmdName': не задана группа (Group) — 1С отвергает при загрузке"; $check15Ok = $false
} elseif (($validCommandGroups -notcontains $groupVal) -and ($groupVal -notmatch '^CommandGroup\.')) {
Report-Error "15. Command '$cmdName': неизвестная группа '$groupVal'. Валидные: $($validCommandGroups -join ', '); либо CommandGroup.<Имя>"; $check15Ok = $false
} elseif ($sectionCommandGroups -contains $groupVal) {
$cptNode = if ($cmdProps) { $cmdProps.SelectSingleNode("md:CommandParameterType", $ns) } else { $null }
$hasCpt = $cptNode -and (($cptNode.SelectNodes("v8:Type", $ns).Count -gt 0) -or ($cptNode.SelectNodes("v8:TypeSet", $ns).Count -gt 0))
if ($hasCpt) {
Report-Error "15. Command '$cmdName': тип параметра (CommandParameterType) недоступен для команд командного интерфейса раздела ('$groupVal')"; $check15Ok = $false
}
}
}
if ($check15Ok -and $cmdCount -gt 0) {
Report-OK "15. Commands: $cmdCount command(s), groups valid"
}
}
# --- Final output ---
& $finalize