From a1131965ccfadfd13766eb59c9f29b6b43dd0fb9 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Thu, 21 May 2026 20:28:45 +0300 Subject: [PATCH] feat(skd): DataSetFieldFolder + GroupItemAuto + empty-field selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Закрывает три gap'a, выявленных при полном прогоне ERP+ACC: 1. DataSetFieldFolder — поле-папка для UI-группировки полей в композиторе настроек. Только dataPath + title, без valueType/role. - DSL: object form поля с `folder: true`. - Compile: при folder=true → . - Decompile: распознать xsi:type, эмитить object form. 2. GroupItemAuto — пустой в groupItems (auto-grouping, аналогично "Auto" в selection). - DSL: строка "Auto" в groupFields. - Compile/decompile: round-trip. 3. Empty в conditionalAppearance/selection (wildcard — apply to all). Раньше — SelectionItem: sentinel. Теперь эмитим как "Auto" (семантический эквивалент через SelectedItemAuto). Новый тест dataset-folder-and-auto-group (round-trip). Versions: compile v1.34→v1.35, decompile v0.16→v0.17. На предыдущем прогоне ERP+ACC: 227 sentinel'ов (218 DataSetFieldFolder + 7 GroupItemAuto + 2 SelectionItem). После — 0. --- .../skd-compile/scripts/skd-compile.ps1 | 20 +++- .../skills/skd-compile/scripts/skd-compile.py | 17 ++- .../skd-decompile/scripts/skd-decompile.ps1 | 25 ++++- .../dataset-folder-and-auto-group.json | 39 +++++++ .../Template.xml | 101 ++++++++++++++++++ .../decompiled.json | 26 +++++ 6 files changed, 221 insertions(+), 7 deletions(-) create mode 100644 tests/skills/cases/skd-decompile/dataset-folder-and-auto-group.json create mode 100644 tests/skills/cases/skd-decompile/snapshots/dataset-folder-and-auto-group/Template.xml create mode 100644 tests/skills/cases/skd-decompile/snapshots/dataset-folder-and-auto-group/decompiled.json diff --git a/.claude/skills/skd-compile/scripts/skd-compile.ps1 b/.claude/skills/skd-compile/scripts/skd-compile.ps1 index 2f8947b1..ff5d2d7c 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.ps1 +++ b/.claude/skills/skd-compile/scripts/skd-compile.ps1 @@ -1,4 +1,4 @@ -# skd-compile v1.34 — Compile 1C DCS from JSON +# skd-compile v1.35 — Compile 1C DCS from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$DefinitionFile, @@ -848,6 +848,19 @@ function Emit-Field { if ($null -ne $fieldDef.inputParameters) { $f["inputParameters"] = $fieldDef.inputParameters } + # folder: true → DataSetFieldFolder (поле-папка для UI-группировки, только dataPath+title) + if ($fieldDef.folder -eq $true) { + $f["folder"] = $true + } + } + + # DataSetFieldFolder — только dataPath + title (для UI-группировки полей в композиторе) + if ($f["folder"]) { + X "$indent" + X "$indent`t$(Esc-Xml $f.dataPath)" + if ($f.title) { Emit-MLText -tag "title" -text $f.title -indent "$indent`t" } + X "$indent" + return } X "$indent" @@ -2239,6 +2252,11 @@ function Emit-GroupItems { X "$indent" foreach ($field in $groupBy) { if ($field -is [string]) { + if ($field -eq 'Auto') { + # Auto-группировка (по аналогии с "Auto" в selection) + X "$indent`t" + continue + } X "$indent`t" X "$indent`t`t$(Esc-Xml $field)" X "$indent`t`tItems" diff --git a/.claude/skills/skd-compile/scripts/skd-compile.py b/.claude/skills/skd-compile/scripts/skd-compile.py index 524fc040..a2fe3ddb 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.py +++ b/.claude/skills/skd-compile/scripts/skd-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# skd-compile v1.34 — Compile 1C DCS from JSON +# skd-compile v1.35 — Compile 1C DCS from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -642,6 +642,18 @@ def emit_field(lines, field_def, indent): # inputParameters — массив элементов, типизированных по форме value if field_def.get('inputParameters') is not None: f['inputParameters'] = field_def['inputParameters'] + # folder: true → DataSetFieldFolder + if field_def.get('folder') is True: + f['folder'] = True + + # DataSetFieldFolder — только dataPath + title + if f.get('folder'): + lines.append(f'{indent}') + lines.append(f'{indent}\t{esc_xml(f["dataPath"])}') + if f.get('title'): + emit_mltext(lines, f'{indent}\t', 'title', f['title']) + lines.append(f'{indent}') + return lines.append(f'{indent}') lines.append(f'{indent}\t{esc_xml(f["dataPath"])}') @@ -1861,6 +1873,9 @@ def emit_group_items(lines, group_by, indent): lines.append(f'{indent}') for field in group_by: if isinstance(field, str): + if field == 'Auto': + lines.append(f'{indent}\t') + continue lines.append(f'{indent}\t') lines.append(f'{indent}\t\t{esc_xml(field)}') lines.append(f'{indent}\t\tItems') diff --git a/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 b/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 index 99356821..0a8f4957 100644 --- a/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 +++ b/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 @@ -1,4 +1,4 @@ -# skd-decompile v0.16 — Decompile 1C DCS Template.xml to JSON DSL (draft) +# skd-decompile v0.17 — Decompile 1C DCS Template.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -1152,6 +1152,9 @@ function Build-SelectionItem { if (-not $xt) { $fName = Get-Text $item "dcsset:field" if ($fName) { return $fName } + # Пустой → wildcard (apply to all) — эквивалентно Auto + $fieldEl = $item.SelectSingleNode("dcsset:field", $ns) + if ($fieldEl) { return 'Auto' } } switch ($xt) { 'SelectedItemAuto' { return 'Auto' } @@ -1352,7 +1355,9 @@ function Get-GroupFields { if (-not $gi) { return ,$gFields } foreach ($gItem in $gi.SelectNodes("dcsset:item", $ns)) { $gxt = Get-LocalXsiType $gItem - if ($gxt -eq 'GroupItemField') { + if ($gxt -eq 'GroupItemAuto') { + $gFields += 'Auto' + } elseif ($gxt -eq 'GroupItemField') { $gf = Get-Text $gItem "dcsset:field" $pat = Get-Text $gItem "dcsset:periodAdditionType" $gt = Get-Text $gItem "dcsset:groupType" @@ -1613,10 +1618,20 @@ function Build-DataSet { $fi = 0 foreach ($fn in $fieldNodes) { $fxsi = Get-LocalXsiType $fn - if ($fxsi -ne 'DataSetFieldField') { - $fields += (New-Sentinel -kind "FieldType:$fxsi" -loc "$loc/field[$fi]" -detail 'Тип поля не DataSetFieldField') - } else { + if ($fxsi -eq 'DataSetFieldField') { $fields += (Build-Field -fieldNode $fn -loc "$loc/field[$fi]") + } elseif ($fxsi -eq 'DataSetFieldFolder') { + # Поле-папка для UI-группировки (только dataPath+title, без типа/роли) + $folderObj = [ordered]@{ + field = (Get-Text $fn "r:dataPath") + folder = $true + } + $titleNode = $fn.SelectSingleNode("r:title", $ns) + $title = Get-MLText $titleNode + if ($title) { $folderObj['title'] = $title } + $fields += $folderObj + } else { + $fields += (New-Sentinel -kind "FieldType:$fxsi" -loc "$loc/field[$fi]" -detail 'Тип поля не DataSetFieldField/Folder') } $fi++ } diff --git a/tests/skills/cases/skd-decompile/dataset-folder-and-auto-group.json b/tests/skills/cases/skd-decompile/dataset-folder-and-auto-group.json new file mode 100644 index 00000000..0bc94b2b --- /dev/null +++ b/tests/skills/cases/skd-decompile/dataset-folder-and-auto-group.json @@ -0,0 +1,39 @@ +{ + "name": "DataSetFieldFolder (поле-папка) + GroupItemAuto в structure", + "preRun": [ + { + "script": "skd-compile/scripts/skd-compile", + "input": { + "dataSets": [{ + "name": "Тест", + "query": "ВЫБРАТЬ * ИЗ Справочник.Сотрудники", + "fields": [ + "Период: date", + { "field": "СальдоНаНачалоПериода", "folder": true, "title": "Сальдо на начало периода" }, + "СальдоНаНачалоПериода.Дт: decimal(15,2)", + "СальдоНаНачалоПериода.Кт: decimal(15,2)" + ] + }], + "settingsVariants": [ + { + "name": "Основной", + "settings": { + "structure": [ + { + "groupFields": ["Auto"], + "children": [ + { "groupFields": ["Период"] } + ] + } + ] + } + } + ] + }, + "args": { "-DefinitionFile": "{inputFile}", "-OutputPath": "Template.xml" }, + "cwd": "{workDir}" + } + ], + "params": { "templatePath": "Template.xml" }, + "outputPath": "decompiled.json" +} diff --git a/tests/skills/cases/skd-decompile/snapshots/dataset-folder-and-auto-group/Template.xml b/tests/skills/cases/skd-decompile/snapshots/dataset-folder-and-auto-group/Template.xml new file mode 100644 index 00000000..3a4dbfea --- /dev/null +++ b/tests/skills/cases/skd-decompile/snapshots/dataset-folder-and-auto-group/Template.xml @@ -0,0 +1,101 @@ + + + + ИсточникДанных1 + Local + + + Тест + + Период + Период + + xs:dateTime + + Date + + + + + СальдоНаНачалоПериода + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Сальдо на начало периода</v8:content> + </v8:item> + + + + СальдоНаНачалоПериода.Дт + СальдоНаНачалоПериода.Дт + + xs:decimal + + 15 + 2 + Any + + + + + СальдоНаНачалоПериода.Кт + СальдоНаНачалоПериода.Кт + + xs:decimal + + 15 + 2 + Any + + + + ИсточникДанных1 + ВЫБРАТЬ * ИЗ Справочник.Сотрудники + + + Основной + + + ru + Основной + + + + + + + + + + + + + + + + + Период + Items + None + 0001-01-01T00:00:00 + 0001-01-01T00:00:00 + + + + + + + + + + + + + diff --git a/tests/skills/cases/skd-decompile/snapshots/dataset-folder-and-auto-group/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/dataset-folder-and-auto-group/decompiled.json new file mode 100644 index 00000000..28d93d0e --- /dev/null +++ b/tests/skills/cases/skd-decompile/snapshots/dataset-folder-and-auto-group/decompiled.json @@ -0,0 +1,26 @@ +{ + "dataSets": [ + { + "name": "Тест", + "query": "ВЫБРАТЬ * ИЗ Справочник.Сотрудники", + "fields": [ + "Период: date", + { + "field": "СальдоНаНачалоПериода", + "folder": true, + "title": "Сальдо на начало периода" + }, + "СальдоНаНачалоПериода.Дт: decimal(15,2)", + "СальдоНаНачалоПериода.Кт: decimal(15,2)" + ] + } + ], + "settingsVariants": [ + { + "name": "Основной", + "settings": { + "structure": "Auto > Период" + } + } + ] +} \ No newline at end of file