hati-rails-api 0.1.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +237 -0
  4. data/hati-rails-api.gemspec +39 -0
  5. data/lib/generators/hati_rails_api/context_generator.rb +270 -0
  6. data/lib/hati_rails_api/context/configuration/configuration.rb +50 -0
  7. data/lib/hati_rails_api/context/configuration/domain_configuration.rb +55 -0
  8. data/lib/hati_rails_api/context/core/error_handler.rb +76 -0
  9. data/lib/hati_rails_api/context/core/loader.rb +54 -0
  10. data/lib/hati_rails_api/context/core/migration.rb +68 -0
  11. data/lib/hati_rails_api/context/core/public_api.rb +114 -0
  12. data/lib/hati_rails_api/context/core.rb +18 -0
  13. data/lib/hati_rails_api/context/extensions/string_extensions.rb +11 -0
  14. data/lib/hati_rails_api/context/generators/base_generator.rb +33 -0
  15. data/lib/hati_rails_api/context/generators/domain_generator.rb +219 -0
  16. data/lib/hati_rails_api/context/generators/file_generation.rb +72 -0
  17. data/lib/hati_rails_api/context/generators/generator.rb +212 -0
  18. data/lib/hati_rails_api/context/generators/layer_component_generator.rb +88 -0
  19. data/lib/hati_rails_api/context/generators/model_endpoint_generator.rb +97 -0
  20. data/lib/hati_rails_api/context/generators/operation_generator.rb +182 -0
  21. data/lib/hati_rails_api/context/layers/operation_layer.rb +45 -0
  22. data/lib/hati_rails_api/context/layers/standard_layer.rb +44 -0
  23. data/lib/hati_rails_api/context/managers/rollback_manager.rb +123 -0
  24. data/lib/hati_rails_api/context/shared/content_generators.rb +125 -0
  25. data/lib/hati_rails_api/context/shared/layer_factory.rb +37 -0
  26. data/lib/hati_rails_api/context.rb +30 -0
  27. data/lib/hati_rails_api/errors/unsupported_operation_error.rb +11 -0
  28. data/lib/hati_rails_api/macro/serializer_macro.rb +13 -0
  29. data/lib/hati_rails_api/response_handler.rb +71 -0
  30. data/lib/hati_rails_api/version.rb +5 -0
  31. data/lib/hati_rails_api.rb +15 -0
  32. metadata +121 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1402a4d0cd8d1aad576c25e026eabe7f59a4124f3263e8d709a5badb35666249
