mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-01 17:27:45 +03:00
feat(meta-validate): Check 10 — warn on empty registers and broken RegisterRecords refs
Add two new validations found via platform snapshot verification: - Registers without any Dimensions/Resources/Attributes → platform rejects - Document.RegisterRecords referencing non-existent register objects Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
3ba6072660
commit
358830c65b
@@ -1,4 +1,4 @@
|
|||||||
# meta-validate v1.2 — Validate 1C metadata object structure
|
# meta-validate v1.3 — Validate 1C metadata object structure
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
param(
|
param(
|
||||||
[Parameter(Mandatory)]
|
[Parameter(Mandatory)]
|
||||||
@@ -998,6 +998,18 @@ if ($propsNode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# CalculationRegister: ActionPeriod=true requires non-empty Schedule
|
||||||
|
if ($mdType -eq "CalculationRegister") {
|
||||||
|
$actionPeriod = $propsNode.SelectSingleNode("md:ActionPeriod", $ns)
|
||||||
|
if ($actionPeriod -and $actionPeriod.InnerText -eq "true") {
|
||||||
|
$schedule = $propsNode.SelectSingleNode("md:Schedule", $ns)
|
||||||
|
if (-not $schedule -or -not $schedule.InnerText.Trim()) {
|
||||||
|
Report-Warn "10. CalculationRegister: ActionPeriod=true but Schedule is empty — platform requires a schedule register"
|
||||||
|
$check10Issues++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# DocumentJournal: RegisteredDocuments should not be empty
|
# DocumentJournal: RegisteredDocuments should not be empty
|
||||||
if ($mdType -eq "DocumentJournal") {
|
if ($mdType -eq "DocumentJournal") {
|
||||||
$regDocs = $propsNode.SelectSingleNode("md:RegisteredDocuments", $ns)
|
$regDocs = $propsNode.SelectSingleNode("md:RegisteredDocuments", $ns)
|
||||||
@@ -1025,6 +1037,48 @@ if ($propsNode) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Register: must have at least one Dimension or Resource (platform rejects empty registers)
|
||||||
|
$regTypesAll = @("AccumulationRegister","AccountingRegister","CalculationRegister","InformationRegister")
|
||||||
|
if ($regTypesAll -contains $mdType -and $childObjNode) {
|
||||||
|
$dims = $childObjNode.SelectNodes("md:Dimension", $ns).Count
|
||||||
|
$ress = $childObjNode.SelectNodes("md:Resource", $ns).Count
|
||||||
|
$attrs = $childObjNode.SelectNodes("md:Attribute", $ns).Count
|
||||||
|
if (($dims + $ress + $attrs) -eq 0) {
|
||||||
|
Report-Warn "10. $mdType`: no Dimensions, Resources, or Attributes — platform will reject"
|
||||||
|
$check10Issues++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Document: RegisterRecords references should point to existing objects in config
|
||||||
|
if ($mdType -eq "Document" -and $script:configDir) {
|
||||||
|
$regRecords = $propsNode.SelectSingleNode("md:RegisterRecords", $ns)
|
||||||
|
if ($regRecords) {
|
||||||
|
$items = $regRecords.SelectNodes("xr:Item", $ns)
|
||||||
|
foreach ($item in $items) {
|
||||||
|
$refVal = $item.InnerText.Trim()
|
||||||
|
if (-not $refVal) { continue }
|
||||||
|
# Parse "AccumulationRegister.Name" → dir AccumulationRegisters/Name
|
||||||
|
$parts = $refVal -split '\.',2
|
||||||
|
if ($parts.Count -eq 2) {
|
||||||
|
$refType = $parts[0]; $refName = $parts[1]
|
||||||
|
$dirMap = @{
|
||||||
|
"AccumulationRegister"="AccumulationRegisters"; "InformationRegister"="InformationRegisters"
|
||||||
|
"AccountingRegister"="AccountingRegisters"; "CalculationRegister"="CalculationRegisters"
|
||||||
|
}
|
||||||
|
$refDir = $dirMap[$refType]
|
||||||
|
if ($refDir) {
|
||||||
|
$refPath = Join-Path $script:configDir "$refDir/$refName"
|
||||||
|
$refXml = Join-Path $script:configDir "$refDir/$refName.xml"
|
||||||
|
if (-not (Test-Path $refPath) -and -not (Test-Path $refXml)) {
|
||||||
|
Report-Warn "10. Document.RegisterRecords references '$refVal' but object not found in config"
|
||||||
|
$check10Issues++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Register: must have at least one registrar document
|
# Register: must have at least one registrar document
|
||||||
$registerTypes = @("AccumulationRegister","AccountingRegister","CalculationRegister","InformationRegister")
|
$registerTypes = @("AccumulationRegister","AccountingRegister","CalculationRegister","InformationRegister")
|
||||||
if ($registerTypes -contains $mdType -and $script:configDir -and $objName -ne "(unknown)") {
|
if ($registerTypes -contains $mdType -and $script:configDir -and $objName -ne "(unknown)") {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# meta-validate v1.2 — Validate 1C metadata object structure (Python port)
|
# meta-validate v1.3 — Validate 1C metadata object structure (Python port)
|
||||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
@@ -942,6 +942,15 @@ if props_node is not None:
|
|||||||
check10_issues += 1
|
check10_issues += 1
|
||||||
print('[HINT] /meta-edit -Operation modify-property -Value "Task=Task.XXX"')
|
print('[HINT] /meta-edit -Operation modify-property -Value "Task=Task.XXX"')
|
||||||
|
|
||||||
|
# CalculationRegister: ActionPeriod=true requires non-empty Schedule
|
||||||
|
if md_type == 'CalculationRegister':
|
||||||
|
action_period = find(props_node, 'md:ActionPeriod')
|
||||||
|
if action_period is not None and text_of(action_period) == 'true':
|
||||||
|
schedule = find(props_node, 'md:Schedule')
|
||||||
|
if schedule is None or not text_of(schedule):
|
||||||
|
report_warn('10. CalculationRegister: ActionPeriod=true but Schedule is empty — platform requires a schedule register')
|
||||||
|
check10_issues += 1
|
||||||
|
|
||||||
# DocumentJournal: RegisteredDocuments should not be empty
|
# DocumentJournal: RegisteredDocuments should not be empty
|
||||||
if md_type == 'DocumentJournal':
|
if md_type == 'DocumentJournal':
|
||||||
reg_docs = find(props_node, 'md:RegisteredDocuments')
|
reg_docs = find(props_node, 'md:RegisteredDocuments')
|
||||||
@@ -969,6 +978,43 @@ if props_node is not None:
|
|||||||
check10_issues += 1
|
check10_issues += 1
|
||||||
print('[HINT] /meta-edit -Operation modify-property -Value "ExtDimensionTypes=ChartOfCharacteristicTypes.XXX"')
|
print('[HINT] /meta-edit -Operation modify-property -Value "ExtDimensionTypes=ChartOfCharacteristicTypes.XXX"')
|
||||||
|
|
||||||
|
# Register: must have at least one Dimension or Resource (platform rejects empty registers)
|
||||||
|
reg_types_all = ('AccumulationRegister', 'AccountingRegister', 'CalculationRegister', 'InformationRegister')
|
||||||
|
if md_type in reg_types_all and child_obj_node is not None:
|
||||||
|
dims = len(find_all(child_obj_node, 'md:Dimension'))
|
||||||
|
ress = len(find_all(child_obj_node, 'md:Resource'))
|
||||||
|
attrs = len(find_all(child_obj_node, 'md:Attribute'))
|
||||||
|
if dims + ress + attrs == 0:
|
||||||
|
report_warn(f"10. {md_type}: no Dimensions, Resources, or Attributes \u2014 platform will reject")
|
||||||
|
check10_issues += 1
|
||||||
|
|
||||||
|
# Document: RegisterRecords references should point to existing objects in config
|
||||||
|
if md_type == 'Document' and config_dir:
|
||||||
|
reg_records = find(props_node, 'md:RegisterRecords')
|
||||||
|
if reg_records is not None:
|
||||||
|
rr_items = find_all(reg_records, 'xr:Item')
|
||||||
|
for item in rr_items:
|
||||||
|
ref_val = (inner_text(item) or '').strip()
|
||||||
|
if not ref_val:
|
||||||
|
continue
|
||||||
|
# Parse "AccumulationRegister.Name" -> dir AccumulationRegisters/Name
|
||||||
|
parts = ref_val.split('.', 1)
|
||||||
|
if len(parts) == 2:
|
||||||
|
ref_type, ref_name = parts
|
||||||
|
dir_map = {
|
||||||
|
'AccumulationRegister': 'AccumulationRegisters',
|
||||||
|
'InformationRegister': 'InformationRegisters',
|
||||||
|
'AccountingRegister': 'AccountingRegisters',
|
||||||
|
'CalculationRegister': 'CalculationRegisters',
|
||||||
|
}
|
||||||
|
ref_dir = dir_map.get(ref_type)
|
||||||
|
if ref_dir:
|
||||||
|
ref_path = os.path.join(config_dir, ref_dir, ref_name)
|
||||||
|
ref_xml = os.path.join(config_dir, ref_dir, ref_name + '.xml')
|
||||||
|
if not os.path.exists(ref_path) and not os.path.exists(ref_xml):
|
||||||
|
report_warn(f"10. Document.RegisterRecords references '{ref_val}' but object not found in config")
|
||||||
|
check10_issues += 1
|
||||||
|
|
||||||
# Register: must have at least one registrar document
|
# Register: must have at least one registrar document
|
||||||
register_types = ('AccumulationRegister', 'AccountingRegister', 'CalculationRegister', 'InformationRegister')
|
register_types = ('AccumulationRegister', 'AccountingRegister', 'CalculationRegister', 'InformationRegister')
|
||||||
if md_type in register_types and config_dir and obj_name != '(unknown)':
|
if md_type in register_types and config_dir and obj_name != '(unknown)':
|
||||||
|
|||||||
Reference in New Issue
Block a user