diff --git a/.claude/skills/role-compile/SKILL.md b/.claude/skills/role-compile/SKILL.md
index 67ba38743..da0a9459e 100644
--- a/.claude/skills/role-compile/SKILL.md
+++ b/.claude/skills/role-compile/SKILL.md
@@ -91,6 +91,13 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/role-compile.ps1" -
Ссылка в `rls`: `"#ДляОбъекта(\"\")"`. Символ `&` автоматически экранируется в XML.
+Длинное условие держи в файле — в значении пишется `@путь` (путь от текущего каталога):
+
+```json
+"objects": [{"name": "Document.Продажа", "preset": "view", "rls": {"Read": "@условие.txt"}}],
+"templates": [{"name": "ДляОбъекта(Мод)", "condition": "@шаблон.txt"}]
+```
+
## Примеры
### Простая роль
diff --git a/.claude/skills/role-compile/scripts/role-compile.ps1 b/.claude/skills/role-compile/scripts/role-compile.ps1
index 6954b57bd..c5d6a7aa6 100644
--- a/.claude/skills/role-compile/scripts/role-compile.ps1
+++ b/.claude/skills/role-compile/scripts/role-compile.ps1
@@ -1,4 +1,4 @@
-# role-compile v1.39 — Compile 1C role from JSON
+# role-compile v1.40 — Compile 1C role from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
[CmdletBinding(PositionalBinding=$false)]
param(
@@ -1072,6 +1072,20 @@ function Validate-RightName {
return $true
}
+# "@путь" в значении условия — текст берётся из файла: условия RLS типовых занимают десятки
+# строк с кавычками, и внутри JSON-строки это источник ошибок экранирования. Путь относительный —
+# от текущего каталога, как в role-edit.
+function Resolve-TextValue([string]$text) {
+ if (-not $text -or -not $text.StartsWith("@")) { return $text }
+ $valueFile = $text.Substring(1).Trim()
+ if (-not [System.IO.Path]::IsPathRooted($valueFile)) { $valueFile = Join-Path (Get-Location).Path $valueFile }
+ if (-not (Test-Path -LiteralPath $valueFile -PathType Leaf)) {
+ Add-ValidationError "Файл значения не найден: $valueFile"
+ return $text
+ }
+ return [System.IO.File]::ReadAllText($valueFile).Trim()
+}
+
# --- 5a. Service roots: expand to leaves ---
# Метаданные сервиса читаются один раз на имя: раскрытие и проверка заимствования
@@ -1290,7 +1304,7 @@ function Parse-ObjectEntry {
foreach ($p in $entry.rls.PSObject.Properties) {
$rlsRight = Translate-RightName $p.Name
if ($rightsMap.Contains($rlsRight)) {
- $rightsMap[$rlsRight].Condition = "$($p.Value)"
+ $rightsMap[$rlsRight].Condition = Resolve-TextValue "$($p.Value)"
} else {
Write-Warning "${objName}: RLS for '$rlsRight' but this right is not in the rights list"
}
@@ -1478,7 +1492,7 @@ if ($def.templates) {
foreach ($tpl in $def.templates) {
X "`t"
X "`t`t$(Esc-XmlText "$($tpl.name)")"
- X "`t`t$(Esc-XmlText "$($tpl.condition)")"
+ X "`t`t$(Esc-XmlText (Resolve-TextValue "$($tpl.condition)"))"
X "`t"
$templateCount++
}
diff --git a/.claude/skills/role-compile/scripts/role-compile.py b/.claude/skills/role-compile/scripts/role-compile.py
index ad9917ea5..a67f3ab99 100644
--- a/.claude/skills/role-compile/scripts/role-compile.py
+++ b/.claude/skills/role-compile/scripts/role-compile.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# role-compile v1.39 — Compile 1C role from JSON
+# role-compile v1.40 — Compile 1C role from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -1165,6 +1165,22 @@ def validate_right_name(object_name, right_name):
return True
+# "@путь" в значении условия — текст берётся из файла: условия RLS типовых занимают десятки
+# строк с кавычками, и внутри JSON-строки это источник ошибок экранирования. Путь относительный —
+# от текущего каталога, как в role-edit.
+def resolve_text_value(text):
+ if not text or not text.startswith("@"):
+ return text
+ value_file = text[1:].strip()
+ if not os.path.isabs(value_file):
+ value_file = os.path.join(os.getcwd(), value_file)
+ if not os.path.isfile(value_file):
+ add_validation_error(f"Файл значения не найден: {value_file}")
+ return text
+ with open(value_file, encoding="utf-8-sig") as f:
+ return f.read().strip()
+
+
MD_NS = 'http://v8.1c.ru/8.3/MDClasses'
# Метаданные сервиса читаются один раз на имя: раскрытие и проверка заимствования
@@ -1364,7 +1380,7 @@ def parse_object_entry(entry):
for p_name, p_value in entry['rls'].items():
rls_right = translate_right_name(p_name)
if rls_right in rights_map:
- rights_map[rls_right]['Condition'] = str(p_value)
+ rights_map[rls_right]['Condition'] = resolve_text_value(str(p_value))
else:
print(f"WARNING: {obj_name}: RLS for '{rls_right}' but this right is not in the rights list", file=sys.stderr)
@@ -1724,7 +1740,7 @@ def main():
for tpl in defn['templates']:
lines.append('\t')
lines.append(f'\t\t{esc_xml_text(str(tpl["name"]))}')
- lines.append(f'\t\t{esc_xml_text(str(tpl["condition"]))}')
+ lines.append(f'\t\t{esc_xml_text(resolve_text_value(str(tpl["condition"])))}')
lines.append('\t')
template_count += 1
diff --git a/tests/skills/cases/role-compile/rls-condition-from-file.json b/tests/skills/cases/role-compile/rls-condition-from-file.json
new file mode 100644
index 000000000..a6760a2ed
--- /dev/null
+++ b/tests/skills/cases/role-compile/rls-condition-from-file.json
@@ -0,0 +1,37 @@
+{
+ "name": "Условие RLS и тело шаблона берутся из файла",
+ "setup": "fixture:view-preset-fx",
+ "cwd": "workDir",
+ "caseFiles": [
+ "rls-usloviye.txt"
+ ],
+ "input": {
+ "name": "РольИзФайла",
+ "synonym": "Роль из файла",
+ "objects": [
+ {
+ "name": "Catalog.Номенклатура",
+ "preset": "view",
+ "rls": {
+ "Read": "@rls-usloviye.txt"
+ }
+ }
+ ],
+ "templates": [
+ {
+ "name": "ПоОрганизации(Мод)",
+ "condition": "@rls-usloviye.txt"
+ }
+ ]
+ },
+ "validatePath": "Roles/РольИзФайла",
+ "expect": {
+ "fileContains": {
+ "file": "Roles/РольИзФайла/Ext/Rights.xml",
+ "text": [
+ "ОграничениеПоОрганизации",
+ "restrictionTemplate"
+ ]
+ }
+ }
+}
diff --git a/tests/skills/cases/role-compile/rls-usloviye.txt b/tests/skills/cases/role-compile/rls-usloviye.txt
new file mode 100644
index 000000000..eaef48d49
--- /dev/null
+++ b/tests/skills/cases/role-compile/rls-usloviye.txt
@@ -0,0 +1,3 @@
+#Если &ОграничениеПоОрганизации #Тогда
+ ГДЕ Организация = &ТекущаяОрганизация
+#КонецЕсли
\ No newline at end of file
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Catalogs/Номенклатура.xml b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Catalogs/Номенклатура.xml
new file mode 100644
index 000000000..0daed60e9
--- /dev/null
+++ b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Catalogs/Номенклатура.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+ UUID-002
+ UUID-003
+
+
+ UUID-004
+ UUID-005
+
+
+ UUID-006
+ UUID-007
+
+
+ UUID-008
+ UUID-009
+
+
+ UUID-010
+ UUID-011
+
+
+
+ Номенклатура
+
+
+ ru
+ Номенклатура
+
+
+
+ false
+ HierarchyFoldersAndItems
+ false
+ 2
+ true
+ true
+
+ 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
+
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Catalogs/Номенклатура/Ext/ObjectModule.bsl b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Catalogs/Номенклатура/Ext/ObjectModule.bsl
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Configuration.xml b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Configuration.xml
new file mode 100644
index 000000000..cde3bcf92
--- /dev/null
+++ b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Configuration.xml
@@ -0,0 +1,254 @@
+
+
+
+
+
+ UUID-002
+ UUID-003
+
+
+ UUID-004
+ UUID-005
+
+
+ UUID-006
+ UUID-007
+
+
+ UUID-008
+ UUID-009
+
+
+ UUID-010
+ UUID-011
+
+
+ UUID-012
+ UUID-013
+
+
+ UUID-014
+ UUID-015
+
+
+
+ TestConfig
+
+
+ ru
+ TestConfig
+
+
+
+
+ Version8_3_24
+ ManagedApplication
+
+ PlatformApplication
+
+ Russian
+
+
+
+
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Biometrics
+ true
+
+
+ Location
+ false
+
+
+ BackgroundLocation
+ false
+
+
+ BluetoothPrinters
+ false
+
+
+ WiFiPrinters
+ false
+
+
+ Contacts
+ false
+
+
+ Calendars
+ false
+
+
+ PushNotifications
+ false
+
+
+ LocalNotifications
+ false
+
+
+ InAppPurchases
+ false
+
+
+ PersonalComputerFileExchange
+ false
+
+
+ Ads
+ false
+
+
+ NumberDialing
+ false
+
+
+ CallProcessing
+ false
+
+
+ CallLog
+ false
+
+
+ AutoSendSMS
+ false
+
+
+ ReceiveSMS
+ false
+
+
+ SMSLog
+ false
+
+
+ Camera
+ false
+
+
+ Microphone
+ false
+
+
+ MusicLibrary
+ false
+
+
+ PictureAndVideoLibraries
+ false
+
+
+ AudioPlaybackAndVibration
+ false
+
+
+ BackgroundAudioPlaybackAndVibration
+ false
+
+
+ InstallPackages
+ false
+
+
+ OSBackup
+ true
+
+
+ ApplicationUsageStatistics
+ false
+
+
+ BarcodeScanning
+ false
+
+
+ BackgroundAudioRecording
+ false
+
+
+ AllFilesAccess
+ false
+
+
+ Videoconferences
+ false
+
+
+ NFC
+ false
+
+
+ DocumentScanning
+ false
+
+
+ SpeechToText
+ false
+
+
+ Geofences
+ false
+
+
+ IncomingShareRequests
+ false
+
+
+ AllIncomingShareRequestsTypesProcessing
+ false
+
+
+
+
+
+ Normal
+
+
+ Language.Русский
+
+
+
+
+
+ Managed
+ NotAutoFree
+ DontUse
+ DontUse
+ TaxiEnableVersion8_2
+ DontUse
+ Version8_3_24
+
+
+
+ Русский
+ РольИзФайла
+ Номенклатура
+ Загрузка
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/DataProcessors/Загрузка.xml b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/DataProcessors/Загрузка.xml
new file mode 100644
index 000000000..fa5caaf26
--- /dev/null
+++ b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/DataProcessors/Загрузка.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+ UUID-002
+ UUID-003
+
+
+ UUID-004
+ UUID-005
+
+
+
+ Загрузка
+
+
+ ru
+ Загрузка
+
+
+
+ true
+
+
+ false
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/DataProcessors/Загрузка/Ext/ManagerModule.bsl b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/DataProcessors/Загрузка/Ext/ManagerModule.bsl
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/DataProcessors/Загрузка/Ext/ObjectModule.bsl b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/DataProcessors/Загрузка/Ext/ObjectModule.bsl
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Ext/ClientApplicationInterface.xml b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Ext/ClientApplicationInterface.xml
new file mode 100644
index 000000000..3c1161b2d
--- /dev/null
+++ b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Ext/ClientApplicationInterface.xml
@@ -0,0 +1,18 @@
+
+
+
+
+ UUID-002
+
+
+
+
+ UUID-004
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Languages/Русский.xml b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Languages/Русский.xml
new file mode 100644
index 000000000..37c60d786
--- /dev/null
+++ b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Languages/Русский.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ Русский
+
+
+ ru
+ Русский
+
+
+
+ ru
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Roles/РольИзФайла.xml b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Roles/РольИзФайла.xml
new file mode 100644
index 000000000..5fe249406
--- /dev/null
+++ b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Roles/РольИзФайла.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ РольИзФайла
+
+
+ ru
+ Роль из файла
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Roles/РольИзФайла/Ext/Rights.xml b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Roles/РольИзФайла/Ext/Rights.xml
new file mode 100644
index 000000000..3bd7e4c29
--- /dev/null
+++ b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/Roles/РольИзФайла/Ext/Rights.xml
@@ -0,0 +1,32 @@
+
+
+ false
+ true
+ false
+
+
+ ПоОрганизации(Мод)
+ #Если &ОграничениеПоОрганизации #Тогда
+ ГДЕ Организация = &ТекущаяОрганизация
+#КонецЕсли
+
+
\ No newline at end of file
diff --git a/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/rls-usloviye.txt b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/rls-usloviye.txt
new file mode 100644
index 000000000..eaef48d49
--- /dev/null
+++ b/tests/skills/cases/role-compile/snapshots/rls-condition-from-file/rls-usloviye.txt
@@ -0,0 +1,3 @@
+#Если &ОграничениеПоОрганизации #Тогда
+ ГДЕ Организация = &ТекущаяОрганизация
+#КонецЕсли
\ No newline at end of file