Skip to content

Add CLI command dab autoentities-configure#3086

Open
Copilot wants to merge 12 commits intomainfrom
copilot/add-autoentities-configure-command
Open

Add CLI command dab autoentities-configure#3086
Copilot wants to merge 12 commits intomainfrom
copilot/add-autoentities-configure-command

Conversation

Copy link
Contributor

Copilot AI commented Jan 30, 2026

Why make this change?

What is this change?

Added autoentities-configure command that upserts autoentities definitions with support for:

  • Pattern matching rules (--patterns.include, --patterns.exclude, --patterns.name)
  • Template configuration for REST, GraphQL, MCP, Health, Cache endpoints
  • Permissions using standard role:actions format

Implementation:

  • AutoentitiesConfigureOptions.cs - Command options class following existing CLI patterns
  • ConfigGenerator.TryConfigureAutoentities() - Main handler with builder methods for patterns, template, and permissions
  • Registered command in Program.cs parser

Bug fixes:

  • AutoentityConverter and AutoentityTemplateConverter - Added missing MCP options serialization logic that prevented MCP settings from persisting to config file
  • AutoentityTemplateConverter - Fixed GraphQL template serialization to only write enabled property, excluding type object (singular/plural) which is determined by generated entities

Improvements:

  • Enhanced error messages to display all valid parameter values using EnumExtensions.GenerateMessageForInvalidInput<T>() pattern
  • Cache level errors now show: "Invalid Source Type: {value}. Valid values are: L1,L1L2"
  • MCP dml-tool errors now show: "Invalid value for template.mcp.dml-tool: {value}. Valid values are: true, false"
  • Permissions validation: Added runtime validation that requires --permissions only when creating a new autoentity definition. When updating an existing definition, permissions are optional and preserved from the existing configuration.

How was this tested?

  • Unit Tests
  • Integration Tests

Added 8 unit tests covering:

  • Create/update operations with patterns and template options
  • Permission parsing with multiple actions
  • Error handling for invalid enum values
  • Multiple coexisting definitions
  • Permissions validation for new vs. existing definitions

Sample Request(s)

# Create new definition with patterns and permissions (permissions required for new definitions)
dab autoentities-configure my-def \
  --patterns.include "dbo.%" "sys.%" \
  --patterns.exclude "dbo.internal%" \
  --patterns.name "{schema}_{table}" \
  --permissions "anonymous:read"

# Configure template options (GraphQL now only writes 'enabled', not 'type')
dab autoentities-configure my-def \
  --template.rest.enabled true \
  --template.graphql.enabled true \
  --template.cache.enabled true \
  --template.cache.ttl-seconds 30 \
  --template.cache.level L1L2

# Update existing definition without permissions (permissions optional for updates)
dab autoentities-configure my-def \
  --template.mcp.dml-tool false \
  --template.cache.ttl-seconds 60

Result in config:

{
  "autoentities": {
    "my-def": {
      "patterns": {
        "include": ["dbo.%", "sys.%"],
        "exclude": ["dbo.internal%"],
        "name": "{schema}_{table}"
      },
      "template": {
        "rest": { "enabled": true },
        "graphql": { "enabled": true },
        "mcp": false,
        "cache": {
          "enabled": true,
          "ttl-seconds": 60,
          "level": "l1l2"
        }
      },
      "permissions": [
        {
          "role": "anonymous",
          "actions": [
            { "action": "read" }
          ]
        }
      ]
    }
  }
}

Notes:

  • GraphQL template now correctly serializes as "graphql": { "enabled": true } without the empty type object that was previously being written.
  • Permissions are required when creating new autoentity definitions but optional when updating existing ones.
Original prompt

This section details on the original issue you should resolve

<issue_title>Add CLI command dab autoentities configure</issue_title>
<issue_description>New CLI commands need to be added in order to allow the users to change the autoentities properties inside of the config file.
Introduce a new autoentities configure subcommand that operates like an upsert.
These commands need to follow the existing coding pattern that we have for the other CLI commands

dab autoentities configure {definition-name} --patterns.include value
dab autoentities configure {definition-name} --patterns.exclude value
dab autoentities configure {definition-name} --patterns.name value

dab autoentities configure {definition-name} --template.mcp.dml-tool value
dab autoentities configure {definition-name} --template.rest.enabled value
dab autoentities configure {definition-name} --template.graphql.enabled value
dab autoentities configure {definition-name} --template.cache.enabled value
dab autoentities configure {definition-name} --template.cache.ttl-seconds value
dab autoentities configure {definition-name} --template.cache.level value
dab autoentities configure {definition-name} --template.health.enabled value

