Added Configuration Schema and Validation - #529
Open
fashxp wants to merge 97 commits into
Open
Conversation
- Extract collectServicesByType() helper method in ConfigurationDefinitionPass to eliminate 8 duplicated foreach loops - Add validateSchemaAwareSettings() helper method in ConfigurationValidationService to reduce duplication across validation methods - Fix line length issue in ConfigurationDefinitionPass (split long line) - Reduces cognitive complexity and improves maintainability
Add @phpstan-ignore-next-line comments for children() method calls that fail type inference with Symfony 6.4.0 (lowest dependencies). The children() method returns NodeParentInterface in older versions instead of NodeBuilder, causing PHPStan to complain about undefined methods like scalarNode(), enumNode(), etc.
Move @phpstan-ignore-next-line comments to the correct lines where the actual failing method calls occur (scalarNode, variableNode, arrayNode, enumNode) instead of on the children() line. PHPStan complains about these method calls, not about children() itself.
# Conflicts: # src/DataSource/Loader/HttpLoader.php
|
# Conflicts: # composer.json # src/Resources/config/pimcore/routing.yml
unified tool naming updated docs added create and save data importer config tool
NotWriteableException is a sibling of ForbiddenException rather than a subclass, so it fell through to the generic handler and reached the agent as an opaque failure. Co-Authored-By: Claude <noreply@anthropic.com>
run_import_config gets its own group so triggering imports can be granted separately from authoring configurations. Both delegate to the Studio import service, which enforces the per configuration rights the Studio button enforces. Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
The class field has to be the brick container, and the brick field has to be filterable, the same rule the non-brick path already applied. Co-Authored-By: Claude <noreply@anthropic.com>
A double encoded escape reached fgetcsv() as two characters, which failed the preview with a raw ValueError. The schema now rejects it while the config is being written, and the interpreter names the offending setting. Co-Authored-By: Claude <noreply@anthropic.com>
The enum listed recurring and cron only, so a configuration scheduled for a single run failed validation on a value the UI itself produces. Co-Authored-By: Claude <noreply@anthropic.com>
Nothing validated the property, so a guess was accepted and stored, and the tool descriptions demanded it anyway. Validation already derives the type from the pipeline; save_import_config now writes that value into each mapping item. Co-Authored-By: Claude <noreply@anthropic.com>
The two new tests built their subjects with newInstanceWithoutConstructor and read private state, which Sonar flags as an accessibility bypass. All three are registered services, so the test container can hand them over directly. Co-Authored-By: Claude <noreply@anthropic.com>
Reading a few rows, proposing a mapping before checking what the class stores, and leaving records without a key each produced a broken configuration that still validated. Co-Authored-By: Claude <noreply@anthropic.com>
Both errors that cost the agent a round trip now carry the answer: the loadable attributes, and the operator that produces an accepted type. Catalogues default to naming settings rather than describing them. Co-Authored-By: Claude <noreply@anthropic.com>
Items are applied in order and each writes its target outright, so splitting one field across several items silently discards all but the last. Co-Authored-By: Claude <noreply@anthropic.com>
Mutually exclusive source columns are a real pattern, but only with writeIfSourceIsEmpty false; the defaults let the last item overwrite. Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts: # .php-cs-fixer.cache
The 132 character line was the only gate blocker. The SqlFileInterpreter override merely narrowed a return type nothing reads, and the fake hosts in the tool tests no longer look like IP addresses. Co-Authored-By: Claude <noreply@anthropic.com>
getServiceSchema() emits type, description and settings, never a label, so the two label-only stubs stopped matching once the brief catalogue started whitelisting keys. Co-Authored-By: Claude <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Import configurations are large, deeply nested documents whose valid shape lives only in the Studio
UI and in the factories that consume them. A hand-written or generated configuration therefore fails
at import time, with an error that points at a symptom rather than at the offending key.
This PR gives every configuration component a machine-readable schema, adds a validation service that
checks a whole configuration against it, and exposes both to AI agents through an optional set of MCP
tools.
Schema and validation
Components now describe their own settings through three optional interfaces:
SchemaAwareInterfaceTreeBuilderfor the settings plus a one-line descriptionDataTargetFieldValidatorInterfaceTransformationTypeAwareInterfaceConfigurationValidationServiceprocesses those trees over a complete configuration and returnserrors carrying the path that failed. It also computes each mapping item's
transformationResultType,which the Studio mapping editor reads to offer the right target attributes.
From the console:
MCP tools (optional)
Eleven tools in three groups, registered only when
mcp/sdkis installed — normally as atransitive dependency of
pimcore/pimcore-agent-bundle, which also serves them. Every tool refuses acaller without the
plugin_datahub_configpermission.pimcore-data-importer-readget_import_config_context,get_import_config_examples,get_class_fields_for_loading,list_import_configs,get_import_config,validate_import_config,enrich_import_config,get_import_statuspimcore-data-importer-direct-writecreate_import_config,save_import_configpimcore-data-importer-executerun_import_configsave_import_configvalidates before it persists, so an invalid configuration is refused rather thanstored. A bundled skill (
src/Resources/skills/data-importer-configuration/SKILL.md) tells the agenthow to compose a configuration and which mistakes to avoid.
Docs and examples
doc/06_Extending/01_Custom_Strategies.md— implementing the three interfaces in a custom strategydoc/06_Extending/03_Configuration_Validation.md— validation service and schema introspectiondoc/07_MCP_Tools.md— the tools, their call order and their argumentsdoc/examples/— three annotated YAML configurationsCompatibility
No BC break. The three interfaces are additive and optional; no existing interface gained a method
and no service was renamed or removed.
mcp/sdkis asuggest, not arequire, so installationswithout it are unaffected apart from the MCP tools not being registered.
The minimum
pimcore/studio-backend-bundlemoves to^2026.3, for the shared MCP toolregistration and error handler.