u-case 5.4.0 → 5.6.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/CLAUDE.md +11 -2
- data/README.md +567 -2
- data/README.pt-BR.md +585 -2
- data/lib/micro/case/check.rb +104 -0
- data/lib/micro/case/config.rb +16 -0
- data/lib/micro/case/error.rb +24 -1
- data/lib/micro/case/result/contract.rb +60 -0
- data/lib/micro/case/version.rb +1 -1
- data/lib/micro/case.rb +72 -11
- data/lib/micro/cases/error.rb +9 -0
- data/lib/micro/cases/flow.rb +46 -8
- data/lib/micro/cases.rb +12 -4
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5539d3b5cac24a50728c4dd8285e2f36c4a155f344a5f95763b8b02afaa64505
|
|
4
|
+
data.tar.gz: 794905f57057a6f198200bbd2b5c3c958440b3fa3154366a636025553a084553
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fc924d76d4e1dbc1dc1a2567688a881a17b726b74210ad57277af2fdd7456e02358501d2f34171d0a027227f5e99a2853aad82f64bca2007e18fefc518e3e622
|
|
7
|
+
data.tar.gz: e20f832a0b48456a653e48710c2444c8649dce2a68477c4299b856b23939074d01457215e6c3290c1e417cd38724318289f27055505d1b2865b90ca4c15fee0d
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
> **Note:** This gem was originally published as `u-service` (versions 0.1.0 – 1.0.0) and renamed to `u-case` starting with `u-case 1.0.0` on 2019-09-15.
|
|
9
9
|
|
|
10
|
+
## [5.6.0] - 2026-05-24
|
|
11
|
+
### Added
|
|
12
|
+
- `Micro::Cases.flow(transaction: true, steps: [...])` and `Micro::Cases.safe_flow(transaction: true, steps: [...])` to wrap an entire flow in an `ActiveRecord::Base.transaction`. Any step that returns a failure (or, in `safe_flow`, raises) triggers an `ActiveRecord::Rollback`. The same kwargs are accepted by the class-level macro: `class MyCase < Micro::Case; flow(transaction: true, steps: [...]); end` (closes #44).
|
|
13
|
+
- `Micro::Cases::Error::TransactionAdapterMissing`, raised on the first call when `transaction: true` is used without `ActiveRecord::Base` loaded. The gem still does **not** require `active_record` automatically — applications must load it themselves.
|
|
14
|
+
- Three new methods on `Micro::Case::Check` — `flow_steps_kwarg!`, `transaction_kwarg!` and `activerecord_loaded!` — so the transaction-flow validation participates in `config.disable_runtime_checks = true`. All inline `raise ArgumentError` / `raise Error::TransactionAdapterMissing` sites in `lib/micro/cases.rb`, `lib/micro/case.rb` and `lib/micro/cases/flow.rb` now route through `Micro::Case.check`, matching the convention introduced in 5.4.0.
|
|
15
|
+
- Multi-database support for transactions. Use cases can declare which ActiveRecord class should own their transactions with the new `transaction with: SomeRecord` class macro (inherited like `flow` / `attributes`); the inline `Micro::Case#transaction(with:)` helper and the flow-level `transaction: { with: SomeRecord }` kwarg share the same `with:` vocabulary. `transaction: true` remains the "use the default" shortcut. A new `Micro::Case.config.default_transaction_class { ApplicationRecord }` callback (block or lambda) lets Rails apps configure the abstract record once in an initializer; the default is `-> { ::ActiveRecord::Base }`. Two new checks (`transaction_owner!`, `transaction_class_callback!`) route the new validations through `Micro::Case::Check`. Resolution order at transaction-open time: call-site `with:` override > host case's `transaction with:` macro > global callback.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
- `Micro::Case#transaction` instance helper signature changed from `transaction(adapter = :activerecord)` to `transaction(adapter = nil, with: nil)`. The pre-5.6.0 form `transaction(:activerecord) { ... }` keeps working as an alias for `transaction { ... }`; any other positional value raises `ArgumentError` (the legacy helper only accepted `:activerecord`).
|
|
19
|
+
- Transaction owners (`with:` on the inline helper, on the class macro, and on the flow `transaction:` kwarg) must be subclasses of `ActiveRecord::Base`. Non-AR classes are rejected with `ArgumentError` — the gem's rollback signaling hardcodes `ActiveRecord::Rollback`, so non-AR transaction objects (Sequel, custom adapters) are explicitly out of scope. The class-macro validation runs at class-eval time when AR is already loaded; otherwise it defers to runtime so initializer load order doesn't break declarations.
|
|
20
|
+
- `Micro::Cases.flow([], steps: [...])` and `safe_flow([], steps: [...])` now treat an empty positional array as "no positional collection" instead of raising the "both provided" error.
|
|
21
|
+
- `Check::Disabled#transaction_kwarg!` now returns `nil` (no transaction) for unrecognized inputs instead of silently coercing them to `true`. A typo under `disable_runtime_checks = true` therefore stays non-transactional rather than upgrading to a real transaction against the default class.
|
|
22
|
+
- READMEs (EN + pt-BR) now document `Micro::Case#transaction` (the inline `transaction { ... }` helper available inside `call!`) and the new flow-level `transaction:` kwarg, including behavior notes for nested transactions (AR-joined semantics), the `Flow`-instance flattening footgun, and the difference between plain and safe transactional flows on exceptions.
|
|
23
|
+
- READMEs (EN + pt-BR) now describe **internal steps** — `Result#then(:symbol)` / `Result#then(method(:name))` / `Result#then(-> { })` / `|` — as u-case's third way of composing a flow, alongside `Micro::Cases.flow` and the class-level `flow` macro. The new section spells out the data-flow contract (each link's `Success` result becomes the next link's kwargs), the transition recording behavior, and the fact that internal steps are fully composable inside outer flows and transactional flows.
|
|
24
|
+
- Transaction composition matrix test suite (`test/micro/cases/flow/transaction_composition_matrix_test.rb`) crossing all 8 wrappers (4 non-tx × 4 tx) at level 1 and level 2 of nesting, plus deep-rollback cases, behavioral parity assertions (tx vs non-tx `result.data` / `transitions` / `accessible_attributes` are equal), and `Result#then` accumulation across a tx boundary.
|
|
25
|
+
- Internal-steps-in-flows test suite (`test/micro/cases/flow/internal_steps_in_flows_test.rb`) that drops symbol-, method- and lambda-based internal-step use cases into every flow wrapper (non-tx and tx) and asserts behavioral parity with the leaf-pair equivalent: accumulated `result.data`, total transition count (3 internal + 3 outer = 6 for a 5-step chain), interleaved transition order, and rollback of internal-step database writes when a `Failure` is returned from inside the internal chain under a transactional outer flow.
|
|
26
|
+
|
|
27
|
+
## [5.5.0] - 2026-05-24
|
|
28
|
+
### Added
|
|
29
|
+
- `Micro::Case.results { |on| ... }` macro to declare a results contract — the allowed `Success`/`Failure` types and the result keys each one requires. `Success(...)` / `Failure(...)` calls that use an undeclared type now raise `Micro::Case::Error::UnexpectedResultType`; calls missing a declared required key raise `Micro::Case::Error::MissingResultKeys`. Use cases without a `results` block keep their previous unrestricted behavior. The check routes through `Micro::Case::Check#results_contract!`, so it is also bypassed when `config.disable_runtime_checks = true` (closes #22). Carve-outs so contracts don't break neighbouring features:
|
|
30
|
+
- Framework-generated `__failure_from_attributes_errors` (the auto-failure produced when `accept:`/`reject:` or ActiveModel validation rejects an input) bypasses the contract — it goes directly to `__set__` rather than through `Failure(...)` — so combining `results` with attribute validation no longer requires declaring `:invalid_attributes`.
|
|
31
|
+
- Rescued exceptions in `Micro::Case::Safe` (which produce `Failure(result: exception)`) bypass the contract.
|
|
32
|
+
- Result hashes with `String` keys are matched against the contract's symbolised required keys — `Success(result: { 'value' => 1 })` satisfies `result: [:value]`, mirroring `Result`'s own tolerance for either key type.
|
|
33
|
+
- Non-`Hash` / non-`Symbol` `result:` arguments fall through to the existing `Micro::Case::Error::InvalidResult` ("must be a Hash") instead of being misreported as missing keys.
|
|
34
|
+
- Non-`Symbol` `type` arguments fall through to `Micro::Case::Error::InvalidResultType` instead of being misreported as undeclared.
|
|
35
|
+
- `Micro::Case.results` raises `ArgumentError` when called on the abstract base class itself, so a stray declaration cannot leak a contract to every subclass in the process.
|
|
36
|
+
|
|
10
37
|
## [5.4.0] - 2026-05-24
|
|
11
38
|
### Added
|
|
12
39
|
- `Micro::Case.config.disable_runtime_checks` config (default `false`) to skip the gem's internal argument/contract checks for better performance in production. All checks are consolidated in `Micro::Case::Check::Enabled` (the default) and `Micro::Case::Check::Disabled` (no-ops with the same signature); the active module is swapped via `Micro::Case.check`. Measured throughput win is JIT-dependent: within noise on stock Ruby (no JIT), ~3–5% on Ruby 3.2 +YJIT, ~4–7% on Ruby 4.0 +PRISM (see `benchmarks/perfomance/runtime_checks/compare.rb`). Closes #45.
|
|
@@ -468,6 +495,8 @@ First release under the `u-case` name (renamed from `u-service`).
|
|
|
468
495
|
- `Micro::Service::Result` with `Success`/`Failure` factories and helper methods for returning typed results from services.
|
|
469
496
|
- Runtime dependency on `u-attributes` for service input declaration.
|
|
470
497
|
|
|
498
|
+
[5.6.0]: https://github.com/serradura/u-case/compare/v5.5.0...v5.6.0
|
|
499
|
+
[5.5.0]: https://github.com/serradura/u-case/compare/v5.4.0...v5.5.0
|
|
471
500
|
[5.4.0]: https://github.com/serradura/u-case/compare/v5.3.1...v5.4.0
|
|
472
501
|
[5.3.1]: https://github.com/serradura/u-case/compare/v5.3.0...v5.3.1
|
|
473
502
|
[5.3.0]: https://github.com/serradura/u-case/compare/v5.2.1...v5.3.0
|
data/CLAUDE.md
CHANGED
|
@@ -90,8 +90,17 @@ Both files are user-facing — keep them in sync with the code:
|
|
|
90
90
|
- **`README.md` and `README.pt-BR.md`**: the **Documentation** table and the
|
|
91
91
|
**Compatibility** table at the top reference the latest released version
|
|
92
92
|
and its dependency bounds. Update both files together — they are
|
|
93
|
-
translations of each other and must stay in lockstep.
|
|
94
|
-
|
|
93
|
+
translations of each other and must stay in lockstep. Any user-visible
|
|
94
|
+
API change requires a README update in the same commit:
|
|
95
|
+
- **New public API** (new macro, new module-level method, new public
|
|
96
|
+
instance method, new error class users can rescue, new config option) —
|
|
97
|
+
add or extend the relevant section in both READMEs with an example.
|
|
98
|
+
- **Changed documented API** — update the existing section in both
|
|
99
|
+
READMEs to match the new behavior.
|
|
100
|
+
- **Removed/deprecated API** — remove or mark the section in both
|
|
101
|
+
READMEs.
|
|
102
|
+
- Pure internal refactors, CI tweaks, and test-only changes don't need
|
|
103
|
+
README updates.
|
|
95
104
|
|
|
96
105
|
## Internal argument checks live in `Micro::Case::Check`
|
|
97
106
|
|