dab autoentities configure {definition-name} --permissions role:actions
```</issue_description>

Copilot AI and others added 3 commits January 30, 2026 20:14
Co-authored-by: RubenCerna2079 <32799214+RubenCerna2079@users.noreply.github.com>
Co-authored-by: RubenCerna2079 <32799214+RubenCerna2079@users.noreply.github.com>
Co-authored-by: RubenCerna2079 <32799214+RubenCerna2079@users.noreply.github.com>
Copilot AI changed the title [WIP] Add CLI command dab autoentities configure Add CLI command dab autoentities-configure Jan 30, 2026
- Fix GraphQL template to only serialize 'enabled' property (not 'type')
- Improve error messages to show all valid parameter values
- Use EnumExtensions.GenerateMessageForInvalidInput for EntityCacheLevel
- Update MCP dml-tool error message to show valid values

Co-authored-by: RubenCerna2079 <32799214+RubenCerna2079@users.noreply.github.com>
- Require permissions when creating a new autoentity definition
- Allow updating existing definitions without providing permissions
- Improve error handling to distinguish between parsing failure and missing permissions

Co-authored-by: RubenCerna2079 <32799214+RubenCerna2079@users.noreply.github.com>
@RubenCerna2079 RubenCerna2079 marked this pull request as ready for review February 13, 2026 21:54
Copilot AI review requested due to automatic review settings February 13, 2026 21:54
@RubenCerna2079
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@RubenCerna2079 RubenCerna2079 added this to the Feb 2026 milestone Feb 13, 2026
@github-project-automation github-project-automation bot moved this to Review In Progress in Data API builder Feb 13, 2026
@RubenCerna2079 RubenCerna2079 linked an issue Feb 13, 2026 that may be closed by this pull request
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new DAB CLI verb to upsert autoentities definitions in the runtime config, so users can configure auto-entity patterns/template/permissions without manually editing JSON. This also updates JSON converters to correctly persist new template options.

Changes:

  • Added autoentities-configure CLI command/options and handler logic (TryConfigureAutoentities) to upsert autoentities definitions.
  • Updated autoentities JSON converters to adjust GraphQL template serialization and to include MCP template serialization.
  • Added unit tests for the new CLI behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/Config/Converters/AutoentityTemplateConverter.cs Changes template serialization (GraphQL now writes only enabled; adds MCP serialization).
src/Config/Converters/AutoentityConverter.cs Ensures template is emitted when MCP user-provided; avoids writing empty permissions.
src/Cli/Program.cs Registers AutoentitiesConfigureOptions with the CLI parser.
src/Cli/ConfigGenerator.cs Implements TryConfigureAutoentities and builders for patterns/template/permissions.
src/Cli/Commands/AutoentitiesConfigureOptions.cs Adds CLI verb/options and handler for autoentities-configure.
src/Cli.Tests/AutoentitiesConfigureTests.cs Adds unit tests covering create/update and invalid inputs.

Comment on lines +123 to +126
if (value?.UserProvidedMcpOptions is true)
{
writer.WritePropertyName("mcp");
JsonSerializer.Serialize(writer, value.Mcp, options);
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

autoentities.template.mcp is serialized via JsonSerializer.Serialize(writer, value.Mcp, options), which will use EntityMcpOptionsConverterFactory and may emit the boolean shorthand (true/false) when only dml-tools was set. The JSON schema for autoentities.template.mcp only allows an object with the dml-tools property (no boolean shorthand and no custom-tool), so the CLI can end up writing a config that fails schema validation (dab validate). Consider writing mcp manually as an object that only includes dml-tools when UserProvidedMcpOptions is true (and avoid emitting/propagating custom-tool in autoentities templates).

Suggested change
if (value?.UserProvidedMcpOptions is true)
{
writer.WritePropertyName("mcp");
JsonSerializer.Serialize(writer, value.Mcp, options);
if (value?.UserProvidedMcpOptions is true && value.Mcp is not null)
{
writer.WritePropertyName("mcp");
writer.WriteStartObject();
if (value.Mcp.DmlTools is not null)
{
writer.WritePropertyName("dml-tools");
JsonSerializer.Serialize(writer, value.Mcp.DmlTools, options);
}
writer.WriteEndObject();

Copilot uses AI. Check for mistakes.
Comment on lines +3027 to +3032
if (options.TemplateCacheTtlSeconds is not null)
{
cacheTtl = options.TemplateCacheTtlSeconds.Value;
cacheUpdated = true;
_logger.LogInformation("Updated template.cache.ttl-seconds for definition '{DefinitionName}'", options.DefinitionName);
}
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template.cache.ttl-seconds is accepted and written without validation. The schema requires a minimum of 1 second, so values like 0 or negative numbers can be persisted by the CLI and then fail schema validation. Consider validating options.TemplateCacheTtlSeconds (e.g., > 0, reusing RuntimeConfigValidatorUtil.IsTTLValid) and returning null/false with a clear error message when invalid.

Copilot uses AI. Check for mistakes.
Comment on lines 2852 to 2871
// Get existing autoentity definition or create a new one
Autoentity? existingAutoentity = null;
if (autoEntitiesDictionary.TryGetValue(options.DefinitionName, out Autoentity? value))
{
existingAutoentity = value;
}

// Build patterns
AutoentityPatterns patterns = BuildAutoentityPatterns(options, existingAutoentity);

// Build template
AutoentityTemplate? template = BuildAutoentityTemplate(options, existingAutoentity);
if (template is null)
{
return false;
}

// Build permissions
EntityPermission[]? permissions = BuildAutoentityPermissions(options, existingAutoentity);

Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation currently allows creating a brand-new autoentities definition without any permissions (and even with no other options, resulting in an empty {} definition written to config). This contradicts the PR description stating permissions are required for new definitions and can lead to generated entities with no access rules configured. Consider adding an explicit check when existingAutoentity is null to require --permissions (and/or require at least one configurable option) before upserting the new definition.

Copilot uses AI. Check for mistakes.
Comment on lines 85 to 118
public void TestConfigureAutoentitiesDefinition_WithTemplateOptions()
{
// Arrange
InitOptions initOptions = CreateBasicInitOptionsForMsSqlWithConfig(config: TEST_RUNTIME_CONFIG_FILE);
Assert.IsTrue(ConfigGenerator.TryGenerateConfig(initOptions, _runtimeConfigLoader!, _fileSystem!));

AutoentitiesConfigureOptions options = new(
definitionName: "test-def",
templateRestEnabled: true,
templateGraphqlEnabled: false,
templateMcpDmlTool: "true",
templateCacheEnabled: true,
templateCacheTtlSeconds: 30,
templateCacheLevel: "L1",
templateHealthEnabled: true,
config: TEST_RUNTIME_CONFIG_FILE
);

// Act
bool success = ConfigGenerator.TryConfigureAutoentities(options, _runtimeConfigLoader!, _fileSystem!);

// Assert
Assert.IsTrue(success);
Assert.IsTrue(_runtimeConfigLoader!.TryLoadConfig(TEST_RUNTIME_CONFIG_FILE, out RuntimeConfig? config));

Autoentity autoentity = config.Autoentities!.AutoEntities["test-def"];
Assert.IsTrue(autoentity.Template.Rest.Enabled);
Assert.IsFalse(autoentity.Template.GraphQL.Enabled);
Assert.IsTrue(autoentity.Template.Mcp!.DmlToolEnabled);
Assert.AreEqual(true, autoentity.Template.Cache.Enabled);
Assert.AreEqual(30, autoentity.Template.Cache.TtlSeconds);
Assert.AreEqual(EntityCacheLevel.L1, autoentity.Template.Cache.Level);
Assert.IsTrue(autoentity.Template.Health.Enabled);
}
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unit tests validate Template.Mcp.DmlToolEnabled on the in-memory object, but they don’t assert the actual JSON persisted to disk. Given EntityMcpOptions can serialize as a boolean shorthand, it would be good to add an assertion that the written config contains autoentities.<def>.template.mcp as an object with a dml-tools property (matching the schema), and that GraphQL template serialization only writes enabled (no type). This would catch regressions in the converters.

Copilot uses AI. Check for mistakes.
Comment on lines 61 to 71
@@ -67,6 +67,7 @@ public static int Execute(string[] args, ILogger cliLogger, IFileSystem fileSyst
(ValidateOptions options) => options.Handler(cliLogger, loader, fileSystem),
(AddTelemetryOptions options) => options.Handler(cliLogger, loader, fileSystem),
(ConfigureOptions options) => options.Handler(cliLogger, loader, fileSystem),
(AutoentitiesConfigureOptions options) => options.Handler(cliLogger, loader, fileSystem),
(ExportOptions options) => options.Handler(cliLogger, loader, fileSystem),
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ParseArguments<...> type parameter order must match the subsequent .MapResult(...) handler order. Here, ExportOptions is listed before AddTelemetryOptions in ParseArguments, but the MapResult lambdas handle AddTelemetryOptions/ConfigureOptions/AutoentitiesConfigureOptions before ExportOptions. This should fail to compile (handler delegate types won’t line up). Reorder either the ParseArguments<...> generic list or the MapResult lambdas so ExportOptions’ handler is in the same position as ExportOptions in the type list.

Copilot uses AI. Check for mistakes.
@RubenCerna2079
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@RubenCerna2079
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

@RubenCerna2079
Copy link
Contributor

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 6 pipeline(s).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Review In Progress

Development

Successfully merging this pull request may close these issues.

Add CLI command dab autoentities configure

2 participants