servus 0.3.0 → 0.4.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 (132) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/servus/event_handler/event_handler_generator.rb +1 -1
  3. data/lib/generators/servus/guard/guard_generator.rb +1 -1
  4. data/lib/generators/servus/guard/templates/guard.rb.erb +5 -3
  5. data/lib/generators/servus/service/service_generator.rb +1 -1
  6. data/lib/servus/base.rb +46 -3
  7. data/lib/servus/config.rb +71 -3
  8. data/lib/servus/events/bus.rb +29 -0
  9. data/lib/servus/events/emitter.rb +15 -0
  10. data/lib/servus/guard.rb +7 -6
  11. data/lib/servus/guards/falsey_guard.rb +3 -3
  12. data/lib/servus/guards/presence_guard.rb +4 -4
  13. data/lib/servus/guards/state_guard.rb +4 -5
  14. data/lib/servus/guards/truthy_guard.rb +3 -3
  15. data/lib/servus/helpers/controller_helpers.rb +40 -0
  16. data/lib/servus/support/errors.rb +16 -0
  17. data/lib/servus/support/lockdown.rb +94 -0
  18. data/lib/servus/support/logger.rb +16 -0
  19. data/lib/servus/support/validator.rb +65 -34
  20. data/lib/servus/testing/example_builders.rb +52 -0
  21. data/lib/servus/testing/matchers.rb +99 -0
  22. data/lib/servus/version.rb +1 -1
  23. data/lib/servus.rb +1 -0
  24. metadata +7 -111
  25. data/.claude/commands/check-docs.md +0 -1
  26. data/.claude/commands/consistency-check.md +0 -1
  27. data/.claude/commands/fine-tooth-comb.md +0 -1
  28. data/.claude/commands/red-green-refactor.md +0 -5
  29. data/.claude/settings.json +0 -24
  30. data/.rspec +0 -3
  31. data/.rubocop.yml +0 -27
  32. data/.yardopts +0 -6
  33. data/CHANGELOG.md +0 -169
  34. data/CLAUDE.md +0 -10
  35. data/IDEAS.md +0 -5
  36. data/LICENSE.txt +0 -21
  37. data/READme.md +0 -856
  38. data/Rakefile +0 -45
  39. data/docs/core/1_overview.md +0 -81
  40. data/docs/core/2_architecture.md +0 -120
  41. data/docs/core/3_service_objects.md +0 -154
  42. data/docs/features/1_schema_validation.md +0 -161
  43. data/docs/features/2_error_handling.md +0 -129
  44. data/docs/features/3_async_execution.md +0 -81
  45. data/docs/features/4_logging.md +0 -64
  46. data/docs/features/5_event_bus.md +0 -244
  47. data/docs/features/6_guards.md +0 -356
  48. data/docs/features/7_lazy_resolvers.md +0 -238
  49. data/docs/features/guards_naming_convention.md +0 -540
  50. data/docs/guides/1_common_patterns.md +0 -90
  51. data/docs/guides/2_migration_guide.md +0 -225
  52. data/docs/integration/1_configuration.md +0 -154
  53. data/docs/integration/2_testing.md +0 -304
  54. data/docs/integration/3_rails_integration.md +0 -99
  55. data/docs/yard/Servus/Base.html +0 -1645
  56. data/docs/yard/Servus/Config.html +0 -582
  57. data/docs/yard/Servus/Extensions/Async/Call.html +0 -400
  58. data/docs/yard/Servus/Extensions/Async/Errors/AsyncError.html +0 -140
  59. data/docs/yard/Servus/Extensions/Async/Errors/JobEnqueueError.html +0 -154
  60. data/docs/yard/Servus/Extensions/Async/Errors/ServiceNotFoundError.html +0 -154
  61. data/docs/yard/Servus/Extensions/Async/Errors.html +0 -128
  62. data/docs/yard/Servus/Extensions/Async/Ext.html +0 -119
  63. data/docs/yard/Servus/Extensions/Async/Job.html +0 -310
  64. data/docs/yard/Servus/Extensions/Async.html +0 -141
  65. data/docs/yard/Servus/Extensions.html +0 -117
  66. data/docs/yard/Servus/Generators/ServiceGenerator.html +0 -261
  67. data/docs/yard/Servus/Generators.html +0 -115
  68. data/docs/yard/Servus/Helpers/ControllerHelpers.html +0 -457
  69. data/docs/yard/Servus/Helpers.html +0 -115
  70. data/docs/yard/Servus/Railtie.html +0 -134
  71. data/docs/yard/Servus/Support/Errors/AuthenticationError.html +0 -287
  72. data/docs/yard/Servus/Support/Errors/BadRequestError.html +0 -283
  73. data/docs/yard/Servus/Support/Errors/ForbiddenError.html +0 -284
  74. data/docs/yard/Servus/Support/Errors/InternalServerError.html +0 -283
  75. data/docs/yard/Servus/Support/Errors/NotFoundError.html +0 -284
  76. data/docs/yard/Servus/Support/Errors/ServiceError.html +0 -489
  77. data/docs/yard/Servus/Support/Errors/ServiceUnavailableError.html +0 -290
  78. data/docs/yard/Servus/Support/Errors/UnauthorizedError.html +0 -200
  79. data/docs/yard/Servus/Support/Errors/UnprocessableEntityError.html +0 -288
  80. data/docs/yard/Servus/Support/Errors/ValidationError.html +0 -200
  81. data/docs/yard/Servus/Support/Errors.html +0 -140
  82. data/docs/yard/Servus/Support/Logger.html +0 -856
  83. data/docs/yard/Servus/Support/Rescuer/BlockContext.html +0 -585
  84. data/docs/yard/Servus/Support/Rescuer/CallOverride.html +0 -257
  85. data/docs/yard/Servus/Support/Rescuer/ClassMethods.html +0 -343
  86. data/docs/yard/Servus/Support/Rescuer.html +0 -267
  87. data/docs/yard/Servus/Support/Response.html +0 -574
  88. data/docs/yard/Servus/Support/Validator.html +0 -1150
  89. data/docs/yard/Servus/Support.html +0 -119
  90. data/docs/yard/Servus/Testing/ExampleBuilders.html +0 -523
  91. data/docs/yard/Servus/Testing/ExampleExtractor.html +0 -578
  92. data/docs/yard/Servus/Testing.html +0 -142
  93. data/docs/yard/Servus.html +0 -343
  94. data/docs/yard/_index.html +0 -535
  95. data/docs/yard/class_list.html +0 -54
  96. data/docs/yard/css/common.css +0 -1
  97. data/docs/yard/css/full_list.css +0 -58
  98. data/docs/yard/css/style.css +0 -503
  99. data/docs/yard/file.1_common_patterns.html +0 -154
  100. data/docs/yard/file.1_configuration.html +0 -115
  101. data/docs/yard/file.1_overview.html +0 -142
  102. data/docs/yard/file.1_schema_validation.html +0 -188
  103. data/docs/yard/file.2_architecture.html +0 -157
  104. data/docs/yard/file.2_error_handling.html +0 -190
  105. data/docs/yard/file.2_migration_guide.html +0 -242
  106. data/docs/yard/file.2_testing.html +0 -227
  107. data/docs/yard/file.3_async_execution.html +0 -145
  108. data/docs/yard/file.3_rails_integration.html +0 -160
  109. data/docs/yard/file.3_service_objects.html +0 -191
  110. data/docs/yard/file.4_logging.html +0 -135
  111. data/docs/yard/file.ErrorHandling.html +0 -190
  112. data/docs/yard/file.READme.html +0 -674
  113. data/docs/yard/file.architecture.html +0 -157
  114. data/docs/yard/file.async_execution.html +0 -145
  115. data/docs/yard/file.common_patterns.html +0 -154
  116. data/docs/yard/file.configuration.html +0 -115
  117. data/docs/yard/file.error_handling.html +0 -190
  118. data/docs/yard/file.logging.html +0 -135
  119. data/docs/yard/file.migration_guide.html +0 -242
  120. data/docs/yard/file.overview.html +0 -142
  121. data/docs/yard/file.rails_integration.html +0 -160
  122. data/docs/yard/file.schema_validation.html +0 -188
  123. data/docs/yard/file.service_objects.html +0 -191
  124. data/docs/yard/file.testing.html +0 -227
  125. data/docs/yard/file_list.html +0 -119
  126. data/docs/yard/frames.html +0 -22
  127. data/docs/yard/index.html +0 -674
  128. data/docs/yard/js/app.js +0 -344
  129. data/docs/yard/js/full_list.js +0 -242
  130. data/docs/yard/js/jquery.js +0 -4
  131. data/docs/yard/method_list.html +0 -542
  132. data/docs/yard/top-level-namespace.html +0 -110
