Document name-first write plan selectors
This commit is contained in:
@@ -770,7 +770,7 @@ METHODS = [
|
||||
{"name": "metadata.form.command_button.write", "transport": "POST /rpc", "description": "Plan/apply a form command workflow: optional BSL handler routine upsert plus form command and visible command button append. Recognizes CommonForm/top-level common forms and object-owned forms; prepares saved-state when needed. XML is analysis/learning input only, not the live adapter write transport."},
|
||||
{"name": "metadata.form.command_button.verify", "transport": "POST /rpc", "description": "Read-only verification for a saved-state form command workflow: command, visible button, embedded handler routine, command-handler link, and button-command link. Accepts the same public form selectors as metadata.form.command_button.write."},
|
||||
{"name": "metadata.module.write_apply", "transport": "POST /rpc", "description": "Orchestrate saved-state BSL module stream writes from module_ref/table/file_name: plan, apply, or apply_and_rollback. Requires explicit saved-state write/apply gates."},
|
||||
{"name": "metadata.write.plan", "transport": "POST /rpc", "description": "Read-only metadata write planner. Resolves full 1C paths or concrete saved-state references, reports layer/provenance requirements, and never applies changes."},
|
||||
{"name": "metadata.write.plan", "transport": "POST /rpc", "description": "Read-only name-first metadata write planner. For forms pass target.kind=form with extension/ref/form and element, command, or attribute plus edits; for modules reuse the public write_plan_target from metadata.saved_state.modules.search. The adapter resolves saved-state SQL handles internally, reports layer/provenance requirements, and never applies changes."},
|
||||
{"name": "metadata.write.preflight", "transport": "POST /rpc", "description": "Read-only preflight for high-level writes. Combines metadata.write.plan with live saved-state verification and reports ready, needs_prepare, needs_resolution, or blocked before any write."},
|
||||
{"name": "metadata.write.capabilities", "transport": "POST /rpc", "description": "Agent-facing matrix of what the adapter can read, plan, and write to the saved-state layer. SQL/storage details are hidden unless include_storage=true."},
|
||||
{"name": "metadata.write", "transport": "POST /rpc", "description": "High-level metadata write orchestrator. Routes saved-state form, module, and scheduled-job schedule targets by public 1C names, builds reviewable proposals, and can apply with explicit saved-state SQL gates. Module writes support text, old/new, and routine_name/routine_text edits with expected_sha1/expected_text_sha1 guards."},
|
||||
@@ -1033,6 +1033,14 @@ METHOD_INPUT_SCHEMAS["metadata.write"] = {
|
||||
"area": {"type": "string", "enum": ["object", "form", "module", "schedule"]},
|
||||
"ref": {"type": "string", "description": "Public 1C object/member ref."},
|
||||
"canonical_path": {"type": "string", "description": "Public 1C code or metadata path."},
|
||||
"extension": {"type": "string", "description": "Public extension name for an extension-owned form or module."},
|
||||
"form": {"type": "string", "description": "Exact 1C form name."},
|
||||
"element": {"type": "string", "description": "Exact 1C form element name."},
|
||||
"command": {"type": "string", "description": "Exact 1C form command name."},
|
||||
"attribute": {"type": "string", "description": "Exact 1C form attribute name."},
|
||||
"module": {"type": "string", "description": "Public module role/name returned by saved-state module search."},
|
||||
"qualified_name": {"type": "string", "description": "Public qualified form or module name returned by search."},
|
||||
"stream_ordinal": {"type": "integer", "minimum": 1, "description": "Public 1-based stream ordinal returned by saved-state module search."},
|
||||
"property": {"type": "string"},
|
||||
"operation": {
|
||||
"type": "string",
|
||||
@@ -1051,6 +1059,17 @@ METHOD_INPUT_SCHEMAS["metadata.write"] = {
|
||||
"extension": {"type": "string"},
|
||||
"property": {"type": "string"},
|
||||
"value": {},
|
||||
"edits": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["property", "value"],
|
||||
"properties": {
|
||||
"property": {"type": "string"},
|
||||
"value": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
"schedule": {"type": "object", "additionalProperties": True},
|
||||
"template_member_ref": {"type": "string"},
|
||||
"new_member_name": {"type": "string"},
|
||||
@@ -1090,6 +1109,18 @@ METHOD_INPUT_SCHEMAS["metadata.write"] = {
|
||||
},
|
||||
"mode": "plan",
|
||||
},
|
||||
{
|
||||
"base_id": "upo_test",
|
||||
"target": {
|
||||
"kind": "form",
|
||||
"extension": "test2",
|
||||
"ref": "Catalog.test2",
|
||||
"form": "t_Форма",
|
||||
"command": "ЗаменаДомена",
|
||||
},
|
||||
"edits": [{"property": "Заголовок", "value": "Замена домена"}],
|
||||
"mode": "plan",
|
||||
},
|
||||
{
|
||||
"base_id": "upo_test",
|
||||
"target": {
|
||||
@@ -1101,6 +1132,78 @@ METHOD_INPUT_SCHEMAS["metadata.write"] = {
|
||||
},
|
||||
],
|
||||
}
|
||||
METHOD_INPUT_SCHEMAS["metadata.write.plan"] = {
|
||||
"type": "object",
|
||||
"required": ["base_id", "target"],
|
||||
"additionalProperties": True,
|
||||
"properties": {
|
||||
"base_id": {"type": "string", "description": "Adapter base identifier."},
|
||||
"target": {
|
||||
"type": "object",
|
||||
"required": ["kind"],
|
||||
"additionalProperties": True,
|
||||
"description": "Prefer a public name-first selector; storage handles are optional follow-up values resolved internally from names.",
|
||||
"properties": {
|
||||
"kind": {"type": "string", "enum": ["form", "module", "metadata"]},
|
||||
"ref": {"type": "string", "description": "Preferred public owner ref, for example Catalog.Номенклатура."},
|
||||
"extension": {"type": "string", "description": "Public extension name."},
|
||||
"form": {"type": "string", "description": "Exact 1C form name."},
|
||||
"element": {"type": "string", "description": "Exact form element name."},
|
||||
"command": {"type": "string", "description": "Exact form command name."},
|
||||
"attribute": {"type": "string", "description": "Exact form attribute name."},
|
||||
"module": {"type": "string", "description": "Public module role/name returned by metadata.saved_state.modules.search."},
|
||||
"qualified_name": {"type": "string", "description": "Public qualified name returned by saved-state search."},
|
||||
"stream_ordinal": {"type": "integer", "minimum": 1},
|
||||
"canonical_path": {"type": "string", "description": "Full public 1C metadata/code path when one is already known."},
|
||||
},
|
||||
},
|
||||
"edits": {
|
||||
"type": "array",
|
||||
"description": "Form property edits. Planning resolves the target but does not apply them.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": ["property", "value"],
|
||||
"properties": {
|
||||
"property": {"type": "string", "description": "Public property presentation or canonical property name."},
|
||||
"value": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
"intent": {"type": "object", "additionalProperties": True, "description": "Module or metadata operation intent."},
|
||||
"resolve_origin": {"type": "boolean", "description": "Resolve a canonical path origin when no saved-state selector is available."},
|
||||
"timeout_seconds": {"type": "integer", "minimum": 1, "maximum": 300},
|
||||
},
|
||||
"examples": [
|
||||
{
|
||||
"base_id": "upo_test",
|
||||
"target": {
|
||||
"kind": "form",
|
||||
"extension": "test2",
|
||||
"ref": "Catalog.test2",
|
||||
"form": "t_Форма",
|
||||
"command": "ЗаменаДомена",
|
||||
},
|
||||
"edits": [{"property": "Заголовок", "value": "Замена домена"}],
|
||||
"resolve_origin": False,
|
||||
},
|
||||
{
|
||||
"base_id": "upo_test",
|
||||
"target": {
|
||||
"kind": "module",
|
||||
"ref": "Catalog.Номенклатура",
|
||||
"module": "Модуль менеджера",
|
||||
"stream_ordinal": 1,
|
||||
},
|
||||
"intent": {
|
||||
"operation": "replace_with_control",
|
||||
"control_fragment": "Процедура Обновить()",
|
||||
"new": "Процедура Обновить()\nКонецПроцедуры",
|
||||
},
|
||||
"resolve_origin": False,
|
||||
},
|
||||
],
|
||||
}
|
||||
METHOD_INPUT_SCHEMAS["metadata.write.preflight"] = copy.deepcopy(METHOD_INPUT_SCHEMAS["metadata.write.plan"])
|
||||
METHOD_INPUT_SCHEMAS["metadata.code_index.build"] = {
|
||||
"type": "object",
|
||||
"required": ["base_id"],
|
||||
|
||||
@@ -21787,6 +21787,27 @@ def test_metadata_write_plan_reports_unresolved_public_form_selector(monkeypatch
|
||||
assert any(problem["code"] == "public_form_target_not_resolved" for problem in result["problems"])
|
||||
|
||||
|
||||
def test_metadata_write_plan_help_describes_name_first_form_and_module_targets() -> None:
|
||||
methods = {
|
||||
row["name"]: row
|
||||
for row in adapter_server.call_method("help.methods", {})["methods"]
|
||||
}
|
||||
|
||||
for method_name in ("metadata.write.plan", "metadata.write.preflight"):
|
||||
method = methods[method_name]
|
||||
target_properties = method["input_schema"]["properties"]["target"]["properties"]
|
||||
assert method["input_schema"]["required"] == ["base_id", "target"]
|
||||
assert {"ref", "extension", "form", "element", "command", "attribute", "module", "qualified_name", "stream_ordinal"} <= set(target_properties)
|
||||
assert method["input_schema"]["properties"]["edits"]["items"]["required"] == ["property", "value"]
|
||||
examples = method["input_schema"]["examples"]
|
||||
assert any((example.get("target") or {}).get("kind") == "form" and (example.get("target") or {}).get("ref") for example in examples)
|
||||
assert any((example.get("target") or {}).get("kind") == "module" and (example.get("target") or {}).get("module") for example in examples)
|
||||
|
||||
description = methods["metadata.write.plan"]["description"]
|
||||
assert "name-first" in description
|
||||
assert "metadata.saved_state.modules.search" in description
|
||||
|
||||
|
||||
def test_metadata_write_preflight_verifies_concrete_saved_state(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
def fake_diff(payload: dict[str, Any]) -> dict[str, Any]:
|
||||
assert payload["module_ref"] == "ConfigCASSave:object-guid__module-guid.0#stream:4"
|
||||
|
||||
Reference in New Issue
Block a user