4
+ data.tar.gz: ef4cfd0e3e3d791692607b8be6223dd371d0ce1184914ca3ce524f2ee05053e8
5
+ SHA512:
6
+ metadata.gz: e57aa35cd26e896573e65ccaf2396eb275b9d8ce1ab9c68473f06439e0ec4f548b650c6411044880fa234007ec9e74512756529110b26f5b55c6da2fde055df2
7
+ data.tar.gz: f56b6a32a3f7d96000873df30e27180d04d8a6a94211fc69840af6845814f174e3867503eb67c019343aeb18bf53e1a5b8715ced60fdff5fb159e058b3ed6b31
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 hackico.ai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # Hati Rails API
2
+
3
+ A high-performance, scalable toolkit for building robust, domain-driven Rails APIs with migration-style code generation, clean architecture, and agentic/AI-ready patterns.
4
+
5
+ ## What is Hati Rails API?
6
+
7
+ Hati Rails API is a Ruby gem that brings **migration-style, pattern-based code generation** to Rails APIs. It enables:
8
+
9
+ - **Domain-driven design** with clear context boundaries
10
+ - **Clean, SOLID architecture** for maintainable codebases
11
+ - **Fast, repeatable development** with migration files and rollback
12
+ - **Agentic/AI-ready workflows**: all code generation is explicit, declarative, and context-driven—perfect for automation and large-scale projects
13
+
14
+ ## Framework Components & How They Work Together
15
+
16
+ ### Context System
17
+
18
+ Centralizes domain logic, boundaries, and code generation. You define “contexts” (domains) in migration files. Each context can have operations, endpoints, models, and any number of custom layers (service, query, validation, serializer, etc.).
19
+
20
+ ### Migration Engine
21
+
22
+ Provides a migration-style, repeatable, and rollbackable way to define and evolve your API structure. Migration files (class-based or DSL) describe what to generate. Running migrations creates or updates code; rollbacks revert changes.
23
+
24
+ ### Generator
25
+
26
+ Orchestrates the actual file generation, tracking, and rollback. Reads migration files, generates code (models, controllers, operations, etc.), and tracks what was created for safe rollback.
27
+
28
+ ### Layer System
29
+
30
+ Supports modular, extensible architecture. Built-in layers include:
31
+
32
+ - **Operation:** Business logic, step-based or simple
33
+ - **Service:** Application services, integrations
34
+ - **Query:** Data access/query objects
35
+ - **Validation:** Input/business validation
36
+ - **Serializer:** Output formatting
37
+ - **Custom:** Add your own (analytics, repository, etc.)
38
+
39
+ ### ResponseHandler
40
+
41
+ Standardizes API responses and error handling. Controllers include this module to automatically handle operation results, errors, and JSON:API formatting.
42
+
43
+ ### Rollback Manager
44
+
45
+ Enables safe, timestamped rollback of generated code. Tracks every file generated by a migration. Rollbacks remove files and clean up empty directories.
46
+
47
+ ### Macro System
48
+
49
+ Provides reusable code patterns and metaprogramming helpers. Macros can be used in operations, layers, or anywhere in the context system to DRY up code and enforce patterns.
50
+
51
+ ### Error Handling
52
+
53
+ Centralizes error types and handling logic. Custom error classes for unsupported operations, configuration issues, and more. Integrated with ResponseHandler for clean API error responses.
54
+
55
+ ### Versioning
56
+
57
+ Tracks the version of the Hati Rails API gem. Ensures agents and humans know which features and patterns are available.
58
+
59
+ **How They Work Together:**
60
+
61
+ - You define your API’s structure and patterns in migration files.
62
+ - The Migration Engine and Generator read these files, using the Layer System to create all necessary code (operations, models, controllers, etc.).
63
+ - ResponseHandler ensures all endpoints behave consistently.
64
+ - Rollback Manager lets you safely undo changes, supporting rapid, iterative, and agent-driven development.
65
+ - Macros and Error Handling provide reusable patterns and robust error management.
66
+ - Versioning ensures compatibility and traceability.
67
+
68
+ The result is a highly modular, pattern-driven, and automation-friendly Rails API framework—ready for both human and AI/agentic development at scale.
69
+
70
+ ## Quick Start
71
+
72
+ ### 1. Install the Gem
73
+
74
+ Add to your Gemfile:
75
+
76
+ ```ruby
77
+ gem 'hati-rails-api'
78
+ ```
79
+
80
+ Then run:
81
+
82
+ ```bash
83
+ bundle install
84
+ ```
85
+
86
+ ### 2. Initialize the Context System
87
+
88
+ ```bash
89
+ rails generate hati_rails_api:context init
90
+ ```
91
+
92
+ This creates:
93
+
94
+ - `config/contexts.rb` (global config)
95
+ - `config/contexts/` (migration files go here)
96
+ - `app/contexts/` (generated code)
97
+
98
+ ### 3. Create a Migration File
99
+
100
+ Generate a migration for a domain:
101
+
102
+ ```bash
103
+ rails generate hati_rails_api:context user --operations=create,update,delete
104
+ ```
105
+
106
+ Edit the generated file in `config/contexts/` to define your domain, operations, and layers.
107
+
108
+ ### 4. Run Migrations
109
+
110
+ Generate all code from migrations:
111
+
112
+ ```bash
113
+ rails generate hati_rails_api:context run --force
114
+ ```
115
+
116
+ ### 5. Rollback (if needed)
117
+
118
+ ```bash
119
+ rails generate hati_rails_api:context rollback --timestamp=YOUR_TIMESTAMP
120
+ ```
121
+
122
+ ## Basic Usage Example
123
+
124
+ A migration file (class-based, AI/agentic-ready):
125
+
126
+ ```ruby
127
+ # config/contexts/20250721001327_create_user_context.rb
128
+ class CreateUserContext < HatiRailsApi::Context::Migration
129
+ def change
130
+ domain :user do |domain|
131
+ domain.operation do |operation|
132
+ operation.component [:create, :update, :delete]
133
+ end
134
+ domain.endpoint true
135
+ domain.model true
136
+ domain.validation
137
+ domain.query
138
+ domain.service
139
+ domain.serializer
140
+ end
141
+ model [:user, :user_token]
142
+ endpoint [:user_status]
143
+ end
144
+ end
145
+
146
+ CreateUserContext.new.run
147
+ ```
148
+
149
+ This will generate:
150
+
151
+ - Operations: `app/contexts/user/operation/create_operation.rb`, etc.
152
+ - Controller: `app/controllers/api/user_controller.rb`
153
+ - Models: `app/models/user.rb`, `app/models/user_token.rb`
154
+ - Additional layers: `app/contexts/user/validation/`, `query/`, `service/`, `serializer/`
155
+
156
+ ## Advanced Usage & Patterns
157
+
158
+ ### Granular/Agentic Steps
159
+
160
+ You can use granular steps to patternize operation logic based on other layers:
161
+
162
+ ```ruby
163
+ domain.operation do |operation|
164
+ operation.component [:authenticate, :authorize]
165
+ operation.step true, granular: true # Will use all other domain layers as steps
166
+ end
167
+ ```
168
+
169
+ ### Custom Layers
170
+
171
+ Add any custom layer to your domain:
172
+
173
+ ```ruby
174
+ domain.analytics do |analytics|
175
+ analytics.component [:event_tracker, :report_generator]
176
+ end
177
+ ```
178
+
179
+ ### Explicit Steps
180
+
181
+ ```ruby
182
+ domain.operation do |operation|
183
+ operation.component [:register]
184
+ operation.step :validate, :persist, :notify
185
+ end
186
+ ```
187
+
188
+ ### Full Example: Scalable, AI-Ready Context
189
+
190
+ ```ruby
191
+ class CreateEcommerceContext < HatiRailsApi::Context::Migration
192
+ def change
193
+ domain :ecommerce do |domain|
194
+ domain.operation do |operation|
195
+ operation.component [:checkout, :refund]
196
+ operation.step true, granular: true
197
+ end
198
+ domain.endpoint true
199
+ domain.model true
200
+ domain.validation { |v| v.component [:payment_validator] }
201
+ domain.query { |q| q.component [:order_finder] }
202
+ domain.service { |s| s.component [:payment_gateway] }
203
+ domain.analytics { |a| a.component [:sales_reporter] }
204
+ end
205
+ model [:order, :payment]
206
+ endpoint [:order_status]
207
+ end
208
+ end
209
+
210
+ CreateEcommerceContext.new.run
211
+ ```
212
+
213
+ ## Library Architecture & Extensibility
214
+
215
+ - **Migration-Driven**: All code generation is declarative and repeatable
216
+ - **Layered**: Add/remove layers as your architecture evolves
217
+ - **Rollbackable**: Every generation is tracked and can be reverted
218
+ - **Composable**: Use as building blocks for agentic/AI workflows
219
+ - **Extensible**: Add new layer types, code templates, or DSL methods
220
+
221
+ ## Why Hati Rails API for AI/Agentic Development?
222
+
223
+ - **Patternization**: All code is generated from explicit, context-rich patterns
224
+ - **Automation-Ready**: Migrations are just Ruby—easy to generate, modify, or analyze with AI agents
225
+ - **Scalable**: Designed for large, fast-moving teams and projects
226
+ - **Robust**: Rollback, test, and iterate safely
227
+ - **Clear Examples**: Every migration is a living, executable example
228
+
229
+ ## Wrap Up
230
+
231
+ Hati Rails API brings the power of migration-driven, pattern-based, and agentic development to Rails APIs. Use it to:
232
+
233
+ - Rapidly scaffold and evolve complex API architectures
234
+ - Automate code generation with AI/agentic tools
235
+ - Maintain clean, robust, and scalable codebases
236
+
237
+ **For more examples, documentation, and advanced patterns, see the [project repo](https://github.com/hackico-ai/hati-rails-api).**
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'hati_rails_api/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = 'hati-rails-api'
10
+ spec.version = HatiRailsApi::VERSION
11
+ spec.authors = ['Mariya Giy', 'Yuri Gi']
12
+ spec.email = ['giy.mariya@gmail.com', 'yurigi.pro@gmail.com']
13
+ spec.license = 'MIT'
14
+
15
+ spec.summary = 'A Rails API tool for building API services.'
16
+ spec.description = 'A Rails API tool for building API services.'
17
+ spec.homepage = "https://github.com/hackico-ai/#{spec.name}"
18
+
19
+ spec.required_ruby_version = '>= 3.0.0'
20
+
21
+ spec.files = Dir['CHANGELOG.md', 'LICENSE', 'README.md', 'hati-rails-api.gemspec', 'lib/**/*']
22
+ spec.bindir = 'bin'
23
+ spec.executables = []
24
+ spec.require_paths = ['lib']
25
+
26
+ spec.metadata['repo_homepage'] = spec.homepage
27
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
28
+
29
+ spec.metadata['homepage_uri'] = spec.homepage
30
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
31
+ spec.metadata['source_code_uri'] = spec.homepage
32
+ spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/issues"
33
+
34
+ spec.metadata['rubygems_mfa_required'] = 'true'
35
+
36
+ spec.add_dependency 'hati-operation'
37
+ spec.add_dependency 'hati-jsonapi-error'
38
+ spec.add_dependency 'railties', '>= 6.0'
39
+ end
@@ -0,0 +1,270 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/base'
5
+
6
+ module HatiRailsApi
7
+ module Generators
8
+ # Rails generator for HatiRailsApi context operations
9
+ # Provides Rails integration for the context system with migration-style workflow
10
+ class ContextGenerator < Rails::Generators::Base
11
+ source_root File.expand_path('templates', __dir__)
12
+
13
+ argument :command, type: :string, default: 'init',
14
+ desc: 'Command: init, run, rollback, list, or domain name for quick generation'
15
+
16
+ class_option :force, type: :boolean, default: false,
17
+ desc: 'Force overwrite existing files'
18
+
19
+ class_option :timestamp, type: :string,
20
+ desc: 'Timestamp for rollback operation'
21
+
22
+ class_option :operations, type: :array, default: [],
23
+ desc: 'Operations to generate for the domain'
24
+
25
+ class_option :endpoint, type: :boolean, default: true,
26
+ desc: 'Generate API endpoint for the domain'
27
+
28
+ def perform_command
29
+ case command.downcase
30
+ when 'init', 'initialize'
31
+ initialize_context
32
+ when 'run', 'execute'
33
+ run_migrations
34
+ when 'rollback', 'rb'
35
+ rollback_generation
36
+ when 'list', 'ls'
37
+ list_generations
38
+ else
39
+ # Treat as domain name for migration creation
40
+ create_domain_migration(command)
41
+ end
42
+ end
43
+
44
+ private
45
+
46
+ def initialize_context
47
+ say 'Initializing HatiRailsApi Context System...', :green
48
+ create_configuration_files
49
+ create_directory_structure
50
+ create_example_migration
51
+ say "\nContext system initialized successfully!", :green
52
+ say 'Check the generated files and examples to get started.', :blue
53
+ say "\nMigration-style workflow:", :yellow
54
+ say ' 1. rails generate hati_rails_api:context user # Create domain migration'
55
+ say ' 2. rails generate hati_rails_api:context run # Execute migrations'
56
+ say ' 3. rails generate hati_rails_api:context rollback # Rollback last'
57
+ say ' 4. rails generate hati_rails_api:context list # Show generations'
58
+ end
59
+
60
+ def create_domain_migration(domain_name)
61
+ say "Creating migration for domain: #{domain_name}", :green
62
+ timestamp = Time.now.strftime('%Y%m%d%H%M%S')
63
+ migration_file = "config/contexts/#{timestamp}_create_#{domain_name}_context.rb"
64
+ operations = if options[:operations].any?
65
+ options[:operations].flat_map { |op| op.split(',') }.map(&:strip)
66
+ else
67
+ ['create', 'update', 'destroy']
68
+ end
69
+ endpoint_enabled = options[:endpoint]
70
+ create_file migration_file, domain_migration_template(domain_name, operations, endpoint_enabled)
71
+ say "Migration created: #{migration_file}", :green
72
+ say 'Edit the migration file to customize the domain configuration', :blue
73
+ say 'Run: rails generate hati_rails_api:context run', :yellow
74
+ end
75
+
76
+ def run_migrations
77
+ say 'Running context migrations...', :green
78
+ migration_files = Dir[Rails.root.join('config', 'contexts', '*_create_*_context.rb')].sort
79
+ if migration_files.empty?
80
+ say_error 'No context migrations found!'
81
+ say 'Create a domain migration first: rails generate hati_rails_api:context user'
82
+ return
83
+ end
84
+ require_context_system
85
+ configure_defaults unless HatiRailsApi::Context.configured?
86
+ executed_count = 0
87
+ migration_files.each do |migration_file|
88
+ executed_count += 1 if execute_migration(migration_file)
89
+ end
90
+ if executed_count > 0
91
+ say "Successfully executed #{executed_count} migration(s)!", :green
92
+ say 'Use --force to override all existing files without prompting', :yellow unless options[:force]
93
+ else
94
+ say 'No new migrations to execute', :blue
95
+ end
96
+ end
97
+
98
+ def execute_migration(migration_file)
99
+ say "Executing: #{File.basename(migration_file)}", :yellow
100
+ begin
101
+ require_context_system
102
+ configure_defaults unless HatiRailsApi::Context.configured?
103
+ migration_content = File.read(migration_file)
104
+ if migration_content.include?('< HatiRailsApi::Context::Migration')
105
+ load migration_file
106
+ else
107
+ HatiRailsApi::Context.generate(force: options[:force]) do |ctx|
108
+ ctx.instance_eval(migration_content, migration_file)
109
+ end
110
+ end
111
+ say "Completed: #{File.basename(migration_file)}", :green
112
+ true
113
+ rescue StandardError => e
114
+ say_error "Error executing #{File.basename(migration_file)}: #{e.message}"
115
+ say_error "Location: #{e.backtrace&.first}"
116
+ false
117
+ end
118
+ end
119
+
120
+ def rollback_generation
121
+ say 'Rolling back generation...', :yellow
122
+ require_context_system
123
+ result = if options[:timestamp]
124
+ HatiRailsApi::Context.rollback(options[:timestamp])
125
+ else
126
+ HatiRailsApi::Context.rollback
127
+ end
128
+ if result
129
+ say 'Rollback completed successfully!', :green
130
+ else
131
+ say_error 'Rollback failed!'
132
+ end
133
+ end
134
+
135
+ def list_generations
136
+ say 'Listing all generations...', :blue
137
+ require_context_system
138
+ HatiRailsApi::Context.list_generations
139
+ end
140
+
141
+ def create_configuration_files
142
+ create_file 'config/contexts.rb', global_config_template
143
+ create_file 'config/contexts/.gitkeep', ''
144
+ end
145
+
146
+ def create_directory_structure
147
+ empty_directory 'app/contexts'
148
+ create_file 'app/contexts/.gitkeep', ''
149
+ end
150
+
151
+ def create_example_migration
152
+ timestamp = Time.now.strftime('%Y%m%d%H%M%S')
153
+ create_file "config/contexts/#{timestamp}_create_example_context.rb", example_migration_template
154
+ end
155
+
156
+ def require_context_system
157
+ require File.expand_path('../../hati_rails_api/context', __dir__)
158
+ end
159
+
160
+ def configure_defaults
161
+ HatiRailsApi::Context.configure do |config|
162
+ config.base_path 'app/contexts'
163
+ config.model path: 'app/models', base: 'ApplicationRecord'
164
+ config.endpoint path: 'app/controllers/api', base: 'ApplicationController'
165
+ end
166
+ end
167
+
168
+ def global_config_template
169
+ <<~RUBY
170
+ # frozen_string_literal: true
171
+
172
+ # HatiRailsApi Global Context Configuration
173
+ # This file contains global settings for the context system
174
+
175
+ require 'hati_rails_api/context'
176
+
177
+ # Configure global settings
178
+ HatiRailsApi::Context.configure do |config|
179
+ config.base_path 'app/contexts'
180
+ config.model path: 'app/models', base: 'ApplicationRecord'
181
+ config.endpoint path: 'app/controllers/api', base: 'ApplicationController'
182
+ end
183
+
184
+ # Global domain configuration (applies to all domains)
185
+ HatiRailsApi::Context.configure do |config|
186
+ config.domain do |domain|
187
+ # Default operation layer with common base
188
+ domain.operation do |operation|
189
+ operation.base 'hati_operation/base'
190
+ end
191
+ end
192
+ end
193
+ RUBY
194
+ end
195
+
196
+ def domain_migration_template(domain_name, operations, endpoint_enabled)
197
+ operation_list = operations.map(&:to_sym).inspect
198
+ timestamp = Time.now.strftime('%Y%m%d%H%M%S')
199
+ class_name = "Create#{domain_name.camelize}Context"
200
+ <<~RUBY
201
+ # frozen_string_literal: true
202
+
203
+ # Context Migration: Create #{domain_name.camelize} Domain
204
+ # Generated at #{Time.now}
205
+
206
+ class #{class_name} < HatiRailsApi::Context::Migration
207
+ def change
208
+ domain :#{domain_name} do |domain|
209
+ # Define operations for this domain
210
+ domain.operation do |operation|
211
+ operation.component #{operation_list}
212
+ end
213
+ # API endpoint configuration
214
+ domain.endpoint #{endpoint_enabled}
215
+ # Optional: Add custom layers
216
+ # domain.validation do |validation|
217
+ # validation.component [:input_validator, :business_validator]
218
+ # end
219
+ # domain.query do |query|
220
+ # query.component [:finder, :searcher]
221
+ # end
222
+ # domain.service do |service|
223
+ # service.component [:mailer, :notifier]
224
+ # end
225
+ # domain.serializer do |serializer|
226
+ # serializer.component [:json_serializer, :xml_serializer]
227
+ # end
228
+ end
229
+ # Optional: Generate domain-specific models
230
+ # model [:#{domain_name}]
231
+ # Optional: Generate additional endpoints
232
+ # endpoint [:#{domain_name}_status]
233
+ end
234
+ end
235
+
236
+ #{class_name}.new.run
237
+ RUBY
238
+ end
239
+
240
+ def example_migration_template
241
+ <<~RUBY
242
+ # frozen_string_literal: true
243
+
244
+ # Example Context Migration
245
+ # This is an example - you can safely delete this file
246
+
247
+ # ctx.domain :ecommerce do |domain|
248
+ # domain.operation do |operation|
249
+ # operation.component [:payment_processing, :inventory_management, :order_fulfillment]
250
+ # end
251
+ # domain.endpoint enabled: true
252
+ # domain.service do |service|
253
+ # service.component [:notification, :analytics]
254
+ # end
255
+ # domain.query do |query|
256
+ # query.component [:product_finder, :order_searcher]
257
+ # end
258
+ # end
259
+
260
+ # ctx.model [:product, :order, :customer]
261
+ # ctx.endpoint [:health, :metrics]
262
+ RUBY
263
+ end
264
+
265
+ def say_error(message)
266
+ say message, :red
267
+ end
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'domain_configuration'
4
+
5
+ module HatiRailsApi
6
+ module Context
7
+ # Main configuration class for the context system
8
+ # Follows Single Responsibility Principle - handles global configuration
9
+ class Configuration
10
+ attr_accessor :model_config, :endpoint_config, :domain_config
11
+
12
+ def initialize
13
+ @base_path = 'app/contexts'
14
+ @model_config = { path: 'app/models', base: 'ApplicationRecord' }
15
+ @endpoint_config = { path: 'app/controllers/api', base: 'ApplicationController' }
16
+ @domain_config = DomainConfiguration.new
17
+ end
18
+
19
+ def base_path(path = nil)
20
+ return @base_path unless path
21
+
22
+ @base_path = path
23
+ end
24
+
25
+ def model(path: nil, base: nil)
26
+ @model_config.merge!(path: path) if path
27
+ @model_config.merge!(base: base) if base
28
+ @model_config
29
+ end
30
+
31
+ def endpoint(enabled = true, **options)
32
+ return @endpoint_config unless enabled || !options.empty?
33
+
34
+ case enabled
35
+ when false
36
+ @endpoint_config = { enabled: false }
37
+ when Hash
38
+ @endpoint_config.merge!(enabled)
39
+ else
40
+ @endpoint_config.merge!(options)
41
+ end
42
+ end
43
+
44
+ def domain(&block)
45
+ @domain_config.instance_eval(&block) if block_given?
46
+ @domain_config
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../shared/layer_factory'
4
+
5
+ module HatiRailsApi
6
+ module Context
7
+ # Domain-specific configuration class
8
+ # Follows Single Responsibility Principle - handles domain layer configuration
9
+ class DomainConfiguration
10
+ include LayerFactory
11
+
12
+ DEFAULT_DOMAIN_STATE = { enabled: false }.freeze
13
+
14
+ attr_reader :layers
15
+
16
+ def initialize
17
+ @layers = {}
18
+ end
19
+
20
+ def operation(&block)
21
+ @layers[:operation] = create_operation_layer(&block)
22
+ end
23
+
24
+ def layer(layer_name, &block)
25
+ @layers[layer_name.to_sym] = create_standard_layer(layer_name, &block)
26
+ end
27
+
28
+ def endpoint(enabled: true, **options)
29
+ @domain_endpoint = create_endpoint_state(enabled, options)
30
+ end
31
+
32
+ def method_missing(method_name, ...)
33
+ result = create_dynamic_layer(method_name, ...)
34
+ return super unless result
35
+
36
+ @layers[method_name.to_sym] = result
37
+ end
38
+
39
+ def respond_to_missing?(_method_name, _include_private = false)
40
+ true
41
+ end
42
+
43
+ private
44
+
45
+ def create_endpoint_state(enabled, options)
46
+ case enabled
47
+ when false then DEFAULT_DOMAIN_STATE
48
+ when true then { enabled: true, options: options, explicit_components: nil }
49
+ when Array then { enabled: true, options: options, explicit_components: enabled }
50
+ when Hash then { enabled: true, options: enabled, explicit_components: nil }
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end