data/CHANGELOG.md DELETED
@@ -1,169 +0,0 @@
1
- ## [0.3.0] - 2026-04-03
2
-
3
- ### Breaking Changes
4
-
5
- - **Failure responses can now carry data**: `failure()` accepts an optional `data:` kwarg. Previously,
6
- `result.data` was guaranteed to be `nil` on failure. Code that checks `result.data` for truthiness
7
- to determine success/failure must switch to `result.success?` or `result.failure?`.
8
- See the [Migration Guide](docs/guides/2_migration_guide.md#migrating-to-030) for details.
9
- - **`Response#with_data` removed**: Replaced by the `data:` kwarg on `failure()`. The `with_data` method
10
- allowed arbitrary mutation of responses after creation, bypassing schema validation.
11
-
12
- ### Added
13
-
14
- - **`lazily` resolver DSL**: Declare lazy record resolvers on services with `lazily :user, finds: User`.
15
- Accepts either an ID or an already-loaded instance — resolves on first access, memoizes the result.
16
- Supports custom columns (`by: :uuid`), array input (via `.where`), and dry-initializer compatibility.
17
- Loaded as an extension via Railtie when ActiveRecord is present.
18
- - **Failure data support**: `failure()` accepts an optional `data:` keyword argument for attaching
19
- structured data to failure responses (e.g., `failure("Declined", data: { reason: "insufficient_funds" })`).
20
- Defaults to `nil` for backwards compatibility with services that don't use it.
21
- - **Failure schema validation**: Define a `failure` schema via the `schema` DSL, `FAILURE_SCHEMA` constant,
22
- or `failure.json` file. When present, failure response data is validated against it — just like success
23
- results are validated against `result` schemas.
24
- - **`servus_failure_example` test helper**: Extracts example values from a service's `failure` schema,
25
- returning a failure `Response` for use in tests.
26
- - **`failure?` predicate on Response**: Complement to `success?` for cleaner conditional handling.
27
- - **`DataObject` wrapper for response data**: Hash data returned by services is wrapped in a read-only
28
- `DataObject` that supports accessor-style access (`result.data.user.email`) alongside bracket access
29
- (`result.data[:user]`). Nested Hashes and Hashes inside Arrays are recursively wrapped. Non-Hash values
30
- (models, nil) pass through unwrapped.
31
-
32
- ## [0.2.1] - 2025-12-20
33
-
34
- ### Added
35
-
36
- - **EventHandler Scheduling Options**: Extended the `invoke` DSL to support ActiveJob scheduling options
37
- - `:wait` - delay execution (e.g., `5.minutes`)
38
- - `:wait_until` - schedule for specific time
39
- - `:priority` - job priority
40
- - `:job_options` - additional ActiveJob options
41
- - Options are passed through to `call_async`, enabling delayed and scheduled event handling
42
-
43
- - **Custom HTTP Error Classes**: Added granular error classes for HTTP status handling
44
- - Error classes for common HTTP statuses (400, 401, 403, 404, 409, 422, 429, 500, 502, 503, 504)
45
- - Each error class has appropriate `http_status` and default `code`/`message`
46
- - Enables more precise error handling and cleaner rescue blocks
47
-
48
- ## [0.2.0] - 2025-12-16
49
-
50
- ### Added
51
-
52
- - **Guards System**: Reusable validation rules with rich error responses
53
- - `Servus::Guard` base class for creating custom guards
54
- - `Servus::Guards` module included in services with `enforce_*!` and `check_*?` methods
55
- - Built-in guards:
56
- - `PresenceGuard` - validates values are present (not nil or empty)
57
- - `TruthyGuard` - validates object attributes are truthy
58
- - `FalseyGuard` - validates object attributes are falsey
59
- - `StateGuard` - validates object attributes match expected value(s)
60
- - Guards auto-define methods when classes inherit from `Servus::Guard`
61
- - Guard DSL: `http_status`, `error_code`, `message` with interpolation support
62
- - Multiple message template formats: String, I18n Symbol, inline Hash, Proc
63
- - Rails auto-loading from `app/guards/*_guard.rb`
64
- - Configuration options: `guards_dir`, `include_default_guards`
65
-
66
- - **GuardError**: New error class for guard validation failures
67
- - Custom `code` and `http_status` per guard
68
- - Services catch `:guard_failure` and wrap in failure response automatically
69
-
70
- ### Changed
71
-
72
- - **Error API Refactored**: Cleaner separation of HTTP status and error body
73
- - All errors now have `http_status` method returning Rails status symbol
74
- - `api_error` returns `{ code:, message: }` for response body only
75
- - Follows community conventions (Stripe, JSON:API) where HTTP status is in header
76
-
77
- - **Controller Helpers Refactored**:
78
- - Renamed `render_service_object_error` to `render_service_error`
79
- - Now takes error object directly instead of `api_error` hash
80
- - Response format: `{ error: { code:, message: } }` with status from `error.http_status`
81
-
82
- ### Breaking Changes
83
-
84
- - `render_service_object_error` renamed to `render_service_error`
85
- - `render_service_error` now accepts error object, not hash: `render_service_error(result.error)` instead of `render_service_error(result.error.api_error)`
86
- - Error response JSON structure changed from `{ code:, message: }` to `{ error: { code:, message: } }`
87
-
88
- ## [0.1.6] - 2025-12-06
89
-
90
- ### Fixed
91
-
92
- - Make `emit_events_for` public in `Servus::Events::Emitter` to allow external event emission
93
-
94
- ## [0.1.5] - 2025-12-03
95
-
96
- ### Added
97
-
98
- - **Event Bus Architecture**: Introduced event-driven architecture for decoupling service logic from side effects
99
- - `Servus::EventHandler` base class for creating event handlers that subscribe to events and invoke services
100
- - `emits` DSL on `Servus::Base` for declaring events that fire on `:success`, `:failure`, or `:error!`
101
- - `Servus::Events::Bus` for routing events to handlers via ActiveSupport::Notifications
102
- - Rails generator: `rails g servus:event_handler event_name` creates handler and spec files
103
- - Event handlers auto-load from `app/events/` directory in Rails applications
104
-
105
- - **Event Payload Validation**: JSON Schema validation for event payloads
106
- - `schema payload: {...}` DSL on EventHandler for declaring payload schemas
107
- - Validation occurs when events are emitted via `EventHandler.emit(payload)`
108
-
109
- - **Event Testing Matchers**: RSpec matchers for testing event emission
110
- - `emit_event(:event_name)` matcher to assert events are emitted
111
- - `emit_event(:event_name).with(payload)` for payload assertions
112
- - `call_service(ServiceClass).with(args)` matcher for handler testing
113
- - `call_service(ServiceClass).async` for async invocation testing
114
-
115
- - **Configuration Options**: New and updated configuration settings
116
- - `config.schemas_dir` - Directory for JSON schema files (default: `app/schemas`)
117
- - `config.services_dir` - Directory for service files (default: `app/services`)
118
- - `config.events_dir` - Directory for event handlers (default: `app/events`)
119
- - `config.strict_event_validation` - Validate handlers subscribe to emitted events (default: `true`)
120
- - `Servus::EventHandler.validate_all_handlers!` for CI validation of handler-event mappings
121
-
122
- - **Generator Improvements**: Enhanced service and event handler generators
123
- - Service templates now include comprehensive YARD documentation
124
- - Service spec templates include example test patterns
125
- - JSON schema templates include proper structure with `$schema` reference
126
- - Event handler templates include full documentation and examples
127
- - `--no-docs` flag to skip documentation comments in generated files
128
-
129
- ### Changed
130
-
131
- - Updated execution flow to include event emission after result validation
132
- - Enhanced Railtie to auto-load event handlers and clear the event bus on reload in development
133
-
134
- ## [0.1.4] - 2025-11-21
135
-
136
- ### Added
137
-
138
- - **Schema DSL method**: `schema arguments: {...}, result: {...}` syntax for cleaner schema definition.
139
- Fully backwards compatible with existing `ARGUMENTS_SCHEMA` and `RESULT_SCHEMA` constants.
140
- - **Test helpers**: `servus_arguments_example` and `servus_result_example` for extracting example values
141
- from schemas in tests
142
- - **`rescue_from` block support**: Override the default failure handler with a custom block
143
- - **YARD documentation**: Configuration with README homepage and markdown file support
144
-
145
- ### Fixed
146
-
147
- - YARD link resolution warnings in documentation
148
-
149
- ## [0.1.3] - 2025-10-10
150
-
151
- ### Added
152
-
153
- - **`call_async`**: Enqueue service calls as background jobs via ActiveJob
154
- - **`Async::Job`**: Job class for async enqueueing with support for ActiveJob `set` options
155
-
156
- ## [0.1.1] - 2025-08-20
157
-
158
- ### Added
159
-
160
- - **`rescue_from`**: Rescue from standard errors and convert them to failure responses with custom error types
161
- - **Controller helpers**: `run_service` and `render_service_object_error` in `Servus::Helpers::ControllerHelpers`
162
-
163
- ### Fixed
164
-
165
- - All rubocop warnings
166
-
167
- ## [0.1.0] - 2025-04-28
168
-
169
- - Initial release
data/CLAUDE.md DELETED
@@ -1,10 +0,0 @@
1
- Before starting a session, always review the latest docs in the following order:
2
-
3
- 1. `/docs/core/**/*.md`
4
- 2. `/docs/features/**/*.md`
5
- 3. `/docs/guides/**/*.md`
6
- 4. `/docs/integration/**/*.md`
7
-
8
- Focus on writing code consistent with the rest of the project. Use existing files as references for conventions and style.
9
-
10
- Ensure new code always encludes world class YARD documentation. If documentation looks out of date or incomplete, suggest a relevant edit.
data/IDEAS.md DELETED
@@ -1,5 +0,0 @@
1
- 1. Make sure Async Jobs don't retry when the job class cant be constantized.
2
-
3
- 2. Improve error handling with an error registry that can be referenced by codes as opposed to fully qualified class names.
4
-
5
- 3. Update generators to not make schema files and instead add schemas to schema: method in generators.
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2025 Sebastian Scholl
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
13
- all 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
21
- THE SOFTWARE.