feat(meta-validate): add forbidden property and DocumentJournal checks

Check 12: detect properties that are invalid for a given metadata type
and would cause LoadConfigFromFiles to fail:
- ChartOfCharacteristicTypes: CodeType
- ChartOfAccounts: Autonumbering, Hierarchical
- ChartOfCalculationTypes: CheckUnique, Autonumbering
- ExchangePlan: CodeType, CheckUnique, Autonumbering

Check 10 extensions:
- DocumentJournal: warn on empty RegisteredDocuments
- Add DependenceOnCalculationTypes to enum validation (Check 4)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-03-07 21:49:57 +03:00
co-authored by Claude Opus 4.6
parent e717d4a57f
commit c2b90a97ef
2 changed files with 84 additions and 0 deletions
@@ -216,6 +216,15 @@ $validPropertyValues = @{
"FillChecking" = @("DontCheck","ShowError","ShowWarning")
"Indexing" = @("DontIndex","Index","IndexWithAdditionalOrder")
"DataHistory" = @("Use","DontUse")
"DependenceOnCalculationTypes" = @("DontUse","RequireCalculationTypes")
}
# Properties forbidden per type (would cause LoadConfigFromFiles error)
$forbiddenProperties = @{
"ChartOfCharacteristicTypes" = @("CodeType")
"ChartOfAccounts" = @("Autonumbering","Hierarchical")
"ChartOfCalculationTypes" = @("CheckUnique","Autonumbering")
"ExchangePlan" = @("CodeType","CheckUnique","Autonumbering")
}
# --- 1. Parse XML ---
@@ -955,6 +964,20 @@ if ($propsNode) {
}
}
# DocumentJournal: RegisteredDocuments should not be empty
if ($mdType -eq "DocumentJournal") {
$regDocs = $propsNode.SelectSingleNode("md:RegisteredDocuments", $ns)
$hasRegDocs = $false
if ($regDocs) {
$items = $regDocs.SelectNodes("v8:Type", $ns)
if ($items.Count -gt 0) { $hasRegDocs = $true }
}
if (-not $hasRegDocs) {
Report-Warn "10. DocumentJournal: no RegisteredDocuments specified"
$check10Issues++
}
}
# ChartOfAccounts: ExtDimensionTypes should be set if MaxExtDimensionCount > 0
if ($mdType -eq "ChartOfAccounts") {
$maxExtDim = $propsNode.SelectSingleNode("md:MaxExtDimensionCount", $ns)
@@ -1071,6 +1094,27 @@ if ($mdType -eq "HTTPService" -and $childObjNode) {
Report-OK "11. HTTPService/WebService: N/A"
}
if ($script:stopped) { & $finalize; exit 1 }
# --- Check 12: Forbidden properties per type ---
if ($propsNode -and $forbiddenProperties.ContainsKey($mdType)) {
$forbidden = $forbiddenProperties[$mdType]
$check12Ok = $true
foreach ($fp in $forbidden) {
$fpNode = $propsNode.SelectSingleNode("md:$fp", $ns)
if ($fpNode) {
Report-Error "12. Forbidden property '$fp' present in $mdType (will fail on LoadConfigFromFiles)"
$check12Ok = $false
}
}
if ($check12Ok) {
Report-OK "12. Forbidden properties: none found"
}
} else {
Report-OK "12. Forbidden properties: N/A"
}
# --- Final output ---
& $finalize
@@ -216,6 +216,15 @@ valid_property_values = {
"FillChecking": ["DontCheck", "ShowError", "ShowWarning"],
"Indexing": ["DontIndex", "Index", "IndexWithAdditionalOrder"],
"DataHistory": ["Use", "DontUse"],
"DependenceOnCalculationTypes": ["DontUse", "RequireCalculationTypes"],
}
# Properties forbidden per type (would cause LoadConfigFromFiles error)
forbidden_properties = {
"ChartOfCharacteristicTypes": ["CodeType"],
"ChartOfAccounts": ["Autonumbering", "Hierarchical"],
"ChartOfCalculationTypes": ["CheckUnique", "Autonumbering"],
"ExchangePlan": ["CodeType", "CheckUnique", "Autonumbering"],
}
# ── Namespaces ───────────────────────────────────────────────
@@ -898,6 +907,18 @@ if props_node is not None:
check10_issues += 1
print('[HINT] /meta-edit -Operation modify-property -Value "Task=Task.XXX"')
# DocumentJournal: RegisteredDocuments should not be empty
if md_type == 'DocumentJournal':
reg_docs = find(props_node, 'md:RegisteredDocuments')
has_reg_docs = False
if reg_docs is not None:
items = find_all(reg_docs, 'v8:Type')
if len(items) > 0:
has_reg_docs = True
if not has_reg_docs:
report_warn('10. DocumentJournal: no RegisteredDocuments specified')
check10_issues += 1
# ChartOfAccounts: ExtDimensionTypes should be set if MaxExtDimensionCount > 0
if md_type == 'ChartOfAccounts':
max_ext_dim = find(props_node, 'md:MaxExtDimensionCount')
@@ -1001,6 +1022,25 @@ elif md_type == "WebService" and child_obj_node is not None:
else:
report_ok("11. HTTPService/WebService: N/A")
if stopped:
finalize()
sys.exit(1)
# ── Check 12: Forbidden properties per type ──────────────────
if props_node is not None and md_type in forbidden_properties:
forbidden = forbidden_properties[md_type]
check12_ok = True
for fp in forbidden:
fp_node = find(props_node, f"md:{fp}")
if fp_node is not None:
report_error(f"12. Forbidden property '{fp}' present in {md_type} (will fail on LoadConfigFromFiles)")
check12_ok = False
if check12_ok:
report_ok("12. Forbidden properties: none found")
else:
report_ok("12. Forbidden properties: N/A")
# ── Final output ──────────────────────────────────────────────
finalize()