package services import ( "github.com/oarkflow/json" v2 "github.com/oarkflow/jsonschema" "github.com/oarkflow/filters" "github.com/oarkflow/metadata" ) type Storage struct { Name string `json:"name" yaml:"name"` Key string `json:"key" yaml:"key"` Driver string `json:"driver" yaml:"driver"` Database string `json:"database" yaml:"database"` Host string `json:"host" yaml:"host"` Username string `json:"username" yaml:"username"` Password string `json:"password" yaml:"password"` Port int `json:"port" yaml:"port"` IndexCache int `json:"index_cache" yaml:"index_cache"` BlockCache int `json:"block_cache" yaml:"block_cache"` InMemory bool `json:"in_memory" yaml:"in_memory"` } type Cache struct { Name string `json:"name" yaml:"name"` Key string `json:"key" yaml:"key"` Driver string `json:"driver" yaml:"driver"` Database string `json:"database" yaml:"database"` Host string `json:"host" yaml:"host"` Username string `json:"username" yaml:"username"` Password string `json:"password" yaml:"password"` Prefix string `json:"prefix" yaml:"prefix"` Port int `json:"port" yaml:"port"` } type Credentials struct { Databases []metadata.Config `json:"databases" yaml:"databases"` Storages []Storage `json:"storages" yaml:"storages"` Caches []Cache `json:"caches" yaml:"caches"` } type Core struct { Consts map[string]any `json:"consts" yaml:"consts"` Enums map[string]map[string]any `json:"enums" yaml:"enums"` Credentials Credentials `json:"credentials" yaml:"credentials"` } type Operation struct { Role string `json:"role" yaml:"role"` Actions []string `json:"actions" yaml:"actions"` } type Query struct { File string `json:"file" yaml:"file"` String string `json:"string" yaml:"string"` } type Model struct { Name string `json:"name" yaml:"name"` OldName string `json:"old_name" yaml:"old_name"` Key string `json:"key" yaml:"key"` Title string `json:"title" yaml:"title"` Database string `json:"database" yaml:"database"` ModelType string `json:"model_type" yaml:"model_type"` StoreFields []string `json:"store_fields" yaml:"store_fields"` IndexFields []string `json:"index_fields" yaml:"index_fields"` Query Query `json:"query" yaml:"query"` Constraints metadata.Constraint `json:"constraints" yaml:"constraints"` Fields []metadata.Field `json:"fields" yaml:"fields"` Operations []Operation `json:"operations" yaml:"operations"` Fulltext bool `json:"fulltext" yaml:"fulltext"` Files map[string]bool `json:"files" yaml:"files"` SortField string `json:"sort_field" yaml:"sort_field"` SortOrder string `json:"sort_order" yaml:"sort_order"` RestApi bool `json:"rest_api" yaml:"rest_api"` SoftDelete bool `json:"soft_delete" yaml:"soft_delete"` Update bool `json:"update" yaml:"update"` } type Property struct { Properties map[string]Property `json:"properties,omitempty" yaml:"properties,omitempty"` Items *RequestSchema `json:"items,omitempty" yaml:"items,omitempty"` Type any `json:"type,omitempty" yaml:"type,omitempty"` Default any `json:"default" yaml:"default"` In string `json:"in,omitempty" yaml:"in,omitempty"` AdditionalProperties bool `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"` } func (p *Property) UnmarshalJSON(data []byte) error { type T Property var pr T err := json.Unmarshal(data, &pr) if err != nil { return err } p.Properties = pr.Properties p.Items = pr.Items p.In = pr.In p.AdditionalProperties = pr.AdditionalProperties switch pr.Type.(type) { case string: p.Type = pr.Type.(string) case []any: var v []string for _, i := range pr.Type.([]any) { v = append(v, i.(string)) } p.Type = v } return nil } type Provider struct { Mapping map[string]any `json:"mapping,omitempty" yaml:"mapping,omitempty"` UpdateMapping map[string]any `json:"update_mapping,omitempty" yaml:"update_mapping,omitempty"` InsertMapping map[string]any `json:"insert_mapping,omitempty" yaml:"insert_mapping,omitempty"` Defaults map[string]any `json:"defaults,omitempty" yaml:"defaults,omitempty"` ProviderType string `json:"provider_type,omitempty" yaml:"provider_type,omitempty"` Database string `json:"database,omitempty" yaml:"database,omitempty"` Source string `json:"source,omitempty" yaml:"source,omitempty"` } type Data struct { Mapping map[string]string `json:"mapping,omitempty" yaml:"mapping,omitempty"` AdditionalData map[string]any `json:"additional_data,omitempty" yaml:"additional_data,omitempty"` GeneratedFields []string `json:"generated_fields,omitempty" yaml:"generated_fields,omitempty"` Conditions map[string]Filter `json:"conditions,omitempty" yaml:"conditions,omitempty"` Providers []Provider `json:"providers,omitempty" yaml:"providers,omitempty"` } type Node struct { Name string `json:"name,omitempty" yaml:"name,omitempty"` ID string `json:"id" yaml:"id"` NodeKey string `json:"node_key" yaml:"node_key"` Node string `json:"node" yaml:"node"` Data Data `json:"data" yaml:"data"` Debug bool `json:"debug" yaml:"debug"` FirstNode bool `json:"first_node" yaml:"first_node"` } type Loop struct { Label string `json:"label" yaml:"label"` Source string `json:"source" yaml:"source"` Target []string `json:"target" yaml:"target"` } type Edge struct { Label string `json:"label" yaml:"label"` Source string `json:"source" yaml:"source"` Target []string `json:"target" yaml:"target"` } type Branch struct { ConditionalNodes map[string]string `json:"conditional_nodes" yaml:"conditional_nodes"` Key string `json:"key" yaml:"key"` } type Handler struct { Name string `json:"name" yaml:"name"` Key string `json:"key" yaml:"key"` DisableLog bool `json:"disable_log" yaml:"disable_log"` Debug bool `json:"debug" yaml:"debug"` Nodes []Node `json:"nodes,omitempty" yaml:"nodes,omitempty"` Edges []Edge `json:"edges,omitempty" yaml:"edges,omitempty"` Branches []Branch `json:"branches,omitempty" yaml:"branches,omitempty"` Loops []Loop `json:"loops,omitempty" yaml:"loops,omitempty"` } type RequestSchema struct { Properties map[string]Property `json:"properties,omitempty" yaml:"properties,omitempty"` Items *RequestSchema `json:"items,omitempty" yaml:"items,omitempty"` Type string `json:"type,omitempty" yaml:"type,omitempty"` MaxLength int `json:"maxLength,omitempty" yaml:"maxLength,omitempty"` Required []string `json:"required,omitempty" yaml:"required,omitempty"` PrimaryKeys []string `json:"primaryKeys,omitempty" yaml:"primaryKeys,omitempty"` Description string `json:"description,omitempty" yaml:"description,omitempty"` AdditionalProperties bool `json:"additionalProperties,omitempty" yaml:"additionalProperties,omitempty"` } type RestrictedFields struct { Fields []string `json:"fields" yaml:"fields"` Roles []string `json:"roles" yaml:"roles"` } type Route struct { Name string `json:"name" yaml:"name"` Description string `json:"description" yaml:"description"` Uri string `json:"route_uri" yaml:"route_uri"` HandlerKey string `json:"handler_key" yaml:"handler_key"` Method string `json:"route_method" yaml:"route_method"` Schema []byte `json:"schema" yaml:"schema"` SchemaFile string `json:"schema_file" yaml:"schema_file"` Rules map[string]string `json:"rules" yaml:"rules"` CustomRules []string `json:"custom_rules" yaml:"custom_rules"` Model string `json:"model" yaml:"model"` Handler Handler `json:"handler" yaml:"handler"` Middlewares []Middleware `json:"middlewares" yaml:"middlewares"` Operation string `json:"operation" yaml:"operation"` RestrictedFields RestrictedFields `json:"restricted_fields" yaml:"restricted_fields"` schema *v2.Schema } func (r *Route) GetSchema() *v2.Schema { if r.schema != nil { return r.schema } return nil } func (r *Route) SetSchema(schema *v2.Schema) { r.schema = schema } type Schedule struct { Enable bool `json:"enable" yaml:"enable"` Interval string `json:"interval" yaml:"interval"` } type BackgroundHandler struct { Queue string `json:"queue" yaml:"queue"` HandlerKey string `json:"handler_key" yaml:"handler_key"` Payload json.RawMessage `json:"payload" yaml:"payload"` Handler Handler `json:"handler" yaml:"handler"` Schedule *Schedule `json:"schedule" yaml:"schedule"` } type Api struct { Prefix string `json:"prefix" yaml:"prefix"` Middlewares []Middleware `json:"middlewares" yaml:"middlewares"` Routes []*Route `json:"routes" yaml:"routes"` } type AllowedStatus struct { Source string `json:"source" yaml:"source"` Target []string `yaml:"target"` } type Transition struct { Source string `json:"source" yaml:"source"` Target string `json:"target" yaml:"target"` Filters map[string]any `json:"filters" yaml:"filters"` Validators []map[string]any `json:"validators" yaml:"validators"` Triggers []map[string]any `json:"triggers" yaml:"triggers"` Actions []map[string]any `json:"actions" yaml:"actions"` } type FlowPipeline struct { ID string `json:"id" yaml:"id"` Statuses []string `json:"statuses" yaml:"statuses"` } type Flow struct { ID string `json:"id" yaml:"id"` Service string `json:"service" yaml:"service"` Entity string `json:"entity" yaml:"entity"` Model string `json:"model" yaml:"model"` StatusField string `json:"status_field" yaml:"status_field"` AggregateBy []string `json:"aggregate_by" yaml:"aggregate_by"` Statuses []string `json:"statuses" yaml:"statuses"` AllowedStatuses []AllowedStatus `json:"allowed_statuses" yaml:"allowed_statuses"` Transitions []Transition `json:"transitions" yaml:"transitions"` Pipelines []FlowPipeline `json:"pipelines" yaml:"pipelines"` } func (f *Flow) GetPipeline(key string) *FlowPipeline { for _, pipeline := range f.Pipelines { if pipeline.ID == key { return &pipeline } } return nil } type Middleware struct { Name string `json:"name" yaml:"name"` Options json.RawMessage `json:"options" yaml:"options"` } type Static struct { Dir string `json:"dir" yaml:"dir"` Prefix string `json:"prefix" yaml:"prefix"` Options struct { ByteRange bool `json:"byte_range" yaml:"byte_range"` Compress bool `json:"compress" yaml:"compress"` Browse bool `json:"browse" yaml:"browse"` IndexFile string `json:"index_file" yaml:"index_file"` } `json:"options" yaml:"options"` } type RenderConfig struct { ID string `json:"id" yaml:"id"` Prefix string `json:"prefix" yaml:"prefix"` Root string `json:"root" yaml:"root"` Index string `json:"index" yaml:"index"` UseIndex bool `json:"use_index" yaml:"use_index"` Compress bool `json:"compress" yaml:"compress"` Extension string `json:"extension" yaml:"extension"` } type Web struct { Prefix string `json:"prefix" yaml:"prefix"` Static *Static `json:"static" yaml:"static"` Render []*RenderConfig `json:"render" yaml:"render"` Middlewares []Middleware `json:"middlewares" yaml:"middlewares"` Apis []Api `json:"apis" yaml:"apis"` } type Schema struct { File string `json:"file" yaml:"file"` Instance *v2.Schema } type Policy struct { Web Web `json:"web" yaml:"web"` Models []Model `json:"models" yaml:"models"` BackgroundHandlers []*BackgroundHandler `json:"background_handlers" yaml:"background_handlers"` Commands []*GenericCommand `json:"commands"` Schemas []Schema `json:"schemas" yaml:"schemas"` Conditions []*filters.Filter `json:"conditions" yaml:"conditions"` ApplicationRules []*filters.ApplicationRule `json:"application_rules" yaml:"application_rules"` Handlers []Handler `json:"handlers" yaml:"handlers"` Flows []Flow `json:"flows" yaml:"flows"` // Enhanced configuration support EnhancedHandlers []EnhancedHandler `json:"enhanced_handlers" yaml:"enhanced_handlers"` EnhancedWorkflows []WorkflowDefinition `json:"enhanced_workflows" yaml:"enhanced_workflows"` ValidationRules []ValidationServiceConfig `json:"validation_rules" yaml:"validation_rules"` } // Enhanced workflow configuration structures type WorkflowConfig struct { Engine string `json:"engine" yaml:"engine"` Version string `json:"version" yaml:"version"` Timeout string `json:"timeout" yaml:"timeout"` RetryPolicy *RetryPolicy `json:"retry_policy,omitempty" yaml:"retry_policy,omitempty"` Metadata map[string]string `json:"metadata,omitempty" yaml:"metadata,omitempty"` } type RetryPolicy struct { MaxAttempts int `json:"max_attempts" yaml:"max_attempts"` BackoffType string `json:"backoff_type" yaml:"backoff_type"` InitialDelay string `json:"initial_delay" yaml:"initial_delay"` } type WorkflowDefinition struct { ID string `json:"id" yaml:"id"` Name string `json:"name" yaml:"name"` Description string `json:"description" yaml:"description"` Version string `json:"version" yaml:"version"` Steps []WorkflowStep `json:"steps" yaml:"steps"` Metadata map[string]string `json:"metadata,omitempty" yaml:"metadata,omitempty"` } type WorkflowStep struct { ID string `json:"id" yaml:"id"` Name string `json:"name" yaml:"name"` Type string `json:"type" yaml:"type"` Handler string `json:"handler" yaml:"handler"` Input map[string]any `json:"input,omitempty" yaml:"input,omitempty"` Condition string `json:"condition,omitempty" yaml:"condition,omitempty"` Metadata map[string]string `json:"metadata,omitempty" yaml:"metadata,omitempty"` } type ValidationRule struct { Field string `json:"field" yaml:"field"` Type string `json:"type" yaml:"type"` Required bool `json:"required" yaml:"required"` Message string `json:"message" yaml:"message"` Options map[string]any `json:"options,omitempty" yaml:"options,omitempty"` } type ValidationProcessor struct { Name string `json:"name" yaml:"name"` Type string `json:"type" yaml:"type"` Config map[string]any `json:"config,omitempty" yaml:"config,omitempty"` } type UserConfig struct { Core Core `json:"core" yaml:"core"` Policy Policy `json:"policies" yaml:"policies"` } func (c *UserConfig) GetModel(source string) *Model { for _, model := range c.Policy.Models { if model.Name == source { return &model } } return nil } func (c *UserConfig) GetSchemaInstance(source string) *Schema { for _, schema := range c.Policy.Schemas { if schema.File == source { return &schema } } return nil } func (c *UserConfig) GetRenderConfig(source string) *RenderConfig { for _, model := range c.Policy.Web.Render { if model.ID == source { return model } } return nil } func (c *UserConfig) GetEntities() (entities []string) { for _, model := range c.Policy.Models { entities = append(entities, model.Name) } return } func (c *UserConfig) GetDatabase(db string) *metadata.Config { for _, database := range c.Core.Credentials.Databases { if database.Key == db { return &database } } return nil } func (c *UserConfig) GetHandler(handlerName string) *Handler { for _, handler := range c.Policy.Handlers { if handler.Key == handlerName { return &handler } } return nil } func (c *UserConfig) GetRoute(name string) *Route { for _, routes := range c.Policy.Web.Apis { for _, route := range routes.Routes { if route.Name == name { return route } } } return nil } func (c *UserConfig) GetHandlerList() (handlers []string) { for _, handler := range c.Policy.Handlers { handlers = append(handlers, handler.Key) } return } func (c *UserConfig) GetSourceDatabase(source string, db ...string) *metadata.Config { if len(db) > 0 && db[0] != "" { for _, database := range c.Core.Credentials.Databases { if database.Key == db[0] { return &database } } } model := c.GetModel(source) if model == nil { return nil } for _, database := range c.Core.Credentials.Databases { if database.Key == model.Database { return &database } } return nil } func (c *UserConfig) GetCondition(key string) *filters.Filter { for _, condition := range c.Policy.Conditions { if condition.Key == key { return condition } } return nil } func (c *UserConfig) GetApplicationRule(key string) *filters.ApplicationRule { for _, applicationRule := range c.Policy.ApplicationRules { if applicationRule.Key == key { return applicationRule } } return nil } func (c *UserConfig) GetFlow(key string) *Flow { for _, flow := range c.Policy.Flows { if flow.ID == key { return &flow } } return nil } // Enhanced methods for workflow engine integration // GetEnhancedHandler retrieves an enhanced handler by key func (c *UserConfig) GetEnhancedHandler(handlerName string) *EnhancedHandler { for _, handler := range c.Policy.EnhancedHandlers { if handler.Key == handlerName { return &handler } } return nil } // GetEnhancedHandlerList returns list of all enhanced handler keys func (c *UserConfig) GetEnhancedHandlerList() (handlers []string) { for _, handler := range c.Policy.EnhancedHandlers { handlers = append(handlers, handler.Key) } return } // GetWorkflowDefinition retrieves a workflow definition by ID func (c *UserConfig) GetWorkflowDefinition(workflowID string) *WorkflowDefinition { for _, workflow := range c.Policy.EnhancedWorkflows { if workflow.ID == workflowID { return &workflow } } return nil } // GetValidationConfig retrieves validation configuration by name func (c *UserConfig) GetValidationConfig(name string) *ValidationServiceConfig { for _, config := range c.Policy.ValidationRules { // Since ValidationServiceConfig doesn't have a name field in enhanced_contracts, // we'll use the index or a different approach if len(c.Policy.ValidationRules) > 0 { return &config } } return nil } // IsEnhancedHandler checks if a handler is configured as enhanced func (c *UserConfig) IsEnhancedHandler(handlerName string) bool { handler := c.GetEnhancedHandler(handlerName) return handler != nil && handler.WorkflowEnabled } // GetAllHandlers returns both traditional and enhanced handlers func (c *UserConfig) GetAllHandlers() map[string]any { handlers := make(map[string]any) // Add traditional handlers for _, handler := range c.Policy.Handlers { handlers[handler.Key] = handler } // Add enhanced handlers for _, handler := range c.Policy.EnhancedHandlers { handlers[handler.Key] = handler } return handlers } // GetHandlerByKey returns either traditional or enhanced handler by key func (c *UserConfig) GetHandlerByKey(key string) any { // Check traditional handlers first if handler := c.GetHandler(key); handler != nil { return *handler } // Check enhanced handlers if handler := c.GetEnhancedHandler(key); handler != nil { return *handler } return nil }