diff --git a/.claude/skills/meta-validate/scripts/meta-validate.ps1 b/.claude/skills/meta-validate/scripts/meta-validate.ps1 index 24aab602..55809ee8 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.ps1 +++ b/.claude/skills/meta-validate/scripts/meta-validate.ps1 @@ -1,4 +1,4 @@ -# meta-validate v1.10 — Validate 1C metadata object structure (+корневой : скаляр без структуры = ошибка) +# meta-validate v1.11 — Validate 1C metadata object structure (+корневой : скаляр без структуры = ошибка) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -1493,6 +1493,36 @@ if ($script:configDir) { } } +# --- Check 17: MDObjectRef form — ссылка должна указывать на ОБЪЕКТ метаданных, а не на тип ссылки --- +# Owners/BasedOn/RegisterRecords/RegisteredDocuments/References содержат путь вида "Catalog.Валюты". +# "CatalogRef.Валюты" — частая ошибка (тип ссылки вместо объекта): платформа отвечает +# «Неизвестный объект метаданных». Вида метаданных, оканчивающегося на Ref, не существует → ERROR. +# Неизвестный первый сегмент без Ref — только WARN (список видов может быть неполон). + +$mdRefNodes = $xmlDoc.SelectNodes("//*[@xsi:type='xr:MDObjectRef']", $ns) +if ($mdRefNodes -and $mdRefNodes.Count -gt 0) { + $knownRoots = @($validTypes) + @($structuralOnlyTypes) + $badRefForm = @{} # значение -> $true (ссылочная форма, гарантированно нерабочая) + $unknownRoot = @{} # значение -> корень + foreach ($rn in $mdRefNodes) { + $rv = $rn.InnerText.Trim() + if (-not $rv) { continue } + $root = $rv.Split('.')[0] + if ($knownRoots -ccontains $root) { continue } + if ($root -cmatch 'Ref$') { $badRefForm[$rv] = $true } else { $unknownRoot[$rv] = $root } + } + foreach ($bk in ($badRefForm.Keys | Sort-Object)) { + $fixed = $bk -replace '^([A-Za-z]+)Ref\.', '$1.' + Report-Error "17. MDObjectRef '$bk' — ссылка на ТИП, а не на объект метаданных; нужно '$fixed' (иначе «Неизвестный объект метаданных» при загрузке)" + } + foreach ($uk in ($unknownRoot.Keys | Sort-Object)) { + Report-Warn "17. MDObjectRef '$uk' — неизвестный вид метаданных '$($unknownRoot[$uk])' (опечатка?)" + } + if ($badRefForm.Count -eq 0 -and $unknownRoot.Count -eq 0) { + Report-OK "17. MDObjectRef form: $($mdRefNodes.Count) checked" + } +} + # --- Final output --- & $finalize diff --git a/.claude/skills/meta-validate/scripts/meta-validate.py b/.claude/skills/meta-validate/scripts/meta-validate.py index f1543834..994e423a 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.py +++ b/.claude/skills/meta-validate/scripts/meta-validate.py @@ -1,4 +1,4 @@ -# meta-validate v1.10 — Validate 1C metadata object structure (Python port) (+корневой : скаляр без структуры = ошибка) +# meta-validate v1.11 — Validate 1C metadata object structure (Python port) (+корневой : скаляр без структуры = ошибка) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import os @@ -1395,6 +1395,36 @@ if config_dir: elif checked_refs: report_ok(f"16. Reference types: {len(checked_refs)} resolved") +# ── Check 17: MDObjectRef form — ссылка на ОБЪЕКТ метаданных, а не на тип ссылки ── +# Owners/BasedOn/RegisterRecords/RegisteredDocuments/References содержат путь вида "Catalog.Валюты". +# "CatalogRef.Валюты" — частая ошибка (тип ссылки вместо объекта): платформа отвечает +# «Неизвестный объект метаданных». Вида метаданных, оканчивающегося на Ref, не существует → ERROR. +# Неизвестный первый сегмент без Ref — только WARN (список видов может быть неполон). + +md_ref_nodes = find_all(root, "//*[@xsi:type='xr:MDObjectRef']") +if md_ref_nodes: + known_roots = tuple(valid_types) + tuple(structural_only_types) + bad_ref_form = {} # значение -> True (ссылочная форма, гарантированно нерабочая) + unknown_root = {} # значение -> корень + for rn in md_ref_nodes: + rv = inner_text(rn).strip() + if not rv: + continue + rroot = rv.split('.')[0] + if rroot in known_roots: + continue + if rroot.endswith('Ref'): + bad_ref_form[rv] = True + else: + unknown_root[rv] = rroot + for bk in sorted(bad_ref_form): + fixed = re.sub(r'^([A-Za-z]+)Ref\.', r'\1.', bk) + report_error(f"17. MDObjectRef '{bk}' — ссылка на ТИП, а не на объект метаданных; нужно '{fixed}' (иначе «Неизвестный объект метаданных» при загрузке)") + for uk in sorted(unknown_root): + report_warn(f"17. MDObjectRef '{uk}' — неизвестный вид метаданных '{unknown_root[uk]}' (опечатка?)") + if not bad_ref_form and not unknown_root: + report_ok(f"17. MDObjectRef form: {len(md_ref_nodes)} checked") + # ── Final output ────────────────────────────────────────────── finalize() diff --git a/tests/skills/cases/meta-validate/error-mdobjectref-type-form.json b/tests/skills/cases/meta-validate/error-mdobjectref-type-form.json new file mode 100644 index 00000000..aa9af28e --- /dev/null +++ b/tests/skills/cases/meta-validate/error-mdobjectref-type-form.json @@ -0,0 +1,9 @@ +{ + "name": "Валидатор находит ошибку: MDObjectRef указывает на тип ссылки вместо объекта метаданных", + "setup": "fixture:catalog-bad-mdobjectref", + "params": { "objectPath": "Catalogs/ДоговорыТест.xml" }, + "expectError": true, + "expect": { + "stdoutContains": "17. MDObjectRef 'CatalogRef.ВалютыТест'" + } +} diff --git a/tests/skills/cases/meta-validate/fixtures/catalog-bad-mdobjectref/Catalogs/ДоговорыТест.xml b/tests/skills/cases/meta-validate/fixtures/catalog-bad-mdobjectref/Catalogs/ДоговорыТест.xml new file mode 100644 index 00000000..aa058e7f --- /dev/null +++ b/tests/skills/cases/meta-validate/fixtures/catalog-bad-mdobjectref/Catalogs/ДоговорыТест.xml @@ -0,0 +1,93 @@ + + + + + + 6baeb62e-97e6-4499-8b70-f3d01537550d + dddc4ad4-26bd-4419-a730-e52dfd769001 + + + 9d21e0de-25b7-4795-bf56-3b4079d934fc + 6ec351b4-1c1c-4302-b418-8bee2278fe53 + + + 0f6c64e1-d4a2-44c4-beb5-fd1a0c677430 + b8f0c243-2e1a-4fd2-95bd-5cb3ede085ea + + + ebf66c45-7189-483a-9735-69649a113dd7 + cf1b1818-49d8-4dc4-890f-7a08289522e2 + + + 826f6ff2-e21e-4872-a142-23aeab5ffe30 + 98a2519d-35ec-452e-84b6-0717bdcec784 + + + + ДоговорыТест + + + ru + Договоры тест + + + + false + HierarchyOfItems + false + 2 + true + true + + CatalogRef.ВалютыТест + + ToItems + 9 + 25 + String + Variable + WholeCatalog + false + true + AsDescription + + Auto + InDialog + false + BothWays + + Catalog.ДоговорыТест.StandardAttribute.Description + Catalog.ДоговорыТест.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Managed + Use + + + + + + Use + Auto + DontUse + false + false + + + +