Skip to content

[Enh]: Support autoentities #2794

Description

What

Add entities automatically.

Why

Super-simplify setup and onboarding.

Note

Autoentities cannot conflict with explicit entities.

Constraints

  • Data-source type: MSSQL-only
  • Object-source type: Table-only
  • When at least one autoentities member is present, the top-level entities section becomes optional.

How

Add new top-level section to the configuration.

{
  "runtime": {},
  "entities": {},
  "autoentities": {} // new
}

This defines the search pattern as well as the entity defaults.

Important

Autoentities are in-memory only. The configuration file is never updated from this behavior.

Configuration

{
  "autoentities": {
    "{definition-name}": {

      "patterns": {
        "include": [ "t1", "t2", "t3", "%.%" ], // default: null which means all. mssql syntax (T-SQL LIKE)
        "exclude": [ "t3" ], // default: null which means none. mssql syntax (T-SQL LIKE)
        "name": "{schema}{object}" // default: null which means "{schema}_{object}". This is interpolation syntax
      }

      "template": {
        "mcp": { "dml-tool": "<boolean>" }, // default: true
        "rest": { "enabled": "<boolean>" }, // default: true
        "graphql": { "enabled": "<boolean>" }, // default: true
        "health": { "enabled": "<boolean>" }, // default: true
        "cache": {
          "enabled": "<boolean>", // default: false
          "ttl-seconds": "<integer>", // default: 5
          "level": "<enum>" // default: L1L2
        }
      },

      "permissions": [ // at least one is required
        {
          "role": "<string>",
          "actions": [
            "*",
            "create",
            "read",
            "update",
            "delete"
          ]
        }
      ]
    }
  }
}

Behavior

Definition and Patterns

  • {definition-name} uniquely identifies a definition in autoentities, used by the CLI for upserts.
  • patterns.include: null includes all (default). Uses MSSQL LIKE syntax validated at runtime.
  • patterns.exclude: null excludes none (default). Uses MSSQL LIKE syntax validated at runtime.
  • patterns.name: null equals {schema}_{object} (default). Supports {schema} and {object} interpolation (for example {schema}{object}) and must be unique.
  • The patterns section is optional and uses defaults when omitted.
  • When an entity matches both include and exclude, exclude wins.

Template and Permissions

  • The template section is optional and uses defaults when omitted.
  • Defaults in template match defaults in entities.
  • The permissions section is required and must contain at least one member.
  • Some properties are inferred from entity names (for example, graphql.type.singular, graphql.type.plural, and rest.path), and duplicates of existing definitions are invalid.

Execution Rules

  • Autoentities supports only MSSQL tables.
  • Default exclusions: schemas sys, INFORMATION_SCHEMA, table __EFMigrationsHistory, and any table with is_shipped = 1.
  • Autoentities runs at startup (dab start) and on Hot Reload of autoentities; it does not re-run when the database schema changes.
  • Generated entities exist only in memory; the configuration file is never updated.
  • Each generated entity tracks its parent {definition-name}.
  • Each autoentities definition executes independently and sequentially.

Validation and Errors

  • Startup stops if an autoentities entity name duplicates one from entities or another autoentities definition.
  • Autoentities fails if resulting {entity-name} values are not unique or if no permissions are defined.
  • Autoentities continues gracefully if filters yield zero entities.
  • include and exclude patterns follow MSSQL LIKE syntax and are validated only by the database at runtime.

Command line

Introduce a new auto-config subcommand that operates like an upsert.

dab auto-config {definition-name} --patterns.include value
dab auto-config {definition-name} --patterns.exclude value
dab auto-config {definition-name} --patterns.name value

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

dab auto-config {definition-name} --permissions role:actions

dab auto-config-simulate --output file.json

CLI Behavior

  • The auto-config subcommand operates like an upsert.
  • It creates the autoentities section if missing.
  • It creates the {definition-name} section if missing.
  • When the literal string null is passed as a value, the value is set to null.
    There is currently no way to remove a property through the CLI.

Health & Logging

Health Endpoint

Include in the endpoint tag: "autoentities-definition: {definition-name}" for autoentities; otherwise omit from health JSON output.

Log Information

{definition-name} created {entity-name} for {schema}.{object} as (1 of 10).

Log Warning

{definition-name} resulted in zero entities.

Log Error

{definition-name} failed. {entity-name} for {schema}.{object} is not unique.
{definition-name} failed. {entity-name} for {schema}.{object} has no primary keys.
{definition-name} failed. {entity-name} for {schema}.{object} has invalid data types.

Suggested Tests

Rename AutogenQueryTests to AutoentitiesQueryTests.

Suggested JSON Schema Update

"autoentities": {
  "type": "object",
  "description": "Defines automatic entity generation rules for MSSQL tables based on include/exclude patterns and defaults.",
  "if": {
    "not": {
      "properties": {
        "data-source": {
          "properties": {
            "database-type": { "const": "mssql" }
          }
        }
      }
    }
  },
  "then": {
    "errorMessage": "Autoentities require the data-source.database-type to be 'mssql'."
  },
  "allOf": [
    {
      "if": {
        "not": {
          "required": ["entities"]
        }
      },
      "then": {
        "properties": {
          "autoentities": {
            "minProperties": 1
          }
        },
        "errorMessage": "The 'entities' section is optional only when at least one autoentities definition exists."
      }
    }
  ],
  "additionalProperties": {
    "type": "object",
    "properties": {
      "patterns": {
        "type": "object",
        "properties": {
          "include": {
            "type": ["string", "null"],
            "description": "MSSQL LIKE pattern for objects to include. Null includes all."
          },
          "exclude": {
            "type": ["string", "null"],
            "description": "MSSQL LIKE pattern for objects to exclude. Null excludes none."
          },
          "name": {
            "type": ["string", "null"],
            "description": "Entity name interpolation pattern using {schema} and {object}. Null defaults to {schema}_{object}."
          }
        },
        "additionalProperties": false
      },
      "template": {
        "type": "object",
        "properties": {
          "mcp": {
            "type": "object",
            "properties": {
              "dml-tool": { "type": "boolean", "default": true }
            },
            "additionalProperties": false
          },
          "rest": {
            "type": "object",
            "properties": {
              "enabled": { "type": "boolean", "default": true }
            },
            "additionalProperties": false
          },
          "graphql": {
            "type": "object",
            "properties": {
              "enabled": { "type": "boolean", "default": true }
            },
            "additionalProperties": false
          },
          "health": {
            "type": "object",
            "properties": {
              "enabled": { "type": "boolean", "default": true }
            },
            "additionalProperties": false
          },
          "cache": {
            "type": "object",
            "properties": {
              "enabled": { "type": "boolean", "default": false },
              "ttl-seconds": { "type": ["integer", "null"] },
              "level": {
                "type": ["string", "null"],
                "enum": ["entity", "record", null]
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "permissions": {
        "type": "array",
        "minItems": 1,
        "items": {
          "type": "object",
          "required": ["role", "actions"],
          "properties": {
            "role": { "type": "string" },
            "actions": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": ["*", "create", "read", "update", "delete"]
              },
              "minItems": 1
            }
          },
          "additionalProperties": false
        }
      }
    },
    "required": ["permissions"],
    "additionalProperties": false
  }
}

Activity

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

Metadata

Metadata

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions