class RailsAiAdmin::Operations::Registry::Definition
Attributes
Public Class Methods
Source
# File lib/rails_ai_admin/operations/registry.rb, line 12 def initialize(resource, key, handler_name = nil) @resource, @key, @handler_name = resource, key.to_s.freeze, handler_name handler_class.validate! if custom? if custom? && scope == :collection klass = handler_class unless klass.lease_duration.is_a?(Numeric) && (5..3600).cover?(klass.lease_duration) && klass.lease_duration > klass.max_duration && klass.execution_window.is_a?(Numeric) && (60..7.days).cover?(klass.execution_window) && klass.max_attempts.is_a?(Integer) && (1..10).cover?(klass.max_attempts) raise ConfigurationError, "Collection execution needs bounded leases, deadlines and attempts; lease must exceed handler duration" end end freeze end
Public Instance Methods
Source
# File lib/rails_ai_admin/operations/registry.rb, line 37 def approval_policy = custom? || key == "destroy" ? :required : :human_submit def idempotency_policy = :intent def audit_policy = :required def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end def initialize(resources) @entries = resources.to_h do |resource| definitions = CRUD.to_h { |key| [ key, Definition.new(resource, key) ] } resource.operation_declarations.each { |key, handler| definitions[key.to_s] = Definition.new(resource, key, handler) } [ resource.key.to_s, definitions.freeze ] end.freeze freeze end def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?) end end end end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 39 def audit_policy = :required def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end def initialize(resources) @entries = resources.to_h do |resource| definitions = CRUD.to_h { |key| [ key, Definition.new(resource, key) ] } resource.operation_declarations.each { |key, handler| definitions[key.to_s] = Definition.new(resource, key, handler) } [ resource.key.to_s, definitions.freeze ] end.freeze freeze end def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?) end end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 75 def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?) end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 25 def custom? = !handler_name.nil? def handler_class return DefaultHandlers::TYPES.fetch(key) unless custom? klass = handler_name.constantize raise ConfigurationError, "Operation handler must inherit RailsAiAdmin::Operation" unless klass.is_a?(Class) && klass < Operation && !(klass < Work) klass end def description = custom? ? handler_class.description : key.humanize def read_only? = false def scope = custom? ? resource.operation_scopes.fetch(key.to_sym) : (key == "create" ? :collection : :member) def expose_to_ai? = false def side_effects? = true def approval_policy = custom? || key == "destroy" ? :required : :human_submit def idempotency_policy = :intent def audit_policy = :required def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end def initialize(resources) @entries = resources.to_h do |resource| definitions = CRUD.to_h { |key| [ key, Definition.new(resource, key) ] } resource.operation_declarations.each { |key, handler| definitions[key.to_s] = Definition.new(resource, key, handler) } [ resource.key.to_s, definitions.freeze ] end.freeze freeze end def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?
Source
# File lib/rails_ai_admin/operations/registry.rb, line 32 def description = custom? ? handler_class.description : key.humanize def read_only? = false def scope = custom? ? resource.operation_scopes.fetch(key.to_sym) : (key == "create" ? :collection : :member) def expose_to_ai? = false def side_effects? = true def approval_policy = custom? || key == "destroy" ? :required : :human_submit def idempotency_policy = :intent def audit_policy = :required def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end def initialize(resources) @entries = resources.to_h do |resource| definitions = CRUD.to_h { |key| [ key, Definition.new(resource, key) ] } resource.operation_declarations.each { |key, handler| definitions[key.to_s] = Definition.new(resource, key, handler) } [ resource.key.to_s, definitions.freeze ] end.freeze freeze end def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?)
Source
# File lib/rails_ai_admin/operations/registry.rb, line 35 def expose_to_ai? = false def side_effects? = true def approval_policy = custom? || key == "destroy" ? :required : :human_submit def idempotency_policy = :intent def audit_policy = :required def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end def initialize(resources) @entries = resources.to_h do |resource| definitions = CRUD.to_h { |key| [ key, Definition.new(resource, key) ] } resource.operation_declarations.each { |key, handler| definitions[key.to_s] = Definition.new(resource, key, handler) } [ resource.key.to_s, definitions.freeze ] end.freeze freeze end def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?) end end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 71 def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 46 def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 26 def handler_class return DefaultHandlers::TYPES.fetch(key) unless custom? klass = handler_name.constantize raise ConfigurationError, "Operation handler must inherit RailsAiAdmin::Operation" unless klass.is_a?(Class) && klass < Operation && !(klass < Work) klass end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 38 def idempotency_policy = :intent def audit_policy = :required def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end def initialize(resources) @entries = resources.to_h do |resource| definitions = CRUD.to_h { |key| [ key, Definition.new(resource, key) ] } resource.operation_declarations.each { |key, handler| definitions[key.to_s] = Definition.new(resource, key, handler) } [ resource.key.to_s, definitions.freeze ] end.freeze freeze end def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?) end end end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 42 def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 40 def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 33 def read_only? = false def scope = custom? ? resource.operation_scopes.fetch(key.to_sym) : (key == "create" ? :collection : :member) def expose_to_ai? = false def side_effects? = true def approval_policy = custom? || key == "destroy" ? :required : :human_submit def idempotency_policy = :intent def audit_policy = :required def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end def initialize(resources) @entries = resources.to_h do |resource| definitions = CRUD.to_h { |key| [ key, Definition.new(resource, key) ] } resource.operation_declarations.each { |key, handler| definitions[key.to_s] = Definition.new(resource, key, handler) } [ resource.key.to_s, definitions.freeze ] end.freeze freeze end def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?) end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 34 def scope = custom? ? resource.operation_scopes.fetch(key.to_sym) : (key == "create" ? :collection : :member) def expose_to_ai? = false def side_effects? = true def approval_policy = custom? || key == "destroy" ? :required : :human_submit def idempotency_policy = :intent def audit_policy = :required def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end def initialize(resources) @entries = resources.to_h do |resource| definitions = CRUD.to_h { |key| [ key, Definition.new(resource, key) ] } resource.operation_declarations.each { |key, handler| definitions[key.to_s] = Definition.new(resource, key, handler) } [ resource.key.to_s, definitions.freeze ] end.freeze freeze end def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?) end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 36 def side_effects? = true def approval_policy = custom? || key == "destroy" ? :required : :human_submit def idempotency_policy = :intent def audit_policy = :required def output_type = custom? && scope == :collection ? :job_ref : :record_ref def input_json_schema(access, record) InputSchema.new(fields(access, record), partial: key == "update" && !custom?).json_schema end def fields(access, record) return [] if key == "destroy" && !custom? return access.fields(:write, record, operation: key) unless custom? allowed = access.operation_fields(key, record) required = handler_class.input.select { |field| field.options[:required] }.map(&:name) raise AccessDenied unless (required - allowed.map(&:name)).empty? allowed end def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end end def initialize(resources) @entries = resources.to_h do |resource| definitions = CRUD.to_h { |key| [ key, Definition.new(resource, key) ] } resource.operation_declarations.each { |key, handler| definitions[key.to_s] = Definition.new(resource, key, handler) } [ resource.key.to_s, definitions.freeze ] end.freeze freeze end def fetch(resource, key) @entries.fetch(resource.key.to_s, {}).fetch(key.to_s) { raise AccessDenied } end def custom(resource) @entries.fetch(resource.key.to_s, {}).values.select(&:custom?) end end end
Source
# File lib/rails_ai_admin/operations/registry.rb, line 55 def signature custom? ? { handler: handler_name, version: handler_class.version, input: handler_class.input.map(&:contract), models: handler_class.atomic_models, duration: handler_class.max_duration, scope: scope, execution: scope == :collection ? [ handler_class.lease_duration, handler_class.execution_window, handler_class.max_attempts ] : nil } : { builtin: key, version: 1 } end