smart_domain 0.1.0

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 (174) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +3 -0
  3. data/CHANGELOG.md +25 -0
  4. data/LICENSE +21 -0
  5. data/README.md +1219 -0
  6. data/Rakefile +12 -0
  7. data/examples/blog_app/.dockerignore +51 -0
  8. data/examples/blog_app/.github/dependabot.yml +12 -0
  9. data/examples/blog_app/.github/workflows/ci.yml +67 -0
  10. data/examples/blog_app/.gitignore +30 -0
  11. data/examples/blog_app/.kamal/hooks/docker-setup.sample +3 -0
  12. data/examples/blog_app/.kamal/hooks/post-app-boot.sample +3 -0
  13. data/examples/blog_app/.kamal/hooks/post-deploy.sample +14 -0
  14. data/examples/blog_app/.kamal/hooks/post-proxy-reboot.sample +3 -0
  15. data/examples/blog_app/.kamal/hooks/pre-app-boot.sample +3 -0
  16. data/examples/blog_app/.kamal/hooks/pre-build.sample +51 -0
  17. data/examples/blog_app/.kamal/hooks/pre-connect.sample +47 -0
  18. data/examples/blog_app/.kamal/hooks/pre-deploy.sample +122 -0
  19. data/examples/blog_app/.kamal/hooks/pre-proxy-reboot.sample +3 -0
  20. data/examples/blog_app/.kamal/secrets +20 -0
  21. data/examples/blog_app/.rubocop.yml +8 -0
  22. data/examples/blog_app/.ruby-version +1 -0
  23. data/examples/blog_app/Dockerfile +76 -0
  24. data/examples/blog_app/Gemfile +63 -0
  25. data/examples/blog_app/Gemfile.lock +408 -0
  26. data/examples/blog_app/README.md +24 -0
  27. data/examples/blog_app/README_EXAMPLE.md +328 -0
  28. data/examples/blog_app/Rakefile +6 -0
  29. data/examples/blog_app/app/assets/images/.keep +0 -0
  30. data/examples/blog_app/app/assets/stylesheets/application.css +10 -0
  31. data/examples/blog_app/app/controllers/api/base_controller.rb +61 -0
  32. data/examples/blog_app/app/controllers/api/v1/posts_controller.rb +158 -0
  33. data/examples/blog_app/app/controllers/api/v1/users_controller.rb +98 -0
  34. data/examples/blog_app/app/controllers/application_controller.rb +7 -0
  35. data/examples/blog_app/app/controllers/concerns/.keep +0 -0
  36. data/examples/blog_app/app/domains/.keep +0 -0
  37. data/examples/blog_app/app/domains/exceptions.rb +19 -0
  38. data/examples/blog_app/app/domains/post_management/events/post_created_event.rb +15 -0
  39. data/examples/blog_app/app/domains/post_management/events/post_deleted_event.rb +13 -0
  40. data/examples/blog_app/app/domains/post_management/events/post_updated_event.rb +13 -0
  41. data/examples/blog_app/app/domains/post_management/handlers/post_notification_handler.rb +33 -0
  42. data/examples/blog_app/app/domains/post_management/models/post.rb +21 -0
  43. data/examples/blog_app/app/domains/post_management/policies/post_policy.rb +49 -0
  44. data/examples/blog_app/app/domains/post_management/post_service.rb +93 -0
  45. data/examples/blog_app/app/domains/post_management/setup.rb +25 -0
  46. data/examples/blog_app/app/domains/user_management/events/user_created_event.rb +15 -0
  47. data/examples/blog_app/app/domains/user_management/events/user_deleted_event.rb +13 -0
  48. data/examples/blog_app/app/domains/user_management/events/user_updated_event.rb +13 -0
  49. data/examples/blog_app/app/domains/user_management/handlers/user_welcome_handler.rb +21 -0
  50. data/examples/blog_app/app/domains/user_management/models/user.rb +11 -0
  51. data/examples/blog_app/app/domains/user_management/policies/user_policy.rb +49 -0
  52. data/examples/blog_app/app/domains/user_management/setup.rb +25 -0
  53. data/examples/blog_app/app/domains/user_management/user_service.rb +93 -0
  54. data/examples/blog_app/app/events/.keep +0 -0
  55. data/examples/blog_app/app/events/application_event.rb +18 -0
  56. data/examples/blog_app/app/handlers/.keep +0 -0
  57. data/examples/blog_app/app/helpers/application_helper.rb +2 -0
  58. data/examples/blog_app/app/javascript/application.js +3 -0
  59. data/examples/blog_app/app/javascript/controllers/application.js +9 -0
  60. data/examples/blog_app/app/javascript/controllers/hello_controller.js +7 -0
  61. data/examples/blog_app/app/javascript/controllers/index.js +4 -0
  62. data/examples/blog_app/app/jobs/application_job.rb +7 -0
  63. data/examples/blog_app/app/mailers/application_mailer.rb +4 -0
  64. data/examples/blog_app/app/models/application_record.rb +3 -0
  65. data/examples/blog_app/app/models/concerns/.keep +0 -0
  66. data/examples/blog_app/app/models/organization.rb +6 -0
  67. data/examples/blog_app/app/policies/.keep +0 -0
  68. data/examples/blog_app/app/policies/application_policy.rb +23 -0
  69. data/examples/blog_app/app/services/.keep +0 -0
  70. data/examples/blog_app/app/services/application_service.rb +24 -0
  71. data/examples/blog_app/app/views/layouts/application.html.erb +29 -0
  72. data/examples/blog_app/app/views/layouts/mailer.html.erb +13 -0
  73. data/examples/blog_app/app/views/layouts/mailer.text.erb +1 -0
  74. data/examples/blog_app/app/views/pwa/manifest.json.erb +22 -0
  75. data/examples/blog_app/app/views/pwa/service-worker.js +26 -0
  76. data/examples/blog_app/bin/brakeman +7 -0
  77. data/examples/blog_app/bin/bundler-audit +6 -0
  78. data/examples/blog_app/bin/ci +6 -0
  79. data/examples/blog_app/bin/dev +2 -0
  80. data/examples/blog_app/bin/docker-entrypoint +8 -0
  81. data/examples/blog_app/bin/importmap +4 -0
  82. data/examples/blog_app/bin/jobs +6 -0
  83. data/examples/blog_app/bin/kamal +27 -0
  84. data/examples/blog_app/bin/rails +4 -0
  85. data/examples/blog_app/bin/rake +4 -0
  86. data/examples/blog_app/bin/rubocop +8 -0
  87. data/examples/blog_app/bin/setup +35 -0
  88. data/examples/blog_app/bin/thrust +5 -0
  89. data/examples/blog_app/config/application.rb +52 -0
  90. data/examples/blog_app/config/boot.rb +4 -0
  91. data/examples/blog_app/config/bundler-audit.yml +5 -0
  92. data/examples/blog_app/config/cable.yml +17 -0
  93. data/examples/blog_app/config/cache.yml +16 -0
  94. data/examples/blog_app/config/ci.rb +19 -0
  95. data/examples/blog_app/config/credentials.yml.enc +1 -0
  96. data/examples/blog_app/config/database.yml +41 -0
  97. data/examples/blog_app/config/deploy.yml +120 -0
  98. data/examples/blog_app/config/environment.rb +5 -0
  99. data/examples/blog_app/config/environments/development.rb +78 -0
  100. data/examples/blog_app/config/environments/production.rb +90 -0
  101. data/examples/blog_app/config/environments/test.rb +53 -0
  102. data/examples/blog_app/config/importmap.rb +7 -0
  103. data/examples/blog_app/config/initializers/active_domain.rb +37 -0
  104. data/examples/blog_app/config/initializers/assets.rb +7 -0
  105. data/examples/blog_app/config/initializers/content_security_policy.rb +29 -0
  106. data/examples/blog_app/config/initializers/filter_parameter_logging.rb +8 -0
  107. data/examples/blog_app/config/initializers/inflections.rb +16 -0
  108. data/examples/blog_app/config/locales/en.yml +31 -0
  109. data/examples/blog_app/config/master.key +1 -0
  110. data/examples/blog_app/config/puma.rb +42 -0
  111. data/examples/blog_app/config/queue.yml +18 -0
  112. data/examples/blog_app/config/recurring.yml +15 -0
  113. data/examples/blog_app/config/routes.rb +27 -0
  114. data/examples/blog_app/config/storage.yml +27 -0
  115. data/examples/blog_app/config.ru +6 -0
  116. data/examples/blog_app/db/cable_schema.rb +11 -0
  117. data/examples/blog_app/db/cache_schema.rb +12 -0
  118. data/examples/blog_app/db/migrate/20251230112502_create_organizations.rb +9 -0
  119. data/examples/blog_app/db/migrate/20251230112503_create_users.rb +12 -0
  120. data/examples/blog_app/db/migrate/20251230112504_create_posts.rb +14 -0
  121. data/examples/blog_app/db/queue_schema.rb +129 -0
  122. data/examples/blog_app/db/schema.rb +46 -0
  123. data/examples/blog_app/db/seeds.rb +9 -0
  124. data/examples/blog_app/lib/api_demo.rb +175 -0
  125. data/examples/blog_app/lib/demo.rb +150 -0
  126. data/examples/blog_app/lib/tasks/.keep +0 -0
  127. data/examples/blog_app/log/.keep +0 -0
  128. data/examples/blog_app/public/400.html +135 -0
  129. data/examples/blog_app/public/404.html +135 -0
  130. data/examples/blog_app/public/406-unsupported-browser.html +135 -0
  131. data/examples/blog_app/public/422.html +135 -0
  132. data/examples/blog_app/public/500.html +135 -0
  133. data/examples/blog_app/public/icon.png +0 -0
  134. data/examples/blog_app/public/icon.svg +3 -0
  135. data/examples/blog_app/public/robots.txt +1 -0
  136. data/examples/blog_app/script/.keep +0 -0
  137. data/examples/blog_app/storage/.keep +0 -0
  138. data/examples/blog_app/tmp/.keep +0 -0
  139. data/examples/blog_app/vendor/.keep +0 -0
  140. data/examples/blog_app/vendor/javascript/.keep +0 -0
  141. data/lib/generators/active_domain/domain/domain_generator.rb +116 -0
  142. data/lib/generators/active_domain/domain/templates/events/created_event.rb.tt +15 -0
  143. data/lib/generators/active_domain/domain/templates/events/deleted_event.rb.tt +13 -0
  144. data/lib/generators/active_domain/domain/templates/events/updated_event.rb.tt +13 -0
  145. data/lib/generators/active_domain/domain/templates/policy.rb.tt +49 -0
  146. data/lib/generators/active_domain/domain/templates/service.rb.tt +93 -0
  147. data/lib/generators/active_domain/domain/templates/setup.rb.tt +27 -0
  148. data/lib/generators/active_domain/install/install_generator.rb +58 -0
  149. data/lib/generators/active_domain/install/templates/README +28 -0
  150. data/lib/generators/active_domain/install/templates/application_event.rb +18 -0
  151. data/lib/generators/active_domain/install/templates/application_policy.rb +23 -0
  152. data/lib/generators/active_domain/install/templates/application_service.rb +24 -0
  153. data/lib/generators/active_domain/install/templates/initializer.rb +37 -0
  154. data/lib/smart_domain/configuration.rb +97 -0
  155. data/lib/smart_domain/domain/exceptions.rb +164 -0
  156. data/lib/smart_domain/domain/policy.rb +215 -0
  157. data/lib/smart_domain/domain/service.rb +230 -0
  158. data/lib/smart_domain/event/adapters/memory.rb +110 -0
  159. data/lib/smart_domain/event/base.rb +176 -0
  160. data/lib/smart_domain/event/handler.rb +98 -0
  161. data/lib/smart_domain/event/mixins.rb +156 -0
  162. data/lib/smart_domain/event/registration.rb +136 -0
  163. data/lib/smart_domain/generators/domain_generator.rb +4 -0
  164. data/lib/smart_domain/generators/install_generator.rb +4 -0
  165. data/lib/smart_domain/handlers/audit_handler.rb +216 -0
  166. data/lib/smart_domain/handlers/metrics_handler.rb +104 -0
  167. data/lib/smart_domain/integration/active_record.rb +169 -0
  168. data/lib/smart_domain/integration/multi_tenancy.rb +115 -0
  169. data/lib/smart_domain/railtie.rb +62 -0
  170. data/lib/smart_domain/tasks/domains.rake +43 -0
  171. data/lib/smart_domain/version.rb +5 -0
  172. data/lib/smart_domain.rb +77 -0
  173. data/smart_domain.gemspec +53 -0
  174. metadata +391 -0
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :active_domain do
4
+ desc "List all registered domains"
5
+ task domains: :environment do
6
+ setup_files = Dir[Rails.root.join("app/domains/**/setup.rb")]
7
+
8
+ if setup_files.empty?
9
+ puts "No domains found in app/domains/"
10
+ puts "Generate your first domain with: rails generate active_domain:domain User"
11
+ else
12
+ puts "Registered domains:"
13
+ setup_files.each do |setup_file|
14
+ domain_path = setup_file.gsub(Rails.root.join("app/domains/").to_s, "")
15
+ domain_name = domain_path.split("/").first
16
+ puts " - #{domain_name}"
17
+ end
18
+ puts "\nTotal: #{setup_files.size} domain(s)"
19
+ end
20
+ end
21
+
22
+ desc "Reload all domain setups"
23
+ task reload: :environment do
24
+ setup_files = Dir[Rails.root.join("app/domains/**/setup.rb")]
25
+
26
+ puts "Reloading #{setup_files.size} domain(s)..."
27
+
28
+ setup_files.each do |setup_file|
29
+ load setup_file
30
+
31
+ domain_path = setup_file.gsub(Rails.root.join("app/domains/").to_s, "")
32
+ domain_name = domain_path.split("/").first.camelize
33
+
34
+ domain_module = domain_name.constantize rescue nil
35
+ if domain_module && domain_module.respond_to?(:setup!)
36
+ domain_module.setup!
37
+ puts " ✓ #{domain_name}"
38
+ end
39
+ end
40
+
41
+ puts "Done!"
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SmartDomain
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_model"
4
+ require "active_support"
5
+ require "active_support/core_ext"
6
+ require "active_record"
7
+ require "logger"
8
+
9
+ require_relative "smart_domain/version"
10
+ require_relative "smart_domain/configuration"
11
+
12
+ # Event system
13
+ require_relative "smart_domain/event/base"
14
+ require_relative "smart_domain/event/mixins"
15
+ require_relative "smart_domain/event/handler"
16
+ require_relative "smart_domain/event/adapters/memory"
17
+
18
+ # Handlers
19
+ require_relative "smart_domain/handlers/audit_handler"
20
+ require_relative "smart_domain/handlers/metrics_handler"
21
+
22
+ # Event registration
23
+ require_relative "smart_domain/event/registration"
24
+
25
+ # Domain patterns
26
+ require_relative "smart_domain/domain/exceptions"
27
+ require_relative "smart_domain/domain/policy"
28
+ require_relative "smart_domain/domain/service"
29
+
30
+ # Rails integration
31
+ require_relative "smart_domain/integration/active_record"
32
+ require_relative "smart_domain/integration/multi_tenancy"
33
+
34
+ # Railtie (loads automatically if Rails is present)
35
+ require_relative "smart_domain/railtie" if defined?(Rails::Railtie)
36
+
37
+ # SmartDomain - Domain-Driven Design and Event-Driven Architecture for Rails
38
+ #
39
+ # SmartDomain brings battle-tested DDD/EDA patterns from the Aeyes healthcare
40
+ # platform to Rails applications. It provides:
41
+ #
42
+ # - Domain events with event bus
43
+ # - Event mixins for 70% boilerplate reduction
44
+ # - Generic handlers for audit and metrics
45
+ # - Domain service pattern
46
+ # - Rails generators for rapid scaffolding
47
+ #
48
+ # @example Quick Start
49
+ # # In config/initializers/smart_domain.rb
50
+ # SmartDomain.configure do |config|
51
+ # config.event_bus_adapter = :memory
52
+ # config.audit_table_enabled = true
53
+ # end
54
+ #
55
+ # # Define a domain event
56
+ # class UserCreatedEvent < SmartDomain::Event::Base
57
+ # attribute :user_id, :string
58
+ # attribute :email, :string
59
+ # end
60
+ #
61
+ # # Publish an event
62
+ # event = UserCreatedEvent.new(
63
+ # event_type: 'user.created',
64
+ # aggregate_id: user.id,
65
+ # aggregate_type: 'User',
66
+ # organization_id: org.id,
67
+ # user_id: user.id,
68
+ # email: user.email
69
+ # )
70
+ # SmartDomain::Event.bus.publish(event)
71
+ #
72
+ # @see https://github.com/rachidalmaach/smart_domain
73
+ module SmartDomain
74
+ class Error < StandardError; end
75
+
76
+ # Your code goes here...
77
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/smart_domain/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "smart_domain"
7
+ spec.version = SmartDomain::VERSION
8
+ spec.authors = ["Rachid Al Maach"]
9
+ spec.email = ["rachid@qraft.nl"]
10
+
11
+ spec.summary = "Smart Domain-Driven Design and Event-Driven Architecture for Rails"
12
+ spec.description = <<~DESC
13
+ SmartDomain brings battle-tested DDD/EDA patterns to Rails applications.
14
+ Inspired by the Aeyes healthcare platform, it provides domain events,
15
+ event bus, generic handlers, and Rails generators for rapid domain scaffolding.
16
+ Features 70% boilerplate reduction through intelligent event handling and
17
+ AI-augmented development patterns.
18
+ DESC
19
+ spec.homepage = "https://github.com/rachid/smart_domain"
20
+ spec.license = "MIT"
21
+ spec.required_ruby_version = ">= 3.0.0"
22
+
23
+ spec.metadata["homepage_uri"] = spec.homepage
24
+ spec.metadata["source_code_uri"] = "https://github.com/rachid/smart_domain"
25
+ spec.metadata["changelog_uri"] = "https://github.com/rachid/smart_domain/blob/main/CHANGELOG.md"
26
+
27
+ spec.files = Dir.chdir(__dir__) do
28
+ `git ls-files -z`.split("\x0").reject do |f|
29
+ (File.expand_path(f) == __FILE__) ||
30
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
31
+ end
32
+ end
33
+
34
+ spec.bindir = "exe"
35
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
36
+ spec.require_paths = ["lib"]
37
+
38
+ # Core dependencies
39
+ spec.add_dependency "rails", ">= 7.0"
40
+ spec.add_dependency "activemodel", ">= 7.0"
41
+ spec.add_dependency "activesupport", ">= 7.0"
42
+ spec.add_dependency "activerecord", ">= 7.0"
43
+
44
+ # Development dependencies
45
+ spec.add_development_dependency "rspec", "~> 3.12"
46
+ spec.add_development_dependency "rspec-rails", "~> 6.0"
47
+ spec.add_development_dependency "factory_bot_rails", "~> 6.2"
48
+ spec.add_development_dependency "faker", "~> 3.2"
49
+ spec.add_development_dependency "rubocop", "~> 1.50"
50
+ spec.add_development_dependency "rubocop-rails", "~> 2.19"
51
+ spec.add_development_dependency "rubocop-rspec", "~> 2.20"
52
+ spec.add_development_dependency "sqlite3", ">= 2.1"
53
+ end
metadata ADDED
@@ -0,0 +1,391 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: smart_domain
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Rachid Al Maach
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2025-12-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '7.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activemodel
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '7.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '7.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '7.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '7.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activerecord
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '7.0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '7.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.12'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.12'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec-rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '6.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '6.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: factory_bot_rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '6.2'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '6.2'
111
+ - !ruby/object:Gem::Dependency
112
+ name: faker
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.2'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.50'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.50'
139
+ - !ruby/object:Gem::Dependency
140
+ name: rubocop-rails
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '2.19'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '2.19'
153
+ - !ruby/object:Gem::Dependency
154
+ name: rubocop-rspec
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '2.20'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '2.20'
167
+ - !ruby/object:Gem::Dependency
168
+ name: sqlite3
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '2.1'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '2.1'
181
+ description: |
182
+ SmartDomain brings battle-tested DDD/EDA patterns to Rails applications.
183
+ Inspired by the Aeyes healthcare platform, it provides domain events,
184
+ event bus, generic handlers, and Rails generators for rapid domain scaffolding.
185
+ Features 70% boilerplate reduction through intelligent event handling and
186
+ AI-augmented development patterns.
187
+ email:
188
+ - rachid@qraft.nl
189
+ executables: []
190
+ extensions: []
191
+ extra_rdoc_files: []
192
+ files:
193
+ - ".rspec"
194
+ - CHANGELOG.md
195
+ - LICENSE
196
+ - README.md
197
+ - Rakefile
198
+ - examples/blog_app/.dockerignore
199
+ - examples/blog_app/.github/dependabot.yml
200
+ - examples/blog_app/.github/workflows/ci.yml
201
+ - examples/blog_app/.gitignore
202
+ - examples/blog_app/.kamal/hooks/docker-setup.sample
203
+ - examples/blog_app/.kamal/hooks/post-app-boot.sample
204
+ - examples/blog_app/.kamal/hooks/post-deploy.sample
205
+ - examples/blog_app/.kamal/hooks/post-proxy-reboot.sample
206
+ - examples/blog_app/.kamal/hooks/pre-app-boot.sample
207
+ - examples/blog_app/.kamal/hooks/pre-build.sample
208
+ - examples/blog_app/.kamal/hooks/pre-connect.sample
209
+ - examples/blog_app/.kamal/hooks/pre-deploy.sample
210
+ - examples/blog_app/.kamal/hooks/pre-proxy-reboot.sample
211
+ - examples/blog_app/.kamal/secrets
212
+ - examples/blog_app/.rubocop.yml
213
+ - examples/blog_app/.ruby-version
214
+ - examples/blog_app/Dockerfile
215
+ - examples/blog_app/Gemfile
216
+ - examples/blog_app/Gemfile.lock
217
+ - examples/blog_app/README.md
218
+ - examples/blog_app/README_EXAMPLE.md
219
+ - examples/blog_app/Rakefile
220
+ - examples/blog_app/app/assets/images/.keep
221
+ - examples/blog_app/app/assets/stylesheets/application.css
222
+ - examples/blog_app/app/controllers/api/base_controller.rb
223
+ - examples/blog_app/app/controllers/api/v1/posts_controller.rb
224
+ - examples/blog_app/app/controllers/api/v1/users_controller.rb
225
+ - examples/blog_app/app/controllers/application_controller.rb
226
+ - examples/blog_app/app/controllers/concerns/.keep
227
+ - examples/blog_app/app/domains/.keep
228
+ - examples/blog_app/app/domains/exceptions.rb
229
+ - examples/blog_app/app/domains/post_management/events/post_created_event.rb
230
+ - examples/blog_app/app/domains/post_management/events/post_deleted_event.rb
231
+ - examples/blog_app/app/domains/post_management/events/post_updated_event.rb
232
+ - examples/blog_app/app/domains/post_management/handlers/post_notification_handler.rb
233
+ - examples/blog_app/app/domains/post_management/models/post.rb
234
+ - examples/blog_app/app/domains/post_management/policies/post_policy.rb
235
+ - examples/blog_app/app/domains/post_management/post_service.rb
236
+ - examples/blog_app/app/domains/post_management/setup.rb
237
+ - examples/blog_app/app/domains/user_management/events/user_created_event.rb
238
+ - examples/blog_app/app/domains/user_management/events/user_deleted_event.rb
239
+ - examples/blog_app/app/domains/user_management/events/user_updated_event.rb
240
+ - examples/blog_app/app/domains/user_management/handlers/user_welcome_handler.rb
241
+ - examples/blog_app/app/domains/user_management/models/user.rb
242
+ - examples/blog_app/app/domains/user_management/policies/user_policy.rb
243
+ - examples/blog_app/app/domains/user_management/setup.rb
244
+ - examples/blog_app/app/domains/user_management/user_service.rb
245
+ - examples/blog_app/app/events/.keep
246
+ - examples/blog_app/app/events/application_event.rb
247
+ - examples/blog_app/app/handlers/.keep
248
+ - examples/blog_app/app/helpers/application_helper.rb
249
+ - examples/blog_app/app/javascript/application.js
250
+ - examples/blog_app/app/javascript/controllers/application.js
251
+ - examples/blog_app/app/javascript/controllers/hello_controller.js
252
+ - examples/blog_app/app/javascript/controllers/index.js
253
+ - examples/blog_app/app/jobs/application_job.rb
254
+ - examples/blog_app/app/mailers/application_mailer.rb
255
+ - examples/blog_app/app/models/application_record.rb
256
+ - examples/blog_app/app/models/concerns/.keep
257
+ - examples/blog_app/app/models/organization.rb
258
+ - examples/blog_app/app/policies/.keep
259
+ - examples/blog_app/app/policies/application_policy.rb
260
+ - examples/blog_app/app/services/.keep
261
+ - examples/blog_app/app/services/application_service.rb
262
+ - examples/blog_app/app/views/layouts/application.html.erb
263
+ - examples/blog_app/app/views/layouts/mailer.html.erb
264
+ - examples/blog_app/app/views/layouts/mailer.text.erb
265
+ - examples/blog_app/app/views/pwa/manifest.json.erb
266
+ - examples/blog_app/app/views/pwa/service-worker.js
267
+ - examples/blog_app/bin/brakeman
268
+ - examples/blog_app/bin/bundler-audit
269
+ - examples/blog_app/bin/ci
270
+ - examples/blog_app/bin/dev
271
+ - examples/blog_app/bin/docker-entrypoint
272
+ - examples/blog_app/bin/importmap
273
+ - examples/blog_app/bin/jobs
274
+ - examples/blog_app/bin/kamal
275
+ - examples/blog_app/bin/rails
276
+ - examples/blog_app/bin/rake
277
+ - examples/blog_app/bin/rubocop
278
+ - examples/blog_app/bin/setup
279
+ - examples/blog_app/bin/thrust
280
+ - examples/blog_app/config.ru
281
+ - examples/blog_app/config/application.rb
282
+ - examples/blog_app/config/boot.rb
283
+ - examples/blog_app/config/bundler-audit.yml
284
+ - examples/blog_app/config/cable.yml
285
+ - examples/blog_app/config/cache.yml
286
+ - examples/blog_app/config/ci.rb
287
+ - examples/blog_app/config/credentials.yml.enc
288
+ - examples/blog_app/config/database.yml
289
+ - examples/blog_app/config/deploy.yml
290
+ - examples/blog_app/config/environment.rb
291
+ - examples/blog_app/config/environments/development.rb
292
+ - examples/blog_app/config/environments/production.rb
293
+ - examples/blog_app/config/environments/test.rb
294
+ - examples/blog_app/config/importmap.rb
295
+ - examples/blog_app/config/initializers/active_domain.rb
296
+ - examples/blog_app/config/initializers/assets.rb
297
+ - examples/blog_app/config/initializers/content_security_policy.rb
298
+ - examples/blog_app/config/initializers/filter_parameter_logging.rb
299
+ - examples/blog_app/config/initializers/inflections.rb
300
+ - examples/blog_app/config/locales/en.yml
301
+ - examples/blog_app/config/master.key
302
+ - examples/blog_app/config/puma.rb
303
+ - examples/blog_app/config/queue.yml
304
+ - examples/blog_app/config/recurring.yml
305
+ - examples/blog_app/config/routes.rb
306
+ - examples/blog_app/config/storage.yml
307
+ - examples/blog_app/db/cable_schema.rb
308
+ - examples/blog_app/db/cache_schema.rb
309
+ - examples/blog_app/db/migrate/20251230112502_create_organizations.rb
310
+ - examples/blog_app/db/migrate/20251230112503_create_users.rb
311
+ - examples/blog_app/db/migrate/20251230112504_create_posts.rb
312
+ - examples/blog_app/db/queue_schema.rb
313
+ - examples/blog_app/db/schema.rb
314
+ - examples/blog_app/db/seeds.rb
315
+ - examples/blog_app/lib/api_demo.rb
316
+ - examples/blog_app/lib/demo.rb
317
+ - examples/blog_app/lib/tasks/.keep
318
+ - examples/blog_app/log/.keep
319
+ - examples/blog_app/public/400.html
320
+ - examples/blog_app/public/404.html
321
+ - examples/blog_app/public/406-unsupported-browser.html
322
+ - examples/blog_app/public/422.html
323
+ - examples/blog_app/public/500.html
324
+ - examples/blog_app/public/icon.png
325
+ - examples/blog_app/public/icon.svg
326
+ - examples/blog_app/public/robots.txt
327
+ - examples/blog_app/script/.keep
328
+ - examples/blog_app/storage/.keep
329
+ - examples/blog_app/tmp/.keep
330
+ - examples/blog_app/vendor/.keep
331
+ - examples/blog_app/vendor/javascript/.keep
332
+ - lib/generators/active_domain/domain/domain_generator.rb
333
+ - lib/generators/active_domain/domain/templates/events/created_event.rb.tt
334
+ - lib/generators/active_domain/domain/templates/events/deleted_event.rb.tt
335
+ - lib/generators/active_domain/domain/templates/events/updated_event.rb.tt
336
+ - lib/generators/active_domain/domain/templates/policy.rb.tt
337
+ - lib/generators/active_domain/domain/templates/service.rb.tt
338
+ - lib/generators/active_domain/domain/templates/setup.rb.tt
339
+ - lib/generators/active_domain/install/install_generator.rb
340
+ - lib/generators/active_domain/install/templates/README
341
+ - lib/generators/active_domain/install/templates/application_event.rb
342
+ - lib/generators/active_domain/install/templates/application_policy.rb
343
+ - lib/generators/active_domain/install/templates/application_service.rb
344
+ - lib/generators/active_domain/install/templates/initializer.rb
345
+ - lib/smart_domain.rb
346
+ - lib/smart_domain/configuration.rb
347
+ - lib/smart_domain/domain/exceptions.rb
348
+ - lib/smart_domain/domain/policy.rb
349
+ - lib/smart_domain/domain/service.rb
350
+ - lib/smart_domain/event/adapters/memory.rb
351
+ - lib/smart_domain/event/base.rb
352
+ - lib/smart_domain/event/handler.rb
353
+ - lib/smart_domain/event/mixins.rb
354
+ - lib/smart_domain/event/registration.rb
355
+ - lib/smart_domain/generators/domain_generator.rb
356
+ - lib/smart_domain/generators/install_generator.rb
357
+ - lib/smart_domain/handlers/audit_handler.rb
358
+ - lib/smart_domain/handlers/metrics_handler.rb
359
+ - lib/smart_domain/integration/active_record.rb
360
+ - lib/smart_domain/integration/multi_tenancy.rb
361
+ - lib/smart_domain/railtie.rb
362
+ - lib/smart_domain/tasks/domains.rake
363
+ - lib/smart_domain/version.rb
364
+ - smart_domain.gemspec
365
+ homepage: https://github.com/rachid/smart_domain
366
+ licenses:
367
+ - MIT
368
+ metadata:
369
+ homepage_uri: https://github.com/rachid/smart_domain
370
+ source_code_uri: https://github.com/rachid/smart_domain
371
+ changelog_uri: https://github.com/rachid/smart_domain/blob/main/CHANGELOG.md
372
+ post_install_message:
373
+ rdoc_options: []
374
+ require_paths:
375
+ - lib
376
+ required_ruby_version: !ruby/object:Gem::Requirement
377
+ requirements:
378
+ - - ">="
379
+ - !ruby/object:Gem::Version
380
+ version: 3.0.0
381
+ required_rubygems_version: !ruby/object:Gem::Requirement
382
+ requirements:
383
+ - - ">="
384
+ - !ruby/object:Gem::Version
385
+ version: '0'
386
+ requirements: []
387
+ rubygems_version: 3.5.22
388
+ signing_key:
389
+ specification_version: 4
390
+ summary: Smart Domain-Driven Design and Event-Driven Architecture for Rails
391
+ test_files: []