Initial SQL-only 1C adapter baseline

This commit is contained in:
2026-07-22 03:03:47 +03:00
commit e2503b77e7
545 changed files with 184711 additions and 0 deletions
+151
View File
@@ -0,0 +1,151 @@
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
sys.path.insert(0, str(ROOT / "plugins" / "1c"))
sys.path.insert(0, str(ROOT / "plugins" / "1c" / "connector"))
import adapter_1c_server as adapter_server # noqa: E402
def require(condition: bool, message: str, failures: list[str]) -> None:
if not condition:
failures.append(message)
def patch_adapter_for_symbol_checks() -> None:
def fake_definition_find(payload: dict[str, Any]) -> dict[str, Any]:
query = str(payload.get("query") or "")
if query == "Артикул":
return {
"schema": "onec_definition_find.v1",
"status": "ok",
"matches": [
{
"canonical_path": "Справочник.Номенклатура.Артикул",
"kind": "Catalog",
"name": "Номенклатура",
}
],
}
if query == "Номенклатура":
return {
"schema": "onec_definition_find.v1",
"status": "ok",
"matches": [
{
"canonical_path": "Справочник.Номенклатура",
"kind": "Catalog",
"name": "Номенклатура",
}
],
}
return {"schema": "onec_definition_find.v1", "status": "ok", "matches": []}
def fake_read_module(payload: dict[str, Any]) -> dict[str, Any]:
return {
"schema": "onec_module_read.v1",
"status": "ok",
"text": "Процедура ПередЗаписью(Отказ) Экспорт\n Отказ = Истина;\nКонецПроцедуры",
"owner": {"kind": "Catalog", "name": "Номенклатура"},
"module": {"name": "Модуль объекта"},
}
def fake_attributes(payload: dict[str, Any]) -> dict[str, Any]:
return {"schema": "onec_metadata_object_attributes.v1", "status": "ok", "attributes": []}
adapter_server.metadata_definition_find = fake_definition_find
adapter_server.read_module = fake_read_module
adapter_server.metadata_object_attributes = fake_attributes
def check_full_path(failures: list[str]) -> None:
result = adapter_server.call_method(
"code.symbol.resolve",
{
"base_id": "upo_test",
"expression": "Справочник.Номенклатура.Артикул",
"module_ref": "ConfigSave:file:0",
},
)
require(result.get("schema") == "onec_bsl_symbol_resolution.v1", "full path must return BSL symbol schema", failures)
require(result.get("status") == "resolved", "full path must resolve", failures)
require(result.get("resolution_kind") == "metadata_path", "full path must be classified as metadata_path", failures)
require(result.get("canonical_path") == "Справочник.Номенклатура.Артикул", "full path must expose canonical_path publicly", failures)
require(result.get("safe_as_metadata_path") is True, "full path must expose safe_as_metadata_path=true", failures)
def check_parameter(failures: list[str]) -> None:
result = adapter_server.call_method(
"code.symbol.resolve",
{
"base_id": "upo_test",
"expression": "Отказ.Код",
"routine_name": "ПередЗаписью",
"module_ref": "ConfigSave:file:0",
},
)
require(result.get("status") == "resolved", "routine parameter must resolve", failures)
require(result.get("resolution_kind") == "parameter", "routine parameter must not be metadata", failures)
require(result.get("context_path") == "Отказ.Код", "routine parameter must expose context_path publicly", failures)
require(result.get("safe_as_metadata_path") is False, "routine parameter must expose safe_as_metadata_path=false", failures)
def check_short_name(failures: list[str]) -> None:
result = adapter_server.call_method(
"code.symbol.resolve",
{
"base_id": "upo_test",
"expression": "Номенклатура.ЕдИзмерение.Код",
"routine_name": "ПередЗаписью",
"module_ref": "ConfigSave:file:0",
},
)
candidates = result.get("candidates") if isinstance(result.get("candidates"), list) else []
require(result.get("status") == "unresolved", "short object name must stay unresolved", failures)
require(result.get("safe_as_metadata_path") is False, "short object name must expose safe_as_metadata_path=false", failures)
require(bool(candidates), "short object name must return ambiguity candidates", failures)
if candidates:
require(candidates[0].get("canonical_path") == "Справочник.Номенклатура", "candidate canonical_path must stay public", failures)
require(candidates[0].get("reason") == "short_object_name_requires_kind", "candidate must explain short name risk", failures)
def run_checks() -> dict[str, Any]:
patch_adapter_for_symbol_checks()
failures: list[str] = []
check_full_path(failures)
check_parameter(failures)
check_short_name(failures)
return {
"schema": "onec_code_symbol_contract_check.v1",
"status": "ok" if not failures else "failed",
"failures": failures,
"checks": {
"full_path_metadata": "full path must resolve as metadata_path",
"parameter_not_metadata": "routine parameter must not be metadata",
"short_name_unsafe": "short object name must remain unsafe",
},
}
def main() -> int:
parser = argparse.ArgumentParser(description="Check adapter-level code.symbol.resolve contract invariants.")
parser.add_argument("--print", action="store_true")
args = parser.parse_args()
report = run_checks()
if args.print or report["status"] != "ok":
print(json.dumps(report, ensure_ascii=False, indent=2))
else:
print("1C code symbol contract status: ok")
return 0 if report["status"] == "ok" else 1
if __name__ == "__main__":
raise SystemExit(main())